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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1256) hide show
  1. package/CHANGELOG.md +5992 -82
  2. package/COMPARISON.md +168 -63
  3. package/CONTRIBUTING.md +121 -0
  4. package/MIGRATING-from-OpenSpec.md +238 -55
  5. package/QUICKSTART.md +302 -0
  6. package/README.md +653 -144
  7. package/ROADMAP.md +1035 -0
  8. package/SCHEMA.md +3916 -263
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +927 -0
  11. package/dist/cli.js +133 -21
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +204 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +309 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +74 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/closing.js +42 -0
  20. package/dist/commands/archive/closing.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
  22. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  24. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  25. package/dist/commands/archive/plan/contracts/openapi.js +193 -0
  26. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  28. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  29. package/dist/commands/archive/plan/document/head.js +151 -0
  30. package/dist/commands/archive/plan/document/head.js.map +1 -0
  31. package/dist/commands/archive/plan/document/links.js +284 -0
  32. package/dist/commands/archive/plan/document/links.js.map +1 -0
  33. package/dist/commands/archive/plan/document/run.js +136 -0
  34. package/dist/commands/archive/plan/document/run.js.map +1 -0
  35. package/dist/commands/archive/plan/gate.js +319 -0
  36. package/dist/commands/archive/plan/gate.js.map +1 -0
  37. package/dist/commands/archive/plan/landscape.js +298 -0
  38. package/dist/commands/archive/plan/landscape.js.map +1 -0
  39. package/dist/commands/archive/plan/model/extending.js +85 -0
  40. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  41. package/dist/commands/archive/plan/refusal.js +106 -0
  42. package/dist/commands/archive/plan/refusal.js.map +1 -0
  43. package/dist/commands/archive/plan/specs.js +318 -0
  44. package/dist/commands/archive/plan/specs.js.map +1 -0
  45. package/dist/commands/archive/plan/state.js +30 -0
  46. package/dist/commands/archive/plan/state.js.map +1 -0
  47. package/dist/commands/archive/run.js +355 -0
  48. package/dist/commands/archive/run.js.map +1 -0
  49. package/dist/commands/archive/shipped.js +49 -0
  50. package/dist/commands/archive/shipped.js.map +1 -0
  51. package/dist/commands/context/context.js +166 -0
  52. package/dist/commands/context/context.js.map +1 -0
  53. package/dist/commands/context/print.js +305 -0
  54. package/dist/commands/context/print.js.map +1 -0
  55. package/dist/commands/delta/delta.js +367 -0
  56. package/dist/commands/delta/delta.js.map +1 -0
  57. package/dist/commands/delta/print.js +221 -0
  58. package/dist/commands/delta/print.js.map +1 -0
  59. package/dist/commands/dependencies.js +6 -8
  60. package/dist/commands/dependencies.js.map +1 -1
  61. package/dist/commands/diff/diff.js +86 -0
  62. package/dist/commands/diff/diff.js.map +1 -0
  63. package/dist/commands/diff/print.js +38 -0
  64. package/dist/commands/diff/print.js.map +1 -0
  65. package/dist/commands/doctor.js +65 -5
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/explain/explain.js +227 -0
  68. package/dist/commands/explain/explain.js.map +1 -0
  69. package/dist/commands/explore.js +39 -28
  70. package/dist/commands/explore.js.map +1 -1
  71. package/dist/commands/gate/gate.js +152 -0
  72. package/dist/commands/gate/gate.js.map +1 -0
  73. package/dist/commands/gate/print.js +66 -0
  74. package/dist/commands/gate/print.js.map +1 -0
  75. package/dist/commands/gherkin/commit.js +105 -0
  76. package/dist/commands/gherkin/commit.js.map +1 -0
  77. package/dist/commands/gherkin/gherkin.js +262 -0
  78. package/dist/commands/gherkin/gherkin.js.map +1 -0
  79. package/dist/commands/gherkin/reconcile.js +146 -0
  80. package/dist/commands/gherkin/reconcile.js.map +1 -0
  81. package/dist/commands/gherkin/render.js +77 -0
  82. package/dist/commands/gherkin/render.js.map +1 -0
  83. package/dist/commands/init/example.js +204 -0
  84. package/dist/commands/init/example.js.map +1 -0
  85. package/dist/commands/init/first-hour.js +72 -0
  86. package/dist/commands/init/first-hour.js.map +1 -0
  87. package/dist/commands/{init.js → init/init.js} +142 -71
  88. package/dist/commands/init/init.js.map +1 -0
  89. package/dist/commands/init/mcp.js +131 -0
  90. package/dist/commands/init/mcp.js.map +1 -0
  91. package/dist/commands/init/options.js +78 -0
  92. package/dist/commands/init/options.js.map +1 -0
  93. package/dist/commands/instructions.js +72 -14
  94. package/dist/commands/instructions.js.map +1 -1
  95. package/dist/commands/list/campaign/campaign.js +63 -0
  96. package/dist/commands/list/campaign/campaign.js.map +1 -0
  97. package/dist/commands/list/campaign/owners.js +65 -0
  98. package/dist/commands/list/campaign/owners.js.map +1 -0
  99. package/dist/commands/list/json.js +155 -0
  100. package/dist/commands/list/json.js.map +1 -0
  101. package/dist/commands/list/list.js +358 -0
  102. package/dist/commands/list/list.js.map +1 -0
  103. package/dist/commands/list/print.js +344 -0
  104. package/dist/commands/list/print.js.map +1 -0
  105. package/dist/commands/list/review.js +120 -0
  106. package/dist/commands/list/review.js.map +1 -0
  107. package/dist/commands/list/suites/suites.js +140 -0
  108. package/dist/commands/list/suites/suites.js.map +1 -0
  109. package/dist/commands/list/views.js +108 -0
  110. package/dist/commands/list/views.js.map +1 -0
  111. package/dist/commands/mcp/dispatch.js +238 -0
  112. package/dist/commands/mcp/dispatch.js.map +1 -0
  113. package/dist/commands/mcp/mcp.js +75 -0
  114. package/dist/commands/mcp/mcp.js.map +1 -0
  115. package/dist/commands/mcp/serve.js +55 -0
  116. package/dist/commands/mcp/serve.js.map +1 -0
  117. package/dist/commands/migrate-openspec/materialize/active.js +175 -0
  118. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  119. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  120. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  121. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  122. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  123. package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
  124. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  125. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  126. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  127. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  128. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  129. package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
  130. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  131. package/dist/commands/migrate-openspec/openspec/error.js +18 -0
  132. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  133. package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
  134. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  135. package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
  136. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  137. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  138. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  139. package/dist/commands/migrate-openspec/print.js +89 -0
  140. package/dist/commands/migrate-openspec/print.js.map +1 -0
  141. package/dist/commands/new/capability-template.js +118 -0
  142. package/dist/commands/new/capability-template.js.map +1 -0
  143. package/dist/commands/new/commit.js +62 -0
  144. package/dist/commands/new/commit.js.map +1 -0
  145. package/dist/commands/new/modifies.js +206 -0
  146. package/dist/commands/new/modifies.js.map +1 -0
  147. package/dist/commands/new/new.js +328 -0
  148. package/dist/commands/new/new.js.map +1 -0
  149. package/dist/commands/new/templates.js +279 -0
  150. package/dist/commands/new/templates.js.map +1 -0
  151. package/dist/commands/open.js +199 -0
  152. package/dist/commands/open.js.map +1 -0
  153. package/dist/commands/policy/format.js +152 -0
  154. package/dist/commands/policy/format.js.map +1 -0
  155. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
  156. package/dist/commands/policy/gate.js.map +1 -0
  157. package/dist/commands/rebase/edit.js +106 -0
  158. package/dist/commands/rebase/edit.js.map +1 -0
  159. package/dist/commands/rebase/living.js +185 -0
  160. package/dist/commands/rebase/living.js.map +1 -0
  161. package/dist/commands/rebase/plan.js +245 -0
  162. package/dist/commands/rebase/plan.js.map +1 -0
  163. package/dist/commands/rebase/rebase.js +300 -0
  164. package/dist/commands/rebase/rebase.js.map +1 -0
  165. package/dist/commands/seed/commit.js +221 -0
  166. package/dist/commands/seed/commit.js.map +1 -0
  167. package/dist/commands/seed/plan.js +278 -0
  168. package/dist/commands/seed/plan.js.map +1 -0
  169. package/dist/commands/seed/seed.js +174 -0
  170. package/dist/commands/seed/seed.js.map +1 -0
  171. package/dist/commands/show/feature.js +182 -0
  172. package/dist/commands/show/feature.js.map +1 -0
  173. package/dist/commands/show/introduced.js +157 -0
  174. package/dist/commands/show/introduced.js.map +1 -0
  175. package/dist/commands/show/marks.js +53 -0
  176. package/dist/commands/show/marks.js.map +1 -0
  177. package/dist/commands/show/service.js +239 -0
  178. package/dist/commands/show/service.js.map +1 -0
  179. package/dist/commands/show/show.js +87 -0
  180. package/dist/commands/show/show.js.map +1 -0
  181. package/dist/commands/status/fleet-next.js +90 -0
  182. package/dist/commands/status/fleet-next.js.map +1 -0
  183. package/dist/commands/status/json.js +47 -0
  184. package/dist/commands/status/json.js.map +1 -0
  185. package/dist/commands/status/print.js +209 -0
  186. package/dist/commands/status/print.js.map +1 -0
  187. package/dist/commands/status/status.js +115 -0
  188. package/dist/commands/status/status.js.map +1 -0
  189. package/dist/commands/steps/steps.js +269 -0
  190. package/dist/commands/steps/steps.js.map +1 -0
  191. package/dist/commands/subsystem/edit.js +192 -0
  192. package/dist/commands/subsystem/edit.js.map +1 -0
  193. package/dist/commands/subsystem/move.js +325 -0
  194. package/dist/commands/subsystem/move.js.map +1 -0
  195. package/dist/commands/subsystem/query.js +113 -0
  196. package/dist/commands/subsystem/query.js.map +1 -0
  197. package/dist/commands/subsystem/subsystem.js +98 -0
  198. package/dist/commands/subsystem/subsystem.js.map +1 -0
  199. package/dist/commands/subsystem/sync.js +318 -0
  200. package/dist/commands/subsystem/sync.js.map +1 -0
  201. package/dist/commands/subsystem/txn/exclude.js +132 -0
  202. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  203. package/dist/commands/subsystem/txn/links.js +128 -0
  204. package/dist/commands/subsystem/txn/links.js.map +1 -0
  205. package/dist/commands/subsystem/txn/report.js +174 -0
  206. package/dist/commands/subsystem/txn/report.js.map +1 -0
  207. package/dist/commands/subsystem/txn/txn.js +196 -0
  208. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  209. package/dist/commands/subsystem/txn/views.js +249 -0
  210. package/dist/commands/subsystem/txn/views.js.map +1 -0
  211. package/dist/commands/tasks/actions.js +107 -0
  212. package/dist/commands/tasks/actions.js.map +1 -0
  213. package/dist/commands/tasks/render.js +253 -0
  214. package/dist/commands/tasks/render.js.map +1 -0
  215. package/dist/commands/tasks/tasks.js +119 -0
  216. package/dist/commands/tasks/tasks.js.map +1 -0
  217. package/dist/commands/unarchive/manifest.js +176 -0
  218. package/dist/commands/unarchive/manifest.js.map +1 -0
  219. package/dist/commands/unarchive/restore.js +254 -0
  220. package/dist/commands/unarchive/restore.js.map +1 -0
  221. package/dist/commands/unarchive/unarchive.js +59 -0
  222. package/dist/commands/unarchive/unarchive.js.map +1 -0
  223. package/dist/commands/validate/arch-coverage.js +245 -0
  224. package/dist/commands/validate/arch-coverage.js.map +1 -0
  225. package/dist/commands/validate/checks/fleet-shape.js +204 -0
  226. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  227. package/dist/commands/validate/checks/health-deps.js +58 -0
  228. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  229. package/dist/commands/validate/checks/introduced.js +102 -0
  230. package/dist/commands/validate/checks/introduced.js.map +1 -0
  231. package/dist/commands/validate/checks/requirements.js +264 -0
  232. package/dist/commands/validate/checks/requirements.js.map +1 -0
  233. package/dist/commands/validate/checks/sources.js +85 -0
  234. package/dist/commands/validate/checks/sources.js.map +1 -0
  235. package/dist/commands/validate/coverage/covers-after.js +105 -0
  236. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  237. package/dist/commands/validate/feature.js +222 -0
  238. package/dist/commands/validate/feature.js.map +1 -0
  239. package/dist/commands/validate/fleet/census.js +93 -0
  240. package/dist/commands/validate/fleet/census.js.map +1 -0
  241. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  242. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  243. package/dist/commands/validate/fleet/landscape.js +371 -0
  244. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  245. package/dist/commands/validate/fleet/load.js +118 -0
  246. package/dist/commands/validate/fleet/load.js.map +1 -0
  247. package/dist/commands/validate/fleet/map/attest.js +98 -0
  248. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  249. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  250. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  251. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  252. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  253. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  254. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  255. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  256. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  257. package/dist/commands/validate/fleet/obligations.js +266 -0
  258. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  259. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  260. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  261. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  262. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  263. package/dist/commands/validate/fleet/scorecard/print.js +71 -0
  264. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  265. package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
  266. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  267. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  268. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  269. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  270. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  271. package/dist/commands/validate/fleet/views/ids.js +75 -0
  272. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  273. package/dist/commands/validate/fleet/views/projects.js +278 -0
  274. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  275. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  276. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  277. package/dist/commands/validate/fleet/views/stale.js +52 -0
  278. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  279. package/dist/commands/validate/links/corpus.js +89 -0
  280. package/dist/commands/validate/links/corpus.js.map +1 -0
  281. package/dist/commands/validate/links/glossary.js +75 -0
  282. package/dist/commands/validate/links/glossary.js.map +1 -0
  283. package/dist/commands/validate/render/repeats.js +63 -0
  284. package/dist/commands/validate/render/repeats.js.map +1 -0
  285. package/dist/commands/validate/render/rollups.js +115 -0
  286. package/dist/commands/validate/render/rollups.js.map +1 -0
  287. package/dist/commands/validate/render/text.js +199 -0
  288. package/dist/commands/validate/render/text.js.map +1 -0
  289. package/dist/commands/validate/report.js +145 -0
  290. package/dist/commands/validate/report.js.map +1 -0
  291. package/dist/commands/validate/scope.js +113 -0
  292. package/dist/commands/validate/scope.js.map +1 -0
  293. package/dist/commands/validate/service/api.js +252 -0
  294. package/dist/commands/validate/service/api.js.map +1 -0
  295. package/dist/commands/validate/service/contracts/generated.js +134 -0
  296. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  297. package/dist/commands/validate/service/events/events.js +241 -0
  298. package/dist/commands/validate/service/events/events.js.map +1 -0
  299. package/dist/commands/validate/service/events/message-producers.js +77 -0
  300. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  301. package/dist/commands/validate/service/evidence-pins.js +177 -0
  302. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  303. package/dist/commands/validate/service/model/diverged.js +226 -0
  304. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  305. package/dist/commands/validate/service/model/grade.js +163 -0
  306. package/dist/commands/validate/service/model/grade.js.map +1 -0
  307. package/dist/commands/validate/service/service.js +310 -0
  308. package/dist/commands/validate/service/service.js.map +1 -0
  309. package/dist/commands/validate/service/specs.js +279 -0
  310. package/dist/commands/validate/service/specs.js.map +1 -0
  311. package/dist/commands/validate/service/spine.js +148 -0
  312. package/dist/commands/validate/service/spine.js.map +1 -0
  313. package/dist/commands/validate/service/usecases/tags.js +113 -0
  314. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  315. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  316. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  317. package/dist/commands/validate/validate.js +363 -0
  318. package/dist/commands/validate/validate.js.map +1 -0
  319. package/dist/commands/verify/cross/diff.js +178 -0
  320. package/dist/commands/verify/cross/diff.js.map +1 -0
  321. package/dist/commands/verify/evidence/contract.js +32 -0
  322. package/dist/commands/verify/evidence/contract.js.map +1 -0
  323. package/dist/commands/verify/evidence/pins.js +52 -0
  324. package/dist/commands/verify/evidence/pins.js.map +1 -0
  325. package/dist/commands/verify/evidence/read.js +81 -0
  326. package/dist/commands/verify/evidence/read.js.map +1 -0
  327. package/dist/commands/verify/frozen.js +263 -0
  328. package/dist/commands/verify/frozen.js.map +1 -0
  329. package/dist/commands/verify/record.js +278 -0
  330. package/dist/commands/verify/record.js.map +1 -0
  331. package/dist/commands/verify/report.js +206 -0
  332. package/dist/commands/verify/report.js.map +1 -0
  333. package/dist/commands/verify/results.js +328 -0
  334. package/dist/commands/verify/results.js.map +1 -0
  335. package/dist/commands/verify/verify.js +220 -0
  336. package/dist/commands/verify/verify.js.map +1 -0
  337. package/dist/commands/vouch/contract.js +11 -0
  338. package/dist/commands/vouch/contract.js.map +1 -0
  339. package/dist/commands/vouch/pack/contract.js +2 -0
  340. package/dist/commands/vouch/pack/contract.js.map +1 -0
  341. package/dist/commands/vouch/pack/pack.js +266 -0
  342. package/dist/commands/vouch/pack/pack.js.map +1 -0
  343. package/dist/commands/vouch/pack/print.js +266 -0
  344. package/dist/commands/vouch/pack/print.js.map +1 -0
  345. package/dist/commands/vouch/pack/sections.js +141 -0
  346. package/dist/commands/vouch/pack/sections.js.map +1 -0
  347. package/dist/commands/vouch/prompt/confirm.js +46 -0
  348. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  349. package/dist/commands/vouch/report.js +101 -0
  350. package/dist/commands/vouch/report.js.map +1 -0
  351. package/dist/commands/vouch/run.js +230 -0
  352. package/dist/commands/vouch/run.js.map +1 -0
  353. package/dist/commands/vouch/sample/plan.js +111 -0
  354. package/dist/commands/vouch/sample/plan.js.map +1 -0
  355. package/dist/commands/vouch/sample/print.js +109 -0
  356. package/dist/commands/vouch/sample/print.js.map +1 -0
  357. package/dist/commands/vouch/vet/verify.js +155 -0
  358. package/dist/commands/vouch/vet/verify.js.map +1 -0
  359. package/dist/commands/vouch/vouch.js +169 -0
  360. package/dist/commands/vouch/vouch.js.map +1 -0
  361. package/dist/core/agent/agents-md/command-map.js +299 -0
  362. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  363. package/dist/core/agent/agents-md/map/explain.js +46 -0
  364. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  365. package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
  366. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  367. package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
  368. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  369. package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
  370. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  371. package/dist/core/agent/agents-md/map/mcp.js +44 -0
  372. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  373. package/dist/core/agent/agents-md/map/status.js +78 -0
  374. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  375. package/dist/core/agent/agents-md/map/subsystem.js +104 -0
  376. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  377. package/dist/core/agent/agents-md/map/usecases.js +138 -0
  378. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  379. package/dist/core/agent/agents-md/refusals.js +273 -0
  380. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  381. package/dist/core/agent/agents-md.js +203 -0
  382. package/dist/core/agent/agents-md.js.map +1 -0
  383. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
  384. package/dist/core/agent/agents-stamp.js.map +1 -0
  385. package/dist/core/agent/contract.js +2 -0
  386. package/dist/core/agent/contract.js.map +1 -0
  387. package/dist/core/agent/protocol.js +193 -0
  388. package/dist/core/agent/protocol.js.map +1 -0
  389. package/dist/core/agent/scaffold.js +254 -0
  390. package/dist/core/agent/scaffold.js.map +1 -0
  391. package/dist/core/agent/support/report.js +144 -0
  392. package/dist/core/agent/support/report.js.map +1 -0
  393. package/dist/core/agent/tools/dialects.js +151 -0
  394. package/dist/core/agent/tools/dialects.js.map +1 -0
  395. package/dist/core/agent/tools/registry.js +193 -0
  396. package/dist/core/agent/tools/registry.js.map +1 -0
  397. package/dist/core/agent/workflows/adopt.js +280 -0
  398. package/dist/core/agent/workflows/adopt.js.map +1 -0
  399. package/dist/core/agent/workflows/check.js +373 -0
  400. package/dist/core/agent/workflows/check.js.map +1 -0
  401. package/dist/core/agent/workflows/closing.js +323 -0
  402. package/dist/core/agent/workflows/closing.js.map +1 -0
  403. package/dist/core/agent/workflows/feature.js +220 -0
  404. package/dist/core/agent/workflows/feature.js.map +1 -0
  405. package/dist/core/agent/workflows/implement.js +188 -0
  406. package/dist/core/agent/workflows/implement.js.map +1 -0
  407. package/dist/core/agent/workflows/reference/authoring.js +311 -0
  408. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  409. package/dist/core/agent/workflows/reference/codes.js +67 -0
  410. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  411. package/dist/core/agent/workflows/reference/done-check.js +210 -0
  412. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  413. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  414. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  415. package/dist/core/agent/workflows/reference/reference.js +19 -0
  416. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  417. package/dist/core/agent/workflows/reference/spine.js +338 -0
  418. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  419. package/dist/core/asyncapi/baseline/plan.js +43 -0
  420. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  421. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  422. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  423. package/dist/core/asyncapi/depth.js +164 -0
  424. package/dist/core/asyncapi/depth.js.map +1 -0
  425. package/dist/core/asyncapi/digest.js +146 -0
  426. package/dist/core/asyncapi/digest.js.map +1 -0
  427. package/dist/core/asyncapi/merge/components.js +92 -0
  428. package/dist/core/asyncapi/merge/components.js.map +1 -0
  429. package/dist/core/asyncapi/merge/error.js +38 -0
  430. package/dist/core/asyncapi/merge/error.js.map +1 -0
  431. package/dist/core/asyncapi/merge/markers.js +290 -0
  432. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  433. package/dist/core/asyncapi/merge/merge.js +195 -0
  434. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  435. package/dist/core/asyncapi/merge/pin.js +83 -0
  436. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  437. package/dist/core/asyncapi/model.js +11 -0
  438. package/dist/core/asyncapi/model.js.map +1 -0
  439. package/dist/core/asyncapi/producers.js +50 -0
  440. package/dist/core/asyncapi/producers.js.map +1 -0
  441. package/dist/core/asyncapi/read.js +263 -0
  442. package/dist/core/asyncapi/read.js.map +1 -0
  443. package/dist/core/brief/brief.js +285 -0
  444. package/dist/core/brief/brief.js.map +1 -0
  445. package/dist/core/brief/checks.js +385 -0
  446. package/dist/core/brief/checks.js.map +1 -0
  447. package/dist/core/brief/landscape.js +273 -0
  448. package/dist/core/brief/landscape.js.map +1 -0
  449. package/dist/core/brief/map/extend.js +84 -0
  450. package/dist/core/brief/map/extend.js.map +1 -0
  451. package/dist/core/brief/map/owed.js +266 -0
  452. package/dist/core/brief/map/owed.js.map +1 -0
  453. package/dist/core/brief/targets.js +304 -0
  454. package/dist/core/brief/targets.js.map +1 -0
  455. package/dist/core/brief/unchecked.js +58 -0
  456. package/dist/core/brief/unchecked.js.map +1 -0
  457. package/dist/core/c4/arch.js +190 -0
  458. package/dist/core/c4/arch.js.map +1 -0
  459. package/dist/core/c4/direction/direction.js +114 -0
  460. package/dist/core/c4/direction/direction.js.map +1 -0
  461. package/dist/core/c4/likec4.js +243 -0
  462. package/dist/core/c4/likec4.js.map +1 -0
  463. package/dist/core/c4/locate/unlocated.js +150 -0
  464. package/dist/core/c4/locate/unlocated.js.map +1 -0
  465. package/dist/core/c4/parsed/deployment.js +160 -0
  466. package/dist/core/c4/parsed/deployment.js.map +1 -0
  467. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  468. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  469. package/dist/core/c4/parsed/specification.js +78 -0
  470. package/dist/core/c4/parsed/specification.js.map +1 -0
  471. package/dist/core/c4/parsed/values.js +110 -0
  472. package/dist/core/c4/parsed/values.js.map +1 -0
  473. package/dist/core/c4/parsed/view-ids.js +113 -0
  474. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  475. package/dist/core/c4/prefetch/fleet.js +134 -0
  476. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  477. package/dist/core/c4/project/architecture.js +161 -0
  478. package/dist/core/c4/project/architecture.js.map +1 -0
  479. package/dist/core/c4/project/batch.js +140 -0
  480. package/dist/core/c4/project/batch.js.map +1 -0
  481. package/dist/core/c4/project/documents.js +89 -0
  482. package/dist/core/c4/project/documents.js.map +1 -0
  483. package/dist/core/c4/project/load.js +219 -0
  484. package/dist/core/c4/project/load.js.map +1 -0
  485. package/dist/core/c4/project/staged.js +277 -0
  486. package/dist/core/c4/project/staged.js.map +1 -0
  487. package/dist/core/c4/resolve/attested.js +0 -0
  488. package/dist/core/c4/resolve/attested.js.map +1 -0
  489. package/dist/core/c4/resolve/external.js +51 -0
  490. package/dist/core/c4/resolve/external.js.map +1 -0
  491. package/dist/core/c4/resolve/service.js +174 -0
  492. package/dist/core/c4/resolve/service.js.map +1 -0
  493. package/dist/core/c4/resolve/steps.js +290 -0
  494. package/dist/core/c4/resolve/steps.js.map +1 -0
  495. package/dist/core/c4/resolve/systems.js +154 -0
  496. package/dist/core/c4/resolve/systems.js.map +1 -0
  497. package/dist/core/c4/root-project/exclude.js +352 -0
  498. package/dist/core/c4/root-project/exclude.js.map +1 -0
  499. package/dist/core/c4/seed/fleet-file.js +201 -0
  500. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  501. package/dist/core/c4/seed/items.js +91 -0
  502. package/dist/core/c4/seed/items.js.map +1 -0
  503. package/dist/core/c4/seed/stamp.js +48 -0
  504. package/dist/core/c4/seed/stamp.js.map +1 -0
  505. package/dist/core/c4/seed/template.js +173 -0
  506. package/dist/core/c4/seed/template.js.map +1 -0
  507. package/dist/core/c4/service-model/created/models.js +96 -0
  508. package/dist/core/c4/service-model/created/models.js.map +1 -0
  509. package/dist/core/c4/service-model/documents.js +47 -0
  510. package/dist/core/c4/service-model/documents.js.map +1 -0
  511. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  512. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  513. package/dist/core/c4/service-model/load.js +165 -0
  514. package/dist/core/c4/service-model/load.js.map +1 -0
  515. package/dist/core/c4/service-model/renderer.js +128 -0
  516. package/dist/core/c4/service-model/renderer.js.map +1 -0
  517. package/dist/core/c4/service-model/shape.js +106 -0
  518. package/dist/core/c4/service-model/shape.js.map +1 -0
  519. package/dist/core/c4/service-model/slice.js +188 -0
  520. package/dist/core/c4/service-model/slice.js.map +1 -0
  521. package/dist/core/c4/source-mask.js +369 -0
  522. package/dist/core/c4/source-mask.js.map +1 -0
  523. package/dist/core/c4/source-scan.js +308 -0
  524. package/dist/core/c4/source-scan.js.map +1 -0
  525. package/dist/core/c4/splice/authored-source.js +167 -0
  526. package/dist/core/c4/splice/authored-source.js.map +1 -0
  527. package/dist/core/c4/splice/contract.js +30 -0
  528. package/dist/core/c4/splice/contract.js.map +1 -0
  529. package/dist/core/c4/splice/delta-blocks.js +126 -0
  530. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  531. package/dist/core/c4/splice/identity/declared.js +87 -0
  532. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  533. package/dist/core/c4/splice/identity/edges.js +73 -0
  534. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  535. package/dist/core/c4/splice/identity/existing.js +80 -0
  536. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  537. package/dist/core/c4/splice/identity/interior.js +80 -0
  538. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  539. package/dist/core/c4/splice/identity/owner.js +50 -0
  540. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  541. package/dist/core/c4/splice/landscape-merge.js +337 -0
  542. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  543. package/dist/core/c4/splice/model/merge.js +151 -0
  544. package/dist/core/c4/splice/model/merge.js.map +1 -0
  545. package/dist/core/c4/splice/placement.js +298 -0
  546. package/dist/core/c4/splice/placement.js.map +1 -0
  547. package/dist/core/c4/splice/text/spot.js +131 -0
  548. package/dist/core/c4/splice/text/spot.js.map +1 -0
  549. package/dist/core/c4/workspace.js +166 -0
  550. package/dist/core/c4/workspace.js.map +1 -0
  551. package/dist/core/capabilities/authoring/notes.js +141 -0
  552. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  553. package/dist/core/capabilities/capabilities.js +124 -0
  554. package/dist/core/capabilities/capabilities.js.map +1 -0
  555. package/dist/core/capabilities/delta/doc.js +47 -0
  556. package/dist/core/capabilities/delta/doc.js.map +1 -0
  557. package/dist/core/capabilities/delta/overlay.js +129 -0
  558. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  559. package/dist/core/capabilities/delta/summary.js +57 -0
  560. package/dist/core/capabilities/delta/summary.js.map +1 -0
  561. package/dist/core/capabilities/delta/tree.js +43 -0
  562. package/dist/core/capabilities/delta/tree.js.map +1 -0
  563. package/dist/core/capabilities/delta/uncovered.js +222 -0
  564. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  565. package/dist/core/capabilities/findings.js +338 -0
  566. package/dist/core/capabilities/findings.js.map +1 -0
  567. package/dist/core/capabilities/realizes/findings.js +174 -0
  568. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  569. package/dist/core/capabilities/realizes/join.js +123 -0
  570. package/dist/core/capabilities/realizes/join.js.map +1 -0
  571. package/dist/core/capabilities/rollup.js +205 -0
  572. package/dist/core/capabilities/rollup.js.map +1 -0
  573. package/dist/core/capabilities/tree.js +104 -0
  574. package/dist/core/capabilities/tree.js.map +1 -0
  575. package/dist/core/capabilities/usecase-join.js +267 -0
  576. package/dist/core/capabilities/usecase-join.js.map +1 -0
  577. package/dist/core/coherence/authoring/scaffold.js +185 -0
  578. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  579. package/dist/core/coherence/authoring/sentinels.js +75 -0
  580. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  581. package/dist/core/coherence/calls/called.js +52 -0
  582. package/dist/core/coherence/calls/called.js.map +1 -0
  583. package/dist/core/coherence/coherence.js +332 -0
  584. package/dist/core/coherence/coherence.js.map +1 -0
  585. package/dist/core/coherence/consumed/operations.js +70 -0
  586. package/dist/core/coherence/consumed/operations.js.map +1 -0
  587. package/dist/core/coherence/consumed/refusal.js +38 -0
  588. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  589. package/dist/core/coherence/covers/health.js +85 -0
  590. package/dist/core/coherence/covers/health.js.map +1 -0
  591. package/dist/core/coherence/declared.js +295 -0
  592. package/dist/core/coherence/declared.js.map +1 -0
  593. package/dist/core/coherence/events/declared.js +191 -0
  594. package/dist/core/coherence/events/declared.js.map +1 -0
  595. package/dist/core/coherence/events/events.js +335 -0
  596. package/dist/core/coherence/events/events.js.map +1 -0
  597. package/dist/core/coherence/events/grades.js +189 -0
  598. package/dist/core/coherence/events/grades.js.map +1 -0
  599. package/dist/core/coherence/events/lookups.js +63 -0
  600. package/dist/core/coherence/events/lookups.js.map +1 -0
  601. package/dist/core/coherence/events/produced.js +100 -0
  602. package/dist/core/coherence/events/produced.js.map +1 -0
  603. package/dist/core/coherence/living.js +198 -0
  604. package/dist/core/coherence/living.js.map +1 -0
  605. package/dist/core/coherence/lookups.js +95 -0
  606. package/dist/core/coherence/lookups.js.map +1 -0
  607. package/dist/core/coherence/pending.js +39 -0
  608. package/dist/core/coherence/pending.js.map +1 -0
  609. package/dist/core/coherence/retired/archived.js +285 -0
  610. package/dist/core/coherence/retired/archived.js.map +1 -0
  611. package/dist/core/coherence/retired/event-pair.js +62 -0
  612. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  613. package/dist/core/coherence/retired/merged.js +79 -0
  614. package/dist/core/coherence/retired/merged.js.map +1 -0
  615. package/dist/core/coherence/retired/retirement.js +49 -0
  616. package/dist/core/coherence/retired/retirement.js.map +1 -0
  617. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  618. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  619. package/dist/core/coherence/retired/revival/revived.js +297 -0
  620. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  621. package/dist/core/conflict-markers.js +60 -0
  622. package/dist/core/conflict-markers.js.map +1 -0
  623. package/dist/core/consumers/after.js +113 -0
  624. package/dist/core/consumers/after.js.map +1 -0
  625. package/dist/core/consumers/consumers.js +296 -0
  626. package/dist/core/consumers/consumers.js.map +1 -0
  627. package/dist/core/consumers/current.js +211 -0
  628. package/dist/core/consumers/current.js.map +1 -0
  629. package/dist/core/consumers/scan.js +46 -0
  630. package/dist/core/consumers/scan.js.map +1 -0
  631. package/dist/core/consumers/state.js +27 -0
  632. package/dist/core/consumers/state.js.map +1 -0
  633. package/dist/core/delta/claims.js +73 -0
  634. package/dist/core/delta/claims.js.map +1 -0
  635. package/dist/core/delta/delta.js +341 -0
  636. package/dist/core/delta/delta.js.map +1 -0
  637. package/dist/core/delta/document.js +177 -0
  638. package/dist/core/delta/document.js.map +1 -0
  639. package/dist/core/delta/scope.js +48 -0
  640. package/dist/core/delta/scope.js.map +1 -0
  641. package/dist/core/delta/select.js +237 -0
  642. package/dist/core/delta/select.js.map +1 -0
  643. package/dist/core/dependencies/dependencies.js +141 -0
  644. package/dist/core/dependencies/dependencies.js.map +1 -0
  645. package/dist/core/dependencies/facts.js +165 -0
  646. package/dist/core/dependencies/facts.js.map +1 -0
  647. package/dist/core/dependencies/fanin.js +88 -0
  648. package/dist/core/dependencies/fanin.js.map +1 -0
  649. package/dist/core/dependencies/graph.js +106 -0
  650. package/dist/core/dependencies/graph.js.map +1 -0
  651. package/dist/core/deployment/delta.js +191 -0
  652. package/dist/core/deployment/delta.js.map +1 -0
  653. package/dist/core/deployment/objects.js +145 -0
  654. package/dist/core/deployment/objects.js.map +1 -0
  655. package/dist/core/diff/base-git.js +230 -0
  656. package/dist/core/diff/base-git.js.map +1 -0
  657. package/dist/core/diff/base-state.js +237 -0
  658. package/dist/core/diff/base-state.js.map +1 -0
  659. package/dist/core/diff/joins.js +136 -0
  660. package/dist/core/diff/joins.js.map +1 -0
  661. package/dist/core/diff/scope/changed-paths.js +204 -0
  662. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  663. package/dist/core/diff/scope/edges.js +82 -0
  664. package/dist/core/diff/scope/edges.js.map +1 -0
  665. package/dist/core/diff/semantic.js +312 -0
  666. package/dist/core/diff/semantic.js.map +1 -0
  667. package/dist/core/docs.js +37 -85
  668. package/dist/core/docs.js.map +1 -1
  669. package/dist/core/doctor/agents.js +238 -0
  670. package/dist/core/doctor/agents.js.map +1 -0
  671. package/dist/core/doctor/config.js +139 -0
  672. package/dist/core/doctor/config.js.map +1 -0
  673. package/dist/core/doctor/doctor.js +355 -0
  674. package/dist/core/doctor/doctor.js.map +1 -0
  675. package/dist/core/doctor/report.js +13 -0
  676. package/dist/core/doctor/report.js.map +1 -0
  677. package/dist/core/doctor/reports/scan.js +242 -0
  678. package/dist/core/doctor/reports/scan.js.map +1 -0
  679. package/dist/core/doctor/residue.js +110 -0
  680. package/dist/core/doctor/residue.js.map +1 -0
  681. package/dist/core/document/apply.js +224 -0
  682. package/dist/core/document/apply.js.map +1 -0
  683. package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
  684. package/dist/core/document/frontmatter.js.map +1 -0
  685. package/dist/core/document/grammar/directives.js +143 -0
  686. package/dist/core/document/grammar/directives.js.map +1 -0
  687. package/dist/core/document/parse.js +286 -0
  688. package/dist/core/document/parse.js.map +1 -0
  689. package/dist/core/document/scenarios.js +238 -0
  690. package/dist/core/document/scenarios.js.map +1 -0
  691. package/dist/core/document/spec.js +234 -0
  692. package/dist/core/document/spec.js.map +1 -0
  693. package/dist/core/{config.js → envelope/config.js} +89 -18
  694. package/dist/core/envelope/config.js.map +1 -0
  695. package/dist/core/envelope/json.js +209 -0
  696. package/dist/core/envelope/json.js.map +1 -0
  697. package/dist/core/{version.js → envelope/version.js} +3 -3
  698. package/dist/core/envelope/version.js.map +1 -0
  699. package/dist/core/explain/families.js +180 -0
  700. package/dist/core/explain/families.js.map +1 -0
  701. package/dist/core/explain/fix-tables.js +178 -0
  702. package/dist/core/explain/fix-tables.js.map +1 -0
  703. package/dist/core/explain/lookup.js +194 -0
  704. package/dist/core/explain/lookup.js.map +1 -0
  705. package/dist/core/explain/refusals.js +49 -0
  706. package/dist/core/explain/refusals.js.map +1 -0
  707. package/dist/core/explain/terms/documents.js +227 -0
  708. package/dist/core/explain/terms/documents.js.map +1 -0
  709. package/dist/core/explain/terms/done-check.js +144 -0
  710. package/dist/core/explain/terms/done-check.js.map +1 -0
  711. package/dist/core/explain/terms/entry.js +14 -0
  712. package/dist/core/explain/terms/entry.js.map +1 -0
  713. package/dist/core/explain/terms/stages.js +71 -0
  714. package/dist/core/explain/terms/stages.js.map +1 -0
  715. package/dist/core/explain/terms/tasks.js +97 -0
  716. package/dist/core/explain/terms/tasks.js.map +1 -0
  717. package/dist/core/explain/terms.js +103 -0
  718. package/dist/core/explain/terms.js.map +1 -0
  719. package/dist/core/explore/describe.js +105 -0
  720. package/dist/core/explore/describe.js.map +1 -0
  721. package/dist/core/explore/explore.js +204 -0
  722. package/dist/core/explore/explore.js.map +1 -0
  723. package/dist/core/fleet-context.js +174 -146
  724. package/dist/core/fleet-context.js.map +1 -1
  725. package/dist/core/gate/checks.js +208 -0
  726. package/dist/core/gate/checks.js.map +1 -0
  727. package/dist/core/gate/partners.js +246 -0
  728. package/dist/core/gate/partners.js.map +1 -0
  729. package/dist/core/gate/report.js +47 -0
  730. package/dist/core/gate/report.js.map +1 -0
  731. package/dist/core/gate/verification.js +176 -0
  732. package/dist/core/gate/verification.js.map +1 -0
  733. package/dist/core/gherkin/digest.js +60 -0
  734. package/dist/core/gherkin/digest.js.map +1 -0
  735. package/dist/core/gherkin/emit.js +177 -0
  736. package/dist/core/gherkin/emit.js.map +1 -0
  737. package/dist/core/gherkin/read.js +76 -0
  738. package/dist/core/gherkin/read.js.map +1 -0
  739. package/dist/core/gherkin/stale.js +210 -0
  740. package/dist/core/gherkin/stale.js.map +1 -0
  741. package/dist/core/gherkin/stamp.js +77 -0
  742. package/dist/core/gherkin/stamp.js.map +1 -0
  743. package/dist/core/gherkin/steps/catalogue.js +154 -0
  744. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  745. package/dist/core/gherkin/steps/inventory.js +98 -0
  746. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  747. package/dist/core/gherkin/steps/phrase.js +72 -0
  748. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  749. package/dist/core/glossary/delta.js +109 -0
  750. package/dist/core/glossary/delta.js.map +1 -0
  751. package/dist/core/glossary/tree.js +73 -0
  752. package/dist/core/glossary/tree.js.map +1 -0
  753. package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
  754. package/dist/core/kernel/concurrency.js.map +1 -0
  755. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  756. package/dist/core/kernel/document-bytes.js.map +1 -0
  757. package/dist/core/kernel/fences.js +42 -0
  758. package/dist/core/kernel/fences.js.map +1 -0
  759. package/dist/core/kernel/ids/capability.js +72 -0
  760. package/dist/core/kernel/ids/capability.js.map +1 -0
  761. package/dist/core/kernel/ids/dirs.js +33 -0
  762. package/dist/core/kernel/ids/dirs.js.map +1 -0
  763. package/dist/core/kernel/ids/feature.js +75 -0
  764. package/dist/core/kernel/ids/feature.js.map +1 -0
  765. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  766. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  767. package/dist/core/kernel/ids/service.js +156 -0
  768. package/dist/core/kernel/ids/service.js.map +1 -0
  769. package/dist/core/kernel/ids/subsystem.js +63 -0
  770. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  771. package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
  772. package/dist/core/kernel/path-safety.js.map +1 -0
  773. package/dist/core/{records.js → kernel/records.js} +11 -0
  774. package/dist/core/kernel/records.js.map +1 -0
  775. package/dist/core/links/backlinks.js +66 -0
  776. package/dist/core/links/backlinks.js.map +1 -0
  777. package/dist/core/links/case.js +74 -0
  778. package/dist/core/links/case.js.map +1 -0
  779. package/dist/core/links/corpus.js +118 -0
  780. package/dist/core/links/corpus.js.map +1 -0
  781. package/dist/core/links/findings.js +110 -0
  782. package/dist/core/links/findings.js.map +1 -0
  783. package/dist/core/links/parse.js +265 -0
  784. package/dist/core/links/parse.js.map +1 -0
  785. package/dist/core/mcp/argv.js +212 -0
  786. package/dist/core/mcp/argv.js.map +1 -0
  787. package/dist/core/mcp/author-tools.js +73 -0
  788. package/dist/core/mcp/author-tools.js.map +1 -0
  789. package/dist/core/mcp/framing.js +46 -0
  790. package/dist/core/mcp/framing.js.map +1 -0
  791. package/dist/core/mcp/protocol.js +280 -0
  792. package/dist/core/mcp/protocol.js.map +1 -0
  793. package/dist/core/mcp/tools.js +324 -0
  794. package/dist/core/mcp/tools.js.map +1 -0
  795. package/dist/core/obligations/obligations.js +106 -0
  796. package/dist/core/obligations/obligations.js.map +1 -0
  797. package/dist/core/openapi/baseline/gate.js +207 -0
  798. package/dist/core/openapi/baseline/gate.js.map +1 -0
  799. package/dist/core/openapi/baseline/plan.js +142 -0
  800. package/dist/core/openapi/baseline/plan.js.map +1 -0
  801. package/dist/core/openapi/baseline/record.js +174 -0
  802. package/dist/core/openapi/baseline/record.js.map +1 -0
  803. package/dist/core/openapi/contract-text.js +33 -0
  804. package/dist/core/openapi/contract-text.js.map +1 -0
  805. package/dist/core/openapi/contract-tree.js +301 -0
  806. package/dist/core/openapi/contract-tree.js.map +1 -0
  807. package/dist/core/openapi/depth.js +136 -0
  808. package/dist/core/openapi/depth.js.map +1 -0
  809. package/dist/core/openapi/digest.js +239 -0
  810. package/dist/core/openapi/digest.js.map +1 -0
  811. package/dist/core/{openapi.js → openapi/doc.js} +54 -108
  812. package/dist/core/openapi/doc.js.map +1 -0
  813. package/dist/core/openapi/merge/components.js +199 -0
  814. package/dist/core/openapi/merge/components.js.map +1 -0
  815. package/dist/core/openapi/merge/error.js +16 -0
  816. package/dist/core/openapi/merge/error.js.map +1 -0
  817. package/dist/core/openapi/merge/markers.js +204 -0
  818. package/dist/core/openapi/merge/markers.js.map +1 -0
  819. package/dist/core/openapi/merge/merge.js +232 -0
  820. package/dist/core/openapi/merge/merge.js.map +1 -0
  821. package/dist/core/openapi/merge/pin.js +110 -0
  822. package/dist/core/openapi/merge/pin.js.map +1 -0
  823. package/dist/core/openspec/decide/capabilities.js +244 -0
  824. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  825. package/dist/core/openspec/decide/dispositions.js +63 -0
  826. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  827. package/dist/core/openspec/decide/renames.js +179 -0
  828. package/dist/core/openspec/decide/renames.js.map +1 -0
  829. package/dist/core/openspec/decide/verdict.js +84 -0
  830. package/dist/core/openspec/decide/verdict.js.map +1 -0
  831. package/dist/core/openspec/inventory.js +220 -0
  832. package/dist/core/openspec/inventory.js.map +1 -0
  833. package/dist/core/openspec/model/mapping.js +78 -0
  834. package/dist/core/openspec/model/mapping.js.map +1 -0
  835. package/dist/core/openspec/model/model.js +70 -0
  836. package/dist/core/openspec/model/model.js.map +1 -0
  837. package/dist/core/openspec/scan/changes.js +241 -0
  838. package/dist/core/openspec/scan/changes.js.map +1 -0
  839. package/dist/core/openspec/scan/config.js +191 -0
  840. package/dist/core/openspec/scan/config.js.map +1 -0
  841. package/dist/core/openspec/scan/shape.js +304 -0
  842. package/dist/core/openspec/scan/shape.js.map +1 -0
  843. package/dist/core/openspec/scan/walk.js +116 -0
  844. package/dist/core/openspec/scan/walk.js.map +1 -0
  845. package/dist/core/openspec/scan/workspace.js +71 -0
  846. package/dist/core/openspec/scan/workspace.js.map +1 -0
  847. package/dist/core/owners/codeowners.js +141 -0
  848. package/dist/core/owners/codeowners.js.map +1 -0
  849. package/dist/core/pack/features.js +120 -0
  850. package/dist/core/pack/features.js.map +1 -0
  851. package/dist/core/pack/joins.js +112 -0
  852. package/dist/core/pack/joins.js.map +1 -0
  853. package/dist/core/pack/living.js +157 -0
  854. package/dist/core/pack/living.js.map +1 -0
  855. package/dist/core/pack/pack.js +120 -0
  856. package/dist/core/pack/pack.js.map +1 -0
  857. package/dist/core/permissions/permissions.js +87 -0
  858. package/dist/core/permissions/permissions.js.map +1 -0
  859. package/dist/core/projection/api.js +84 -0
  860. package/dist/core/projection/api.js.map +1 -0
  861. package/dist/core/projection/arch-slice.js +63 -0
  862. package/dist/core/projection/arch-slice.js.map +1 -0
  863. package/dist/core/projection/events.js +34 -0
  864. package/dist/core/projection/events.js.map +1 -0
  865. package/dist/core/projection/introduced.js +14 -0
  866. package/dist/core/projection/introduced.js.map +1 -0
  867. package/dist/core/provenance/findings.js +244 -0
  868. package/dist/core/provenance/findings.js.map +1 -0
  869. package/dist/core/provenance/git.js +201 -0
  870. package/dist/core/provenance/git.js.map +1 -0
  871. package/dist/core/provenance/gitq/moves.js +139 -0
  872. package/dist/core/provenance/gitq/moves.js.map +1 -0
  873. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  874. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  875. package/dist/core/provenance/sample/scope.js +238 -0
  876. package/dist/core/provenance/sample/scope.js.map +1 -0
  877. package/dist/core/provenance/sample/sections.js +61 -0
  878. package/dist/core/provenance/sample/sections.js.map +1 -0
  879. package/dist/core/provenance/sources.js +280 -0
  880. package/dist/core/provenance/sources.js.map +1 -0
  881. package/dist/core/provenance/stamp.js +220 -0
  882. package/dist/core/provenance/stamp.js.map +1 -0
  883. package/dist/core/provenance/walk.js +157 -0
  884. package/dist/core/provenance/walk.js.map +1 -0
  885. package/dist/core/repo/authored/paths.js +210 -0
  886. package/dist/core/repo/authored/paths.js.map +1 -0
  887. package/dist/core/repo/entries.js +126 -0
  888. package/dist/core/repo/entries.js.map +1 -0
  889. package/dist/core/repo/paths.js +322 -0
  890. package/dist/core/repo/paths.js.map +1 -0
  891. package/dist/core/repo/repo.js +308 -0
  892. package/dist/core/repo/repo.js.map +1 -0
  893. package/dist/core/repo/service-target.js +153 -0
  894. package/dist/core/repo/service-target.js.map +1 -0
  895. package/dist/core/repo/state.js +58 -0
  896. package/dist/core/repo/state.js.map +1 -0
  897. package/dist/core/repo/tree/find.js +61 -0
  898. package/dist/core/repo/tree/find.js.map +1 -0
  899. package/dist/core/repo/tree/fs.js +90 -0
  900. package/dist/core/repo/tree/fs.js.map +1 -0
  901. package/dist/core/repo/tree/marker.js +61 -0
  902. package/dist/core/repo/tree/marker.js.map +1 -0
  903. package/dist/core/repo/tree/render/body.js +258 -0
  904. package/dist/core/repo/tree/render/body.js.map +1 -0
  905. package/dist/core/repo/tree/render/projects.js +182 -0
  906. package/dist/core/repo/tree/render/projects.js.map +1 -0
  907. package/dist/core/repo/tree/render/service/header.js +125 -0
  908. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  909. package/dist/core/repo/tree/render/service/peers.js +28 -0
  910. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  911. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  912. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  913. package/dist/core/repo/tree/render/service/views.js +78 -0
  914. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  915. package/dist/core/repo/tree/render/stale.js +42 -0
  916. package/dist/core/repo/tree/render/stale.js.map +1 -0
  917. package/dist/core/repo/tree/render/text.js +84 -0
  918. package/dist/core/repo/tree/render/text.js.map +1 -0
  919. package/dist/core/repo/tree/render/views.js +293 -0
  920. package/dist/core/repo/tree/render/views.js.map +1 -0
  921. package/dist/core/repo/tree/walk.js +255 -0
  922. package/dist/core/repo/tree/walk.js.map +1 -0
  923. package/dist/core/results.js +146 -14
  924. package/dist/core/results.js.map +1 -1
  925. package/dist/core/scaffold/landscape.js +239 -0
  926. package/dist/core/scaffold/landscape.js.map +1 -0
  927. package/dist/core/scaffold/legacy.js +271 -0
  928. package/dist/core/scaffold/legacy.js.map +1 -0
  929. package/dist/core/scaffold/readme.js +84 -0
  930. package/dist/core/scaffold/readme.js.map +1 -0
  931. package/dist/core/staging/commit.js +252 -0
  932. package/dist/core/staging/commit.js.map +1 -0
  933. package/dist/core/staging/interrupted.js +96 -0
  934. package/dist/core/staging/interrupted.js.map +1 -0
  935. package/dist/core/staging/lock.js +268 -0
  936. package/dist/core/staging/lock.js.map +1 -0
  937. package/dist/core/staging/recovery/finding.js +35 -0
  938. package/dist/core/staging/recovery/finding.js.map +1 -0
  939. package/dist/core/staging/recovery/intent.js +95 -0
  940. package/dist/core/staging/recovery/intent.js.map +1 -0
  941. package/dist/core/staging/recovery/recover.js +204 -0
  942. package/dist/core/staging/recovery/recover.js.map +1 -0
  943. package/dist/core/staging/recovery/residue.js +62 -0
  944. package/dist/core/staging/recovery/residue.js.map +1 -0
  945. package/dist/core/staging/snapshot/manifest.js +188 -0
  946. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  947. package/dist/core/staging/snapshot/snapshot.js +196 -0
  948. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  949. package/dist/core/staging/txn/forward.js +181 -0
  950. package/dist/core/staging/txn/forward.js.map +1 -0
  951. package/dist/core/staging/txn/journal.js +139 -0
  952. package/dist/core/staging/txn/journal.js.map +1 -0
  953. package/dist/core/staging/txn/transaction.js +75 -0
  954. package/dist/core/staging/txn/transaction.js.map +1 -0
  955. package/dist/core/staging/writes.js +113 -0
  956. package/dist/core/staging/writes.js.map +1 -0
  957. package/dist/core/status/actions/execution.js +60 -0
  958. package/dist/core/status/actions/execution.js.map +1 -0
  959. package/dist/core/status/contracts.js +126 -0
  960. package/dist/core/status/contracts.js.map +1 -0
  961. package/dist/core/status/feature/artifacts.js +196 -0
  962. package/dist/core/status/feature/artifacts.js.map +1 -0
  963. package/dist/core/status/feature/feature.js +214 -0
  964. package/dist/core/status/feature/feature.js.map +1 -0
  965. package/dist/core/status/feature/next.js +163 -0
  966. package/dist/core/status/feature/next.js.map +1 -0
  967. package/dist/core/status/feature/state.js +21 -0
  968. package/dist/core/status/feature/state.js.map +1 -0
  969. package/dist/core/status/feature/words.js +96 -0
  970. package/dist/core/status/feature/words.js.map +1 -0
  971. package/dist/core/status/fleet/fleet.js +216 -0
  972. package/dist/core/status/fleet/fleet.js.map +1 -0
  973. package/dist/core/status/fleet/next.js +302 -0
  974. package/dist/core/status/fleet/next.js.map +1 -0
  975. package/dist/core/status/interrupted.js +97 -0
  976. package/dist/core/status/interrupted.js.map +1 -0
  977. package/dist/core/status/report.js +31 -0
  978. package/dist/core/status/report.js.map +1 -0
  979. package/dist/core/status/scan.js +41 -0
  980. package/dist/core/status/scan.js.map +1 -0
  981. package/dist/core/status/verification.js +216 -0
  982. package/dist/core/status/verification.js.map +1 -0
  983. package/dist/core/tasks/packet.js +199 -0
  984. package/dist/core/tasks/packet.js.map +1 -0
  985. package/dist/core/tasks/record.js +43 -0
  986. package/dist/core/tasks/record.js.map +1 -0
  987. package/dist/core/tasks/sources.js +181 -0
  988. package/dist/core/tasks/sources.js.map +1 -0
  989. package/dist/core/tasks/stamps.js +76 -0
  990. package/dist/core/tasks/stamps.js.map +1 -0
  991. package/dist/core/tasks/unit.js +0 -0
  992. package/dist/core/tasks/unit.js.map +1 -0
  993. package/dist/core/usecases/capability.js +166 -0
  994. package/dist/core/usecases/capability.js.map +1 -0
  995. package/dist/core/usecases/delta/claims.js +140 -0
  996. package/dist/core/usecases/delta/claims.js.map +1 -0
  997. package/dist/core/usecases/delta/flows.js +101 -0
  998. package/dist/core/usecases/delta/flows.js.map +1 -0
  999. package/dist/core/usecases/delta/modified.js +315 -0
  1000. package/dist/core/usecases/delta/modified.js.map +1 -0
  1001. package/dist/core/usecases/delta/overlay.js +76 -0
  1002. package/dist/core/usecases/delta/overlay.js.map +1 -0
  1003. package/dist/core/usecases/fleet.js +296 -0
  1004. package/dist/core/usecases/fleet.js.map +1 -0
  1005. package/dist/core/usecases/grade/capability-tag.js +93 -0
  1006. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  1007. package/dist/core/usecases/grade/feature.js +88 -0
  1008. package/dist/core/usecases/grade/feature.js.map +1 -0
  1009. package/dist/core/usecases/grade/requirement-tag.js +94 -0
  1010. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  1011. package/dist/core/usecases/grade/steps.js +266 -0
  1012. package/dist/core/usecases/grade/steps.js.map +1 -0
  1013. package/dist/core/usecases/grade/usecases.js +112 -0
  1014. package/dist/core/usecases/grade/usecases.js.map +1 -0
  1015. package/dist/core/usecases/operations.js +123 -0
  1016. package/dist/core/usecases/operations.js.map +1 -0
  1017. package/dist/core/usecases/place.js +44 -0
  1018. package/dist/core/usecases/place.js.map +1 -0
  1019. package/dist/core/usecases/service/exclude.js +119 -0
  1020. package/dist/core/usecases/service/exclude.js.map +1 -0
  1021. package/dist/core/usecases/service/flows.js +164 -0
  1022. package/dist/core/usecases/service/flows.js.map +1 -0
  1023. package/dist/core/usecases/suites/participants.js +83 -0
  1024. package/dist/core/usecases/suites/participants.js.map +1 -0
  1025. package/dist/core/usecases/suites/suites.js +45 -0
  1026. package/dist/core/usecases/suites/suites.js.map +1 -0
  1027. package/dist/core/usecases/touch.js +101 -0
  1028. package/dist/core/usecases/touch.js.map +1 -0
  1029. package/dist/core/verify/answers.js +180 -0
  1030. package/dist/core/verify/answers.js.map +1 -0
  1031. package/dist/core/verify/build.js +170 -0
  1032. package/dist/core/verify/build.js.map +1 -0
  1033. package/dist/core/verify/checklist.js +259 -0
  1034. package/dist/core/verify/checklist.js.map +1 -0
  1035. package/dist/core/verify/claims/identity.js +61 -0
  1036. package/dist/core/verify/claims/identity.js.map +1 -0
  1037. package/dist/core/verify/cross/diff.js +97 -0
  1038. package/dist/core/verify/cross/diff.js.map +1 -0
  1039. package/dist/core/verify/evidence/contract.js +169 -0
  1040. package/dist/core/verify/evidence/contract.js.map +1 -0
  1041. package/dist/core/verify/location.js +67 -0
  1042. package/dist/core/verify/location.js.map +1 -0
  1043. package/dist/core/verify/pins/lint.js +158 -0
  1044. package/dist/core/verify/pins/lint.js.map +1 -0
  1045. package/dist/core/verify/pins/pin.js +95 -0
  1046. package/dist/core/verify/pins/pin.js.map +1 -0
  1047. package/dist/core/verify/read/file.js +224 -0
  1048. package/dist/core/verify/read/file.js.map +1 -0
  1049. package/dist/core/verify/read/shape.js +169 -0
  1050. package/dist/core/verify/read/shape.js.map +1 -0
  1051. package/dist/core/verify/read/union.js +105 -0
  1052. package/dist/core/verify/read/union.js.map +1 -0
  1053. package/dist/core/verify/record.js +165 -0
  1054. package/dist/core/verify/record.js.map +1 -0
  1055. package/dist/core/verify/store/commit.js +99 -0
  1056. package/dist/core/verify/store/commit.js.map +1 -0
  1057. package/dist/core/verify/store/render.js +61 -0
  1058. package/dist/core/verify/store/render.js.map +1 -0
  1059. package/dist/core/vocabulary/health.js +91 -0
  1060. package/dist/core/vocabulary/health.js.map +1 -0
  1061. package/dist/core/vocabulary/issue.js +59 -0
  1062. package/dist/core/vocabulary/issue.js.map +1 -0
  1063. package/dist/core/vocabulary/maturity.js +216 -0
  1064. package/dist/core/vocabulary/maturity.js.map +1 -0
  1065. package/dist/core/vocabulary/report.js +90 -0
  1066. package/dist/core/vocabulary/report.js.map +1 -0
  1067. package/dist/core/vocabulary/steps.js +266 -0
  1068. package/dist/core/vocabulary/steps.js.map +1 -0
  1069. package/dist/core/workspace/discover.js +239 -0
  1070. package/dist/core/workspace/discover.js.map +1 -0
  1071. package/dist/core/workspace/render.js +52 -0
  1072. package/dist/core/workspace/render.js.map +1 -0
  1073. package/examples/README.md +232 -0
  1074. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  1075. package/examples/docs/architecture/capabilities.yaml +31 -0
  1076. package/examples/docs/architecture/landscape.likec4 +336 -0
  1077. package/examples/docs/architecture/obligations.yaml +23 -0
  1078. package/examples/docs/architecture/permissions.yaml +50 -0
  1079. package/examples/docs/architecture/services.likec4 +70 -0
  1080. package/examples/docs/architecture/subsystems.likec4 +18 -0
  1081. package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
  1082. package/examples/docs/capabilities/checkout/spec.md +55 -0
  1083. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  1084. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  1085. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  1086. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  1087. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  1088. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  1089. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
  1090. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  1091. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  1092. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  1093. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  1094. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  1095. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
  1096. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  1097. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  1098. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  1099. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  1100. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  1101. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  1102. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  1103. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  1104. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  1105. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  1106. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
  1107. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  1108. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  1109. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  1110. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  1111. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  1112. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  1113. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  1114. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  1115. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  1116. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  1117. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  1118. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  1119. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  1120. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  1121. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  1122. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  1123. package/examples/docs/glossary/order.md +15 -0
  1124. package/examples/docs/glossary/payments/authorization.md +14 -0
  1125. package/examples/docs/likec4.config.json +8 -0
  1126. package/examples/docs/loam.json +3 -0
  1127. package/examples/docs/services/checkout-web/model.likec4 +92 -0
  1128. package/examples/docs/services/checkout-web/spec.md +91 -0
  1129. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  1130. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  1131. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  1132. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  1133. package/examples/docs/services/order-service/arch.spec.md +134 -0
  1134. package/examples/docs/services/order-service/asyncapi.yaml +109 -0
  1135. package/examples/docs/services/order-service/health.yaml +57 -0
  1136. package/examples/docs/services/order-service/model.likec4 +126 -0
  1137. package/examples/docs/services/order-service/openapi.yaml +257 -0
  1138. package/examples/docs/services/order-service/runbook.md +62 -0
  1139. package/examples/docs/services/order-service/spec.md +134 -0
  1140. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  1141. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  1142. package/examples/docs/services/payment-service/arch.spec.md +76 -0
  1143. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  1144. package/examples/docs/services/payment-service/health.yaml +39 -0
  1145. package/examples/docs/services/payment-service/model.likec4 +68 -0
  1146. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  1147. package/examples/docs/services/payment-service/runbook.md +37 -0
  1148. package/examples/docs/services/payment-service/spec.md +88 -0
  1149. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  1150. package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
  1151. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  1152. package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
  1153. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  1154. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  1155. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  1156. package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
  1157. package/examples/docs/services/platform/notification-service/health.yaml +40 -0
  1158. package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
  1159. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  1160. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  1161. package/examples/docs/services/platform/subsystem.yaml +2 -0
  1162. package/examples/fleet.yaml +57 -0
  1163. package/package.json +19 -6
  1164. package/dist/commands/adopt.js +0 -240
  1165. package/dist/commands/adopt.js.map +0 -1
  1166. package/dist/commands/archive.js +0 -1313
  1167. package/dist/commands/archive.js.map +0 -1
  1168. package/dist/commands/delta.js +0 -388
  1169. package/dist/commands/delta.js.map +0 -1
  1170. package/dist/commands/docs-repo-gate.js.map +0 -1
  1171. package/dist/commands/format.js +0 -17
  1172. package/dist/commands/format.js.map +0 -1
  1173. package/dist/commands/gherkin.js +0 -309
  1174. package/dist/commands/gherkin.js.map +0 -1
  1175. package/dist/commands/init.js.map +0 -1
  1176. package/dist/commands/list.js +0 -295
  1177. package/dist/commands/list.js.map +0 -1
  1178. package/dist/commands/migrate-openspec.js +0 -950
  1179. package/dist/commands/migrate-openspec.js.map +0 -1
  1180. package/dist/commands/new.js +0 -413
  1181. package/dist/commands/new.js.map +0 -1
  1182. package/dist/commands/rebase.js +0 -356
  1183. package/dist/commands/rebase.js.map +0 -1
  1184. package/dist/commands/show.js +0 -320
  1185. package/dist/commands/show.js.map +0 -1
  1186. package/dist/commands/status.js +0 -262
  1187. package/dist/commands/status.js.map +0 -1
  1188. package/dist/commands/unarchive.js +0 -317
  1189. package/dist/commands/unarchive.js.map +0 -1
  1190. package/dist/commands/validate.js +0 -1773
  1191. package/dist/commands/validate.js.map +0 -1
  1192. package/dist/commands/verify.js +0 -775
  1193. package/dist/commands/verify.js.map +0 -1
  1194. package/dist/commands/vouch.js +0 -421
  1195. package/dist/commands/vouch.js.map +0 -1
  1196. package/dist/core/agent.js +0 -2173
  1197. package/dist/core/agent.js.map +0 -1
  1198. package/dist/core/agents-stamp.js.map +0 -1
  1199. package/dist/core/arch.js +0 -130
  1200. package/dist/core/arch.js.map +0 -1
  1201. package/dist/core/asyncapi.js +0 -253
  1202. package/dist/core/asyncapi.js.map +0 -1
  1203. package/dist/core/brief.js +0 -755
  1204. package/dist/core/brief.js.map +0 -1
  1205. package/dist/core/coherence.js +0 -577
  1206. package/dist/core/coherence.js.map +0 -1
  1207. package/dist/core/concurrency.js.map +0 -1
  1208. package/dist/core/config.js.map +0 -1
  1209. package/dist/core/delta.js +0 -476
  1210. package/dist/core/delta.js.map +0 -1
  1211. package/dist/core/dependencies.js +0 -356
  1212. package/dist/core/dependencies.js.map +0 -1
  1213. package/dist/core/doctor.js +0 -596
  1214. package/dist/core/doctor.js.map +0 -1
  1215. package/dist/core/document-bytes.js.map +0 -1
  1216. package/dist/core/explore.js +0 -225
  1217. package/dist/core/explore.js.map +0 -1
  1218. package/dist/core/frontmatter.js.map +0 -1
  1219. package/dist/core/gherkin.js +0 -463
  1220. package/dist/core/gherkin.js.map +0 -1
  1221. package/dist/core/health.js +0 -67
  1222. package/dist/core/health.js.map +0 -1
  1223. package/dist/core/ids.js +0 -122
  1224. package/dist/core/ids.js.map +0 -1
  1225. package/dist/core/issue.js +0 -9
  1226. package/dist/core/issue.js.map +0 -1
  1227. package/dist/core/json.js +0 -74
  1228. package/dist/core/json.js.map +0 -1
  1229. package/dist/core/likec4.js +0 -489
  1230. package/dist/core/likec4.js.map +0 -1
  1231. package/dist/core/maturity.js +0 -66
  1232. package/dist/core/maturity.js.map +0 -1
  1233. package/dist/core/openapi-merge.js +0 -552
  1234. package/dist/core/openapi-merge.js.map +0 -1
  1235. package/dist/core/openapi.js.map +0 -1
  1236. package/dist/core/openspec-inventory.js +0 -1440
  1237. package/dist/core/openspec-inventory.js.map +0 -1
  1238. package/dist/core/path-safety.js.map +0 -1
  1239. package/dist/core/provenance.js +0 -787
  1240. package/dist/core/provenance.js.map +0 -1
  1241. package/dist/core/records.js.map +0 -1
  1242. package/dist/core/repo.js +0 -438
  1243. package/dist/core/repo.js.map +0 -1
  1244. package/dist/core/report.js +0 -47
  1245. package/dist/core/report.js.map +0 -1
  1246. package/dist/core/spec.js +0 -505
  1247. package/dist/core/spec.js.map +0 -1
  1248. package/dist/core/staging.js +0 -890
  1249. package/dist/core/staging.js.map +0 -1
  1250. package/dist/core/status.js +0 -1132
  1251. package/dist/core/status.js.map +0 -1
  1252. package/dist/core/steps.js +0 -72
  1253. package/dist/core/steps.js.map +0 -1
  1254. package/dist/core/verify.js +0 -807
  1255. package/dist/core/verify.js.map +0 -1
  1256. package/dist/core/version.js.map +0 -1
@@ -0,0 +1,126 @@
1
+ /**
2
+ * What a delta may declare that the landscape merge cannot carry.
3
+ *
4
+ * `planLandscapeMerge` splices out of the delta's `model { }` block and nothing
5
+ * else. That is correct — the living landscape is a model plus the views its own
6
+ * authors chose — but it used to be SILENT: a delta declaring `deployment { }`
7
+ * or a `dynamic view` archived at exit 0, reported `+N element(s), +M
8
+ * relationship(s)` exactly as usual, and the block was simply gone. The merge's
9
+ * own parse net cannot catch it either, because a landscape missing a deployment
10
+ * model is perfectly legal — there is nothing to fail on. Nobody finds out until
11
+ * somebody goes looking for a diagram that was archived months ago.
12
+ *
13
+ * So the loss is made a refusal, which is the same doctrine as the merge's other
14
+ * mechanical refusals (an unlocatable declaration, two statements on one line):
15
+ * the input cannot be spliced as authored, `--approve` deliberately does not
16
+ * override it — that flag overrides loam's JUDGMENT about coherence, never its
17
+ * ability to carry an axis — and nothing is written.
18
+ *
19
+ * ## Why views are graded and not simply banned
20
+ *
21
+ * `loam new` scaffolds a `views { view <feat> { include * } }` block into every
22
+ * delta.likec4 (commands/new/templates.ts), so refusing the block outright would
23
+ * refuse loam's own scaffold on its first archive. It is there to be RENDERED
24
+ * while the feature is in flight, and it is meant not to travel.
25
+ *
26
+ * The line drawn here is recoverability, and it is the only line that survives
27
+ * the scaffold:
28
+ *
29
+ * - A static `view` is a rendering OF the model. Once the merge lands, the
30
+ * whole model is in landscape.likec4, so the author can restate the view
31
+ * there at any time from information that still exists. Dropping it loses a
32
+ * convenience.
33
+ * - A `dynamic view`'s ordered steps, and a `deployment { }` block's topology,
34
+ * exist in NO other document the fleet keeps. When the merge drops those,
35
+ * the information is gone. That is what gets refused. Rule 26 sharpens the
36
+ * stakes rather than the rule: a `dynamic view`'s steps are now something
37
+ * loam READS, so dropping one silently would discard checked content, not
38
+ * merely a convenience.
39
+ *
40
+ * A residual is accepted knowingly: a delta carrying a SECOND static view still
41
+ * loses it without a word. Refusing that would mean telling an author with two
42
+ * preview views to delete one, which is a false refusal on a harmless file, and
43
+ * the loss there is recoverable by the argument above.
44
+ *
45
+ * ## The dynamic-view refusal is unchanged; its ADVICE moved
46
+ *
47
+ * A `dynamic view` still cannot ride inside `delta.likec4`, and the reason is
48
+ * mechanical rather than a policy about where flows belong: this document
49
+ * re-declares the landscape's own identifiers to anchor its new edges and
50
+ * carries its own `specification` block because LikeC4 parses it standalone, so
51
+ * it cannot be staged beside the map in one project — a duplicate specification
52
+ * is an error blamed on both files, and a re-declared element is a duplicate id.
53
+ * What changed is where the refusal sends the author. It used to say
54
+ * `architecture/landscape.likec4`, which was the only honest answer while the
55
+ * axis had no feature-delta path: a flow could not ship with the change that
56
+ * made it true. `features/<FEAT>/usecases/<name>.likec4` is that path
57
+ * (`core/usecases/delta/flows.ts`), and it is a views-only document — which is
58
+ * exactly why it stages beside the map when this one cannot.
59
+ */
60
+ import { maskSource, topLevelBlocks } from "../source-mask.js";
61
+ import { LandscapeSpliceError } from "./contract.js";
62
+ /**
63
+ * Top-level blocks a delta can declare. `specification` and `model` are absent
64
+ * on purpose: the specification is re-declared in every delta because LikeC4
65
+ * parses each one standalone, and the model is the thing being spliced.
66
+ */
67
+ const TOP_LEVEL_BLOCK = /\b(deployment|global|views)\s*\{/g;
68
+ /** A `dynamic view` / `deployment view` inside a views block — the irrecoverable kinds. */
69
+ const AUTHORED_VIEW = /\b(dynamic|deployment)\s+view\b/;
70
+ function refuse(block, detail, home) {
71
+ throw new LandscapeSpliceError(`delta.likec4 declares ${detail}, and the landscape merge splices only what is inside \`model { }\` — ` +
72
+ `archiving would drop it silently, so nothing was written. Move the ${block} into ` +
73
+ `${home} and re-run the archive.`);
74
+ }
75
+ /** Where the living documents keep what this delta cannot carry. */
76
+ const LANDSCAPE_HOME = "architecture/landscape.likec4, where the living documents keep it,";
77
+ /** Where a FEATURE keeps TOPOLOGY — the third whole-file slot, added with the deployment axis. */
78
+ const DEPLOYMENT_HOME = "features/<FEAT>/deployment/<name>.likec4 — a document of its own, which `loam archive` copies into " +
79
+ "architecture/ and `loam unarchive` takes back; say `extend` in it to add to a region the living map " +
80
+ "already declares —";
81
+ /** Where a FEATURE keeps a flow — a slot of its own, not the living tree. See the header. */
82
+ const FLOW_HOME = "features/<FEAT>/usecases/<name>.likec4 — a views-only document of its own, which `loam archive` copies into " +
83
+ "architecture/usecases/ and `loam unarchive` takes back —";
84
+ /**
85
+ * Refuse a delta whose non-model blocks the merge would discard.
86
+ *
87
+ * Runs over MASKED source, so a `deployment {` written inside a comment or a
88
+ * description string cannot trigger it — the same masking discipline
89
+ * `scanModel` splices under, and for the same reason: this refuses an archive,
90
+ * and a refusal a comment can provoke is worse than the silence it replaced.
91
+ *
92
+ * Only a block at depth 0 is a top-level declaration (`topLevelBlocks`), and
93
+ * `deployment` at depth 1 is an ordinary `specification { deploymentNode … }`
94
+ * or a view predicate.
95
+ */
96
+ export function assertMergeableDelta(deltaText) {
97
+ const { code } = maskSource(deltaText);
98
+ for (const { match: m, body: inner } of topLevelBlocks(code, TOP_LEVEL_BLOCK)) {
99
+ const block = m[1];
100
+ if (block !== "views") {
101
+ refuse(`\`${block} { }\` block`, `a top-level \`${block} { }\` block`,
102
+ // The refusal is unchanged and always will be — this document
103
+ // re-declares the landscape's identifiers and carries its own
104
+ // `specification`, so it cannot be staged beside the map in one project.
105
+ // What changed is where it sends the author: a feature introducing
106
+ // topology WITH the change that makes it true now has a slot of its
107
+ // own, and pointing at the living landscape was the advice that made
108
+ // the axis's headline case a two-pull-request job. `global { }` has no
109
+ // such slot and keeps the living home.
110
+ block === "deployment" ? DEPLOYMENT_HOME : LANDSCAPE_HOME);
111
+ }
112
+ const authored = AUTHORED_VIEW.exec(inner);
113
+ if (authored !== null) {
114
+ const kind = authored[1];
115
+ refuse(`\`${kind} view\``, `a \`${kind} view\` in its \`views { }\` block — a view of that kind describes ordering or topology ` +
116
+ `recorded in no other document, unlike the static preview view \`loam new\` scaffolds`,
117
+ // A deployment view is topology and belongs in the living map; a dynamic
118
+ // view is a flow, and a flow now has a feature slot of its own. Sending
119
+ // an author to the living landscape for one they are introducing WITH
120
+ // this change was the advice that made the axis's headline case a
121
+ // two-pull-request job.
122
+ kind === "dynamic" ? FLOW_HOME : DEPLOYMENT_HOME);
123
+ }
124
+ }
125
+ }
126
+ //# sourceMappingURL=delta-blocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delta-blocks.js","sourceRoot":"","sources":["../../../../src/core/c4/splice/delta-blocks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD;;;;GAIG;AACH,MAAM,eAAe,GAAG,mCAAmC,CAAC;AAE5D,2FAA2F;AAC3F,MAAM,aAAa,GAAG,iCAAiC,CAAC;AAExD,SAAS,MAAM,CAAC,KAAa,EAAE,MAAc,EAAE,IAAY;IACzD,MAAM,IAAI,oBAAoB,CAC5B,yBAAyB,MAAM,wEAAwE;QACrG,sEAAsE,KAAK,QAAQ;QACnF,GAAG,IAAI,0BAA0B,CACpC,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,cAAc,GAAG,oEAAoE,CAAC;AAE5F,kGAAkG;AAClG,MAAM,eAAe,GACnB,qGAAqG;IACrG,sGAAsG;IACtG,oBAAoB,CAAC;AAEvB,6FAA6F;AAC7F,MAAM,SAAS,GACb,8GAA8G;IAC9G,0DAA0D,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IACvC,KAAK,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,CAAC;QAC9E,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;QACpB,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,MAAM,CACJ,KAAK,KAAK,cAAc,EACxB,iBAAiB,KAAK,cAAc;YACpC,8DAA8D;YAC9D,8DAA8D;YAC9D,yEAAyE;YACzE,mEAAmE;YACnE,oEAAoE;YACpE,qEAAqE;YACrE,uEAAuE;YACvE,uCAAuC;YACvC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,cAAc,CAC1D,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;YAC1B,MAAM,CACJ,KAAK,IAAI,SAAS,EAClB,OAAO,IAAI,0FAA0F;gBACnG,sFAAsF;YACxF,yEAAyE;YACzE,wEAAwE;YACxE,sEAAsE;YACtE,kEAAkE;YAClE,wBAAwB;YACxB,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CACjD,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["/**\n * What a delta may declare that the landscape merge cannot carry.\n *\n * `planLandscapeMerge` splices out of the delta's `model { }` block and nothing\n * else. That is correct — the living landscape is a model plus the views its own\n * authors chose — but it used to be SILENT: a delta declaring `deployment { }`\n * or a `dynamic view` archived at exit 0, reported `+N element(s), +M\n * relationship(s)` exactly as usual, and the block was simply gone. The merge's\n * own parse net cannot catch it either, because a landscape missing a deployment\n * model is perfectly legal — there is nothing to fail on. Nobody finds out until\n * somebody goes looking for a diagram that was archived months ago.\n *\n * So the loss is made a refusal, which is the same doctrine as the merge's other\n * mechanical refusals (an unlocatable declaration, two statements on one line):\n * the input cannot be spliced as authored, `--approve` deliberately does not\n * override it — that flag overrides loam's JUDGMENT about coherence, never its\n * ability to carry an axis — and nothing is written.\n *\n * ## Why views are graded and not simply banned\n *\n * `loam new` scaffolds a `views { view <feat> { include * } }` block into every\n * delta.likec4 (commands/new/templates.ts), so refusing the block outright would\n * refuse loam's own scaffold on its first archive. It is there to be RENDERED\n * while the feature is in flight, and it is meant not to travel.\n *\n * The line drawn here is recoverability, and it is the only line that survives\n * the scaffold:\n *\n * - A static `view` is a rendering OF the model. Once the merge lands, the\n * whole model is in landscape.likec4, so the author can restate the view\n * there at any time from information that still exists. Dropping it loses a\n * convenience.\n * - A `dynamic view`'s ordered steps, and a `deployment { }` block's topology,\n * exist in NO other document the fleet keeps. When the merge drops those,\n * the information is gone. That is what gets refused. Rule 26 sharpens the\n * stakes rather than the rule: a `dynamic view`'s steps are now something\n * loam READS, so dropping one silently would discard checked content, not\n * merely a convenience.\n *\n * A residual is accepted knowingly: a delta carrying a SECOND static view still\n * loses it without a word. Refusing that would mean telling an author with two\n * preview views to delete one, which is a false refusal on a harmless file, and\n * the loss there is recoverable by the argument above.\n *\n * ## The dynamic-view refusal is unchanged; its ADVICE moved\n *\n * A `dynamic view` still cannot ride inside `delta.likec4`, and the reason is\n * mechanical rather than a policy about where flows belong: this document\n * re-declares the landscape's own identifiers to anchor its new edges and\n * carries its own `specification` block because LikeC4 parses it standalone, so\n * it cannot be staged beside the map in one project — a duplicate specification\n * is an error blamed on both files, and a re-declared element is a duplicate id.\n * What changed is where the refusal sends the author. It used to say\n * `architecture/landscape.likec4`, which was the only honest answer while the\n * axis had no feature-delta path: a flow could not ship with the change that\n * made it true. `features/<FEAT>/usecases/<name>.likec4` is that path\n * (`core/usecases/delta/flows.ts`), and it is a views-only document — which is\n * exactly why it stages beside the map when this one cannot.\n */\nimport { maskSource, topLevelBlocks } from \"../source-mask.js\";\nimport { LandscapeSpliceError } from \"./contract.js\";\n\n/**\n * Top-level blocks a delta can declare. `specification` and `model` are absent\n * on purpose: the specification is re-declared in every delta because LikeC4\n * parses each one standalone, and the model is the thing being spliced.\n */\nconst TOP_LEVEL_BLOCK = /\\b(deployment|global|views)\\s*\\{/g;\n\n/** A `dynamic view` / `deployment view` inside a views block — the irrecoverable kinds. */\nconst AUTHORED_VIEW = /\\b(dynamic|deployment)\\s+view\\b/;\n\nfunction refuse(block: string, detail: string, home: string): never {\n throw new LandscapeSpliceError(\n `delta.likec4 declares ${detail}, and the landscape merge splices only what is inside \\`model { }\\` — ` +\n `archiving would drop it silently, so nothing was written. Move the ${block} into ` +\n `${home} and re-run the archive.`,\n );\n}\n\n/** Where the living documents keep what this delta cannot carry. */\nconst LANDSCAPE_HOME = \"architecture/landscape.likec4, where the living documents keep it,\";\n\n/** Where a FEATURE keeps TOPOLOGY — the third whole-file slot, added with the deployment axis. */\nconst DEPLOYMENT_HOME =\n \"features/<FEAT>/deployment/<name>.likec4 — a document of its own, which `loam archive` copies into \" +\n \"architecture/ and `loam unarchive` takes back; say `extend` in it to add to a region the living map \" +\n \"already declares —\";\n\n/** Where a FEATURE keeps a flow — a slot of its own, not the living tree. See the header. */\nconst FLOW_HOME =\n \"features/<FEAT>/usecases/<name>.likec4 — a views-only document of its own, which `loam archive` copies into \" +\n \"architecture/usecases/ and `loam unarchive` takes back —\";\n\n/**\n * Refuse a delta whose non-model blocks the merge would discard.\n *\n * Runs over MASKED source, so a `deployment {` written inside a comment or a\n * description string cannot trigger it — the same masking discipline\n * `scanModel` splices under, and for the same reason: this refuses an archive,\n * and a refusal a comment can provoke is worse than the silence it replaced.\n *\n * Only a block at depth 0 is a top-level declaration (`topLevelBlocks`), and\n * `deployment` at depth 1 is an ordinary `specification { deploymentNode … }`\n * or a view predicate.\n */\nexport function assertMergeableDelta(deltaText: string): void {\n const { code } = maskSource(deltaText);\n for (const { match: m, body: inner } of topLevelBlocks(code, TOP_LEVEL_BLOCK)) {\n const block = m[1]!;\n if (block !== \"views\") {\n refuse(\n `\\`${block} { }\\` block`,\n `a top-level \\`${block} { }\\` block`,\n // The refusal is unchanged and always will be — this document\n // re-declares the landscape's identifiers and carries its own\n // `specification`, so it cannot be staged beside the map in one project.\n // What changed is where it sends the author: a feature introducing\n // topology WITH the change that makes it true now has a slot of its\n // own, and pointing at the living landscape was the advice that made\n // the axis's headline case a two-pull-request job. `global { }` has no\n // such slot and keeps the living home.\n block === \"deployment\" ? DEPLOYMENT_HOME : LANDSCAPE_HOME,\n );\n }\n const authored = AUTHORED_VIEW.exec(inner);\n if (authored !== null) {\n const kind = authored[1]!;\n refuse(\n `\\`${kind} view\\``,\n `a \\`${kind} view\\` in its \\`views { }\\` block — a view of that kind describes ordering or topology ` +\n `recorded in no other document, unlike the static preview view \\`loam new\\` scaffolds`,\n // A deployment view is topology and belongs in the living map; a dynamic\n // view is a flow, and a flow now has a feature slot of its own. Sending\n // an author to the living landscape for one they are introducing WITH\n // this change was the advice that made the axis's headline case a\n // two-pull-request job.\n kind === \"dynamic\" ? FLOW_HOME : DEPLOYMENT_HOME,\n );\n }\n }\n}\n"]}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * What the fleet's extending models ALREADY declare — the half of the archive's
3
+ * existence check that does not live on the map.
4
+ *
5
+ * The check has two joins: by id, and by TITLE for a delta that spells an
6
+ * element under its own identifier rather than the map's. Only the id half ever
7
+ * learned about the models the merge now writes into, so a container a service
8
+ * already draws under a different id was spliced in beside itself and the
9
+ * service silently grew two boxes with one name — while the SAME delta against
10
+ * the same title ON THE MAP adds nothing (review of E1). One rule, two
11
+ * documents, two answers.
12
+ *
13
+ * THE MODEL HALF IS SCOPED TO ITS SERVICE, and the map's is deliberately not.
14
+ * The map's global title index is the id-less fallback for documents written
15
+ * before `metadata { service }` existed, and it carries a hazard its own
16
+ * comment states: two services' boxes sharing a title join to each other unless
17
+ * both sides are bound. A service's interior is exactly where that would bite —
18
+ * every extending model in a fleet names a container 'api' — so a model's
19
+ * declaration joins by title only against an addition resolving to the SAME
20
+ * explicitly bound service. Either side unbound means no title join at all: an
21
+ * addition landing beside a namesake is a duplicate the author can see, and a
22
+ * wrongly skipped one is a container that quietly never arrived.
23
+ *
24
+ * The reader is the SCAN and not a parse, for the reason the caller states: ids
25
+ * are exact inside the fqn namespace the map and its models share, and parsing
26
+ * every model here would cost one LikeC4 workspace per service to answer a
27
+ * question about text. Two kinds of declaration therefore carry no title, and
28
+ * neither loses anything: one whose head names no title (LikeC4 titles it after
29
+ * its own name, and a model's default and a delta's differ exactly when their
30
+ * ids do — which the id join already covers) and one writing its title as a
31
+ * body property.
32
+ */
33
+ import { ancestorIds } from "../../../kernel/ids/fqn/ancestors.js";
34
+ /**
35
+ * Index the scanned models.
36
+ *
37
+ * `bindEls` is the corpus the service binding resolves against — the living
38
+ * map's elements plus the delta's, the same one routing uses, because a model's
39
+ * declaration is bound by an ancestor the MAP owns and a delta's addition by an
40
+ * ancestor either document may.
41
+ */
42
+ export function modelDeclarations(scans, bindEls) {
43
+ const bound = new Map();
44
+ for (const e of bindEls)
45
+ if (e.service !== undefined)
46
+ bound.set(e.id, e.service);
47
+ // An EXPLICIT binding on the id or an ancestor, and nothing else.
48
+ // `serviceResolver`'s last rung answers with the element's own title or its
49
+ // raw id — the rung its own comment calls the one that lies — and here that
50
+ // would file two unbound services' containers under invented names and then
51
+ // let those names join.
52
+ const serviceOf = (id) => {
53
+ for (const candidate of ancestorIds(id)) {
54
+ const service = bound.get(candidate);
55
+ if (service !== undefined)
56
+ return service;
57
+ }
58
+ return undefined;
59
+ };
60
+ const ids = [];
61
+ const titles = new Set();
62
+ for (const { scan } of scans) {
63
+ for (const e of scan?.elements ?? []) {
64
+ // An `extend` frame declares nothing: it reopens an element the map owns.
65
+ if (e.extend === true)
66
+ continue;
67
+ ids.push(e.id);
68
+ if (e.title === undefined)
69
+ continue;
70
+ const service = serviceOf(e.id);
71
+ if (service !== undefined)
72
+ titles.add(titleKey(service, e.title));
73
+ }
74
+ }
75
+ return {
76
+ ids,
77
+ declaresTitle: (id, title) => {
78
+ const service = serviceOf(id);
79
+ return service !== undefined && titles.has(titleKey(service, title));
80
+ },
81
+ };
82
+ }
83
+ /** Length-prefixed: a service id and a title cannot spell another pair's key. */
84
+ function titleKey(service, title) {
85
+ return `${service.length}:${service}${title}`;
86
+ }
87
+ //# sourceMappingURL=declared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declared.js","sourceRoot":"","sources":["../../../../../src/core/c4/splice/identity/declared.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAenE;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAmD,EACnD,OAAwB;IAExB,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IACjF,kEAAkE;IAClE,4EAA4E;IAC5E,4EAA4E;IAC5E,4EAA4E;IAC5E,wBAAwB;IACxB,MAAM,SAAS,GAAG,CAAC,EAAU,EAA+B,EAAE;QAC5D,KAAK,MAAM,SAAS,IAAI,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;YACxC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACrC,IAAI,OAAO,KAAK,SAAS;gBAAE,OAAO,OAAO,CAAC;QAC5C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IACF,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,QAAQ,IAAI,EAAE,EAAE,CAAC;YACrC,0EAA0E;YAC1E,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI;gBAAE,SAAS;YAChC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACf,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;gBAAE,SAAS;YACpC,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAChC,IAAI,OAAO,KAAK,SAAS;gBAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IACD,OAAO;QACL,GAAG;QACH,aAAa,EAAE,CAAC,EAAE,EAAE,KAAK,EAAW,EAAE;YACpC,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;YAC9B,OAAO,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACvE,CAAC;KACF,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,SAAS,QAAQ,CAAC,OAAwB,EAAE,KAAa;IACvD,OAAO,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;AAChD,CAAC","sourcesContent":["/**\n * What the fleet's extending models ALREADY declare — the half of the archive's\n * existence check that does not live on the map.\n *\n * The check has two joins: by id, and by TITLE for a delta that spells an\n * element under its own identifier rather than the map's. Only the id half ever\n * learned about the models the merge now writes into, so a container a service\n * already draws under a different id was spliced in beside itself and the\n * service silently grew two boxes with one name — while the SAME delta against\n * the same title ON THE MAP adds nothing (review of E1). One rule, two\n * documents, two answers.\n *\n * THE MODEL HALF IS SCOPED TO ITS SERVICE, and the map's is deliberately not.\n * The map's global title index is the id-less fallback for documents written\n * before `metadata { service }` existed, and it carries a hazard its own\n * comment states: two services' boxes sharing a title join to each other unless\n * both sides are bound. A service's interior is exactly where that would bite —\n * every extending model in a fleet names a container 'api' — so a model's\n * declaration joins by title only against an addition resolving to the SAME\n * explicitly bound service. Either side unbound means no title join at all: an\n * addition landing beside a namesake is a duplicate the author can see, and a\n * wrongly skipped one is a container that quietly never arrived.\n *\n * The reader is the SCAN and not a parse, for the reason the caller states: ids\n * are exact inside the fqn namespace the map and its models share, and parsing\n * every model here would cost one LikeC4 workspace per service to answer a\n * question about text. Two kinds of declaration therefore carry no title, and\n * neither loses anything: one whose head names no title (LikeC4 titles it after\n * its own name, and a model's default and a delta's differ exactly when their\n * ids do — which the id join already covers) and one writing its title as a\n * body property.\n */\nimport { ancestorIds } from \"../../../kernel/ids/fqn/ancestors.js\";\nimport type { DeclaredService } from \"../../../kernel/ids/service.js\";\nimport type { Elem } from \"../../likec4.js\";\nimport type { ScannedModel } from \"../../source-scan.js\";\n\nexport interface ModelDeclarations {\n /** Every id an extending model declares — the id join's share, and exact. */\n ids: string[];\n /**\n * True when some model already declares an element titled `title` inside the\n * service `id` resolves to. False whenever either side is unbound.\n */\n declaresTitle: (id: string, title: string) => boolean;\n}\n\n/**\n * Index the scanned models.\n *\n * `bindEls` is the corpus the service binding resolves against — the living\n * map's elements plus the delta's, the same one routing uses, because a model's\n * declaration is bound by an ancestor the MAP owns and a delta's addition by an\n * ancestor either document may.\n */\nexport function modelDeclarations(\n scans: ReadonlyArray<{ scan: ScannedModel | null }>,\n bindEls: readonly Elem[],\n): ModelDeclarations {\n const bound = new Map<string, DeclaredService>();\n for (const e of bindEls) if (e.service !== undefined) bound.set(e.id, e.service);\n // An EXPLICIT binding on the id or an ancestor, and nothing else.\n // `serviceResolver`'s last rung answers with the element's own title or its\n // raw id — the rung its own comment calls the one that lies — and here that\n // would file two unbound services' containers under invented names and then\n // let those names join.\n const serviceOf = (id: string): DeclaredService | undefined => {\n for (const candidate of ancestorIds(id)) {\n const service = bound.get(candidate);\n if (service !== undefined) return service;\n }\n return undefined;\n };\n const ids: string[] = [];\n const titles = new Set<string>();\n for (const { scan } of scans) {\n for (const e of scan?.elements ?? []) {\n // An `extend` frame declares nothing: it reopens an element the map owns.\n if (e.extend === true) continue;\n ids.push(e.id);\n if (e.title === undefined) continue;\n const service = serviceOf(e.id);\n if (service !== undefined) titles.add(titleKey(service, e.title));\n }\n }\n return {\n ids,\n declaresTitle: (id, title): boolean => {\n const service = serviceOf(id);\n return service !== undefined && titles.has(titleKey(service, title));\n },\n };\n}\n\n/** Length-prefixed: a service id and a title cannot spell another pair's key. */\nfunction titleKey(service: DeclaredService, title: string): string {\n return `${service.length}:${service}${title}`;\n}\n"]}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Which AUTHORED STATEMENT a parsed addition was written as — the key that
3
+ * matches a `Rel` back to its bytes in delta.likec4, so the splice carries the
4
+ * declaration verbatim instead of re-serializing it.
5
+ *
6
+ * Stricter than `relKey` below on purpose, and asking a different question:
7
+ * `relKey` decides whether the living document already HAS this edge, across
8
+ * two id namespaces, so it joins on titles; this one runs inside ONE document
9
+ * where ids are exact, and it must tell apart two statements the merge would
10
+ * otherwise hand each other's bytes. Both endpoints, the title, all three spine
11
+ * keys and the tags, because a pool entry shared by two additions gives the
12
+ * second one the first one's authored source.
13
+ *
14
+ * The tags are a SET, and a parsed `Rel`'s are not the ones written in the
15
+ * statement: since LikeC4 1.59.0 a relationship kind can carry tags
16
+ * (`relationship publishes { #async }`), and the parse hands every edge of the
17
+ * kind its kind's tags, deduplicated against the statement's own (measured at
18
+ * the 1.59.2 pin). A scanned statement carries only what is written in it, so
19
+ * `scannedStatementKey` adds its kind's tags before keying — keyed as written,
20
+ * every edge of a tagged kind found no statement, and archive refused a delta
21
+ * `validate --feature` and `status` had called ready (`merge-failed`, or
22
+ * `usecase.flow-invalid` when the feature had flows; 2026-10).
23
+ */
24
+ export function relStatementKey(r) {
25
+ const spine = [r.op ?? "", r.publishes ?? "", r.consumes ?? ""];
26
+ return JSON.stringify([r.source, r.target, r.title ?? "", ...spine, [...new Set(r.tags)].sort()]);
27
+ }
28
+ /**
29
+ * A scanned statement's `relStatementKey`, with the tags its kind gives it —
30
+ * what the parse of the same statement carries. `kindTags` is the document's
31
+ * `specification.relationshipKindTags` (`../../parsed/specification.ts`); a
32
+ * document whose kinds carry no tags keys exactly as `relStatementKey` does.
33
+ */
34
+ export function scannedStatementKey(s, kindTags) {
35
+ const inherited = s.kind === undefined ? [] : (kindTags[s.kind] ?? []);
36
+ return relStatementKey({ ...s, tags: [...s.tags, ...inherited] });
37
+ }
38
+ /**
39
+ * The order of loam-inserted relationships that share a landing region:
40
+ * (source title, target title, the three spine keys, title) as one comparable
41
+ * string. Titles, not ids — the namespaces differ. The same edge must sort
42
+ * identically as today's addition and as a statement in the next archive's
43
+ * scan, so every field is one BOTH `Rel` and `ScannedRel` carry.
44
+ */
45
+ export function relSortKey(els, r) {
46
+ const spine = [r.op ?? "", r.publishes ?? "", r.consumes ?? ""];
47
+ return JSON.stringify([titleOf(els, r.source), titleOf(els, r.target), ...spine, r.title ?? ""]);
48
+ }
49
+ /**
50
+ * What makes two edges the same edge. Endpoints are compared by TITLE, which is
51
+ * stable across the delta's and the landscape's id namespaces.
52
+ *
53
+ * An edge carrying a SPINE KEY — `op`, `publishes` or `consumes` — IS that call
54
+ * or that message, whatever it is titled: retitling it must not merge a second
55
+ * copy. An edge with none has only its title. Separate namespaces, because they
56
+ * are separate things: an op-less edge titled `authorizePayment` is not the edge
57
+ * whose operationId is authorizePayment, and keying on `op ?? title` quietly
58
+ * merged only one of them.
59
+ *
60
+ * ALL THREE keys, not just `op`. While the other two were out, a delta edge differing from a
61
+ * living one only by `metadata { publishes 'x' }` hashed the same, counted as already present,
62
+ * and was dropped — `+0 relationship(s)` at exit 0 over a binding that never reached the map.
63
+ */
64
+ export function relKey(els, r) {
65
+ const src = titleOf(els, r.source);
66
+ const tgt = titleOf(els, r.target);
67
+ const spine = [r.op ?? "", r.publishes ?? "", r.consumes ?? ""];
68
+ return JSON.stringify(spine.some((v) => v !== "") ? ["spine", src, tgt, ...spine] : ["title", src, tgt, r.title ?? ""]);
69
+ }
70
+ export function titleOf(elements, id) {
71
+ return elements.find((e) => e.id === id)?.title ?? id;
72
+ }
73
+ //# sourceMappingURL=edges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edges.js","sourceRoot":"","sources":["../../../../../src/core/c4/splice/identity/edges.ts"],"names":[],"mappings":"AAwBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,eAAe,CAAC,CAAmB;IACjD,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACpG,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,CAAa,EAAE,QAAkB;IACnE,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACvE,OAAO,eAAe,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,GAAW,EACX,CAAyG;IAEzG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;AACnG,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,CAAM;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;AAC1H,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,QAAgB,EAAE,EAAU;IAClD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,EAAE,CAAC;AACxD,CAAC","sourcesContent":["/**\n * How the landscape merge decides that two relationships are the SAME EDGE,\n * and in what order equal ones are written.\n *\n * A subject of its own, and not a corner of placement: everything in\n * `../placement.ts` answers *where in the text* a statement goes, in byte\n * offsets, while everything here answers *which statement this is*, as a\n * comparable string. The merge asks the identity question first and the\n * placement question second, and getting the first one wrong is the failure\n * mode that is silent — a delta edge that hashes the same as a living one is\n * counted as already present and dropped at exit 0, with `+0 relationship(s)`\n * printed over a binding that never reached the map.\n *\n * Both keys are built from fields BOTH `Rel` and `ScannedRel` carry, because\n * the same edge must key identically as today's addition and as a statement in\n * the next archive's scan of the file it was written into. A field only one of\n * them has would make the merge disagree with itself one archive later. The one\n * field the two read differently — the tags, which the parse inherits from the\n * relationship's kind — is reconciled on the scanned side (`scannedStatementKey`).\n */\nimport type { Elem, Rel } from \"../../likec4.js\";\nimport type { ScannedRel } from \"../../source-scan.js\";\nimport type { KindTags } from \"../contract.js\";\n\n/**\n * Which AUTHORED STATEMENT a parsed addition was written as — the key that\n * matches a `Rel` back to its bytes in delta.likec4, so the splice carries the\n * declaration verbatim instead of re-serializing it.\n *\n * Stricter than `relKey` below on purpose, and asking a different question:\n * `relKey` decides whether the living document already HAS this edge, across\n * two id namespaces, so it joins on titles; this one runs inside ONE document\n * where ids are exact, and it must tell apart two statements the merge would\n * otherwise hand each other's bytes. Both endpoints, the title, all three spine\n * keys and the tags, because a pool entry shared by two additions gives the\n * second one the first one's authored source.\n *\n * The tags are a SET, and a parsed `Rel`'s are not the ones written in the\n * statement: since LikeC4 1.59.0 a relationship kind can carry tags\n * (`relationship publishes { #async }`), and the parse hands every edge of the\n * kind its kind's tags, deduplicated against the statement's own (measured at\n * the 1.59.2 pin). A scanned statement carries only what is written in it, so\n * `scannedStatementKey` adds its kind's tags before keying — keyed as written,\n * every edge of a tagged kind found no statement, and archive refused a delta\n * `validate --feature` and `status` had called ready (`merge-failed`, or\n * `usecase.flow-invalid` when the feature had flows; 2026-10).\n */\nexport function relStatementKey(r: Rel | ScannedRel): string {\n const spine = [r.op ?? \"\", r.publishes ?? \"\", r.consumes ?? \"\"];\n return JSON.stringify([r.source, r.target, r.title ?? \"\", ...spine, [...new Set(r.tags)].sort()]);\n}\n\n/**\n * A scanned statement's `relStatementKey`, with the tags its kind gives it —\n * what the parse of the same statement carries. `kindTags` is the document's\n * `specification.relationshipKindTags` (`../../parsed/specification.ts`); a\n * document whose kinds carry no tags keys exactly as `relStatementKey` does.\n */\nexport function scannedStatementKey(s: ScannedRel, kindTags: KindTags): string {\n const inherited = s.kind === undefined ? [] : (kindTags[s.kind] ?? []);\n return relStatementKey({ ...s, tags: [...s.tags, ...inherited] });\n}\n\n/**\n * The order of loam-inserted relationships that share a landing region:\n * (source title, target title, the three spine keys, title) as one comparable\n * string. Titles, not ids — the namespaces differ. The same edge must sort\n * identically as today's addition and as a statement in the next archive's\n * scan, so every field is one BOTH `Rel` and `ScannedRel` carry.\n */\nexport function relSortKey(\n els: Elem[],\n r: { source: string; target: string; title?: string; op?: string; publishes?: string; consumes?: string },\n): string {\n const spine = [r.op ?? \"\", r.publishes ?? \"\", r.consumes ?? \"\"];\n return JSON.stringify([titleOf(els, r.source), titleOf(els, r.target), ...spine, r.title ?? \"\"]);\n}\n\n/**\n * What makes two edges the same edge. Endpoints are compared by TITLE, which is\n * stable across the delta's and the landscape's id namespaces.\n *\n * An edge carrying a SPINE KEY — `op`, `publishes` or `consumes` — IS that call\n * or that message, whatever it is titled: retitling it must not merge a second\n * copy. An edge with none has only its title. Separate namespaces, because they\n * are separate things: an op-less edge titled `authorizePayment` is not the edge\n * whose operationId is authorizePayment, and keying on `op ?? title` quietly\n * merged only one of them.\n *\n * ALL THREE keys, not just `op`. While the other two were out, a delta edge differing from a\n * living one only by `metadata { publishes 'x' }` hashed the same, counted as already present,\n * and was dropped — `+0 relationship(s)` at exit 0 over a binding that never reached the map.\n */\nexport function relKey(els: Elem[], r: Rel): string {\n const src = titleOf(els, r.source);\n const tgt = titleOf(els, r.target);\n const spine = [r.op ?? \"\", r.publishes ?? \"\", r.consumes ?? \"\"];\n return JSON.stringify(spine.some((v) => v !== \"\") ? [\"spine\", src, tgt, ...spine] : [\"title\", src, tgt, r.title ?? \"\"]);\n}\n\nexport function titleOf(elements: Elem[], id: string): string {\n return elements.find((e) => e.id === id)?.title ?? id;\n}\n"]}
@@ -0,0 +1,80 @@
1
+ import { scanModel } from "../../source-scan.js";
2
+ import { modelDeclarations } from "./declared.js";
3
+ import { relKey } from "./edges.js";
4
+ /**
5
+ * Report (never guess) when a title join would cross two bound services: with
6
+ * both sides carrying an explicit `metadata { service }` binding and every
7
+ * binding disagreeing, they are provably DIFFERENT services' boxes sharing a
8
+ * title ('API', 'Database'). Skipping would silently drop the addition, and any
9
+ * delta edge into it would then refuse the whole archive at the merge's parse
10
+ * net with a message about nothing.
11
+ */
12
+ export function newAdditions(req) {
13
+ const { livingEls, livingRels, bindEls, deltaElements, candidates, models, borrowed } = req;
14
+ const modelScans = models.map((model) => ({ scan: scanModel(model.text, borrowed) }));
15
+ const declared = modelDeclarations(modelScans, bindEls);
16
+ const haveIds = new Set([...livingEls.map((e) => e.id), ...declared.ids]);
17
+ // The title join needs the matched element back, not just membership: the
18
+ // cross-service guard below compares service BINDINGS across the join.
19
+ const byTitle = new Map();
20
+ const seeTitle = (el) => {
21
+ byTitle.set(el.title, [...(byTitle.get(el.title) ?? []), el]);
22
+ };
23
+ for (const el of livingEls)
24
+ seeTitle(el);
25
+ const els = [];
26
+ for (const e of candidates.els) {
27
+ if (haveIds.has(e.id))
28
+ continue;
29
+ // The addition's OWN service first, and before the map's global title
30
+ // index: a box this service's model already draws is existence, whoever
31
+ // else on the map happens to share the title.
32
+ if (declared.declaresTitle(e.id, e.title))
33
+ continue;
34
+ const sameTitle = byTitle.get(e.title);
35
+ if (sameTitle !== undefined) {
36
+ // A title match is the id-less fallback join, and skipping on it is only
37
+ // safe when the two sides could be the same box.
38
+ if (e.service !== undefined && sameTitle.every((m) => m.service !== undefined && m.service !== e.service)) {
39
+ return { els, rels: [], declaredIds: new Set(declared.ids), collision: { addition: e, living: sameTitle[0] } };
40
+ }
41
+ // KNOWN (narrowed by the guard above): with EITHER side unbound the title
42
+ // join stays trusting — the unbound title-fallback is the legal legacy
43
+ // pattern — so a cross-service collision hiding behind an unbound element
44
+ // is still silently skipped here. Scoping titles per service is backlog.
45
+ continue;
46
+ }
47
+ haveIds.add(e.id);
48
+ seeTitle(e);
49
+ els.push(e);
50
+ }
51
+ // An edge already in the landscape consumes one delta edge of the same
52
+ // identity, which is what keeps re-archiving idempotent.
53
+ const have = new Map();
54
+ for (const r of livingRels) {
55
+ const k = relKey(livingEls, r);
56
+ have.set(k, (have.get(k) ?? 0) + 1);
57
+ }
58
+ // An edge an extending model already draws consumes a delta edge exactly as a
59
+ // living map edge does — keyed through the DELTA's elements, because the
60
+ // model spells its endpoints in the map's fqn namespace and the delta must
61
+ // too for the nesting to resolve at all.
62
+ for (const { scan } of modelScans) {
63
+ for (const r of scan?.rels ?? []) {
64
+ const k = relKey(deltaElements, r);
65
+ have.set(k, (have.get(k) ?? 0) + 1);
66
+ }
67
+ }
68
+ const rels = [];
69
+ for (const r of candidates.rels) {
70
+ const k = relKey(deltaElements, r);
71
+ const n = have.get(k) ?? 0;
72
+ if (n > 0) {
73
+ have.set(k, n - 1);
74
+ continue;
75
+ }
76
+ rels.push(r);
77
+ }
78
+ return { els, rels, declaredIds: new Set(declared.ids) };
79
+ }
80
+ //# sourceMappingURL=existing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"existing.js","sourceRoot":"","sources":["../../../../../src/core/c4/splice/identity/existing.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,SAAS,EAAkB,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAqDpC;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,GAAoB;IAC/C,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;IAC5F,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,MAAM,QAAQ,GAAG,iBAAiB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,QAAQ,GAAG,CAAC,EAAQ,EAAQ,EAAE;QAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAChE,CAAC,CAAC;IACF,KAAK,MAAM,EAAE,IAAI,SAAS;QAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,GAAG,GAAW,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAAE,SAAS;QAChC,sEAAsE;QACtE,wEAAwE;QACxE,8CAA8C;QAC9C,IAAI,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC;YAAE,SAAS;QACpD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,yEAAyE;YACzE,iDAAiD;YACjD,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1G,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC;YAClH,CAAC;YACD,0EAA0E;YAC1E,uEAAuE;YACvE,0EAA0E;YAC1E,yEAAyE;YACzE,SAAS;QACX,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClB,QAAQ,CAAC,CAAC,CAAC,CAAC;QACZ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IAED,uEAAuE;IACvE,yDAAyD;IACzD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,8EAA8E;IAC9E,yEAAyE;IACzE,2EAA2E;IAC3E,yCAAyC;IACzC,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,UAAU,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAU,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACnB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACf,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;AAC3D,CAAC","sourcesContent":["/**\n * Which of a delta's tagged declarations the living fleet does NOT already have\n * — the third identity question of the archive's C4 merge, beside `./edges.ts`'s\n * \"which statement is this\" and `./owner.ts`'s \"which document owns it\".\n *\n * It moved out of `../landscape-merge.ts` when that file crossed the 400-line\n * limit, and this is the seam it wanted: everything here runs BEFORE a single\n * byte is placed, over parsed views and scans alone, and answers one question\n * that has nothing to do with where anything lands. What is left behind is the\n * splice itself.\n *\n * TWO JOINS, and the asymmetry between them is the whole subject. Ids are exact\n * and are checked against the map AND against every extending model, so\n * re-archiving is idempotent whichever document an addition landed in. Titles\n * are the id-less fallback every repository written before\n * `metadata { service }` relies on: global on the map (with the cross-service\n * collision refused rather than silently skipped) and scoped to one service in\n * the models, for the reason `./declared.ts` states.\n *\n * Relationships are matched by COUNT, not by membership: two edges the model\n * cannot tell apart are still two edges, and dropping the second one silently\n * loses a call the author drew.\n */\nimport type { Elem, Rel } from \"../../likec4.js\";\nimport { scanModel, type ScanKinds } from \"../../source-scan.js\";\nimport type { ExtendingModel } from \"../contract.js\";\nimport { modelDeclarations } from \"./declared.js\";\nimport { relKey } from \"./edges.js\";\n\nexport interface ExistingRequest {\n /** The living map's parsed elements. */\n livingEls: Elem[];\n /** The living map's parsed relationships. */\n livingRels: Rel[];\n /**\n * The corpus a service binding resolves against — the living map's elements\n * plus the delta's, so a declaration the delta introduces resolves the moment\n * its bytes would land.\n */\n bindEls: Elem[];\n /** EVERY element the delta declares — edge identity reads past the tagged ones. */\n deltaElements: Elem[];\n /** The delta's tagged elements and relationships: the candidate additions. */\n candidates: { els: Elem[]; rels: Rel[] };\n /** The fleet's extending models, whose declarations count as existence too. */\n models: readonly ExtendingModel[];\n /**\n * The kinds those models borrow from the map. A model's `kind name`\n * declaration or `a .kind b` edge the scan cannot see is one this join counts\n * as missing: the archive spliced a second copy of an edge the model already\n * drew in the dotted form (2026-10).\n */\n borrowed?: ScanKinds;\n}\n\nexport interface Additions {\n /** The tagged elements no living document already declares. */\n els: Elem[];\n /** The tagged relationships no living document already draws. */\n rels: Rel[];\n /**\n * Every id the extending models declare. Routing needs it as well: an\n * `extend` block's children are map fqns, so a container a model already draws\n * anchors an addition's id chain in the map's namespace exactly as a living\n * element does (`./owner.ts`).\n */\n declaredIds: Set<string>;\n /**\n * A title join the merge must refuse rather than take, present only when one\n * was found — the caller stops there and nothing is written.\n *\n * REPORTED, not thrown, and that is a package rule rather than a style\n * preference: `LandscapeSpliceError` lives in `../contract.ts`, and importing\n * it as a VALUE from here would make `splice/` and `splice/identity/` import\n * each other (`scripts/package-graph.mjs` refuses the cycle). The refusal text\n * belongs to the merge anyway — it is the one that decides to write.\n */\n collision?: { addition: Elem; living: Elem };\n}\n\n/**\n * Report (never guess) when a title join would cross two bound services: with\n * both sides carrying an explicit `metadata { service }` binding and every\n * binding disagreeing, they are provably DIFFERENT services' boxes sharing a\n * title ('API', 'Database'). Skipping would silently drop the addition, and any\n * delta edge into it would then refuse the whole archive at the merge's parse\n * net with a message about nothing.\n */\nexport function newAdditions(req: ExistingRequest): Additions {\n const { livingEls, livingRels, bindEls, deltaElements, candidates, models, borrowed } = req;\n const modelScans = models.map((model) => ({ scan: scanModel(model.text, borrowed) }));\n const declared = modelDeclarations(modelScans, bindEls);\n const haveIds = new Set([...livingEls.map((e) => e.id), ...declared.ids]);\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 livingEls) seeTitle(el);\n const els: Elem[] = [];\n for (const e of candidates.els) {\n if (haveIds.has(e.id)) continue;\n // The addition's OWN service first, and before the map's global title\n // index: a box this service's model already draws is existence, whoever\n // else on the map happens to share the title.\n if (declared.declaresTitle(e.id, e.title)) 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.\n if (e.service !== undefined && sameTitle.every((m) => m.service !== undefined && m.service !== e.service)) {\n return { els, rels: [], declaredIds: new Set(declared.ids), collision: { addition: e, living: sameTitle[0]! } };\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 els.push(e);\n }\n\n // An edge already in the landscape consumes one delta edge of the same\n // identity, which is what keeps re-archiving idempotent.\n const have = new Map<string, number>();\n for (const r of livingRels) {\n const k = relKey(livingEls, r);\n have.set(k, (have.get(k) ?? 0) + 1);\n }\n // An edge an extending model already draws consumes a delta edge exactly as a\n // living map edge does — keyed through the DELTA's elements, because the\n // model spells its endpoints in the map's fqn namespace and the delta must\n // too for the nesting to resolve at all.\n for (const { scan } of modelScans) {\n for (const r of scan?.rels ?? []) {\n const k = relKey(deltaElements, r);\n have.set(k, (have.get(k) ?? 0) + 1);\n }\n }\n const rels: Rel[] = [];\n for (const r of candidates.rels) {\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 rels.push(r);\n }\n return { els, rels, declaredIds: new Set(declared.ids) };\n}\n"]}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * `./owner.ts`'s question one construct up: not "whose interior is this id" but
3
+ * "does this whole NEW BLOCK hand its interior over" — decided ONCE per block,
4
+ * and read by BOTH halves of the archive's routing.
5
+ *
6
+ * A service the feature INTRODUCES arrives as one tagged element whose authored
7
+ * bytes already hold its containers. Those containers carry no feature tag of
8
+ * their own — LikeC4 does not inherit tags — so per-addition routing cannot see
9
+ * them: they rode onto the map inside their parent, and the service's extending
10
+ * model could then never declare them, because writing the container the adopt
11
+ * brief prescribes made the map's copy a duplicate and the service `c4.invalid`
12
+ * (verification 2026-09-04, refutation of E1). So the box lands on the map
13
+ * without its interior and the children go into the model's `extend <fqn> { }`
14
+ * block, which `../model/merge.ts` creates.
15
+ *
16
+ * ONE DECISION, NOT TWO, and that is the whole reason this is a module rather
17
+ * than a closure inside `../landscape-merge.ts`. A child of such a block CAN
18
+ * carry the feature tag, and then both halves see it: per-addition routing reads
19
+ * its tag and sends it to the model, while the block decision leaves the same
20
+ * child's bytes on the map. Each half was right on its own and the merge
21
+ * declared the child twice — `merge-failed`, exit 1, nothing written, on a delta
22
+ * neither half was wrong about (re-verification 2026-09-04). `covering` is what
23
+ * makes the routing defer: a declaration written inside a block is the BLOCK's
24
+ * to place, whether or not it is tagged.
25
+ *
26
+ * A block holding a RELATIONSHIP statement rides whole. Such an edge names its
27
+ * endpoints by their LOCAL names inside the block, and the model merge anchors a
28
+ * relationship at the model block's top level — splitting the two apart would
29
+ * leave the map naming children it no longer declares, and `api -> worker` at a
30
+ * model's top level resolves to nothing. The edge rides with its block, for the
31
+ * same reason its siblings do.
32
+ */
33
+ import { parentIdOf } from "../../../kernel/ids/fqn/ancestors.js";
34
+ export function planInteriors(req) {
35
+ const { scan, deltaElements, owner, addedEls } = req;
36
+ const byId = new Map(scan.elements.map((e) => [e.id, e]));
37
+ const blocks = [];
38
+ const routed = [];
39
+ const omit = [];
40
+ for (const e of addedEls) {
41
+ // A block is an addition that lands on the MAP (nothing owns its parent)
42
+ // and whose own interior belongs to a model. An addition routed away is not
43
+ // a block: its children ride inside its bytes into the same model, which is
44
+ // `../model/merge.ts`'s own `rides` rule.
45
+ if (owner(parentIdOf(e.id)) !== undefined)
46
+ continue;
47
+ const model = owner(e.id);
48
+ if (model === undefined)
49
+ continue;
50
+ // Not in the scan: the splice loop refuses on its own, with the message that
51
+ // names the declaration it could not locate.
52
+ const src = byId.get(e.id);
53
+ if (src === undefined)
54
+ continue;
55
+ const kids = scan.elements.filter((c) => parentIdOf(c.id) === e.id);
56
+ if (kids.length === 0)
57
+ continue;
58
+ const els = kids
59
+ .map((c) => deltaElements.find((x) => x.id === c.id))
60
+ .filter((x) => x !== undefined);
61
+ // A child the parse does not carry is one the model merge could not splice
62
+ // either (it splices by id), so the whole block rides rather than losing it.
63
+ const splits = els.length === kids.length && !scan.rels.some((r) => r.start >= src.start && r.end <= src.end);
64
+ blocks.push({ range: { start: src.start, end: src.end }, fate: splits ? "split" : "whole" });
65
+ if (!splits)
66
+ continue;
67
+ routed.push({ model, els });
68
+ omit.push(...kids.map((c) => ({ start: c.start, end: c.end })));
69
+ }
70
+ return {
71
+ omit,
72
+ routed,
73
+ covering: (at) => blocks.find((b) => inside(at, b.range))?.fate ?? null,
74
+ };
75
+ }
76
+ /** Strictly inside: the ranges of two declarations nest or are disjoint, never overlap. */
77
+ function inside(at, block) {
78
+ return at.start >= block.start && at.end <= block.end && (at.start !== block.start || at.end !== block.end);
79
+ }
80
+ //# sourceMappingURL=interior.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interior.js","sourceRoot":"","sources":["../../../../../src/core/c4/splice/identity/interior.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAuClE,MAAM,UAAU,aAAa,CAAC,GAAoB;IAChD,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;IACrD,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,MAAM,MAAM,GAAmD,EAAE,CAAC;IAClE,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,MAAM,IAAI,GAAkB,EAAE,CAAC;IAE/B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,yEAAyE;QACzE,4EAA4E;QAC5E,4EAA4E;QAC5E,0CAA0C;QAC1C,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS;YAAE,SAAS;QACpD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,6EAA6E;QAC7E,6CAA6C;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3B,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACpE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAChC,MAAM,GAAG,GAAG,IAAI;aACb,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACpD,MAAM,CAAC,CAAC,CAAC,EAAa,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;QAC7C,2EAA2E;QAC3E,6EAA6E;QAC7E,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9G,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7F,IAAI,CAAC,MAAM;YAAE,SAAS;QACtB,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,OAAO;QACL,IAAI;QACJ,MAAM;QACN,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,IAAI,IAAI;KACxE,CAAC;AACJ,CAAC;AAED,2FAA2F;AAC3F,SAAS,MAAM,CAAC,EAAe,EAAE,KAAkB;IACjD,OAAO,EAAE,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC;AAC9G,CAAC","sourcesContent":["/**\n * `./owner.ts`'s question one construct up: not \"whose interior is this id\" but\n * \"does this whole NEW BLOCK hand its interior over\" — decided ONCE per block,\n * and read by BOTH halves of the archive's routing.\n *\n * A service the feature INTRODUCES arrives as one tagged element whose authored\n * bytes already hold its containers. Those containers carry no feature tag of\n * their own — LikeC4 does not inherit tags — so per-addition routing cannot see\n * them: they rode onto the map inside their parent, and the service's extending\n * model could then never declare them, because writing the container the adopt\n * brief prescribes made the map's copy a duplicate and the service `c4.invalid`\n * (verification 2026-09-04, refutation of E1). So the box lands on the map\n * without its interior and the children go into the model's `extend <fqn> { }`\n * block, which `../model/merge.ts` creates.\n *\n * ONE DECISION, NOT TWO, and that is the whole reason this is a module rather\n * than a closure inside `../landscape-merge.ts`. A child of such a block CAN\n * carry the feature tag, and then both halves see it: per-addition routing reads\n * its tag and sends it to the model, while the block decision leaves the same\n * child's bytes on the map. Each half was right on its own and the merge\n * declared the child twice — `merge-failed`, exit 1, nothing written, on a delta\n * neither half was wrong about (re-verification 2026-09-04). `covering` is what\n * makes the routing defer: a declaration written inside a block is the BLOCK's\n * to place, whether or not it is tagged.\n *\n * A block holding a RELATIONSHIP statement rides whole. Such an edge names its\n * endpoints by their LOCAL names inside the block, and the model merge anchors a\n * relationship at the model block's top level — splitting the two apart would\n * leave the map naming children it no longer declares, and `api -> worker` at a\n * model's top level resolves to nothing. The edge rides with its block, for the\n * same reason its siblings do.\n */\nimport { parentIdOf } from \"../../../kernel/ids/fqn/ancestors.js\";\nimport type { Elem } from \"../../likec4.js\";\nimport type { ScannedModel } from \"../../source-scan.js\";\nimport type { SourceRange } from \"../authored-source.js\";\nimport type { ExtendingModel } from \"../contract.js\";\n\n/** What one block decided about everything written inside it. */\nexport type BlockFate = \"whole\" | \"split\";\n\nexport interface InteriorRequest {\n /** The delta's declarations located in source — the bytes every decision is about. */\n scan: ScannedModel;\n /** EVERY element the delta declares: a child the parse does not carry cannot be routed. */\n deltaElements: readonly Elem[];\n /** Which document owns a given parent id's interior (`./owner.ts`). */\n owner: (parentId: string) => ExtendingModel | undefined;\n /** The delta's declarations this merge is adding — where the blocks are found. */\n addedEls: readonly Elem[];\n}\n\n/** One split block's share: what its service's model takes, and what the map must drop. */\nexport interface RoutedInterior {\n model: ExtendingModel;\n els: Elem[];\n}\n\nexport interface Interiors {\n /** Delta ranges the map's spliced bytes must leave behind — the split blocks' children. */\n readonly omit: readonly SourceRange[];\n /** What each split block hands the model that owns it. */\n readonly routed: readonly RoutedInterior[];\n /**\n * The decision of the block a statement is written INSIDE, or null when no\n * block holds it and ordinary routing applies. A block's own declaration is\n * not inside itself and answers null.\n */\n covering: (at: SourceRange) => BlockFate | null;\n}\n\nexport function planInteriors(req: InteriorRequest): Interiors {\n const { scan, deltaElements, owner, addedEls } = req;\n const byId = new Map(scan.elements.map((e) => [e.id, e]));\n const blocks: Array<{ range: SourceRange; fate: BlockFate }> = [];\n const routed: RoutedInterior[] = [];\n const omit: SourceRange[] = [];\n\n for (const e of addedEls) {\n // A block is an addition that lands on the MAP (nothing owns its parent)\n // and whose own interior belongs to a model. An addition routed away is not\n // a block: its children ride inside its bytes into the same model, which is\n // `../model/merge.ts`'s own `rides` rule.\n if (owner(parentIdOf(e.id)) !== undefined) continue;\n const model = owner(e.id);\n if (model === undefined) continue;\n // Not in the scan: the splice loop refuses on its own, with the message that\n // names the declaration it could not locate.\n const src = byId.get(e.id);\n if (src === undefined) continue;\n const kids = scan.elements.filter((c) => parentIdOf(c.id) === e.id);\n if (kids.length === 0) continue;\n const els = kids\n .map((c) => deltaElements.find((x) => x.id === c.id))\n .filter((x): x is Elem => x !== undefined);\n // A child the parse does not carry is one the model merge could not splice\n // either (it splices by id), so the whole block rides rather than losing it.\n const splits = els.length === kids.length && !scan.rels.some((r) => r.start >= src.start && r.end <= src.end);\n blocks.push({ range: { start: src.start, end: src.end }, fate: splits ? \"split\" : \"whole\" });\n if (!splits) continue;\n routed.push({ model, els });\n omit.push(...kids.map((c) => ({ start: c.start, end: c.end })));\n }\n\n return {\n omit,\n routed,\n covering: (at) => blocks.find((b) => inside(at, b.range))?.fate ?? null,\n };\n}\n\n/** Strictly inside: the ranges of two declarations nest or are disjoint, never overlap. */\nfunction inside(at: SourceRange, block: SourceRange): boolean {\n return at.start >= block.start && at.end <= block.end && (at.start !== block.start || at.end !== block.end);\n}\n"]}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Which DOCUMENT owns the home of a new declaration — the other identity
3
+ * question the archive's C4 merge asks, beside `./edges.ts`'s "which statement
4
+ * is this".
5
+ *
6
+ * A declaration nested under a service's element belongs to that service's
7
+ * `model.likec4` when the model EXTENDS the fleet map: that is the only
8
+ * document allowed to declare the service's interior (SCHEMA.md, "the map holds
9
+ * no service's interior"), and the map's copy becomes a duplicate the moment
10
+ * the model writes its own — which is exactly what the adopt brief tells a
11
+ * service to do, and exactly the failure this closes (verification 2026-09-04,
12
+ * E1).
13
+ *
14
+ * The PARENT is what resolves, never the element itself, so the caller hands in
15
+ * the parent id and this answers "whose interior is that". A service's own
16
+ * element on the map has a parent that stands for nothing — a grouping box, or
17
+ * the model root — so it resolves to no service with a model, stays on the map,
18
+ * and every service-level edge between two of them stays with it. Asking about a
19
+ * service element's OWN id is the same question one level down, and that is how
20
+ * the landscape merge learns where a NEW service's interior belongs.
21
+ *
22
+ * A service with a STANDALONE model, or none at all, is simply absent from the
23
+ * list and therefore owns nothing here: the map draws its containers, which is
24
+ * legal and is what every repository did before the extending shape existed.
25
+ */
26
+ import { ancestorIds } from "../../../kernel/ids/fqn/ancestors.js";
27
+ import { serviceResolver } from "../../resolve/service.js";
28
+ export function ownerOf(req) {
29
+ const { bindEls, living, declared, added, models } = req;
30
+ if (models.length === 0)
31
+ return () => undefined;
32
+ const byService = new Map(models.map((m) => [m.service, m]));
33
+ const resolve = serviceResolver(bindEls);
34
+ return (parentId) => {
35
+ if (parentId === "")
36
+ return undefined;
37
+ // Walk up until the chain reaches an id the map's namespace already holds.
38
+ // Everything below that point has to be a declaration this delta ADDS —
39
+ // a child of a container the same delta introduces, or the new service
40
+ // element itself — because those ids will exist once the merge lands.
41
+ for (const a of ancestorIds(parentId)) {
42
+ if (living.has(a) || declared.has(a))
43
+ break;
44
+ if (!added.has(a))
45
+ return undefined;
46
+ }
47
+ return byService.get(resolve(parentId));
48
+ };
49
+ }
50
+ //# sourceMappingURL=owner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner.js","sourceRoot":"","sources":["../../../../../src/core/c4/splice/identity/owner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AAEnE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAsC3D,MAAM,UAAU,OAAO,CAAC,GAAiB;IACvC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IACzD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACzC,OAAO,CAAC,QAAgB,EAA8B,EAAE;QACtD,IAAI,QAAQ,KAAK,EAAE;YAAE,OAAO,SAAS,CAAC;QACtC,2EAA2E;QAC3E,wEAAwE;QACxE,uEAAuE;QACvE,sEAAsE;QACtE,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,MAAM;YAC5C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,OAAO,SAAS,CAAC;QACtC,CAAC;QACD,OAAO,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Which DOCUMENT owns the home of a new declaration — the other identity\n * question the archive's C4 merge asks, beside `./edges.ts`'s \"which statement\n * is this\".\n *\n * A declaration nested under a service's element belongs to that service's\n * `model.likec4` when the model EXTENDS the fleet map: that is the only\n * document allowed to declare the service's interior (SCHEMA.md, \"the map holds\n * no service's interior\"), and the map's copy becomes a duplicate the moment\n * the model writes its own — which is exactly what the adopt brief tells a\n * service to do, and exactly the failure this closes (verification 2026-09-04,\n * E1).\n *\n * The PARENT is what resolves, never the element itself, so the caller hands in\n * the parent id and this answers \"whose interior is that\". A service's own\n * element on the map has a parent that stands for nothing — a grouping box, or\n * the model root — so it resolves to no service with a model, stays on the map,\n * and every service-level edge between two of them stays with it. Asking about a\n * service element's OWN id is the same question one level down, and that is how\n * the landscape merge learns where a NEW service's interior belongs.\n *\n * A service with a STANDALONE model, or none at all, is simply absent from the\n * list and therefore owns nothing here: the map draws its containers, which is\n * legal and is what every repository did before the extending shape existed.\n */\nimport { ancestorIds } from \"../../../kernel/ids/fqn/ancestors.js\";\nimport type { Elem } from \"../../likec4.js\";\nimport { serviceResolver } from \"../../resolve/service.js\";\nimport type { ExtendingModel } from \"../contract.js\";\n\nexport interface OwnerRequest {\n /**\n * The corpus the parent id resolves against — the LIVING map's elements plus\n * the delta's own, so an element the delta introduces resolves the moment its\n * bytes would land.\n */\n bindEls: Elem[];\n /**\n * The ids the LIVING map declares. Reaching one is what proves the id chain is\n * spelled in the map's own namespace.\n */\n living: ReadonlySet<string>;\n /**\n * The ids the fleet's extending models declare inside their `extend` blocks.\n * Those are map fqns too — an `extend` frame reopens an element the map owns —\n * so a container already drawn in a model anchors the chain exactly as a living\n * one does, and an edge into a child of it still routes.\n */\n declared: ReadonlySet<string>;\n /**\n * The ids this merge is ADDING: the delta's declarations that survived the\n * existence joins. An id that is neither living, declared, nor added is one the\n * delta spells under its OWN name for an element the map already holds under\n * another — the legacy title join, which the landscape merge still merges for.\n * Routing it would open an `extend` block on an fqn the map has never heard of,\n * and the model's parse net would refuse an archive that used to merge\n * (verification 2026-09-04, refutation of E1: the guard used to accept any\n * chain whose ANCESTOR was living, so a title-joined name inside a group the\n * map declares — `marketplace.orderSvc` under the living `marketplace` — passed\n * it and every grouped fleet's legacy delta became `merge-failed`).\n */\n added: ReadonlySet<string>;\n models: readonly ExtendingModel[];\n}\n\nexport function ownerOf(req: OwnerRequest): (parentId: string) => ExtendingModel | undefined {\n const { bindEls, living, declared, added, models } = req;\n if (models.length === 0) return () => undefined;\n const byService = new Map(models.map((m) => [m.service, m]));\n const resolve = serviceResolver(bindEls);\n return (parentId: string): ExtendingModel | undefined => {\n if (parentId === \"\") return undefined;\n // Walk up until the chain reaches an id the map's namespace already holds.\n // Everything below that point has to be a declaration this delta ADDS —\n // a child of a container the same delta introduces, or the new service\n // element itself — because those ids will exist once the merge lands.\n for (const a of ancestorIds(parentId)) {\n if (living.has(a) || declared.has(a)) break;\n if (!added.has(a)) return undefined;\n }\n return byService.get(resolve(parentId));\n };\n}\n"]}