@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,308 @@
1
+ /**
2
+ * The text-level view of a LikeC4 document: which bytes each declaration owns.
3
+ *
4
+ * loam's archive merges the landscape by SPLICING authored text, not by
5
+ * re-rendering a parsed model — a re-render would reformat every line somebody
6
+ * wrote. So the merge needs both views of the same file: the parsed one
7
+ * (`likec4.ts`) for what the model MEANS, and this one for where each
8
+ * declaration physically is. A key only one of them reads is a key the merge
9
+ * silently drops, which is why `metadata` handling is spelled out in both.
10
+ */
11
+ import { maskSource, matchBrace, statementEnd, statementHead, topLevelBlocks } from "./source-mask.js";
12
+ /** The element and relationship kinds the `specification` blocks of `text` declare — with `also`'s, when given. */
13
+ export function kindsDeclared(text, also) {
14
+ const { code } = maskSource(text);
15
+ const kinds = new Set(also?.kinds);
16
+ const relKinds = new Set(also?.relKinds);
17
+ for (const sm of code.matchAll(/\bspecification\s*\{/g)) {
18
+ const sClose = matchBrace(code, sm.index + sm[0].length - 1);
19
+ if (sClose === -1)
20
+ continue;
21
+ for (const em of code.slice(sm.index, sClose).matchAll(/\b(element|relationship)\s+([A-Za-z_][\w-]*)/g)) {
22
+ (em[1] === "element" ? kinds : relKinds).add(em[2]);
23
+ }
24
+ }
25
+ return { kinds, relKinds };
26
+ }
27
+ /**
28
+ * Locate every element and relationship declaration inside the top-level
29
+ * `model { ... }` blocks of a LikeC4 source, with the byte range each one
30
+ * occupies. This is the splice map `loam archive` merges the landscape with:
31
+ * the parsed model says WHAT exists, this says WHERE its authored text is —
32
+ * verbatim, so nothing the parser does not model (technology, style, links)
33
+ * can be lost by rebuilding it.
34
+ *
35
+ * Every block is read, in document order, and each declaration records which
36
+ * one it sits in (`block`); ids, endpoints and nesting are one namespace
37
+ * across all of them, because that is how LikeC4 merges them.
38
+ *
39
+ * Both declaration forms are recognised — `name = kind ...` always, and
40
+ * `kind name ...` for any kind the document's own `specification` block
41
+ * declares, or `borrowed` names. Relationship endpoints are resolved the way LikeC4 reads them:
42
+ * innermost enclosing scope outward, then the top level, then a unique leaf
43
+ * name anywhere; `it`/`this` (and an omitted source) mean the enclosing
44
+ * element. A name that resolves nowhere is left as written — the caller's
45
+ * match against the parsed model then fails loudly instead of guessing.
46
+ *
47
+ * Returns null when there is no model block at all. Callers only hand in documents
48
+ * LikeC4 has already parsed, so the scan can trust balanced braces.
49
+ */
50
+ export function scanModel(text, borrowed) {
51
+ const masked = maskSource(text);
52
+ const { code, literals } = masked;
53
+ // EVERY top-level `model { }` block, and only those (`topLevelBlocks`): a
54
+ // document may hold any number, and LikeC4 reads them as one model. The
55
+ // scan used to stop at the FIRST match, so every declaration in a later
56
+ // block was invisible — the landscape parsed, `validate --all` was green,
57
+ // and archive refused with a message about two declarations sharing a line
58
+ // (a fleet on 0.2.0-alpha.7, 2026-10). Depth zero is the other half of the
59
+ // same fix: the bare first match also took a nested `model {` — a kind or a
60
+ // view NAMED model (`element model { … }`), written above the real block —
61
+ // for the model.
62
+ const blocks = [];
63
+ for (const { match } of topLevelBlocks(code, /\bmodel\s*\{/g)) {
64
+ const open = match.index + match[0].length - 1;
65
+ const close = matchBrace(code, open);
66
+ if (close === -1)
67
+ break;
68
+ blocks.push({ open, close });
69
+ }
70
+ if (blocks.length === 0)
71
+ return null;
72
+ // Element kinds from the specification block(s): the `<kind> <name>`
73
+ // declaration form is recognisable only by its first token being a kind.
74
+ // Relationship kinds likewise, for the `source .kind target` edge form.
75
+ const { kinds, relKinds } = kindsDeclared(text, borrowed);
76
+ const indentOf = (at) => {
77
+ const nl = text.lastIndexOf("\n", at - 1);
78
+ const ws = text.slice(nl + 1, at);
79
+ return /^[ \t]*$/.test(ws) ? ws : "";
80
+ };
81
+ const literalIn = (from, to) => literals.find((l) => l.start >= from && l.end <= to);
82
+ // A key is a whole identifier, and LikeC4's identifiers carry hyphens. `\b`
83
+ // took the `-` for a boundary, so `op-version 'v2'` above `op 'cancelOrdr'`
84
+ // was read as op `'v2'`, a `#op-critical` tag as the key `op` naming the
85
+ // literal after it — the next property's — and `validate --all --base`
86
+ // graded neither op the branch wrote: the scanned edge matched no parsed one,
87
+ // so the misspelt `cancelOrdr` went green where the plain run reports
88
+ // `spine.op-undefined` (probed on main at 171555d; 57b33ad fixed the same
89
+ // hyphen for ids and not here).
90
+ const keyedLiteral = (key, range) => {
91
+ if (range === null)
92
+ return undefined;
93
+ const re = new RegExp(`(?<![\\w-])${key}(?![\\w-])`, "g");
94
+ re.lastIndex = range.from;
95
+ const km = re.exec(code);
96
+ if (km === null || km.index >= range.to)
97
+ return undefined;
98
+ return literalIn(km.index, range.to)?.value;
99
+ };
100
+ // The spine keys are METADATA keys — the parsed `Rel` reads them out of
101
+ // `metadata { }` and nowhere else (`likec4.ts`) — so the scan reads them only
102
+ // there. Read from the whole body, a bare `#op` tag (a legal tag name) above a
103
+ // `description` was the key `op` once more, whatever the boundary rule.
104
+ const metadataOf = (body) => {
105
+ if (body === null)
106
+ return null;
107
+ const re = /(?<![\w-])metadata\s*\{/g;
108
+ re.lastIndex = body.from;
109
+ const mm = re.exec(code);
110
+ if (mm === null || mm.index >= body.to)
111
+ return null;
112
+ const open = mm.index + mm[0].length - 1;
113
+ const shut = matchBrace(code, open);
114
+ return shut === -1 || shut > body.to ? null : { from: open + 1, to: shut };
115
+ };
116
+ // A bodyless statement's end — its trailing comment included, unless that
117
+ // comment runs on past the line (`statementEnd` says why).
118
+ const bodylessEnd = (from, to) => statementEnd(text, masked, { start: from, end: to });
119
+ const elements = [];
120
+ const raw = [];
121
+ const stack = [];
122
+ for (const [block, { open, close }] of blocks.entries()) {
123
+ let i = open + 1;
124
+ while (i < close) {
125
+ const ch = code[i];
126
+ if (/\s/.test(ch)) {
127
+ i += 1;
128
+ continue;
129
+ }
130
+ if (ch === "}") {
131
+ const frame = stack.pop();
132
+ if (frame !== undefined) {
133
+ frame.el.bodyClose = i;
134
+ frame.el.end = i + 1;
135
+ elements.push(frame.el);
136
+ }
137
+ i += 1;
138
+ continue;
139
+ }
140
+ // A statement's head: up to its own `{`, the end of the line, or the
141
+ // enclosing block's `}` on the same line — whichever comes first, unless
142
+ // LikeC4 reads on past the newline (`statementHead` says when it does).
143
+ const stmtStart = i;
144
+ const { end: headEnd, opener } = statementHead(masked, i, close);
145
+ const head = code.slice(stmtStart, headEnd);
146
+ const parentId = stack.length > 0 ? stack[stack.length - 1].id : "";
147
+ // `extend <fqn> { … }` — the extending model's one construct, and the only
148
+ // frame here whose id is not minted from the enclosing scope: it names an
149
+ // element the fleet map already declares, so its children are `<fqn>.<name>`
150
+ // and a reference inside it resolves against that scope. Without this the
151
+ // block fell through to the property-line arm and everything in it was
152
+ // invisible, which is why the archive spliced a service's interior into the
153
+ // map instead (verification 2026-09-04, E1).
154
+ const extended = opener === -1 ? null : /^extend\s+([A-Za-z_][\w.-]*)\s*$/.exec(head);
155
+ if (extended !== null) {
156
+ const id = parentId === "" ? extended[1] : `${parentId}.${extended[1]}`;
157
+ const el = {
158
+ id,
159
+ start: stmtStart,
160
+ end: headEnd,
161
+ bodyOpen: opener,
162
+ bodyClose: -1,
163
+ indent: indentOf(stmtStart),
164
+ block,
165
+ extend: true,
166
+ };
167
+ stack.push({ id, el });
168
+ i = opener + 1;
169
+ continue;
170
+ }
171
+ // Classify: `name = kind` first, then a relationship (the arrow cannot hide
172
+ // in a string — the head is masked), then the `kind name` form, else a
173
+ // property/tag line that is consumed whole, nested block included.
174
+ let localName = null;
175
+ const assign = /^([A-Za-z_][\w-]*)\s*=\s*[A-Za-z_]/.exec(head);
176
+ if (assign !== null) {
177
+ localName = assign[1];
178
+ }
179
+ else if (!head.includes("->")) {
180
+ const toks = head.trim().split(/\s+/);
181
+ if (toks.length >= 2 && kinds.has(toks[0]) && /^[A-Za-z_][\w-]*$/.test(toks[1])) {
182
+ localName = toks[1];
183
+ }
184
+ }
185
+ if (localName !== null) {
186
+ const id = parentId === "" ? localName : `${parentId}.${localName}`;
187
+ const el = {
188
+ id,
189
+ start: stmtStart,
190
+ end: headEnd,
191
+ bodyOpen: opener,
192
+ bodyClose: -1,
193
+ indent: indentOf(stmtStart),
194
+ block,
195
+ };
196
+ const titled = literalIn(stmtStart, headEnd)?.value;
197
+ if (titled !== undefined)
198
+ el.title = titled;
199
+ if (opener !== -1) {
200
+ stack.push({ id, el });
201
+ i = opener + 1;
202
+ }
203
+ else {
204
+ el.end = bodylessEnd(stmtStart, headEnd);
205
+ elements.push(el);
206
+ i = headEnd;
207
+ }
208
+ continue;
209
+ }
210
+ const am = relationHead(head, relKinds);
211
+ if (am !== null || head.includes("->")) {
212
+ const bClose = opener === -1 ? -1 : matchBrace(code, opener);
213
+ const stmtEnd = opener === -1 ? bodylessEnd(stmtStart, headEnd) : bClose === -1 ? close : bClose + 1;
214
+ if (am !== null) {
215
+ const arrowEnd = stmtStart + am.length;
216
+ const body = opener === -1 ? null : { from: opener + 1, to: stmtEnd - 1 };
217
+ const meta = metadataOf(body);
218
+ const title = literalIn(arrowEnd, headEnd)?.value ?? keyedLiteral("title", body);
219
+ const tags = [];
220
+ for (const tm of code.slice(stmtStart, stmtEnd).matchAll(/#([\w-]+)/g))
221
+ tags.push(tm[1]);
222
+ raw.push({
223
+ srcLit: am.src,
224
+ tgtLit: am.tgt,
225
+ parent: parentId,
226
+ start: stmtStart,
227
+ end: stmtEnd,
228
+ indent: indentOf(stmtStart),
229
+ block,
230
+ title,
231
+ op: keyedLiteral("op", meta),
232
+ publishes: keyedLiteral("publishes", meta),
233
+ consumes: keyedLiteral("consumes", meta),
234
+ tags,
235
+ kind: am.kind,
236
+ });
237
+ }
238
+ i = Math.max(stmtEnd, headEnd);
239
+ continue;
240
+ }
241
+ if (opener !== -1) {
242
+ const bClose = matchBrace(code, opener);
243
+ i = bClose === -1 ? close : bClose + 1;
244
+ }
245
+ else {
246
+ i = headEnd;
247
+ }
248
+ }
249
+ }
250
+ // Resolve relationship endpoints against everything declared anywhere in the
251
+ // model — LikeC4 resolution is not order-dependent, so neither is this.
252
+ const ids = new Set(elements.map((e) => e.id));
253
+ const byLeaf = new Map();
254
+ for (const e of elements) {
255
+ const leaf = e.id.slice(e.id.lastIndexOf(".") + 1);
256
+ byLeaf.set(leaf, [...(byLeaf.get(leaf) ?? []), e.id]);
257
+ }
258
+ const resolve = (lit, enclosing) => {
259
+ if (lit === undefined || lit === "it" || lit === "this")
260
+ return enclosing;
261
+ const segs = lit.split(".");
262
+ let base;
263
+ for (let scope = enclosing; scope !== "" && base === undefined;) {
264
+ if (ids.has(`${scope}.${segs[0]}`))
265
+ base = `${scope}.${segs[0]}`;
266
+ const dot = scope.lastIndexOf(".");
267
+ scope = dot === -1 ? "" : scope.slice(0, dot);
268
+ }
269
+ if (base === undefined && ids.has(segs[0]))
270
+ base = segs[0];
271
+ if (base === undefined) {
272
+ const leafed = byLeaf.get(segs[0]);
273
+ if (leafed !== undefined && leafed.length === 1)
274
+ base = leafed[0];
275
+ }
276
+ return [base ?? segs[0], ...segs.slice(1)].join(".");
277
+ };
278
+ const rels = raw.map(({ srcLit, tgtLit, parent, ...r }) => ({
279
+ ...r,
280
+ source: resolve(srcLit, parent),
281
+ target: resolve(tgtLit, parent),
282
+ }));
283
+ elements.sort((a, b) => a.start - b.start);
284
+ return { blocks, elements, rels };
285
+ }
286
+ /**
287
+ * A relationship head's endpoints as written, its kind, and where its arrow form ends —
288
+ * null for any other head. Three forms, each with the source omittable inside
289
+ * an element: `a -> b`, `a -[kind]-> b`, and `a .kind b` for a relationship
290
+ * kind the specification declares, which the scan used to skip as a property
291
+ * line, so archive refused a valid map on a relationship count.
292
+ *
293
+ * Ids carry hyphens (`entity-service`): LikeC4's identifier is
294
+ * `[a-zA-Z_][-\w]*`, and the `\w`-only spelling here made such an element, or
295
+ * an edge naming one, invisible. The lexer's greed is why `a->b` without a
296
+ * space is not a form worth reading — LikeC4 takes `a-` for the id and rejects
297
+ * the document.
298
+ */
299
+ function relationHead(head, relKinds) {
300
+ const arrow = /^([A-Za-z_][\w.-]*)?\s*(?:-\[\s*([^\]]*?)\s*\])?->\s*([A-Za-z_][\w.-]*)/.exec(head);
301
+ if (arrow !== null)
302
+ return { src: arrow[1], tgt: arrow[3], kind: arrow[2] || undefined, length: arrow[0].length };
303
+ const dotted = /^(?:([A-Za-z_][\w.-]*)\s+)?\.([A-Za-z_][\w-]*)\s+([A-Za-z_][\w.-]*)/.exec(head);
304
+ if (dotted === null || !relKinds.has(dotted[2]))
305
+ return null;
306
+ return { src: dotted[1], tgt: dotted[3], kind: dotted[2], length: dotted[0].length };
307
+ }
308
+ //# sourceMappingURL=source-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-scan.js","sourceRoot":"","sources":["../../../src/core/c4/source-scan.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The text-level view of a LikeC4 document: which bytes each declaration owns.\n *\n * loam's archive merges the landscape by SPLICING authored text, not by\n * re-rendering a parsed model — a re-render would reformat every line somebody\n * wrote. So the merge needs both views of the same file: the parsed one\n * (`likec4.ts`) for what the model MEANS, and this one for where each\n * declaration physically is. A key only one of them reads is a key the merge\n * silently drops, which is why `metadata` handling is spelled out in both.\n */\nimport { maskSource, matchBrace, statementEnd, statementHead, topLevelBlocks, type SourceLiteral } from \"./source-mask.js\";\n\nexport interface ScannedElement {\n /** Full dotted id — `parent.child` for a nested declaration. */\n id: string;\n /** Span of the whole declaration: first head character to one past its end. */\n start: number;\n end: number;\n /** Its own body braces; -1 when the declaration has no body. */\n bodyOpen: number;\n bodyClose: number;\n /** Leading whitespace of the declaration's first line. */\n indent: string;\n /** Index into `ScannedModel.blocks` of the `model { }` block it is written in. */\n block: number;\n /**\n * The title the declaration's HEAD names — the first string literal before\n * its body, which is where both declaration forms write it (pinned against\n * the parser by `test/likec4-scan-parity.test.ts`).\n *\n * Absent when the head names none: LikeC4 then titles the element after its\n * own name, and a default title is one the archive's title join must not\n * match on — `splice/identity/declared.ts` says why, and why losing it costs\n * that join nothing.\n */\n title?: string;\n /**\n * True for an `extend <fqn> { … }` frame — a block that DECLARES nothing and\n * reopens an element another document owns. Its id is the fqn as written, and\n * its children hang off that, which is what lets the archive splice a\n * service's interior into the model that owns it. Placement must skip it: it\n * is not a top-level declaration of this document, so anchoring beside it\n * would group additions around a box that lives somewhere else.\n */\n extend?: true;\n}\n\n/** A relationship statement located in source, endpoints resolved to full ids (best effort). */\nexport interface ScannedRel {\n source: string;\n target: string;\n title?: string;\n op?: string;\n /** `metadata { publishes '...' }` — see `Rel.publishes`. */\n publishes?: string;\n /** `metadata { consumes '...' }` — see `Rel.consumes`. */\n consumes?: string;\n /** The tags WRITTEN in the statement — never its kind's, which LikeC4 adds to the parsed `Rel` (`splice/identity/edges.ts`). */\n tags: string[];\n /** The relationship kind the head names — `-[kind]->` or `.kind` — absent for a plain `->`. */\n kind?: string;\n start: number;\n end: number;\n indent: string;\n /** Index into `ScannedModel.blocks` of the `model { }` block it is written in. */\n block: number;\n}\n\n/** A half-open `[from, to)` run of the masked code — a body, or the metadata block inside one. */\ninterface CodeRange {\n from: number;\n to: number;\n}\n\n/** One top-level `model { }` block: its own braces. */\nexport interface ScannedBlock {\n open: number;\n close: number;\n}\n\nexport interface ScannedModel {\n /**\n * Every top-level `model { }` block, in document order — never empty. LikeC4\n * merges them into one model, so an id or an endpoint resolves across all of\n * them; which block a NEW declaration is written into is placement's choice\n * (`splice/placement.ts`, `HOME_BLOCK`), never the scan's.\n */\n blocks: ScannedBlock[];\n /** In document order. A nested declaration's span lies inside its parent's. */\n elements: ScannedElement[];\n rels: ScannedRel[];\n}\n\n/**\n * Kinds a document uses without declaring them, because its project does: an EXTENDING model has no\n * `specification` and borrows the map's. Without them its `kind name` declarations and `a .kind b` edges read\n * as property lines — archive spliced around such an edge, duplicated it, and refused a child of such a\n * container as nesting under nothing (2026-10). `kindsDeclared` reads them off the map's text.\n */\nexport interface ScanKinds {\n kinds: ReadonlySet<string>;\n relKinds: ReadonlySet<string>;\n}\n\n/** The element and relationship kinds the `specification` blocks of `text` declare — with `also`'s, when given. */\nexport function kindsDeclared(text: string, also?: ScanKinds): ScanKinds {\n const { code } = maskSource(text);\n const kinds = new Set(also?.kinds);\n const relKinds = new Set(also?.relKinds);\n for (const sm of code.matchAll(/\\bspecification\\s*\\{/g)) {\n const sClose = matchBrace(code, sm.index + sm[0].length - 1);\n if (sClose === -1) continue;\n for (const em of code.slice(sm.index, sClose).matchAll(/\\b(element|relationship)\\s+([A-Za-z_][\\w-]*)/g)) {\n (em[1] === \"element\" ? kinds : relKinds).add(em[2]!);\n }\n }\n return { kinds, relKinds };\n}\n\n/**\n * Locate every element and relationship declaration inside the top-level\n * `model { ... }` blocks of a LikeC4 source, with the byte range each one\n * occupies. This is the splice map `loam archive` merges the landscape with:\n * the parsed model says WHAT exists, this says WHERE its authored text is —\n * verbatim, so nothing the parser does not model (technology, style, links)\n * can be lost by rebuilding it.\n *\n * Every block is read, in document order, and each declaration records which\n * one it sits in (`block`); ids, endpoints and nesting are one namespace\n * across all of them, because that is how LikeC4 merges them.\n *\n * Both declaration forms are recognised — `name = kind ...` always, and\n * `kind name ...` for any kind the document's own `specification` block\n * declares, or `borrowed` names. Relationship endpoints are resolved the way LikeC4 reads them:\n * innermost enclosing scope outward, then the top level, then a unique leaf\n * name anywhere; `it`/`this` (and an omitted source) mean the enclosing\n * element. A name that resolves nowhere is left as written — the caller's\n * match against the parsed model then fails loudly instead of guessing.\n *\n * Returns null when there is no model block at all. Callers only hand in documents\n * LikeC4 has already parsed, so the scan can trust balanced braces.\n */\nexport function scanModel(text: string, borrowed?: ScanKinds): ScannedModel | null {\n const masked = maskSource(text);\n const { code, literals } = masked;\n // EVERY top-level `model { }` block, and only those (`topLevelBlocks`): a\n // document may hold any number, and LikeC4 reads them as one model. The\n // scan used to stop at the FIRST match, so every declaration in a later\n // block was invisible — the landscape parsed, `validate --all` was green,\n // and archive refused with a message about two declarations sharing a line\n // (a fleet on 0.2.0-alpha.7, 2026-10). Depth zero is the other half of the\n // same fix: the bare first match also took a nested `model {` — a kind or a\n // view NAMED model (`element model { … }`), written above the real block —\n // for the model.\n const blocks: ScannedBlock[] = [];\n for (const { match } of topLevelBlocks(code, /\\bmodel\\s*\\{/g)) {\n const open = match.index + match[0].length - 1;\n const close = matchBrace(code, open);\n if (close === -1) break;\n blocks.push({ open, close });\n }\n if (blocks.length === 0) return null;\n\n // Element kinds from the specification block(s): the `<kind> <name>`\n // declaration form is recognisable only by its first token being a kind.\n // Relationship kinds likewise, for the `source .kind target` edge form.\n const { kinds, relKinds } = kindsDeclared(text, borrowed);\n\n const indentOf = (at: number): string => {\n const nl = text.lastIndexOf(\"\\n\", at - 1);\n const ws = text.slice(nl + 1, at);\n return /^[ \\t]*$/.test(ws) ? ws : \"\";\n };\n const literalIn = (from: number, to: number): SourceLiteral | undefined =>\n literals.find((l) => l.start >= from && l.end <= to);\n // A key is a whole identifier, and LikeC4's identifiers carry hyphens. `\\b`\n // took the `-` for a boundary, so `op-version 'v2'` above `op 'cancelOrdr'`\n // was read as op `'v2'`, a `#op-critical` tag as the key `op` naming the\n // literal after it — the next property's — and `validate --all --base`\n // graded neither op the branch wrote: the scanned edge matched no parsed one,\n // so the misspelt `cancelOrdr` went green where the plain run reports\n // `spine.op-undefined` (probed on main at 171555d; 57b33ad fixed the same\n // hyphen for ids and not here).\n const keyedLiteral = (key: string, range: CodeRange | null): string | undefined => {\n if (range === null) return undefined;\n const re = new RegExp(`(?<![\\\\w-])${key}(?![\\\\w-])`, \"g\");\n re.lastIndex = range.from;\n const km = re.exec(code);\n if (km === null || km.index >= range.to) return undefined;\n return literalIn(km.index, range.to)?.value;\n };\n // The spine keys are METADATA keys — the parsed `Rel` reads them out of\n // `metadata { }` and nowhere else (`likec4.ts`) — so the scan reads them only\n // there. Read from the whole body, a bare `#op` tag (a legal tag name) above a\n // `description` was the key `op` once more, whatever the boundary rule.\n const metadataOf = (body: CodeRange | null): CodeRange | null => {\n if (body === null) return null;\n const re = /(?<![\\w-])metadata\\s*\\{/g;\n re.lastIndex = body.from;\n const mm = re.exec(code);\n if (mm === null || mm.index >= body.to) return null;\n const open = mm.index + mm[0].length - 1;\n const shut = matchBrace(code, open);\n return shut === -1 || shut > body.to ? null : { from: open + 1, to: shut };\n };\n // A bodyless statement's end — its trailing comment included, unless that\n // comment runs on past the line (`statementEnd` says why).\n const bodylessEnd = (from: number, to: number): number => statementEnd(text, masked, { start: from, end: to });\n\n const elements: ScannedElement[] = [];\n // A relationship as the walk meets it: endpoints as written, resolved below once every declaration is known.\n type RawRel = Omit<ScannedRel, \"source\" | \"target\"> & { srcLit?: string; tgtLit: string; parent: string };\n const raw: RawRel[] = [];\n const stack: Array<{ id: string; el: ScannedElement }> = [];\n\n for (const [block, { open, close }] of blocks.entries()) {\n let i = open + 1;\n while (i < close) {\n const ch = code[i]!;\n if (/\\s/.test(ch)) {\n i += 1;\n continue;\n }\n if (ch === \"}\") {\n const frame = stack.pop();\n if (frame !== undefined) {\n frame.el.bodyClose = i;\n frame.el.end = i + 1;\n elements.push(frame.el);\n }\n i += 1;\n continue;\n }\n\n // A statement's head: up to its own `{`, the end of the line, or the\n // enclosing block's `}` on the same line — whichever comes first, unless\n // LikeC4 reads on past the newline (`statementHead` says when it does).\n const stmtStart = i;\n const { end: headEnd, opener } = statementHead(masked, i, close);\n const head = code.slice(stmtStart, headEnd);\n const parentId = stack.length > 0 ? stack[stack.length - 1]!.id : \"\";\n\n // `extend <fqn> { … }` — the extending model's one construct, and the only\n // frame here whose id is not minted from the enclosing scope: it names an\n // element the fleet map already declares, so its children are `<fqn>.<name>`\n // and a reference inside it resolves against that scope. Without this the\n // block fell through to the property-line arm and everything in it was\n // invisible, which is why the archive spliced a service's interior into the\n // map instead (verification 2026-09-04, E1).\n const extended = opener === -1 ? null : /^extend\\s+([A-Za-z_][\\w.-]*)\\s*$/.exec(head);\n if (extended !== null) {\n const id = parentId === \"\" ? extended[1]! : `${parentId}.${extended[1]!}`;\n const el: ScannedElement = {\n id,\n start: stmtStart,\n end: headEnd,\n bodyOpen: opener,\n bodyClose: -1,\n indent: indentOf(stmtStart),\n block,\n extend: true,\n };\n stack.push({ id, el });\n i = opener + 1;\n continue;\n }\n\n // Classify: `name = kind` first, then a relationship (the arrow cannot hide\n // in a string — the head is masked), then the `kind name` form, else a\n // property/tag line that is consumed whole, nested block included.\n let localName: string | null = null;\n const assign = /^([A-Za-z_][\\w-]*)\\s*=\\s*[A-Za-z_]/.exec(head);\n if (assign !== null) {\n localName = assign[1]!;\n } else if (!head.includes(\"->\")) {\n const toks = head.trim().split(/\\s+/);\n if (toks.length >= 2 && kinds.has(toks[0]!) && /^[A-Za-z_][\\w-]*$/.test(toks[1]!)) {\n localName = toks[1]!;\n }\n }\n\n if (localName !== null) {\n const id = parentId === \"\" ? localName : `${parentId}.${localName}`;\n const el: ScannedElement = {\n id,\n start: stmtStart,\n end: headEnd,\n bodyOpen: opener,\n bodyClose: -1,\n indent: indentOf(stmtStart),\n block,\n };\n const titled = literalIn(stmtStart, headEnd)?.value;\n if (titled !== undefined) el.title = titled;\n if (opener !== -1) {\n stack.push({ id, el });\n i = opener + 1;\n } else {\n el.end = bodylessEnd(stmtStart, headEnd);\n elements.push(el);\n i = headEnd;\n }\n continue;\n }\n\n const am = relationHead(head, relKinds);\n if (am !== null || head.includes(\"->\")) {\n const bClose = opener === -1 ? -1 : matchBrace(code, opener);\n const stmtEnd = opener === -1 ? bodylessEnd(stmtStart, headEnd) : bClose === -1 ? close : bClose + 1;\n if (am !== null) {\n const arrowEnd = stmtStart + am.length;\n const body = opener === -1 ? null : { from: opener + 1, to: stmtEnd - 1 };\n const meta = metadataOf(body);\n const title = literalIn(arrowEnd, headEnd)?.value ?? keyedLiteral(\"title\", body);\n const tags: string[] = [];\n for (const tm of code.slice(stmtStart, stmtEnd).matchAll(/#([\\w-]+)/g)) tags.push(tm[1]!);\n raw.push({\n srcLit: am.src,\n tgtLit: am.tgt,\n parent: parentId,\n start: stmtStart,\n end: stmtEnd,\n indent: indentOf(stmtStart),\n block,\n title,\n op: keyedLiteral(\"op\", meta),\n publishes: keyedLiteral(\"publishes\", meta),\n consumes: keyedLiteral(\"consumes\", meta),\n tags,\n kind: am.kind,\n });\n }\n i = Math.max(stmtEnd, headEnd);\n continue;\n }\n\n if (opener !== -1) {\n const bClose = matchBrace(code, opener);\n i = bClose === -1 ? close : bClose + 1;\n } else {\n i = headEnd;\n }\n }\n }\n\n // Resolve relationship endpoints against everything declared anywhere in the\n // model — LikeC4 resolution is not order-dependent, so neither is this.\n const ids = new Set(elements.map((e) => e.id));\n const byLeaf = new Map<string, string[]>();\n for (const e of elements) {\n const leaf = e.id.slice(e.id.lastIndexOf(\".\") + 1);\n byLeaf.set(leaf, [...(byLeaf.get(leaf) ?? []), e.id]);\n }\n const resolve = (lit: string | undefined, enclosing: string): string => {\n if (lit === undefined || lit === \"it\" || lit === \"this\") return enclosing;\n const segs = lit.split(\".\");\n let base: string | undefined;\n for (let scope = enclosing; scope !== \"\" && base === undefined; ) {\n if (ids.has(`${scope}.${segs[0]!}`)) base = `${scope}.${segs[0]!}`;\n const dot = scope.lastIndexOf(\".\");\n scope = dot === -1 ? \"\" : scope.slice(0, dot);\n }\n if (base === undefined && ids.has(segs[0]!)) base = segs[0]!;\n if (base === undefined) {\n const leafed = byLeaf.get(segs[0]!);\n if (leafed !== undefined && leafed.length === 1) base = leafed[0]!;\n }\n return [base ?? segs[0]!, ...segs.slice(1)].join(\".\");\n };\n\n const rels: ScannedRel[] = raw.map(({ srcLit, tgtLit, parent, ...r }) => ({\n ...r,\n source: resolve(srcLit, parent),\n target: resolve(tgtLit, parent),\n }));\n\n elements.sort((a, b) => a.start - b.start);\n return { blocks, elements, rels };\n}\n\n/**\n * A relationship head's endpoints as written, its kind, and where its arrow form ends —\n * null for any other head. Three forms, each with the source omittable inside\n * an element: `a -> b`, `a -[kind]-> b`, and `a .kind b` for a relationship\n * kind the specification declares, which the scan used to skip as a property\n * line, so archive refused a valid map on a relationship count.\n *\n * Ids carry hyphens (`entity-service`): LikeC4's identifier is\n * `[a-zA-Z_][-\\w]*`, and the `\\w`-only spelling here made such an element, or\n * an edge naming one, invisible. The lexer's greed is why `a->b` without a\n * space is not a form worth reading — LikeC4 takes `a-` for the id and rejects\n * the document.\n */\nfunction relationHead(head: string, relKinds: ReadonlySet<string>): { src: string | undefined; tgt: string; kind?: string; length: number } | null {\n const arrow = /^([A-Za-z_][\\w.-]*)?\\s*(?:-\\[\\s*([^\\]]*?)\\s*\\])?->\\s*([A-Za-z_][\\w.-]*)/.exec(head);\n if (arrow !== null) return { src: arrow[1], tgt: arrow[3]!, kind: arrow[2] || undefined, length: arrow[0].length };\n const dotted = /^(?:([A-Za-z_][\\w.-]*)\\s+)?\\.([A-Za-z_][\\w-]*)\\s+([A-Za-z_][\\w.-]*)/.exec(head);\n if (dotted === null || !relKinds.has(dotted[2]!)) return null;\n return { src: dotted[1], tgt: dotted[3]!, kind: dotted[2], length: dotted[0].length };\n}\n"]}
@@ -0,0 +1,167 @@
1
+ import { maskSource, matchBrace } from "../source-mask.js";
2
+ export function spliceSource(deltaText, decl, carry) {
3
+ const { featureId, indent: targetIndent, omit = [] } = carry;
4
+ const block = deltaText.slice(decl.start, decl.end);
5
+ const cuts = omit
6
+ .filter((r) => r.start >= decl.start && r.end <= decl.end)
7
+ .map((r) => wholeLines(block, r.start - decl.start, r.end - decl.start));
8
+ return reindent(stripFeatureTag(block, featureId, cuts), decl.indent, targetIndent);
9
+ }
10
+ /**
11
+ * Widen a cut to the whole lines it sits on, when it has them to itself.
12
+ *
13
+ * A scanned declaration's span starts at its first character and ends one past
14
+ * its last brace, so cutting it verbatim would leave the leading indent and the
15
+ * trailing newline behind as a blank line — and the emptied-line rule below only
16
+ * fires on a removal a line contains. A cut sharing its line with other code is
17
+ * left exactly as asked.
18
+ */
19
+ function wholeLines(block, start, end) {
20
+ const lineStart = block.lastIndexOf("\n", start - 1) + 1;
21
+ if (!/^[ \t]*$/.test(block.slice(lineStart, start)))
22
+ return [start, end];
23
+ const nl = block.indexOf("\n", end);
24
+ const to = nl === -1 ? block.length : nl;
25
+ if (!/^[ \t\r]*$/.test(block.slice(end, to)))
26
+ return [start, end];
27
+ return [lineStart, nl === -1 ? block.length : nl + 1];
28
+ }
29
+ /**
30
+ * Rewrite the line endings a merge INSERTED to the ones the document already
31
+ * uses.
32
+ *
33
+ * Splicing composes bytes from two files, and the delta's newlines are not
34
+ * necessarily the living document's: on a repository without `core.autocrlf`
35
+ * normalisation a CRLF landscape or model came back with a handful of bare-LF
36
+ * lines in the spliced region — two conventions in one file, noisy in an editor
37
+ * and in every diff (verification 2026-09-04, W-CRLF). One helper for both
38
+ * merges, because both had it.
39
+ *
40
+ * Only a document with ONE convention is corrected, and then in whichever
41
+ * direction it uses: a file that is already mixed has no convention to match, and
42
+ * guessing one would rewrite lines nobody touched.
43
+ */
44
+ export function matchLineEndings(document, merged) {
45
+ const crlf = (document.match(/\r\n/g) ?? []).length;
46
+ const bare = (document.match(/(?<!\r)\n/g) ?? []).length;
47
+ if (crlf > 0 && bare === 0)
48
+ return merged.replace(/(?<!\r)\n/g, "\r\n");
49
+ if (bare > 0 && crlf === 0)
50
+ return merged.replace(/\r\n/g, "\n");
51
+ return merged;
52
+ }
53
+ function stripFeatureTag(block, featureId, cuts) {
54
+ const { code } = maskSource(block);
55
+ const esc = featureId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
56
+ const removals = cuts.map(([s, e]) => [s, e]);
57
+ for (const m of block.matchAll(new RegExp(`#${esc}(?![\\w-])`, "g"))) {
58
+ // Only tags in CODE count — a description quoting "#FEAT-1" is content.
59
+ if (code.slice(m.index, m.index + m[0].length) !== m[0])
60
+ continue;
61
+ let s = m.index;
62
+ let e = s + m[0].length;
63
+ // A tag list's separators go with the tag they separate. LikeC4 reads a
64
+ // list as `#a #b, #c;` — one or more tags first, then `,` groups, then an
65
+ // optional `;` — so `#FEAT-1, #x` stripped to `, #x` and `#FEAT-1;` to a
66
+ // bare `;`, and the parse net refused a delta LikeC4 accepts. The comma
67
+ // after the tag goes with it, else the comma before it; the `;` only when
68
+ // no tag is left in front of it.
69
+ const commaAfter = /^[ \t]*,[ \t]*/.exec(code.slice(e));
70
+ const commaBefore = /,[ \t]*$/.exec(code.slice(0, s));
71
+ const semi = /^[ \t]*;/.exec(code.slice(e));
72
+ if (commaAfter !== null) {
73
+ removals.push([s, e + commaAfter[0].length]);
74
+ continue;
75
+ }
76
+ if (commaBefore !== null) {
77
+ removals.push([commaBefore.index, e]);
78
+ continue;
79
+ }
80
+ if (semi !== null && !/#[\w-]+\s*$/.test(code.slice(0, s)))
81
+ e += semi[0].length;
82
+ // Take the whitespace on ONE side with the token — trailing first, so
83
+ // `#FEAT-1 #critical` leaves `#critical` at its own indent, and a token at
84
+ // the end of a line does not leave a trailing space behind.
85
+ if (block[e] === " " || block[e] === "\t") {
86
+ while (block[e] === " " || block[e] === "\t")
87
+ e += 1;
88
+ }
89
+ else {
90
+ while (s > 0 && (block[s - 1] === " " || block[s - 1] === "\t"))
91
+ s -= 1;
92
+ }
93
+ removals.push([s, e]);
94
+ }
95
+ if (removals.length === 0)
96
+ return block;
97
+ // A line the strip emptied disappears whole, newline included.
98
+ for (let lineStart = 0; lineStart < block.length;) {
99
+ const nl = block.indexOf("\n", lineStart);
100
+ const lineEnd = nl === -1 ? block.length : nl + 1;
101
+ if (removals.some(([s, e]) => s >= lineStart && e <= lineEnd) &&
102
+ /^\s*$/.test(residual(block, lineStart, nl === -1 ? block.length : nl, removals))) {
103
+ removals.push([lineStart, lineEnd]);
104
+ }
105
+ lineStart = lineEnd;
106
+ }
107
+ // A body the strip emptied goes too, braces and all — but only one the strip
108
+ // emptied: braces that were authored empty are authored bytes and survive.
109
+ for (let at = code.indexOf("{"); at !== -1; at = code.indexOf("{", at + 1)) {
110
+ const closeAt = matchBrace(code, at);
111
+ if (closeAt === -1)
112
+ continue;
113
+ if (!removals.some(([s, e]) => s > at && e <= closeAt))
114
+ continue;
115
+ if (!/^\s*$/.test(residual(block, at + 1, closeAt, removals)))
116
+ continue;
117
+ let s = at;
118
+ while (s > 0 && /\s/.test(block[s - 1]))
119
+ s -= 1;
120
+ removals.push([s, closeAt + 1]);
121
+ }
122
+ return applyRemovals(block, removals);
123
+ }
124
+ /** The text of [from, to) with the removal ranges cut out. */
125
+ function residual(text, from, to, removals) {
126
+ let out = "";
127
+ for (let i = from; i < to; i += 1) {
128
+ if (!removals.some(([s, e]) => i >= s && i < e))
129
+ out += text[i];
130
+ }
131
+ return out;
132
+ }
133
+ function applyRemovals(text, removals) {
134
+ const sorted = [...removals].sort((a, b) => a[0] - b[0] || b[1] - a[1]);
135
+ let out = "";
136
+ let i = 0;
137
+ for (const [s, e] of sorted) {
138
+ if (s > i)
139
+ out += text.slice(i, s);
140
+ if (e > i)
141
+ i = e;
142
+ }
143
+ return out + text.slice(i);
144
+ }
145
+ /**
146
+ * Rebase a block's indentation: the `base` its lines carried in the delta
147
+ * becomes `target`. The first line arrives with no leading whitespace (the
148
+ * scanner's span starts at the declaration itself), so it only gains `target`.
149
+ *
150
+ * A CRLF delta's blank line is `"\r"`, not `""`, so splitting on `\n` alone used
151
+ * to hand a non-empty body to the rule below and every blank line inside a
152
+ * spliced block came out carrying the target indent as trailing whitespace. The
153
+ * carriage return is set aside and put back, which leaves the line's own ending
154
+ * exactly as authored for `matchLineEndings` to reconcile.
155
+ */
156
+ function reindent(block, base, target) {
157
+ return block
158
+ .split("\n")
159
+ .map((line, k) => {
160
+ const cr = line.endsWith("\r");
161
+ const raw = cr ? line.slice(0, -1) : line;
162
+ const body = k === 0 ? raw : raw.startsWith(base) ? raw.slice(base.length) : raw;
163
+ return (body.length === 0 ? "" : target + body) + (cr ? "\r" : "");
164
+ })
165
+ .join("\n");
166
+ }
167
+ //# sourceMappingURL=authored-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authored-source.js","sourceRoot":"","sources":["../../../../src/core/c4/splice/authored-source.ts"],"names":[],"mappings":"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","sourcesContent":["import { maskSource, matchBrace } from \"../source-mask.js\";\n\n/** A half-open byte range of `deltaText`, as the source scan reports one. */\nexport interface SourceRange {\n start: number;\n end: number;\n}\n\n/**\n * A declaration's authored source, ready to land in the living landscape:\n * byte-verbatim except that the feature's own tag is stripped (with the `,` or\n * `;` that set it apart in a tag list, which would otherwise be left stray) and\n * the indentation is rebased from where the block sat in the delta to where it\n * lands. A construct the strip leaves empty goes too — a line that held only\n * the tag disappears whole, and `x = kind 'y' { #FEAT-1 }` lands as\n * `x = kind 'y'`, not as a pair of empty braces.\n *\n * `omit` cuts named ranges of the delta out on the way over, and it exists for\n * one caller: a NEW service element whose interior belongs to that service's\n * extending model. The children come along in the parent's bytes — they carry no\n * feature tag of their own, because LikeC4 does not inherit tags, so nothing in\n * the addition set can see them — and the map must take the box without them or\n * the model can never declare them (verification 2026-09-04, refutation of E1).\n * The ranges join the tag's removals, so a body they empty collapses the same\n * way `#FEAT-1`-only braces do.\n */\n/** How a declaration is carried over: whose tag to drop, where it lands, and what to leave behind. */\nexport interface Carry {\n featureId: string;\n /** The indent of the position the block lands at. */\n indent: string;\n /** Delta ranges cut out on the way over — see the banner; `[]` when nothing rides separately. */\n omit?: readonly SourceRange[];\n}\n\nexport function spliceSource(\n deltaText: string,\n decl: { start: number; end: number; indent: string },\n carry: Carry,\n): string {\n const { featureId, indent: targetIndent, omit = [] } = carry;\n const block = deltaText.slice(decl.start, decl.end);\n const cuts = omit\n .filter((r) => r.start >= decl.start && r.end <= decl.end)\n .map((r) => wholeLines(block, r.start - decl.start, r.end - decl.start));\n return reindent(stripFeatureTag(block, featureId, cuts), decl.indent, targetIndent);\n}\n\n/**\n * Widen a cut to the whole lines it sits on, when it has them to itself.\n *\n * A scanned declaration's span starts at its first character and ends one past\n * its last brace, so cutting it verbatim would leave the leading indent and the\n * trailing newline behind as a blank line — and the emptied-line rule below only\n * fires on a removal a line contains. A cut sharing its line with other code is\n * left exactly as asked.\n */\nfunction wholeLines(block: string, start: number, end: number): [number, number] {\n const lineStart = block.lastIndexOf(\"\\n\", start - 1) + 1;\n if (!/^[ \\t]*$/.test(block.slice(lineStart, start))) return [start, end];\n const nl = block.indexOf(\"\\n\", end);\n const to = nl === -1 ? block.length : nl;\n if (!/^[ \\t\\r]*$/.test(block.slice(end, to))) return [start, end];\n return [lineStart, nl === -1 ? block.length : nl + 1];\n}\n\n/**\n * Rewrite the line endings a merge INSERTED to the ones the document already\n * uses.\n *\n * Splicing composes bytes from two files, and the delta's newlines are not\n * necessarily the living document's: on a repository without `core.autocrlf`\n * normalisation a CRLF landscape or model came back with a handful of bare-LF\n * lines in the spliced region — two conventions in one file, noisy in an editor\n * and in every diff (verification 2026-09-04, W-CRLF). One helper for both\n * merges, because both had it.\n *\n * Only a document with ONE convention is corrected, and then in whichever\n * direction it uses: a file that is already mixed has no convention to match, and\n * guessing one would rewrite lines nobody touched.\n */\nexport function matchLineEndings(document: string, merged: string): string {\n const crlf = (document.match(/\\r\\n/g) ?? []).length;\n const bare = (document.match(/(?<!\\r)\\n/g) ?? []).length;\n if (crlf > 0 && bare === 0) return merged.replace(/(?<!\\r)\\n/g, \"\\r\\n\");\n if (bare > 0 && crlf === 0) return merged.replace(/\\r\\n/g, \"\\n\");\n return merged;\n}\n\nfunction stripFeatureTag(block: string, featureId: string, cuts: ReadonlyArray<[number, number]>): string {\n const { code } = maskSource(block);\n const esc = featureId.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const removals: Array<[number, number]> = cuts.map(([s, e]) => [s, e]);\n for (const m of block.matchAll(new RegExp(`#${esc}(?![\\\\w-])`, \"g\"))) {\n // Only tags in CODE count — a description quoting \"#FEAT-1\" is content.\n if (code.slice(m.index, m.index + m[0].length) !== m[0]) continue;\n let s = m.index;\n let e = s + m[0].length;\n // A tag list's separators go with the tag they separate. LikeC4 reads a\n // list as `#a #b, #c;` — one or more tags first, then `,` groups, then an\n // optional `;` — so `#FEAT-1, #x` stripped to `, #x` and `#FEAT-1;` to a\n // bare `;`, and the parse net refused a delta LikeC4 accepts. The comma\n // after the tag goes with it, else the comma before it; the `;` only when\n // no tag is left in front of it.\n const commaAfter = /^[ \\t]*,[ \\t]*/.exec(code.slice(e));\n const commaBefore = /,[ \\t]*$/.exec(code.slice(0, s));\n const semi = /^[ \\t]*;/.exec(code.slice(e));\n if (commaAfter !== null) {\n removals.push([s, e + commaAfter[0].length]);\n continue;\n }\n if (commaBefore !== null) {\n removals.push([commaBefore.index, e]);\n continue;\n }\n if (semi !== null && !/#[\\w-]+\\s*$/.test(code.slice(0, s))) e += semi[0].length;\n // Take the whitespace on ONE side with the token — trailing first, so\n // `#FEAT-1 #critical` leaves `#critical` at its own indent, and a token at\n // the end of a line does not leave a trailing space behind.\n if (block[e] === \" \" || block[e] === \"\\t\") {\n while (block[e] === \" \" || block[e] === \"\\t\") e += 1;\n } else {\n while (s > 0 && (block[s - 1] === \" \" || block[s - 1] === \"\\t\")) s -= 1;\n }\n removals.push([s, e]);\n }\n if (removals.length === 0) return block;\n\n // A line the strip emptied disappears whole, newline included.\n for (let lineStart = 0; lineStart < block.length; ) {\n const nl = block.indexOf(\"\\n\", lineStart);\n const lineEnd = nl === -1 ? block.length : nl + 1;\n if (\n removals.some(([s, e]) => s >= lineStart && e <= lineEnd) &&\n /^\\s*$/.test(residual(block, lineStart, nl === -1 ? block.length : nl, removals))\n ) {\n removals.push([lineStart, lineEnd]);\n }\n lineStart = lineEnd;\n }\n\n // A body the strip emptied goes too, braces and all — but only one the strip\n // emptied: braces that were authored empty are authored bytes and survive.\n for (let at = code.indexOf(\"{\"); at !== -1; at = code.indexOf(\"{\", at + 1)) {\n const closeAt = matchBrace(code, at);\n if (closeAt === -1) continue;\n if (!removals.some(([s, e]) => s > at && e <= closeAt)) continue;\n if (!/^\\s*$/.test(residual(block, at + 1, closeAt, removals))) continue;\n let s = at;\n while (s > 0 && /\\s/.test(block[s - 1]!)) s -= 1;\n removals.push([s, closeAt + 1]);\n }\n return applyRemovals(block, removals);\n}\n\n/** The text of [from, to) with the removal ranges cut out. */\nfunction residual(text: string, from: number, to: number, removals: Array<[number, number]>): string {\n let out = \"\";\n for (let i = from; i < to; i += 1) {\n if (!removals.some(([s, e]) => i >= s && i < e)) out += text[i];\n }\n return out;\n}\n\nfunction applyRemovals(text: string, removals: Array<[number, number]>): string {\n const sorted = [...removals].sort((a, b) => a[0] - b[0] || b[1] - a[1]);\n let out = \"\";\n let i = 0;\n for (const [s, e] of sorted) {\n if (s > i) out += text.slice(i, s);\n if (e > i) i = e;\n }\n return out + text.slice(i);\n}\n\n/**\n * Rebase a block's indentation: the `base` its lines carried in the delta\n * becomes `target`. The first line arrives with no leading whitespace (the\n * scanner's span starts at the declaration itself), so it only gains `target`.\n *\n * A CRLF delta's blank line is `\"\\r\"`, not `\"\"`, so splitting on `\\n` alone used\n * to hand a non-empty body to the rule below and every blank line inside a\n * spliced block came out carrying the target indent as trailing whitespace. The\n * carriage return is set aside and put back, which leaves the line's own ending\n * exactly as authored for `matchLineEndings` to reconcile.\n */\nfunction reindent(block: string, base: string, target: string): string {\n return block\n .split(\"\\n\")\n .map((line, k) => {\n const cr = line.endsWith(\"\\r\");\n const raw = cr ? line.slice(0, -1) : line;\n const body = k === 0 ? raw : raw.startsWith(base) ? raw.slice(base.length) : raw;\n return (body.length === 0 ? \"\" : target + body) + (cr ? \"\\r\" : \"\");\n })\n .join(\"\\n\");\n}\n"]}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * A landscape merge the splicer could not compute. Every one is mechanical —
3
+ * the input cannot be spliced as authored, never a judgment `--approve` may
4
+ * override — and it is thrown at plan time, so nothing has been written.
5
+ * `archiveErrorCode` (commands/archive/archive.ts) owns the mapping to `merge-failed`;
6
+ * the splicer itself never names a CLI code.
7
+ */
8
+ export class LandscapeSpliceError extends Error {
9
+ }
10
+ /**
11
+ * Refuse a splice the splice map cannot see once it has landed — the document
12
+ * scanned the same number of statements after the insert as before it.
13
+ *
14
+ * Every insert adds at least one declaration or edge, so an unchanged count
15
+ * means the bytes went somewhere the scan reads as nothing: inside a comment or
16
+ * a string. LikeC4 reads it the same way, so the parse net passes a document
17
+ * that simply lacks the addition, and the archive printed "+1 relationship(s)"
18
+ * over an edge that was never there (review, 2026-10-22, on a block comment
19
+ * whose last line starts with `//`). Placement is meant never to do this; this
20
+ * is what turns a placement bug into `merge-failed` instead of silent loss.
21
+ */
22
+ export function assertSpliceVisible(before, after, what) {
23
+ const count = (s) => (s === null ? 0 : s.elements.length + s.rels.length);
24
+ if (count(after) > count(before))
25
+ return;
26
+ throw new LandscapeSpliceError(`placing '${what}' would land it where neither the splice map nor LikeC4 reads it — inside a comment or a string — ` +
27
+ `so the merge would lose it while reporting it merged; nothing was written. Move the comment it would land in, ` +
28
+ `then re-run, and report the shape`);
29
+ }
30
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../../src/core/c4/splice/contract.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;CAAG;AAElD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA2B,EAAE,KAA0B,EAAE,IAAY;IACvG,MAAM,KAAK,GAAG,CAAC,CAAsB,EAAU,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvG,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QAAE,OAAO;IACzC,MAAM,IAAI,oBAAoB,CAC5B,YAAY,IAAI,oGAAoG;QAClH,gHAAgH;QAChH,mCAAmC,CACtC,CAAC;AACJ,CAAC","sourcesContent":["import type { Elem, Rel } from \"../likec4.js\";\nimport type { ScanKinds, ScannedModel } from \"../source-scan.js\";\n\n/**\n * A landscape merge the splicer could not compute. Every one is mechanical —\n * the input cannot be spliced as authored, never a judgment `--approve` may\n * override — and it is thrown at plan time, so nothing has been written.\n * `archiveErrorCode` (commands/archive/archive.ts) owns the mapping to `merge-failed`;\n * the splicer itself never names a CLI code.\n */\nexport class LandscapeSpliceError extends Error {}\n\n/**\n * Refuse a splice the splice map cannot see once it has landed — the document\n * scanned the same number of statements after the insert as before it.\n *\n * Every insert adds at least one declaration or edge, so an unchanged count\n * means the bytes went somewhere the scan reads as nothing: inside a comment or\n * a string. LikeC4 reads it the same way, so the parse net passes a document\n * that simply lacks the addition, and the archive printed \"+1 relationship(s)\"\n * over an edge that was never there (review, 2026-10-22, on a block comment\n * whose last line starts with `//`). Placement is meant never to do this; this\n * is what turns a placement bug into `merge-failed` instead of silent loss.\n */\nexport function assertSpliceVisible(before: ScannedModel | null, after: ScannedModel | null, what: string): void {\n const count = (s: ScannedModel | null): number => (s === null ? 0 : s.elements.length + s.rels.length);\n if (count(after) > count(before)) return;\n throw new LandscapeSpliceError(\n `placing '${what}' would land it where neither the splice map nor LikeC4 reads it — inside a comment or a string — ` +\n `so the merge would lose it while reporting it merged; nothing was written. Move the comment it would land in, ` +\n `then re-run, and report the shape`,\n );\n}\n\n/**\n * A service whose `model.likec4` EXTENDS the fleet map — the document that owns\n * that service's interior, and therefore the one a nested addition belongs in.\n *\n * The merge takes these as TEXT already in hand, exactly as it takes the\n * landscape: reading the fleet and writing the result stay with the caller.\n * A service with a standalone model, or none, is simply absent from the list,\n * and the merge then behaves as it did before the extending shape existed.\n */\nexport interface ExtendingModel {\n /** The `services/<…>/<svc>` directory name — what an element's binding resolves to. */\n service: string;\n /** Repo-relative and `/`-separated: what a message names and where the caller writes. */\n path: string;\n /** The living model source, as authored. */\n text: string;\n}\n\n/** What one extending model owes this feature — routed, not yet spliced. */\nexport interface ModelAdditions {\n model: ExtendingModel;\n els: Elem[];\n rels: Rel[];\n /**\n * The kinds the model borrows from the map it extends, read off the landscape\n * this merge spliced: a model declares none of its own, and its scan cannot\n * see a `kind name` declaration or an `a .kind b` edge without them.\n */\n borrowed: ScanKinds;\n}\n\n/**\n * The tags each relationship kind of the DELTA gives every edge of that kind —\n * its `specification.relationshipKindTags`. The parsed additions carry them and\n * the delta's statements do not, so the splice needs the table to match one to\n * the other (`./identity/edges.ts`, `scannedStatementKey`).\n */\nexport type KindTags = Readonly<Record<string, readonly string[]>>;\n\nexport interface LandscapePlan {\n /** The merged landscape source, or null when everything was already there. */\n content: string | null;\n addedEls: Elem[];\n addedRels: Rel[];\n /**\n * The additions this merge routed AWAY from the map, per model that owns\n * them. Empty when the request named no extending models — the shape every\n * caller had before the routing existed. `./model/merge.ts` turns each entry\n * into that model's merged text.\n */\n models: ModelAdditions[];\n}\n\n/**\n * Everything the landscape splicer reads, as text and parsed views already in\n * hand. The merge is a pure text-to-text computation — reading the two files\n * (and deciding to write the result) stays with the caller, which is also what\n * keeps the splicer free of the staging layer.\n */\nexport interface LandscapeMergeRequest {\n /** The living landscape.likec4, decoded by the caller's readUtf8. */\n landscapeText: string;\n /** delta.likec4 as authored — the bytes the additions are spliced from. */\n deltaText: string;\n /** EVERY element the delta declares — the title join and the parent lookup read past the tagged ones. */\n deltaElements: Elem[];\n /** The delta's elements tagged with the feature: the candidate additions. */\n newEls: Elem[];\n /** The delta's relationships tagged with the feature. */\n newRels: Rel[];\n featureId: string;\n /** The delta's relationship kinds' tags. Omitted reads as a delta whose kinds carry none. */\n deltaKindTags?: KindTags;\n /**\n * The fleet's extending models. Omitted (or empty) is the pre-extending\n * behaviour byte for byte: every addition lands on the map.\n */\n models?: readonly ExtendingModel[];\n}\n"]}