@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,244 @@
1
+ /**
2
+ * Which service owns which capability, and which feature owns which change —
3
+ * the two decisions a human has to make, graded against what the scan found.
4
+ *
5
+ * The routing this produces is what everything downstream selects with, which
6
+ * is why `servicesForRequirement` is returned as a function rather than as a
7
+ * map: a split capability routes per REQUIREMENT and a single-service one
8
+ * routes wholesale, and a caller that reimplemented that choice would put a
9
+ * living requirement and its own delta in different services.
10
+ */
11
+ import { resolve } from "node:path";
12
+ import { dictionary, ownValue } from "../../kernel/records.js";
13
+ import { FEATURE_ID_RULE, isFeatureId } from "../../kernel/ids/feature.js";
14
+ import { compareIds } from "../../repo/entries.js";
15
+ import { parseRequirements } from "../../document/parse.js";
16
+ import {} from "../../document/spec.js";
17
+ import {} from "../model/mapping.js";
18
+ import {} from "../model/model.js";
19
+ import { titleFromChangeId } from "../scan/changes.js";
20
+ export function capabilityDecisions(scan) {
21
+ const { root, mapping, bound, inventoryDigest, livingRequirements, active, renamed } = scan;
22
+ // Capability ownership must cover the active horizon too: a brand-new
23
+ // capability may exist only under changes/<id>/specs until archive.
24
+ //
25
+ // `routedNames` is the subset a split capability must actually allocate. A
26
+ // renamed requirement is routed by its FROM — that is what keeps the delta in
27
+ // the same services as the living text it rewrites — so demanding an
28
+ // allocation for its TO as well asked a reviewer for a decision apply ignores.
29
+ const requirementNamesByCapability = new Map();
30
+ const routedNamesByCapability = new Map();
31
+ const activeChangesByCapability = new Map();
32
+ const activeRenamePairs = renamed.filter((rename) => rename.scope === "active"
33
+ && rename.from !== null && rename.from !== ""
34
+ && rename.to !== null && rename.to !== "");
35
+ for (const [capability, requirements] of livingRequirements) {
36
+ requirementNamesByCapability.set(capability, new Set(requirements.map((item) => item.name)));
37
+ routedNamesByCapability.set(capability, new Set(requirements.map((item) => item.name)));
38
+ }
39
+ for (const change of active) {
40
+ for (const spec of change.specs) {
41
+ const names = requirementNamesByCapability.get(spec.capability) ?? new Set();
42
+ const routed = routedNamesByCapability.get(spec.capability) ?? new Set();
43
+ for (const name of spec.requirementNames) {
44
+ names.add(name);
45
+ const pairs = activeRenamePairs.filter((rename) => rename.changeId === change.id
46
+ && rename.capability === spec.capability
47
+ && (name === rename.from || name === rename.to));
48
+ routed.add(pairs.length === 1 ? pairs[0].from : name);
49
+ }
50
+ requirementNamesByCapability.set(spec.capability, names);
51
+ routedNamesByCapability.set(spec.capability, routed);
52
+ const changes = activeChangesByCapability.get(spec.capability) ?? new Set();
53
+ changes.add(change.id);
54
+ activeChangesByCapability.set(spec.capability, changes);
55
+ }
56
+ }
57
+ const allCapabilityIds = [...requirementNamesByCapability.keys()].sort(compareIds);
58
+ const mappingIssues = [];
59
+ if (bound) {
60
+ if (mapping.source === null) {
61
+ mappingIssues.push({
62
+ code: "mapping.source-missing",
63
+ key: "source",
64
+ message: "Mapping is not bound to an audited source root and inventory digest.",
65
+ });
66
+ }
67
+ else {
68
+ if (resolve(mapping.source.root) !== root) {
69
+ mappingIssues.push({
70
+ code: "mapping.source-root-mismatch",
71
+ key: "source.root",
72
+ message: `Mapping was created for ${mapping.source.root}, not ${root}.`,
73
+ });
74
+ }
75
+ if (mapping.source.inventoryDigest !== inventoryDigest) {
76
+ mappingIssues.push({
77
+ code: "mapping.source-digest-mismatch",
78
+ key: "source.inventoryDigest",
79
+ message: `OpenSpec source changed after audit (${mapping.source.inventoryDigest} != ${inventoryDigest}).`,
80
+ });
81
+ }
82
+ }
83
+ }
84
+ const capabilityIds = new Set(allCapabilityIds);
85
+ for (const capability of Object.keys(mapping.capabilities)) {
86
+ if (!capabilityIds.has(capability)) {
87
+ mappingIssues.push({
88
+ code: "mapping.unknown-capability",
89
+ key: capability,
90
+ message: `Mapping names unknown capability '${capability}'.`,
91
+ });
92
+ }
93
+ }
94
+ const mappingDecisions = allCapabilityIds.map((capability) => {
95
+ const capabilityMapping = ownValue(mapping.capabilities, capability)
96
+ ?? { services: [], requirementServices: dictionary() };
97
+ const services = [...new Set(capabilityMapping.services)]
98
+ .filter((service) => service.trim() !== "")
99
+ .sort(compareIds);
100
+ const requirementNames = [...(requirementNamesByCapability.get(capability) ?? [])].sort(compareIds);
101
+ const requirementNameSet = new Set(requirementNames);
102
+ const routedNames = [...(routedNamesByCapability.get(capability) ?? [])].sort(compareIds);
103
+ const requirementServices = dictionary();
104
+ for (const [requirement, allocated] of Object.entries(capabilityMapping.requirementServices)) {
105
+ if (!requirementNameSet.has(requirement)) {
106
+ mappingIssues.push({
107
+ code: "mapping.unknown-requirement",
108
+ key: `${capability}:${requirement}`,
109
+ message: `Capability '${capability}' mapping names unknown requirement '${requirement}'.`,
110
+ });
111
+ continue;
112
+ }
113
+ const selected = [...new Set(allocated)].filter(Boolean).sort(compareIds);
114
+ requirementServices[requirement] = selected;
115
+ for (const service of selected) {
116
+ if (!services.includes(service)) {
117
+ mappingIssues.push({
118
+ code: "mapping.requirement-service-unknown",
119
+ key: `${capability}:${requirement}`,
120
+ message: `Requirement '${requirement}' is allocated to '${service}', which is not in capability '${capability}' services.`,
121
+ });
122
+ }
123
+ }
124
+ }
125
+ // Only routed names get an empty slot in the skeleton: an unroutable name
126
+ // offered for allocation is a decision that changes nothing.
127
+ for (const requirement of routedNames) {
128
+ if (ownValue(requirementServices, requirement) === undefined)
129
+ requirementServices[requirement] = [];
130
+ }
131
+ if (services.length > 1) {
132
+ for (const requirement of routedNames) {
133
+ if ((ownValue(requirementServices, requirement) ?? []).length === 0) {
134
+ mappingIssues.push({
135
+ code: "mapping.requirement-allocation-missing",
136
+ key: `${capability}:${requirement}`,
137
+ message: `Split capability '${capability}' must allocate requirement '${requirement}' to at least one selected service.`,
138
+ });
139
+ }
140
+ }
141
+ for (const service of services) {
142
+ if (!Object.values(requirementServices).some((selected) => selected.includes(service))) {
143
+ mappingIssues.push({
144
+ code: "mapping.service-allocation-empty",
145
+ key: `${capability}:${service}`,
146
+ message: `Split capability '${capability}' selects service '${service}' but allocates no requirement to it.`,
147
+ });
148
+ }
149
+ }
150
+ }
151
+ return {
152
+ capability,
153
+ service: services.length === 1 ? services[0] : null,
154
+ services,
155
+ requirementServices,
156
+ suggestedService: capability.split("/").at(-1) ?? capability,
157
+ hasLivingSpec: livingRequirements.has(capability),
158
+ activeChanges: [...(activeChangesByCapability.get(capability) ?? [])].sort(compareIds),
159
+ status: services.length === 0 ? "needsMapping" : "mapped",
160
+ };
161
+ });
162
+ const decisionsByCapability = new Map(mappingDecisions.map((decision) => [decision.capability, decision]));
163
+ const servicesForRequirement = (capability, requirement) => {
164
+ const decision = decisionsByCapability.get(capability);
165
+ if (decision === undefined)
166
+ return [];
167
+ return decision.services.length === 1
168
+ ? decision.services
169
+ : ownValue(decision.requirementServices, requirement) ?? [];
170
+ };
171
+ const livingByService = new Map();
172
+ for (const [capability, requirements] of livingRequirements) {
173
+ for (const requirement of requirements) {
174
+ for (const service of servicesForRequirement(capability, requirement.name)) {
175
+ const routed = livingByService.get(service) ?? [];
176
+ routed.push({ capability, requirement });
177
+ livingByService.set(service, routed);
178
+ }
179
+ }
180
+ }
181
+ const activeChangeIds = new Set(active.map((change) => change.id));
182
+ for (const change of Object.keys(mapping.changes)) {
183
+ if (!activeChangeIds.has(change)) {
184
+ mappingIssues.push({
185
+ code: "mapping.unknown-change",
186
+ key: change,
187
+ message: `Mapping names unknown active change '${change}'.`,
188
+ });
189
+ }
190
+ }
191
+ const changeDecisions = active.map((change, index) => {
192
+ const suggestedTitle = titleFromChangeId(change.id);
193
+ const selected = ownValue(mapping.changes, change.id);
194
+ const feature = selected?.feature ?? null;
195
+ const title = selected?.title?.trim() ?? suggestedTitle;
196
+ if (selected !== undefined && title === "") {
197
+ mappingIssues.push({
198
+ code: "mapping.change-title-missing",
199
+ key: change.id,
200
+ message: `Active change '${change.id}' needs a non-empty title.`,
201
+ });
202
+ }
203
+ if (feature !== null && !isFeatureId(feature)) {
204
+ mappingIssues.push({
205
+ code: "mapping.feature-id-invalid",
206
+ key: change.id,
207
+ message: `Active change '${change.id}' maps to invalid loam feature id '${feature}'. ${FEATURE_ID_RULE}`,
208
+ });
209
+ }
210
+ return {
211
+ change: change.id,
212
+ feature,
213
+ title,
214
+ suggestedFeature: `FEAT-${index + 1}`,
215
+ suggestedTitle,
216
+ status: feature === null || title === "" ? "needsFeature" : "mapped",
217
+ };
218
+ });
219
+ const featureOwners = new Map();
220
+ for (const decision of changeDecisions) {
221
+ if (decision.feature === null || !isFeatureId(decision.feature))
222
+ continue;
223
+ const key = decision.feature.toLowerCase();
224
+ const owners = featureOwners.get(key) ?? [];
225
+ owners.push(decision.change);
226
+ featureOwners.set(key, owners);
227
+ }
228
+ for (const [feature, owners] of featureOwners) {
229
+ if (owners.length > 1) {
230
+ mappingIssues.push({
231
+ code: "mapping.feature-id-duplicate",
232
+ key: feature,
233
+ message: `Loam feature id '${feature}' is assigned to multiple OpenSpec changes: ${owners.join(", ")}.`,
234
+ });
235
+ }
236
+ }
237
+ return {
238
+ mappingIssues,
239
+ mappingDecisions,
240
+ changeDecisions,
241
+ routing: { servicesForRequirement, livingByService },
242
+ };
243
+ }
244
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../../src/core/openspec/decide/capabilities.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Which service owns which capability, and which feature owns which change —\n * the two decisions a human has to make, graded against what the scan found.\n *\n * The routing this produces is what everything downstream selects with, which\n * is why `servicesForRequirement` is returned as a function rather than as a\n * map: a split capability routes per REQUIREMENT and a single-service one\n * routes wholesale, and a caller that reimplemented that choice would put a\n * living requirement and its own delta in different services.\n */\nimport { resolve } from \"node:path\";\nimport { dictionary, ownValue } from \"../../kernel/records.js\";\nimport { FEATURE_ID_RULE, isFeatureId } from \"../../kernel/ids/feature.js\";\nimport { compareIds } from \"../../repo/entries.js\";\nimport { parseRequirements } from \"../../document/parse.js\";\nimport { type Requirement } from \"../../document/spec.js\";\nimport {\n type OpenSpecMapping,\n type CapabilityMappingDecision,\n type OpenSpecChangeDecision,\n type OpenSpecMappingIssue,\n} from \"../model/mapping.js\";\nimport { type OpenSpecChange, type OpenSpecRenamedUsage } from \"../model/model.js\";\nimport { titleFromChangeId } from \"../scan/changes.js\";\n\n/** Everything the workspace scan found, before any decision is graded. */\nexport interface Scan {\n root: string;\n mapping: OpenSpecMapping;\n /** Whether a mapping was SUPPLIED — an audit grades no source binding. */\n bound: boolean;\n inventoryDigest: string;\n livingRequirements: Map<string, Requirement[]>;\n active: OpenSpecChange[];\n renamed: OpenSpecRenamedUsage[];\n}\n\n/** How a requirement reaches a service, once the capability decisions are in. */\nexport interface Routing {\n servicesForRequirement(capability: string, requirement: string): string[];\n livingByService: Map<string, Array<{ capability: string; requirement: Requirement }>>;\n}\n\nexport interface Decisions {\n mappingIssues: OpenSpecMappingIssue[];\n mappingDecisions: CapabilityMappingDecision[];\n changeDecisions: OpenSpecChangeDecision[];\n routing: Routing;\n}\n\nexport function capabilityDecisions(scan: Scan): Decisions {\n const { root, mapping, bound, inventoryDigest, livingRequirements, active, renamed } = scan;\n // Capability ownership must cover the active horizon too: a brand-new\n // capability may exist only under changes/<id>/specs until archive.\n //\n // `routedNames` is the subset a split capability must actually allocate. A\n // renamed requirement is routed by its FROM — that is what keeps the delta in\n // the same services as the living text it rewrites — so demanding an\n // allocation for its TO as well asked a reviewer for a decision apply ignores.\n const requirementNamesByCapability = new Map<string, Set<string>>();\n const routedNamesByCapability = new Map<string, Set<string>>();\n const activeChangesByCapability = new Map<string, Set<string>>();\n const activeRenamePairs = renamed.filter((rename) =>\n rename.scope === \"active\"\n && rename.from !== null && rename.from !== \"\"\n && rename.to !== null && rename.to !== \"\");\n for (const [capability, requirements] of livingRequirements) {\n requirementNamesByCapability.set(capability, new Set(requirements.map((item) => item.name)));\n routedNamesByCapability.set(capability, new Set(requirements.map((item) => item.name)));\n }\n for (const change of active) {\n for (const spec of change.specs) {\n const names = requirementNamesByCapability.get(spec.capability) ?? new Set<string>();\n const routed = routedNamesByCapability.get(spec.capability) ?? new Set<string>();\n for (const name of spec.requirementNames) {\n names.add(name);\n const pairs = activeRenamePairs.filter((rename) =>\n rename.changeId === change.id\n && rename.capability === spec.capability\n && (name === rename.from || name === rename.to));\n routed.add(pairs.length === 1 ? pairs[0]!.from! : name);\n }\n requirementNamesByCapability.set(spec.capability, names);\n routedNamesByCapability.set(spec.capability, routed);\n const changes = activeChangesByCapability.get(spec.capability) ?? new Set<string>();\n changes.add(change.id);\n activeChangesByCapability.set(spec.capability, changes);\n }\n }\n const allCapabilityIds = [...requirementNamesByCapability.keys()].sort(compareIds);\n\n const mappingIssues: OpenSpecMappingIssue[] = [];\n if (bound) {\n if (mapping.source === null) {\n mappingIssues.push({\n code: \"mapping.source-missing\",\n key: \"source\",\n message: \"Mapping is not bound to an audited source root and inventory digest.\",\n });\n } else {\n if (resolve(mapping.source.root) !== root) {\n mappingIssues.push({\n code: \"mapping.source-root-mismatch\",\n key: \"source.root\",\n message: `Mapping was created for ${mapping.source.root}, not ${root}.`,\n });\n }\n if (mapping.source.inventoryDigest !== inventoryDigest) {\n mappingIssues.push({\n code: \"mapping.source-digest-mismatch\",\n key: \"source.inventoryDigest\",\n message: `OpenSpec source changed after audit (${mapping.source.inventoryDigest} != ${inventoryDigest}).`,\n });\n }\n }\n }\n const capabilityIds = new Set(allCapabilityIds);\n for (const capability of Object.keys(mapping.capabilities)) {\n if (!capabilityIds.has(capability)) {\n mappingIssues.push({\n code: \"mapping.unknown-capability\",\n key: capability,\n message: `Mapping names unknown capability '${capability}'.`,\n });\n }\n }\n const mappingDecisions: CapabilityMappingDecision[] = allCapabilityIds.map((capability) => {\n const capabilityMapping = ownValue(mapping.capabilities, capability)\n ?? { services: [], requirementServices: dictionary<string[]>() };\n const services = [...new Set(capabilityMapping.services)]\n .filter((service) => service.trim() !== \"\")\n .sort(compareIds);\n const requirementNames = [...(requirementNamesByCapability.get(capability) ?? [])].sort(compareIds);\n const requirementNameSet = new Set(requirementNames);\n const routedNames = [...(routedNamesByCapability.get(capability) ?? [])].sort(compareIds);\n const requirementServices = dictionary<string[]>();\n for (const [requirement, allocated] of Object.entries(capabilityMapping.requirementServices)) {\n if (!requirementNameSet.has(requirement)) {\n mappingIssues.push({\n code: \"mapping.unknown-requirement\",\n key: `${capability}:${requirement}`,\n message: `Capability '${capability}' mapping names unknown requirement '${requirement}'.`,\n });\n continue;\n }\n const selected = [...new Set(allocated)].filter(Boolean).sort(compareIds);\n requirementServices[requirement] = selected;\n for (const service of selected) {\n if (!services.includes(service)) {\n mappingIssues.push({\n code: \"mapping.requirement-service-unknown\",\n key: `${capability}:${requirement}`,\n message: `Requirement '${requirement}' is allocated to '${service}', which is not in capability '${capability}' services.`,\n });\n }\n }\n }\n // Only routed names get an empty slot in the skeleton: an unroutable name\n // offered for allocation is a decision that changes nothing.\n for (const requirement of routedNames) {\n if (ownValue(requirementServices, requirement) === undefined) requirementServices[requirement] = [];\n }\n if (services.length > 1) {\n for (const requirement of routedNames) {\n if ((ownValue(requirementServices, requirement) ?? []).length === 0) {\n mappingIssues.push({\n code: \"mapping.requirement-allocation-missing\",\n key: `${capability}:${requirement}`,\n message: `Split capability '${capability}' must allocate requirement '${requirement}' to at least one selected service.`,\n });\n }\n }\n for (const service of services) {\n if (!Object.values(requirementServices).some((selected) => selected.includes(service))) {\n mappingIssues.push({\n code: \"mapping.service-allocation-empty\",\n key: `${capability}:${service}`,\n message: `Split capability '${capability}' selects service '${service}' but allocates no requirement to it.`,\n });\n }\n }\n }\n return {\n capability,\n service: services.length === 1 ? services[0]! : null,\n services,\n requirementServices,\n suggestedService: capability.split(\"/\").at(-1) ?? capability,\n hasLivingSpec: livingRequirements.has(capability),\n activeChanges: [...(activeChangesByCapability.get(capability) ?? [])].sort(compareIds),\n status: services.length === 0 ? \"needsMapping\" : \"mapped\",\n };\n });\n const decisionsByCapability = new Map(mappingDecisions.map((decision) => [decision.capability, decision]));\n const servicesForRequirement = (capability: string, requirement: string): string[] => {\n const decision = decisionsByCapability.get(capability);\n if (decision === undefined) return [];\n return decision.services.length === 1\n ? decision.services\n : ownValue(decision.requirementServices, requirement) ?? [];\n };\n const livingByService = new Map<string, Array<{ capability: string; requirement: ReturnType<typeof parseRequirements>[number] }>>();\n for (const [capability, requirements] of livingRequirements) {\n for (const requirement of requirements) {\n for (const service of servicesForRequirement(capability, requirement.name)) {\n const routed = livingByService.get(service) ?? [];\n routed.push({ capability, requirement });\n livingByService.set(service, routed);\n }\n }\n }\n\n const activeChangeIds = new Set(active.map((change) => change.id));\n for (const change of Object.keys(mapping.changes)) {\n if (!activeChangeIds.has(change)) {\n mappingIssues.push({\n code: \"mapping.unknown-change\",\n key: change,\n message: `Mapping names unknown active change '${change}'.`,\n });\n }\n }\n const changeDecisions: OpenSpecChangeDecision[] = active.map((change, index) => {\n const suggestedTitle = titleFromChangeId(change.id);\n const selected = ownValue(mapping.changes, change.id);\n const feature = selected?.feature ?? null;\n const title = selected?.title?.trim() ?? suggestedTitle;\n if (selected !== undefined && title === \"\") {\n mappingIssues.push({\n code: \"mapping.change-title-missing\",\n key: change.id,\n message: `Active change '${change.id}' needs a non-empty title.`,\n });\n }\n if (feature !== null && !isFeatureId(feature)) {\n mappingIssues.push({\n code: \"mapping.feature-id-invalid\",\n key: change.id,\n message: `Active change '${change.id}' maps to invalid loam feature id '${feature}'. ${FEATURE_ID_RULE}`,\n });\n }\n return {\n change: change.id,\n feature,\n title,\n suggestedFeature: `FEAT-${index + 1}`,\n suggestedTitle,\n status: feature === null || title === \"\" ? \"needsFeature\" : \"mapped\",\n };\n });\n const featureOwners = new Map<string, string[]>();\n for (const decision of changeDecisions) {\n if (decision.feature === null || !isFeatureId(decision.feature)) continue;\n const key = decision.feature.toLowerCase();\n const owners = featureOwners.get(key) ?? [];\n owners.push(decision.change);\n featureOwners.set(key, owners);\n }\n for (const [feature, owners] of featureOwners) {\n if (owners.length > 1) {\n mappingIssues.push({\n code: \"mapping.feature-id-duplicate\",\n key: feature,\n message: `Loam feature id '${feature}' is assigned to multiple OpenSpec changes: ${owners.join(\", \")}.`,\n });\n }\n }\n return {\n mappingIssues,\n mappingDecisions,\n changeDecisions,\n routing: { servicesForRequirement, livingByService },\n };\n}\n"]}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * What happens to each authored artifact loam has no equivalent for: a
3
+ * proposal, a task list, a design note.
4
+ *
5
+ * Every one of them is a decision rather than a default, because the honest
6
+ * answers differ per corpus — one team's `design.md` is an ADR, another's is a
7
+ * scratchpad. A disposition nobody chose is the one way this migration could
8
+ * quietly drop authored work, so an unset one blocks readiness.
9
+ */
10
+ import { ownValue } from "../../kernel/records.js";
11
+ import {} from "../model/mapping.js";
12
+ import {} from "../model/model.js";
13
+ export function artifactDispositions(artifacts, mapping, activeChangeIds, mappingIssues) {
14
+ const decisionKinds = new Set(["proposal", "tasks", "change-design"]);
15
+ const artifactDecisions = artifacts
16
+ // Never offer a disposition for an artifact no enumerated change owns —
17
+ // dot-prefixed change directories are refused, not migrated, and a
18
+ // `selectedDisposition` recorded for one is a decision about nothing.
19
+ .filter((artifact) => artifact.scope === "active"
20
+ && decisionKinds.has(artifact.kind)
21
+ && artifact.changeId !== undefined
22
+ && activeChangeIds.has(artifact.changeId))
23
+ .map((artifact) => {
24
+ const selected = ownValue(mapping.artifacts, artifact.path) ?? null;
25
+ return {
26
+ path: artifact.path,
27
+ kind: artifact.kind,
28
+ suggestedDisposition: artifact.disposition,
29
+ disposition: selected,
30
+ status: selected === null ? "needsDisposition" : "mapped",
31
+ };
32
+ });
33
+ const artifactPaths = new Set(artifactDecisions.map((decision) => decision.path));
34
+ // Sets of plain strings: the question being asked is "is this authored value
35
+ // one of the ones this kind accepts", and a set of the union could not be
36
+ // asked it without an assertion putting the answer back where it started.
37
+ const dispositionsByKind = {
38
+ proposal: new Set(["convert-to-intent", "retain-read-only", "manual-review"]),
39
+ tasks: new Set(["preserve-as-legacy-checklist", "retain-read-only", "manual-review"]),
40
+ "change-design": new Set(["review-as-feature-adr", "retain-read-only", "manual-review"]),
41
+ };
42
+ for (const [path, disposition] of Object.entries(mapping.artifacts)) {
43
+ if (!artifactPaths.has(path)) {
44
+ mappingIssues.push({
45
+ code: "mapping.unknown-artifact",
46
+ key: path,
47
+ message: `Mapping names unknown active authored artifact '${path}'.`,
48
+ });
49
+ }
50
+ else {
51
+ const decision = artifactDecisions.find((item) => item.path === path);
52
+ if (dispositionsByKind[decision.kind].has(disposition))
53
+ continue;
54
+ mappingIssues.push({
55
+ code: "mapping.invalid-artifact-disposition",
56
+ key: path,
57
+ message: `${decision.kind} artifact '${path}' has unsupported disposition '${disposition}'.`,
58
+ });
59
+ }
60
+ }
61
+ return artifactDecisions;
62
+ }
63
+ //# sourceMappingURL=dispositions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispositions.js","sourceRoot":"","sources":["../../../../src/core/openspec/decide/dispositions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAmD,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAmF,MAAM,mBAAmB,CAAC;AAEpH,MAAM,UAAU,oBAAoB,CAClC,SAA6B,EAC7B,OAAwB,EACxB,eAAoC,EACpC,aAAqC;IAEnC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAuB,CAAC,UAAU,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC;IAC5F,MAAM,iBAAiB,GAA+B,SAAS;QAC7D,wEAAwE;QACxE,mEAAmE;QACnE,sEAAsE;SACrE,MAAM,CAAC,CAAC,QAAQ,EAAmF,EAAE,CACpG,QAAQ,CAAC,KAAK,KAAK,QAAQ;WACxB,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;WAChC,QAAQ,CAAC,QAAQ,KAAK,SAAS;WAC/B,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;SAC3C,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAChB,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;QACpE,OAAO;YACL,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,oBAAoB,EAAE,QAAQ,CAAC,WAAW;YAC1C,WAAW,EAAE,QAAQ;YACrB,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,kBAA2B,CAAC,CAAC,CAAC,QAAiB;SAC5E,CAAC;IACJ,CAAC,CAAC,CAAC;IACL,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAClF,6EAA6E;IAC7E,0EAA0E;IAC1E,0EAA0E;IAC1E,MAAM,kBAAkB,GAAkE;QACxF,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,eAAe,CAAC,CAAC;QAC7E,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,8BAA8B,EAAE,kBAAkB,EAAE,eAAe,CAAC,CAAC;QACrF,eAAe,EAAE,IAAI,GAAG,CAAC,CAAC,uBAAuB,EAAE,kBAAkB,EAAE,eAAe,CAAC,CAAC;KACzF,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QACpE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,0BAA0B;gBAChC,GAAG,EAAE,IAAI;gBACT,OAAO,EAAE,mDAAmD,IAAI,IAAI;aACrE,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAE,CAAC;YACvE,IAAI,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;gBAAE,SAAS;YACjE,aAAa,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,sCAAsC;gBAC5C,GAAG,EAAE,IAAI;gBACT,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,cAAc,IAAI,kCAAkC,WAAW,IAAI;aAC7F,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACH,OAAO,iBAAiB,CAAC;AAC3B,CAAC","sourcesContent":["/**\n * What happens to each authored artifact loam has no equivalent for: a\n * proposal, a task list, a design note.\n *\n * Every one of them is a decision rather than a default, because the honest\n * answers differ per corpus — one team's `design.md` is an ADR, another's is a\n * scratchpad. A disposition nobody chose is the one way this migration could\n * quietly drop authored work, so an unset one blocks readiness.\n */\nimport { ownValue } from \"../../kernel/records.js\";\nimport { type OpenSpecMapping, type OpenSpecMappingIssue } from \"../model/mapping.js\";\nimport { type OpenSpecArtifact, type OpenSpecArtifactDecision, type OpenSpecArtifactKind } from \"../model/model.js\";\n\nexport function artifactDispositions(\n artifacts: OpenSpecArtifact[],\n mapping: OpenSpecMapping,\n activeChangeIds: ReadonlySet<string>,\n mappingIssues: OpenSpecMappingIssue[],\n): OpenSpecArtifactDecision[] {\n const decisionKinds = new Set<OpenSpecArtifactKind>([\"proposal\", \"tasks\", \"change-design\"]);\n const artifactDecisions: OpenSpecArtifactDecision[] = artifacts\n // Never offer a disposition for an artifact no enumerated change owns —\n // dot-prefixed change directories are refused, not migrated, and a\n // `selectedDisposition` recorded for one is a decision about nothing.\n .filter((artifact): artifact is OpenSpecArtifact & { kind: \"proposal\" | \"tasks\" | \"change-design\" } =>\n artifact.scope === \"active\"\n && decisionKinds.has(artifact.kind)\n && artifact.changeId !== undefined\n && activeChangeIds.has(artifact.changeId))\n .map((artifact) => {\n const selected = ownValue(mapping.artifacts, artifact.path) ?? null;\n return {\n path: artifact.path,\n kind: artifact.kind,\n suggestedDisposition: artifact.disposition,\n disposition: selected,\n status: selected === null ? \"needsDisposition\" as const : \"mapped\" as const,\n };\n });\n const artifactPaths = new Set(artifactDecisions.map((decision) => decision.path));\n // Sets of plain strings: the question being asked is \"is this authored value\n // one of the ones this kind accepts\", and a set of the union could not be\n // asked it without an assertion putting the answer back where it started.\n const dispositionsByKind: Record<OpenSpecArtifactDecision[\"kind\"], ReadonlySet<string>> = {\n proposal: new Set([\"convert-to-intent\", \"retain-read-only\", \"manual-review\"]),\n tasks: new Set([\"preserve-as-legacy-checklist\", \"retain-read-only\", \"manual-review\"]),\n \"change-design\": new Set([\"review-as-feature-adr\", \"retain-read-only\", \"manual-review\"]),\n };\n for (const [path, disposition] of Object.entries(mapping.artifacts)) {\n if (!artifactPaths.has(path)) {\n mappingIssues.push({\n code: \"mapping.unknown-artifact\",\n key: path,\n message: `Mapping names unknown active authored artifact '${path}'.`,\n });\n } else {\n const decision = artifactDecisions.find((item) => item.path === path)!;\n if (dispositionsByKind[decision.kind].has(disposition)) continue;\n mappingIssues.push({\n code: \"mapping.invalid-artifact-disposition\",\n key: path,\n message: `${decision.kind} artifact '${path}' has unsupported disposition '${disposition}'.`,\n });\n }\n }\n return artifactDecisions;\n}\n"]}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Every active RENAMED pair resolved against the living source of truth.
3
+ *
4
+ * This is the identity problem the whole package exists for: OpenSpec renames
5
+ * by writing FROM/TO bullets, loam renames by carrying one stable
6
+ * `Requirement-ID` through a MODIFIED requirement, and nothing mechanical
7
+ * bridges the two. So each pair is either resolved to an id the living text
8
+ * already carries, or it becomes a decision a human has to make — never a
9
+ * guess, because a wrong identity silently merges one requirement's text over
10
+ * another's.
11
+ *
12
+ * It MUTATES the usages it resolves rather than returning new ones: a rename is
13
+ * one fact seen in one file, and two copies of it — one resolved, one not — is
14
+ * exactly the bug this resolution exists to prevent.
15
+ */
16
+ import { ownValue } from "../../kernel/records.js";
17
+ import { REQUIREMENT_ID_RE, requirementIdDeclarations } from "../../document/spec.js";
18
+ import {} from "../model/mapping.js";
19
+ import {} from "../model/model.js";
20
+ import {} from "./capabilities.js";
21
+ export function resolveRenames(scan, routing, mappingIssues) {
22
+ const { mapping, livingRequirements, renamed } = scan;
23
+ const { livingByService, servicesForRequirement } = routing;
24
+ const activeRenames = renamed.filter((rename) => rename.scope === "active");
25
+ const renameKeys = new Set(activeRenames.map((rename) => rename.key));
26
+ for (const [key, requirementId] of Object.entries(mapping.renames)) {
27
+ if (!renameKeys.has(key)) {
28
+ mappingIssues.push({
29
+ code: "mapping.unknown-rename",
30
+ key,
31
+ message: `Mapping names unknown RENAMED pair '${key}'.`,
32
+ });
33
+ }
34
+ else if (!REQUIREMENT_ID_RE.test(requirementId)) {
35
+ mappingIssues.push({
36
+ code: "mapping.invalid-requirement-id",
37
+ key,
38
+ message: `RENAMED pair '${key}' has invalid Requirement-ID '${requirementId}'.`,
39
+ });
40
+ }
41
+ }
42
+ // Resolve every rename against the living source of truth. A mapped id is
43
+ // only needed when the source requirement does not already carry one.
44
+ for (const rename of activeRenames) {
45
+ if (rename.from === null || rename.from === "" || rename.to === null || rename.to === "")
46
+ continue;
47
+ const living = livingRequirements.get(rename.capability) ?? [];
48
+ const matches = living.filter((requirement) => requirement.name === rename.from);
49
+ if (matches.length === 0) {
50
+ mappingIssues.push({
51
+ code: "mapping.rename-source-missing",
52
+ key: rename.key,
53
+ message: `RENAMED source '${rename.from}' does not exist in living capability '${rename.capability}'.`,
54
+ });
55
+ rename.requirementId = null;
56
+ rename.status = "needsIdentity";
57
+ continue;
58
+ }
59
+ if (matches.length > 1) {
60
+ mappingIssues.push({
61
+ code: "mapping.rename-source-ambiguous",
62
+ key: rename.key,
63
+ message: `RENAMED source '${rename.from}' matches ${matches.length} living requirements in '${rename.capability}'.`,
64
+ });
65
+ rename.requirementId = null;
66
+ rename.status = "needsIdentity";
67
+ continue;
68
+ }
69
+ const source = matches[0];
70
+ const declarations = requirementIdDeclarations(source);
71
+ if (declarations.length > 0
72
+ && (declarations.length !== 1 || !REQUIREMENT_ID_RE.test(declarations[0]))) {
73
+ rename.existingRequirementId = source.id ?? null;
74
+ rename.requirementId = null;
75
+ rename.status = "needsIdentity";
76
+ mappingIssues.push({
77
+ code: "mapping.rename-source-id-invalid",
78
+ key: rename.key,
79
+ message: `RENAMED source '${rename.from}' has ${declarations.length === 1 ? "an invalid" : "repeated"} Requirement-ID declaration; repair the living source before migration.`,
80
+ });
81
+ continue;
82
+ }
83
+ rename.existingRequirementId = source.id ?? null;
84
+ const requestedId = ownValue(mapping.renames, rename.key) ?? null;
85
+ if (source.id !== undefined && requestedId !== null && requestedId !== source.id) {
86
+ mappingIssues.push({
87
+ code: "mapping.rename-existing-id-conflict",
88
+ key: rename.key,
89
+ message: `RENAMED source '${rename.from}' already has Requirement-ID '${source.id}'; mapping cannot replace it with '${requestedId}'.`,
90
+ });
91
+ }
92
+ rename.requirementId = source.id ?? requestedId;
93
+ rename.status = rename.requirementId === null ? "needsIdentity" : "mapped";
94
+ const routedServices = servicesForRequirement(rename.capability, rename.from);
95
+ if (rename.requirementId !== null) {
96
+ const collisionServices = routedServices.filter((service) => (livingByService.get(service) ?? []).some((entry) => entry.requirement !== source && entry.requirement.id === rename.requirementId));
97
+ if (collisionServices.length > 0) {
98
+ mappingIssues.push({
99
+ code: "mapping.rename-id-conflict",
100
+ key: rename.key,
101
+ message: `RENAMED identity '${rename.requirementId}' already belongs to another living requirement in mapped service(s): ${collisionServices.join(", ")}.`,
102
+ });
103
+ }
104
+ }
105
+ const targetCollisionServices = routedServices.filter((service) => (livingByService.get(service) ?? []).some((entry) => entry.requirement !== source && entry.requirement.name === rename.to));
106
+ if (rename.to === rename.from || targetCollisionServices.length > 0) {
107
+ mappingIssues.push({
108
+ code: "mapping.rename-target-conflict",
109
+ key: rename.key,
110
+ message: rename.to === rename.from
111
+ ? `RENAMED target '${rename.to}' is the same as its living source.`
112
+ : `RENAMED target '${rename.to}' conflicts in mapped service(s): ${targetCollisionServices.join(", ")}.`,
113
+ });
114
+ }
115
+ }
116
+ const renameSources = new Map();
117
+ const renameTargets = new Map();
118
+ for (const rename of activeRenames) {
119
+ if (rename.from === null || rename.to === null)
120
+ continue;
121
+ for (const service of servicesForRequirement(rename.capability, rename.from)) {
122
+ const sourceKey = `${service}\0${rename.from}`;
123
+ const targetKey = `${service}\0${rename.to}`;
124
+ const sources = renameSources.get(sourceKey) ?? [];
125
+ sources.push(rename);
126
+ renameSources.set(sourceKey, sources);
127
+ const targets = renameTargets.get(targetKey) ?? [];
128
+ targets.push(rename);
129
+ renameTargets.set(targetKey, targets);
130
+ }
131
+ }
132
+ for (const [key, uses] of renameSources) {
133
+ if (uses.length > 1) {
134
+ mappingIssues.push({
135
+ code: "mapping.rename-double-source",
136
+ key: key.replace("\0", ":"),
137
+ message: `Living requirement '${uses[0].from}' is renamed by multiple active changes: ${uses.map((item) => item.changeId).join(", ")}.`,
138
+ });
139
+ }
140
+ }
141
+ for (const [key, uses] of renameTargets) {
142
+ if (uses.length > 1) {
143
+ mappingIssues.push({
144
+ code: "mapping.rename-double-target",
145
+ key: key.replace("\0", ":"),
146
+ message: `Multiple active renames target '${uses[0].to}' in mapped service '${key.split("\0")[0]}'.`,
147
+ });
148
+ }
149
+ if (renameSources.has(key)) {
150
+ mappingIssues.push({
151
+ code: "mapping.rename-chain",
152
+ key: key.replace("\0", ":"),
153
+ message: `Active rename chain through '${uses[0].to}' must be collapsed into one reviewed rename.`,
154
+ });
155
+ }
156
+ }
157
+ const renameIdOwners = new Map();
158
+ for (const rename of activeRenames) {
159
+ if (rename.requirementId === null || rename.from === null)
160
+ continue;
161
+ for (const service of servicesForRequirement(rename.capability, rename.from)) {
162
+ const key = `${service}\0${rename.requirementId}`;
163
+ const owners = renameIdOwners.get(key) ?? new Set();
164
+ owners.add(`${rename.capability}:${rename.from}`);
165
+ renameIdOwners.set(key, owners);
166
+ }
167
+ }
168
+ for (const [key, owners] of renameIdOwners) {
169
+ if (owners.size > 1) {
170
+ const [service, requirementId] = key.split("\0");
171
+ mappingIssues.push({
172
+ code: "mapping.rename-id-conflict",
173
+ key,
174
+ message: `Requirement-ID '${requirementId}' is assigned to different RENAMED sources in mapped service '${service}': ${[...owners].join(", ")}.`,
175
+ });
176
+ }
177
+ }
178
+ }
179
+ //# sourceMappingURL=renames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renames.js","sourceRoot":"","sources":["../../../../src/core/openspec/decide/renames.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Every active RENAMED pair resolved against the living source of truth.\n *\n * This is the identity problem the whole package exists for: OpenSpec renames\n * by writing FROM/TO bullets, loam renames by carrying one stable\n * `Requirement-ID` through a MODIFIED requirement, and nothing mechanical\n * bridges the two. So each pair is either resolved to an id the living text\n * already carries, or it becomes a decision a human has to make — never a\n * guess, because a wrong identity silently merges one requirement's text over\n * another's.\n *\n * It MUTATES the usages it resolves rather than returning new ones: a rename is\n * one fact seen in one file, and two copies of it — one resolved, one not — is\n * exactly the bug this resolution exists to prevent.\n */\nimport { ownValue } from \"../../kernel/records.js\";\nimport { REQUIREMENT_ID_RE, requirementIdDeclarations } from \"../../document/spec.js\";\nimport { type OpenSpecMappingIssue } from \"../model/mapping.js\";\nimport { type OpenSpecRenamedUsage } from \"../model/model.js\";\nimport { type Scan, type Routing } from \"./capabilities.js\";\n\nexport function resolveRenames(scan: Scan, routing: Routing, mappingIssues: OpenSpecMappingIssue[]): void {\n const { mapping, livingRequirements, renamed } = scan;\n const { livingByService, servicesForRequirement } = routing;\n const activeRenames = renamed.filter((rename) => rename.scope === \"active\");\n const renameKeys = new Set(activeRenames.map((rename) => rename.key));\n for (const [key, requirementId] of Object.entries(mapping.renames)) {\n if (!renameKeys.has(key)) {\n mappingIssues.push({\n code: \"mapping.unknown-rename\",\n key,\n message: `Mapping names unknown RENAMED pair '${key}'.`,\n });\n } else if (!REQUIREMENT_ID_RE.test(requirementId)) {\n mappingIssues.push({\n code: \"mapping.invalid-requirement-id\",\n key,\n message: `RENAMED pair '${key}' has invalid Requirement-ID '${requirementId}'.`,\n });\n }\n }\n\n // Resolve every rename against the living source of truth. A mapped id is\n // only needed when the source requirement does not already carry one.\n for (const rename of activeRenames) {\n if (rename.from === null || rename.from === \"\" || rename.to === null || rename.to === \"\") continue;\n const living = livingRequirements.get(rename.capability) ?? [];\n const matches = living.filter((requirement) => requirement.name === rename.from);\n if (matches.length === 0) {\n mappingIssues.push({\n code: \"mapping.rename-source-missing\",\n key: rename.key,\n message: `RENAMED source '${rename.from}' does not exist in living capability '${rename.capability}'.`,\n });\n rename.requirementId = null;\n rename.status = \"needsIdentity\";\n continue;\n }\n if (matches.length > 1) {\n mappingIssues.push({\n code: \"mapping.rename-source-ambiguous\",\n key: rename.key,\n message: `RENAMED source '${rename.from}' matches ${matches.length} living requirements in '${rename.capability}'.`,\n });\n rename.requirementId = null;\n rename.status = \"needsIdentity\";\n continue;\n }\n const source = matches[0]!;\n const declarations = requirementIdDeclarations(source);\n if (declarations.length > 0\n && (declarations.length !== 1 || !REQUIREMENT_ID_RE.test(declarations[0]!))) {\n rename.existingRequirementId = source.id ?? null;\n rename.requirementId = null;\n rename.status = \"needsIdentity\";\n mappingIssues.push({\n code: \"mapping.rename-source-id-invalid\",\n key: rename.key,\n message: `RENAMED source '${rename.from}' has ${declarations.length === 1 ? \"an invalid\" : \"repeated\"} Requirement-ID declaration; repair the living source before migration.`,\n });\n continue;\n }\n rename.existingRequirementId = source.id ?? null;\n const requestedId = ownValue(mapping.renames, rename.key) ?? null;\n if (source.id !== undefined && requestedId !== null && requestedId !== source.id) {\n mappingIssues.push({\n code: \"mapping.rename-existing-id-conflict\",\n key: rename.key,\n message: `RENAMED source '${rename.from}' already has Requirement-ID '${source.id}'; mapping cannot replace it with '${requestedId}'.`,\n });\n }\n rename.requirementId = source.id ?? requestedId;\n rename.status = rename.requirementId === null ? \"needsIdentity\" : \"mapped\";\n const routedServices = servicesForRequirement(rename.capability, rename.from);\n if (rename.requirementId !== null) {\n const collisionServices = routedServices.filter((service) =>\n (livingByService.get(service) ?? []).some(\n (entry) => entry.requirement !== source && entry.requirement.id === rename.requirementId,\n ));\n if (collisionServices.length > 0) {\n mappingIssues.push({\n code: \"mapping.rename-id-conflict\",\n key: rename.key,\n message: `RENAMED identity '${rename.requirementId}' already belongs to another living requirement in mapped service(s): ${collisionServices.join(\", \")}.`,\n });\n }\n }\n const targetCollisionServices = routedServices.filter((service) =>\n (livingByService.get(service) ?? []).some(\n (entry) => entry.requirement !== source && entry.requirement.name === rename.to,\n ));\n if (rename.to === rename.from || targetCollisionServices.length > 0) {\n mappingIssues.push({\n code: \"mapping.rename-target-conflict\",\n key: rename.key,\n message: rename.to === rename.from\n ? `RENAMED target '${rename.to}' is the same as its living source.`\n : `RENAMED target '${rename.to}' conflicts in mapped service(s): ${targetCollisionServices.join(\", \")}.`,\n });\n }\n }\n\n const renameSources = new Map<string, OpenSpecRenamedUsage[]>();\n const renameTargets = new Map<string, OpenSpecRenamedUsage[]>();\n for (const rename of activeRenames) {\n if (rename.from === null || rename.to === null) continue;\n for (const service of servicesForRequirement(rename.capability, rename.from)) {\n const sourceKey = `${service}\\0${rename.from}`;\n const targetKey = `${service}\\0${rename.to}`;\n const sources = renameSources.get(sourceKey) ?? [];\n sources.push(rename);\n renameSources.set(sourceKey, sources);\n const targets = renameTargets.get(targetKey) ?? [];\n targets.push(rename);\n renameTargets.set(targetKey, targets);\n }\n }\n for (const [key, uses] of renameSources) {\n if (uses.length > 1) {\n mappingIssues.push({\n code: \"mapping.rename-double-source\",\n key: key.replace(\"\\0\", \":\"),\n message: `Living requirement '${uses[0]!.from}' is renamed by multiple active changes: ${uses.map((item) => item.changeId).join(\", \")}.`,\n });\n }\n }\n for (const [key, uses] of renameTargets) {\n if (uses.length > 1) {\n mappingIssues.push({\n code: \"mapping.rename-double-target\",\n key: key.replace(\"\\0\", \":\"),\n message: `Multiple active renames target '${uses[0]!.to}' in mapped service '${key.split(\"\\0\")[0]}'.`,\n });\n }\n if (renameSources.has(key)) {\n mappingIssues.push({\n code: \"mapping.rename-chain\",\n key: key.replace(\"\\0\", \":\"),\n message: `Active rename chain through '${uses[0]!.to}' must be collapsed into one reviewed rename.`,\n });\n }\n }\n const renameIdOwners = new Map<string, Set<string>>();\n for (const rename of activeRenames) {\n if (rename.requirementId === null || rename.from === null) continue;\n for (const service of servicesForRequirement(rename.capability, rename.from)) {\n const key = `${service}\\0${rename.requirementId}`;\n const owners = renameIdOwners.get(key) ?? new Set<string>();\n owners.add(`${rename.capability}:${rename.from}`);\n renameIdOwners.set(key, owners);\n }\n }\n for (const [key, owners] of renameIdOwners) {\n if (owners.size > 1) {\n const [service, requirementId] = key.split(\"\\0\");\n mappingIssues.push({\n code: \"mapping.rename-id-conflict\",\n key,\n message: `Requirement-ID '${requirementId}' is assigned to different RENAMED sources in mapped service '${service}': ${[...owners].join(\", \")}.`,\n });\n }\n }\n}\n"]}