@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,304 @@
1
+ /**
2
+ * Is this document a shape loam can migrate?
3
+ *
4
+ * The living side and the change side are graded separately because they fail
5
+ * differently: a living spec that will not parse is a corpus loam cannot read,
6
+ * while a change spec carries RENAMED pairs, which are the one OpenSpec
7
+ * construct with no loam equivalent and the reason this package has an identity
8
+ * problem to solve at all.
9
+ *
10
+ * Nothing here decides anything — it appends findings to the `Ingest` it was
11
+ * given. The decisions are in `../decide/`.
12
+ */
13
+ import { readFile } from "node:fs/promises";
14
+ import { ownValue } from "../../kernel/records.js";
15
+ import { fenceTracker } from "../../kernel/fences.js";
16
+ import { isRequirementsHeading, parseRequirements, sectionHeadings } from "../../document/parse.js";
17
+ import { KIND_RE, requirementIdProblems } from "../../document/spec.js";
18
+ import {} from "./workspace.js";
19
+ import { portable } from "./walk.js";
20
+ import {} from "../model/model.js";
21
+ export function countsFor(requirements) {
22
+ return {
23
+ requirements: requirements.length,
24
+ scenarios: requirements.reduce((sum, requirement) => sum + requirement.scenarios.length, 0),
25
+ };
26
+ }
27
+ export function addCounts(target, source) {
28
+ target.specFiles += source.specFiles;
29
+ target.requirements += source.requirements;
30
+ target.scenarios += source.scenarios;
31
+ }
32
+ /**
33
+ * An ATX heading's optional closing run — `### Requirement: Foo ###` renders as
34
+ * `Foo`, so the run is not part of the name (OpenSpec 1.13.1 strips it the same
35
+ * way). Only a run after a space or tab closes a heading, so `C#` keeps its `#`.
36
+ */
37
+ const CLOSING_HASHES = /[ \t]+#+[ \t]*$/;
38
+ /** A REMOVED entry written as a bullet carrying the heading — any CommonMark marker. */
39
+ const REMOVED_BULLET = /^\s*[-*+]\s*`?###\s*Requirement:\s*(.+?)`?\s*$/;
40
+ export function cleanRenameName(value) {
41
+ return value
42
+ .trim()
43
+ .replace(/^`|`$/g, "")
44
+ .replace(/^###\s+Requirement:\s*/i, "")
45
+ .replace(CLOSING_HASHES, "")
46
+ .trim();
47
+ }
48
+ /**
49
+ * OpenSpec's requirement grammar, as `parseRequirements` reads it. The two read
50
+ * the same Markdown except where OpenSpec accepts more, and every OpenSpec
51
+ * read in the migration goes through here so audit and `--apply` cannot
52
+ * disagree about a name:
53
+ *
54
+ * - a closing `#` run on a `### Requirement:` / `#### Scenario:` heading is
55
+ * dropped. Kept, a living `### Requirement: Invoice totals ###` audited
56
+ * "ready", staged under the name `Invoice totals ###`, and the change's
57
+ * MODIFIED `Invoice totals` then failed `loam validate` as
58
+ * `delta.modified-unknown` with a "Did you mean ADDED?" that sent the author
59
+ * the wrong way.
60
+ * - a `## REMOVED Requirements` list of bullets (`-`, `*` or `+`) each naming
61
+ * a requirement heading reads as that heading. v1.9.0 already accepted the
62
+ * `-` list and 1.13.0 added the other two markers; loam read neither, so a
63
+ * removal-only change was `openspec.change-empty`.
64
+ *
65
+ * A line-for-line rewrite, never a reflow, so every line number a finding
66
+ * cites still points at the author's file — and loam's own parser is not
67
+ * touched: a closing run in a loam document is the author's to keep.
68
+ */
69
+ export function openspecRequirements(raw) {
70
+ const lines = raw.replace(/^\uFEFF/, "").split(/\r?\n/);
71
+ const fenced = fencedLines(lines);
72
+ let removed = false;
73
+ const rewritten = lines.map((line, index) => {
74
+ if (fenced[index] === true)
75
+ return line;
76
+ if (/^##\s+/.test(line) && !line.startsWith("###"))
77
+ removed = KIND_RE.exec(line)?.[1]?.toUpperCase() === "REMOVED";
78
+ const bullet = removed ? REMOVED_BULLET.exec(line) : null;
79
+ const heading = bullet === null ? line : `### Requirement: ${bullet[1]}`;
80
+ return /^(###\s+Requirement:|####\s+Scenario:)/.test(heading) ? heading.replace(CLOSING_HASHES, "") : heading;
81
+ });
82
+ return parseRequirements(rewritten.join("\n"));
83
+ }
84
+ export function changeSpecCoordinates(path, scope) {
85
+ const prefix = scope === "active" ? /^changes\/([^/]+)\/specs\/(.+)\/spec\.md$/ : /^changes\/archive\/([^/]+)\/specs\/(.+)\/spec\.md$/;
86
+ const match = prefix.exec(path);
87
+ return { changeId: match?.[1] ?? "", capability: match?.[2] ?? "" };
88
+ }
89
+ /**
90
+ * Which lines are fenced content, marker included — the same rule
91
+ * `parseRequirements` and `sectionHeadings` apply, read from the one place it
92
+ * is spelled (`core/kernel/fences.ts`). This used to be a private copy of it,
93
+ * written while the rule still lived inside the parser module; a second copy is
94
+ * how two walks of one file come to disagree about where a fence ends.
95
+ * Without it a FROM/TO line inside a fenced example of the rename syntax became
96
+ * a phantom pair, and the only cure was editing the OpenSpec source migration
97
+ * promises never to touch.
98
+ */
99
+ export function fencedLines(lines) {
100
+ const fenced = fenceTracker();
101
+ return lines.map((line) => fenced(line));
102
+ }
103
+ export function renameUsages(path, raw, scope, mapped) {
104
+ const lines = raw.replace(/^\uFEFF/, "").split(/\r?\n/);
105
+ const fenced = fencedLines(lines);
106
+ const headings = sectionHeadings(raw);
107
+ const coordinates = changeSpecCoordinates(path, scope);
108
+ const output = [];
109
+ for (const [headingIndex, heading] of headings.entries()) {
110
+ if (!/^##\s+RENAMED\s+Requirements?\s*:?\s*$/i.test(heading.text))
111
+ continue;
112
+ const end = headings[headingIndex + 1]?.line ?? lines.length + 1;
113
+ const pairs = [];
114
+ let pendingFrom = null;
115
+ for (let line = heading.line; line < end - 1; line += 1) {
116
+ if (fenced[line] === true)
117
+ continue;
118
+ const text = lines[line] ?? "";
119
+ // The bullet is optional and any CommonMark marker counts, as in
120
+ // OpenSpec since 1.13.0 (v1.9.0 already took a bare `FROM:`): a `*`
121
+ // pair used to read as no pair at all, `openspec.renamed-malformed`
122
+ // saying "must contain a FROM/TO pair" about a section that had one.
123
+ const from = /^\s*[-*+]?\s*FROM:\s*(.*?)\s*$/i.exec(text);
124
+ if (from !== null) {
125
+ if (pendingFrom !== null)
126
+ pairs.push({ from: pendingFrom, to: null });
127
+ pendingFrom = cleanRenameName(from[1] ?? "");
128
+ continue;
129
+ }
130
+ const to = /^\s*[-*+]?\s*TO:\s*(.*?)\s*$/i.exec(text);
131
+ if (to !== null) {
132
+ pairs.push({ from: pendingFrom, to: cleanRenameName(to[1] ?? "") });
133
+ pendingFrom = null;
134
+ }
135
+ }
136
+ if (pendingFrom !== null)
137
+ pairs.push({ from: pendingFrom, to: null });
138
+ if (pairs.length === 0)
139
+ pairs.push({ from: null, to: null });
140
+ pairs.forEach((pair, pairIndex) => {
141
+ const key = `${path}:${heading.line}:${pairIndex + 1}`;
142
+ const requirementId = ownValue(mapped, key) ?? null;
143
+ output.push({
144
+ key,
145
+ path,
146
+ line: heading.line,
147
+ scope,
148
+ changeId: coordinates.changeId,
149
+ capability: coordinates.capability,
150
+ from: pair.from,
151
+ to: pair.to,
152
+ existingRequirementId: null,
153
+ requirementId,
154
+ status: requirementId === null ? "needsIdentity" : "mapped",
155
+ });
156
+ });
157
+ }
158
+ return output;
159
+ }
160
+ /**
161
+ * Record one shape loam cannot migrate.
162
+ *
163
+ * The finding is a record rather than three positional strings because code,
164
+ * path and message are all strings and nothing but their order distinguished
165
+ * them — two of the three were transposed at a call site once, and the report
166
+ * named the message as the path.
167
+ */
168
+ export function issue(target, scope, finding) {
169
+ target.push({ ...finding, scope });
170
+ }
171
+ export function inspectLivingShape(path, raw, unsupported) {
172
+ const requirements = openspecRequirements(raw);
173
+ if (requirements.length === 0) {
174
+ issue(unsupported, "living", {
175
+ code: "openspec.living-empty",
176
+ path: path,
177
+ message: "Living spec has no parseable Requirement headings.",
178
+ });
179
+ return;
180
+ }
181
+ const outside = requirements.filter((requirement) => requirement.section === undefined || !isRequirementsHeading(requirement.section));
182
+ if (outside.length > 0) {
183
+ issue(unsupported, "living", {
184
+ code: "openspec.living-requirements-outside-section",
185
+ path: path,
186
+ message: `${outside.length} requirement(s) are outside the canonical ## Requirements section.`,
187
+ });
188
+ }
189
+ if (requirements.some((requirement) => requirement.kind !== "BASE")) {
190
+ issue(unsupported, "living", {
191
+ code: "openspec.living-delta-section",
192
+ path: path,
193
+ message: "Living spec contains delta-kind requirements.",
194
+ });
195
+ }
196
+ }
197
+ export function inspectChangeShape(unsupported, path, raw, found) {
198
+ const { scope, renames } = found;
199
+ const requirements = openspecRequirements(raw);
200
+ const fileRenames = renames.filter((rename) => rename.path === path);
201
+ for (const rename of fileRenames) {
202
+ if (rename.from === null || rename.from === "" || rename.to === null || rename.to === "") {
203
+ issue(unsupported, scope, {
204
+ code: "openspec.renamed-malformed",
205
+ path: path,
206
+ message: `RENAMED Requirements at line ${rename.line} must contain a FROM/TO pair.`,
207
+ });
208
+ }
209
+ }
210
+ if (requirements.length === 0) {
211
+ // A well-formed rename-only delta is meaningful even though the requirement
212
+ // parser correctly returns no requirement blocks for it.
213
+ if (fileRenames.length === 0) {
214
+ issue(unsupported, scope, {
215
+ code: "openspec.change-empty",
216
+ path: path,
217
+ message: "Change spec has no parseable Requirement headings.",
218
+ });
219
+ }
220
+ return;
221
+ }
222
+ // `## Requirements` is the heading OpenSpec's own living-spec template
223
+ // mandates, so this is the shape a team produces by copying a living spec into
224
+ // a change directory. It parses, it is counted, and nothing routes it: only
225
+ // delta-kind requirements reach the staged feature. Blocking is what keeps the
226
+ // per-change counters and what actually lands the same number.
227
+ const quoted = requirements.filter((requirement) => requirement.kind === "BASE"
228
+ && requirement.section !== undefined
229
+ && isRequirementsHeading(requirement.section));
230
+ if (quoted.length > 0) {
231
+ unsupported.push({
232
+ code: "openspec.change-quoted-requirements",
233
+ path,
234
+ message: `${quoted.length} requirement(s) sit under ## Requirements in a change delta, which stages nothing; re-home them under ADDED, MODIFIED, or REMOVED.`,
235
+ scope,
236
+ });
237
+ }
238
+ const stranded = requirements.filter((requirement) => requirement.kind === "BASE"
239
+ && (requirement.section === undefined || !isRequirementsHeading(requirement.section)));
240
+ if (stranded.length === requirements.length) {
241
+ issue(unsupported, scope, {
242
+ code: "openspec.change-without-delta-sections",
243
+ path: path,
244
+ message: "Change requirements are not under ADDED, MODIFIED, REMOVED, or the explicitly non-merging ## Requirements section.",
245
+ });
246
+ }
247
+ else if (stranded.length > 0) {
248
+ issue(unsupported, scope, {
249
+ code: "openspec.change-requirements-outside-delta-sections",
250
+ path: path,
251
+ message: `${stranded.length} requirement(s) would be stranded outside delta sections.`,
252
+ });
253
+ }
254
+ }
255
+ /**
256
+ * The parsed requirements come back with the counts because both callers wanted
257
+ * them and each opened the file a second time to get its own copy — two reads
258
+ * of the same bytes per spec.md, and two readings of it: the counts came from
259
+ * this parse while the requirement names, and the living corpus every rename is
260
+ * resolved against, came from the other. A file edited mid-audit could be
261
+ * counted from one of them and routed from the other.
262
+ */
263
+ export async function inspectSpecFile(ingest, absolute, kind, scope) {
264
+ const { root, mapping, renamed, unsupported } = ingest;
265
+ const path = portable(root, absolute);
266
+ const raw = await readFile(absolute, "utf8");
267
+ const requirements = openspecRequirements(raw);
268
+ const counts = { specFiles: 1, ...countsFor(requirements) };
269
+ const issueScope = kind === "living" ? "living" : scope ?? "active";
270
+ for (const problem of requirementIdProblems(requirements)) {
271
+ if (problem.kind === "invalid") {
272
+ issue(unsupported, issueScope, {
273
+ code: "openspec.requirement-id-invalid",
274
+ path: path,
275
+ message: `Requirement '${problem.requirement}' has invalid Requirement-ID '${problem.value}'; use [A-Za-z][A-Za-z0-9._-]{0,127}.`,
276
+ });
277
+ }
278
+ else if (problem.kind === "repeated") {
279
+ issue(unsupported, issueScope, {
280
+ code: "openspec.requirement-id-repeated",
281
+ path: path,
282
+ message: `Requirement '${problem.requirement}' declares Requirement-ID ${problem.values.length} times; keep exactly one identity line.`,
283
+ });
284
+ }
285
+ else {
286
+ issue(unsupported, issueScope, {
287
+ code: "openspec.requirement-id-duplicate",
288
+ path: path,
289
+ message: `Requirement-ID '${problem.id}' is shared by ${problem.requirements.map((name) => `'${name}'`).join(", ")}.`,
290
+ });
291
+ }
292
+ }
293
+ if (kind === "living") {
294
+ inspectLivingShape(path, raw, unsupported);
295
+ }
296
+ else {
297
+ const changeScope = scope ?? "active";
298
+ const usages = renameUsages(path, raw, changeScope, mapping.renames);
299
+ renamed.push(...usages);
300
+ inspectChangeShape(unsupported, path, raw, { scope: changeScope, renames: usages });
301
+ }
302
+ return { path, counts, requirements };
303
+ }
304
+ //# sourceMappingURL=shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape.js","sourceRoot":"","sources":["../../../../src/core/openspec/scan/shape.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Is this document a shape loam can migrate?\n *\n * The living side and the change side are graded separately because they fail\n * differently: a living spec that will not parse is a corpus loam cannot read,\n * while a change spec carries RENAMED pairs, which are the one OpenSpec\n * construct with no loam equivalent and the reason this package has an identity\n * problem to solve at all.\n *\n * Nothing here decides anything — it appends findings to the `Ingest` it was\n * given. The decisions are in `../decide/`.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { ownValue } from \"../../kernel/records.js\";\nimport { fenceTracker } from \"../../kernel/fences.js\";\nimport { isRequirementsHeading, parseRequirements, sectionHeadings } from \"../../document/parse.js\";\nimport { KIND_RE, requirementIdProblems } from \"../../document/spec.js\";\nimport { type Ingest } from \"./workspace.js\";\nimport { portable } from \"./walk.js\";\nimport {\n type OpenSpecCounts,\n type OpenSpecRenamedUsage,\n type OpenSpecUnsupportedShape,\n type OpenSpecIssueScope,\n} from \"../model/model.js\";\n\nexport function countsFor(requirements: ReturnType<typeof parseRequirements>): Omit<OpenSpecCounts, \"specFiles\"> {\n return {\n requirements: requirements.length,\n scenarios: requirements.reduce((sum, requirement) => sum + requirement.scenarios.length, 0),\n };\n}\n\nexport function addCounts(target: OpenSpecCounts, source: OpenSpecCounts): void {\n target.specFiles += source.specFiles;\n target.requirements += source.requirements;\n target.scenarios += source.scenarios;\n}\n\n/**\n * An ATX heading's optional closing run — `### Requirement: Foo ###` renders as\n * `Foo`, so the run is not part of the name (OpenSpec 1.13.1 strips it the same\n * way). Only a run after a space or tab closes a heading, so `C#` keeps its `#`.\n */\nconst CLOSING_HASHES = /[ \\t]+#+[ \\t]*$/;\n\n/** A REMOVED entry written as a bullet carrying the heading — any CommonMark marker. */\nconst REMOVED_BULLET = /^\\s*[-*+]\\s*`?###\\s*Requirement:\\s*(.+?)`?\\s*$/;\n\nexport function cleanRenameName(value: string): string {\n return value\n .trim()\n .replace(/^`|`$/g, \"\")\n .replace(/^###\\s+Requirement:\\s*/i, \"\")\n .replace(CLOSING_HASHES, \"\")\n .trim();\n}\n\n/**\n * OpenSpec's requirement grammar, as `parseRequirements` reads it. The two read\n * the same Markdown except where OpenSpec accepts more, and every OpenSpec\n * read in the migration goes through here so audit and `--apply` cannot\n * disagree about a name:\n *\n * - a closing `#` run on a `### Requirement:` / `#### Scenario:` heading is\n * dropped. Kept, a living `### Requirement: Invoice totals ###` audited\n * \"ready\", staged under the name `Invoice totals ###`, and the change's\n * MODIFIED `Invoice totals` then failed `loam validate` as\n * `delta.modified-unknown` with a \"Did you mean ADDED?\" that sent the author\n * the wrong way.\n * - a `## REMOVED Requirements` list of bullets (`-`, `*` or `+`) each naming\n * a requirement heading reads as that heading. v1.9.0 already accepted the\n * `-` list and 1.13.0 added the other two markers; loam read neither, so a\n * removal-only change was `openspec.change-empty`.\n *\n * A line-for-line rewrite, never a reflow, so every line number a finding\n * cites still points at the author's file — and loam's own parser is not\n * touched: a closing run in a loam document is the author's to keep.\n */\nexport function openspecRequirements(raw: string): ReturnType<typeof parseRequirements> {\n const lines = raw.replace(/^\\uFEFF/, \"\").split(/\\r?\\n/);\n const fenced = fencedLines(lines);\n let removed = false;\n const rewritten = lines.map((line, index) => {\n if (fenced[index] === true) return line;\n if (/^##\\s+/.test(line) && !line.startsWith(\"###\")) removed = KIND_RE.exec(line)?.[1]?.toUpperCase() === \"REMOVED\";\n const bullet = removed ? REMOVED_BULLET.exec(line) : null;\n const heading = bullet === null ? line : `### Requirement: ${bullet[1]!}`;\n return /^(###\\s+Requirement:|####\\s+Scenario:)/.test(heading) ? heading.replace(CLOSING_HASHES, \"\") : heading;\n });\n return parseRequirements(rewritten.join(\"\\n\"));\n}\n\nexport function changeSpecCoordinates(\n path: string,\n scope: \"active\" | \"archive\",\n): { changeId: string; capability: string } {\n const prefix = scope === \"active\" ? /^changes\\/([^/]+)\\/specs\\/(.+)\\/spec\\.md$/ : /^changes\\/archive\\/([^/]+)\\/specs\\/(.+)\\/spec\\.md$/;\n const match = prefix.exec(path);\n return { changeId: match?.[1] ?? \"\", capability: match?.[2] ?? \"\" };\n}\n\n/**\n * Which lines are fenced content, marker included — the same rule\n * `parseRequirements` and `sectionHeadings` apply, read from the one place it\n * is spelled (`core/kernel/fences.ts`). This used to be a private copy of it,\n * written while the rule still lived inside the parser module; a second copy is\n * how two walks of one file come to disagree about where a fence ends.\n * Without it a FROM/TO line inside a fenced example of the rename syntax became\n * a phantom pair, and the only cure was editing the OpenSpec source migration\n * promises never to touch.\n */\nexport function fencedLines(lines: string[]): boolean[] {\n const fenced = fenceTracker();\n return lines.map((line) => fenced(line));\n}\n\nexport function renameUsages(\n path: string,\n raw: string,\n scope: \"active\" | \"archive\",\n mapped: Record<string, string>,\n): OpenSpecRenamedUsage[] {\n const lines = raw.replace(/^\\uFEFF/, \"\").split(/\\r?\\n/);\n const fenced = fencedLines(lines);\n const headings = sectionHeadings(raw);\n const coordinates = changeSpecCoordinates(path, scope);\n const output: OpenSpecRenamedUsage[] = [];\n for (const [headingIndex, heading] of headings.entries()) {\n if (!/^##\\s+RENAMED\\s+Requirements?\\s*:?\\s*$/i.test(heading.text)) continue;\n const end = headings[headingIndex + 1]?.line ?? lines.length + 1;\n const pairs: Array<{ from: string | null; to: string | null }> = [];\n let pendingFrom: string | null = null;\n for (let line = heading.line; line < end - 1; line += 1) {\n if (fenced[line] === true) continue;\n const text = lines[line] ?? \"\";\n // The bullet is optional and any CommonMark marker counts, as in\n // OpenSpec since 1.13.0 (v1.9.0 already took a bare `FROM:`): a `*`\n // pair used to read as no pair at all, `openspec.renamed-malformed`\n // saying \"must contain a FROM/TO pair\" about a section that had one.\n const from = /^\\s*[-*+]?\\s*FROM:\\s*(.*?)\\s*$/i.exec(text);\n if (from !== null) {\n if (pendingFrom !== null) pairs.push({ from: pendingFrom, to: null });\n pendingFrom = cleanRenameName(from[1] ?? \"\");\n continue;\n }\n const to = /^\\s*[-*+]?\\s*TO:\\s*(.*?)\\s*$/i.exec(text);\n if (to !== null) {\n pairs.push({ from: pendingFrom, to: cleanRenameName(to[1] ?? \"\") });\n pendingFrom = null;\n }\n }\n if (pendingFrom !== null) pairs.push({ from: pendingFrom, to: null });\n if (pairs.length === 0) pairs.push({ from: null, to: null });\n pairs.forEach((pair, pairIndex) => {\n const key = `${path}:${heading.line}:${pairIndex + 1}`;\n const requirementId = ownValue(mapped, key) ?? null;\n output.push({\n key,\n path,\n line: heading.line,\n scope,\n changeId: coordinates.changeId,\n capability: coordinates.capability,\n from: pair.from,\n to: pair.to,\n existingRequirementId: null,\n requirementId,\n status: requirementId === null ? \"needsIdentity\" : \"mapped\",\n });\n });\n }\n return output;\n}\n\n/**\n * Record one shape loam cannot migrate.\n *\n * The finding is a record rather than three positional strings because code,\n * path and message are all strings and nothing but their order distinguished\n * them — two of the three were transposed at a call site once, and the report\n * named the message as the path.\n */\nexport function issue(\n target: OpenSpecUnsupportedShape[],\n scope: OpenSpecIssueScope,\n finding: { code: string; path: string; message: string },\n): void {\n target.push({ ...finding, scope });\n}\n\nexport function inspectLivingShape(\n path: string,\n raw: string,\n unsupported: OpenSpecUnsupportedShape[],\n): void {\n const requirements = openspecRequirements(raw);\n if (requirements.length === 0) {\n issue(unsupported, \"living\", {\n code: \"openspec.living-empty\",\n path: path,\n message: \"Living spec has no parseable Requirement headings.\",\n });\n return;\n }\n const outside = requirements.filter(\n (requirement) => requirement.section === undefined || !isRequirementsHeading(requirement.section),\n );\n if (outside.length > 0) {\n issue(unsupported, \"living\", {\n code: \"openspec.living-requirements-outside-section\",\n path: path,\n message: `${outside.length} requirement(s) are outside the canonical ## Requirements section.`,\n });\n }\n if (requirements.some((requirement) => requirement.kind !== \"BASE\")) {\n issue(unsupported, \"living\", {\n code: \"openspec.living-delta-section\",\n path: path,\n message: \"Living spec contains delta-kind requirements.\",\n });\n }\n}\n\nexport function inspectChangeShape(\n unsupported: OpenSpecUnsupportedShape[],\n path: string,\n raw: string,\n found: { scope: \"active\" | \"archive\"; renames: OpenSpecRenamedUsage[] },\n): void {\n const { scope, renames } = found;\n const requirements = openspecRequirements(raw);\n const fileRenames = renames.filter((rename) => rename.path === path);\n for (const rename of fileRenames) {\n if (rename.from === null || rename.from === \"\" || rename.to === null || rename.to === \"\") {\n issue(unsupported, scope, {\n code: \"openspec.renamed-malformed\",\n path: path,\n message: `RENAMED Requirements at line ${rename.line} must contain a FROM/TO pair.`,\n });\n }\n }\n if (requirements.length === 0) {\n // A well-formed rename-only delta is meaningful even though the requirement\n // parser correctly returns no requirement blocks for it.\n if (fileRenames.length === 0) {\n issue(unsupported, scope, {\n code: \"openspec.change-empty\",\n path: path,\n message: \"Change spec has no parseable Requirement headings.\",\n });\n }\n return;\n }\n // `## Requirements` is the heading OpenSpec's own living-spec template\n // mandates, so this is the shape a team produces by copying a living spec into\n // a change directory. It parses, it is counted, and nothing routes it: only\n // delta-kind requirements reach the staged feature. Blocking is what keeps the\n // per-change counters and what actually lands the same number.\n const quoted = requirements.filter(\n (requirement) => requirement.kind === \"BASE\"\n && requirement.section !== undefined\n && isRequirementsHeading(requirement.section),\n );\n if (quoted.length > 0) {\n unsupported.push({\n code: \"openspec.change-quoted-requirements\",\n path,\n message: `${quoted.length} requirement(s) sit under ## Requirements in a change delta, which stages nothing; re-home them under ADDED, MODIFIED, or REMOVED.`,\n scope,\n });\n }\n const stranded = requirements.filter(\n (requirement) => requirement.kind === \"BASE\"\n && (requirement.section === undefined || !isRequirementsHeading(requirement.section)),\n );\n if (stranded.length === requirements.length) {\n issue(unsupported, scope, {\n code: \"openspec.change-without-delta-sections\",\n path: path,\n message: \"Change requirements are not under ADDED, MODIFIED, REMOVED, or the explicitly non-merging ## Requirements section.\",\n });\n } else if (stranded.length > 0) {\n issue(unsupported, scope, {\n code: \"openspec.change-requirements-outside-delta-sections\",\n path: path,\n message: `${stranded.length} requirement(s) would be stranded outside delta sections.`,\n });\n }\n}\n\n/**\n * The parsed requirements come back with the counts because both callers wanted\n * them and each opened the file a second time to get its own copy — two reads\n * of the same bytes per spec.md, and two readings of it: the counts came from\n * this parse while the requirement names, and the living corpus every rename is\n * resolved against, came from the other. A file edited mid-audit could be\n * counted from one of them and routed from the other.\n */\nexport async function inspectSpecFile(\n ingest: Ingest,\n absolute: string,\n kind: \"living\" | \"change\",\n scope: \"active\" | \"archive\" | null,\n): Promise<{ path: string; counts: OpenSpecCounts; requirements: ReturnType<typeof parseRequirements> }> {\n const { root, mapping, renamed, unsupported } = ingest;\n const path = portable(root, absolute);\n const raw = await readFile(absolute, \"utf8\");\n const requirements = openspecRequirements(raw);\n const counts = { specFiles: 1, ...countsFor(requirements) };\n const issueScope = kind === \"living\" ? \"living\" : scope ?? \"active\";\n for (const problem of requirementIdProblems(requirements)) {\n if (problem.kind === \"invalid\") {\n issue(unsupported, issueScope, {\n code: \"openspec.requirement-id-invalid\",\n path: path,\n message: `Requirement '${problem.requirement}' has invalid Requirement-ID '${problem.value}'; use [A-Za-z][A-Za-z0-9._-]{0,127}.`,\n });\n } else if (problem.kind === \"repeated\") {\n issue(unsupported, issueScope, {\n code: \"openspec.requirement-id-repeated\",\n path: path,\n message: `Requirement '${problem.requirement}' declares Requirement-ID ${problem.values.length} times; keep exactly one identity line.`,\n });\n } else {\n issue(unsupported, issueScope, {\n code: \"openspec.requirement-id-duplicate\",\n path: path,\n message: `Requirement-ID '${problem.id}' is shared by ${problem.requirements.map((name) => `'${name}'`).join(\", \")}.`,\n });\n }\n }\n if (kind === \"living\") {\n inspectLivingShape(path, raw, unsupported);\n } else {\n const changeScope = scope ?? \"active\";\n const usages = renameUsages(path, raw, changeScope, mapping.renames);\n renamed.push(...usages);\n inspectChangeShape(unsupported, path, raw, { scope: changeScope, renames: usages });\n }\n return { path, counts, requirements };\n}\n"]}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Reading the tree: which directories exist, which files are under them, which
3
+ * of them are symlinks, and the digest that binds a mapping to what was audited.
4
+ *
5
+ * Symlinks are enumerated rather than followed. The whole package reads
6
+ * somebody else's repository, so "what is under this directory" has to be a
7
+ * question about THIS workspace — a link out of it is a finding, never a file
8
+ * to walk into.
9
+ */
10
+ import { createHash } from "node:crypto";
11
+ import { lstat, readFile, readdir, stat } from "node:fs/promises";
12
+ import { dirname, join, relative, sep } from "node:path";
13
+ import { parse as parseYaml } from "yaml";
14
+ import { isPathInside } from "../../kernel/path-safety.js";
15
+ import { asRecord } from "../../kernel/records.js";
16
+ import { compareIds } from "../../repo/entries.js";
17
+ export async function isDirectory(path) {
18
+ try {
19
+ return (await stat(path)).isDirectory();
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ export function portable(root, path) {
26
+ return relative(root, path).split(sep).join("/");
27
+ }
28
+ /** Stable inventory namespace: planning-root relative, with one explicit external prefix. */
29
+ export function sourceInventoryPath(root, absolute) {
30
+ if (isPathInside(root, absolute))
31
+ return portable(root, absolute);
32
+ return `@workspace/${portable(dirname(root), absolute)}`;
33
+ }
34
+ export async function subdirs(path) {
35
+ if (!await isDirectory(path))
36
+ return [];
37
+ return (await readdir(path, { withFileTypes: true }))
38
+ .filter((entry) => entry.isDirectory() && !entry.name.startsWith("."))
39
+ .map((entry) => entry.name)
40
+ .sort(compareIds);
41
+ }
42
+ /**
43
+ * Exactly what `subdirs` drops. walkTree does not drop it, so a change behind a
44
+ * dot-directory was never enumerated as a change while its files were still
45
+ * classified, counted and given a disposition slot — a decision recorded as
46
+ * selected for an artifact nothing migrates.
47
+ */
48
+ export async function hiddenSubdirs(path) {
49
+ if (!await isDirectory(path))
50
+ return [];
51
+ return (await readdir(path, { withFileTypes: true }))
52
+ .filter((entry) => entry.isDirectory() && entry.name.startsWith("."))
53
+ .map((entry) => entry.name)
54
+ .sort(compareIds);
55
+ }
56
+ /**
57
+ * Every regular file and every symbolic link under `path`, sorted and
58
+ * depth-first, skipping `.git`. Links are inventoried, never followed into
59
+ * unbound source trees. One walk serves both answers because a link's Dirent
60
+ * is neither a directory nor a file, so recording links separately leaves the
61
+ * file set and the set of directories descended exactly what two walks gave.
62
+ * A `Dirent` reports a link as a link, never as what it points at, so a link
63
+ * to a directory is recorded and never descended: the walk cannot leave the
64
+ * tree through one.
65
+ */
66
+ export async function walkTree(path) {
67
+ const files = [];
68
+ const links = [];
69
+ const walk = async (dir) => {
70
+ const entries = (await readdir(dir, { withFileTypes: true }))
71
+ .filter((entry) => entry.name !== ".git")
72
+ .sort((a, b) => compareIds(a.name, b.name));
73
+ for (const entry of entries) {
74
+ const absolute = join(dir, entry.name);
75
+ if (entry.isSymbolicLink())
76
+ links.push(absolute);
77
+ else if (entry.isDirectory())
78
+ await walk(absolute);
79
+ else if (entry.isFile())
80
+ files.push(absolute);
81
+ }
82
+ };
83
+ if (await isDirectory(path))
84
+ await walk(path);
85
+ return { files, links };
86
+ }
87
+ export async function isSymbolicLink(path) {
88
+ try {
89
+ return (await lstat(path)).isSymbolicLink();
90
+ }
91
+ catch {
92
+ return false;
93
+ }
94
+ }
95
+ export async function yamlRecord(path) {
96
+ const parsed = parseYaml(await readFile(path, "utf8"));
97
+ const record = asRecord(parsed);
98
+ if (record === null)
99
+ throw new Error("expected a YAML mapping");
100
+ return record;
101
+ }
102
+ export async function digestInventory(root, files) {
103
+ const hash = createHash("sha256");
104
+ // v3 narrowed the covered set to living + active. The version string is what
105
+ // stops a v2 mapping from being accepted against a v3 reading of the same tree.
106
+ hash.update("loam-openspec-inventory-v3\0");
107
+ for (const absolute of [...new Set(files)].sort((a, b) => compareIds(sourceInventoryPath(root, a), sourceInventoryPath(root, b)))) {
108
+ const path = sourceInventoryPath(root, absolute);
109
+ const bytes = await readFile(absolute);
110
+ hash.update(`${path.length}:${path}:${bytes.length}:`);
111
+ hash.update(bytes);
112
+ hash.update("\0");
113
+ }
114
+ return `sha256:${hash.digest("hex")}`;
115
+ }
116
+ //# sourceMappingURL=walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.js","sourceRoot":"","sources":["../../../../src/core/openspec/scan/walk.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Reading the tree: which directories exist, which files are under them, which\n * of them are symlinks, and the digest that binds a mapping to what was audited.\n *\n * Symlinks are enumerated rather than followed. The whole package reads\n * somebody else's repository, so \"what is under this directory\" has to be a\n * question about THIS workspace — a link out of it is a finding, never a file\n * to walk into.\n */\nimport { createHash } from \"node:crypto\";\nimport { lstat, readFile, readdir, stat } from \"node:fs/promises\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { isPathInside } from \"../../kernel/path-safety.js\";\nimport { asRecord } from \"../../kernel/records.js\";\nimport { compareIds } from \"../../repo/entries.js\";\n\nexport async function isDirectory(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isDirectory();\n } catch {\n return false;\n }\n}\n\nexport function portable(root: string, path: string): string {\n return relative(root, path).split(sep).join(\"/\");\n}\n\n/** Stable inventory namespace: planning-root relative, with one explicit external prefix. */\nexport function sourceInventoryPath(root: string, absolute: string): string {\n if (isPathInside(root, absolute)) return portable(root, absolute);\n return `@workspace/${portable(dirname(root), absolute)}`;\n}\n\nexport async function subdirs(path: string): Promise<string[]> {\n if (!await isDirectory(path)) return [];\n return (await readdir(path, { withFileTypes: true }))\n .filter((entry) => entry.isDirectory() && !entry.name.startsWith(\".\"))\n .map((entry) => entry.name)\n .sort(compareIds);\n}\n\n/**\n * Exactly what `subdirs` drops. walkTree does not drop it, so a change behind a\n * dot-directory was never enumerated as a change while its files were still\n * classified, counted and given a disposition slot — a decision recorded as\n * selected for an artifact nothing migrates.\n */\nexport async function hiddenSubdirs(path: string): Promise<string[]> {\n if (!await isDirectory(path)) return [];\n return (await readdir(path, { withFileTypes: true }))\n .filter((entry) => entry.isDirectory() && entry.name.startsWith(\".\"))\n .map((entry) => entry.name)\n .sort(compareIds);\n}\n\n/**\n * Every regular file and every symbolic link under `path`, sorted and\n * depth-first, skipping `.git`. Links are inventoried, never followed into\n * unbound source trees. One walk serves both answers because a link's Dirent\n * is neither a directory nor a file, so recording links separately leaves the\n * file set and the set of directories descended exactly what two walks gave.\n * A `Dirent` reports a link as a link, never as what it points at, so a link\n * to a directory is recorded and never descended: the walk cannot leave the\n * tree through one.\n */\nexport async function walkTree(path: string): Promise<{ files: string[]; links: string[] }> {\n const files: string[] = [];\n const links: string[] = [];\n const walk = async (dir: string): Promise<void> => {\n const entries = (await readdir(dir, { withFileTypes: true }))\n .filter((entry) => entry.name !== \".git\")\n .sort((a, b) => compareIds(a.name, b.name));\n for (const entry of entries) {\n const absolute = join(dir, entry.name);\n if (entry.isSymbolicLink()) links.push(absolute);\n else if (entry.isDirectory()) await walk(absolute);\n else if (entry.isFile()) files.push(absolute);\n }\n };\n if (await isDirectory(path)) await walk(path);\n return { files, links };\n}\n\nexport async function isSymbolicLink(path: string): Promise<boolean> {\n try {\n return (await lstat(path)).isSymbolicLink();\n } catch {\n return false;\n }\n}\n\nexport async function yamlRecord(path: string): Promise<Record<string, unknown>> {\n const parsed: unknown = parseYaml(await readFile(path, \"utf8\"));\n const record = asRecord(parsed);\n if (record === null) throw new Error(\"expected a YAML mapping\");\n return record;\n}\n\nexport async function digestInventory(root: string, files: string[]): Promise<string> {\n const hash = createHash(\"sha256\");\n // v3 narrowed the covered set to living + active. The version string is what\n // stops a v2 mapping from being accepted against a v3 reading of the same tree.\n hash.update(\"loam-openspec-inventory-v3\\0\");\n for (const absolute of [...new Set(files)].sort((a, b) => compareIds(sourceInventoryPath(root, a), sourceInventoryPath(root, b)))) {\n const path = sourceInventoryPath(root, absolute);\n const bytes = await readFile(absolute);\n hash.update(`${path.length}:${path}:${bytes.length}:`);\n hash.update(bytes);\n hash.update(\"\\0\");\n }\n return `sha256:${hash.digest(\"hex\")}`;\n}\n"]}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Where the workspace is, how its paths are spelled, and the record every
3
+ * reader of it carries.
4
+ *
5
+ * `Ingest` exists because the five readers below it all need the same four
6
+ * things — the root, the mapping being checked, and the two lists they append
7
+ * findings to — and none of them may take four parameters plus its own. It is
8
+ * the read in progress, so the accumulators live in it: a scan that returned
9
+ * its findings instead would have to merge five arrays whose ORDER is what the
10
+ * `--json` contract pins.
11
+ */
12
+ import { existsSync } from "node:fs";
13
+ import { realpath } from "node:fs/promises";
14
+ import { basename, dirname, join, resolve } from "node:path";
15
+ import {} from "../model/mapping.js";
16
+ import { OpenSpecRootError } from "../model/model.js";
17
+ import { isDirectory, isSymbolicLink } from "./walk.js";
18
+ export async function looksLikeOpenSpec(path) {
19
+ return existsSync(join(path, "config.yaml"))
20
+ || existsSync(join(path, "project.md"))
21
+ || existsSync(join(path, ".openspec.yaml"))
22
+ || await isDirectory(join(path, "specs"))
23
+ || await isDirectory(join(path, "changes"));
24
+ }
25
+ export async function locateOpenSpecRoot(input) {
26
+ const requestedRoot = resolve(input);
27
+ if (!await isDirectory(requestedRoot)) {
28
+ throw new OpenSpecRootError(`OpenSpec root is missing or is not a directory: ${requestedRoot}`);
29
+ }
30
+ const inputRoot = await realpath(requestedRoot);
31
+ const nested = join(inputRoot, "openspec");
32
+ const storeMarker = join(inputRoot, ".openspec-store", "store.yaml");
33
+ const hasNestedShape = await looksLikeOpenSpec(nested);
34
+ const hasDirectShape = await looksLikeOpenSpec(inputRoot);
35
+ if (hasNestedShape && hasDirectShape) {
36
+ throw new OpenSpecRootError(`Ambiguous OpenSpec root ${inputRoot}: both the directory itself and ${nested} contain OpenSpec planning shapes. Pass the intended root explicitly.`);
37
+ }
38
+ if (hasNestedShape) {
39
+ await assertPlanningRootNotLinked(nested);
40
+ return { inputRoot, root: nested, kind: existsSync(storeMarker) ? "store" : "project" };
41
+ }
42
+ // The shape decides the root, the Store marker only decides the kind. Deciding
43
+ // "store" first sent `root` to <store>/openspec for a checkout that keeps its
44
+ // planning shape at the checkout root: a directory that does not exist reads
45
+ // as an empty, fully compatible workspace, and apply then stages nothing.
46
+ if (hasDirectShape) {
47
+ const parentStoreMarker = basename(inputRoot) === "openspec"
48
+ ? join(dirname(inputRoot), ".openspec-store", "store.yaml")
49
+ : "";
50
+ const store = existsSync(storeMarker) || (parentStoreMarker !== "" && existsSync(parentStoreMarker));
51
+ return { inputRoot, root: inputRoot, kind: store ? "store" : "openspec-root" };
52
+ }
53
+ // OpenSpec stores may omit empty planning directories. Keep their canonical
54
+ // future root at <store>/openspec so paths do not change after the first spec
55
+ // — but only when that directory is really there. Auditing a root that does
56
+ // not exist is how a Store checkout came back `ready` over invisible content.
57
+ if (existsSync(storeMarker)) {
58
+ await assertPlanningRootNotLinked(nested);
59
+ if (!await isDirectory(nested)) {
60
+ throw new OpenSpecRootError(`Store checkout ${inputRoot} has no OpenSpec planning content: neither ${nested} nor config.yaml, project.md, specs/ or changes/ at the checkout root.`);
61
+ }
62
+ return { inputRoot, root: nested, kind: "store" };
63
+ }
64
+ throw new OpenSpecRootError(`No OpenSpec workspace found at ${inputRoot} (expected openspec/config.yaml, specs/, changes/, project.md, or .openspec-store/store.yaml).`);
65
+ }
66
+ export async function assertPlanningRootNotLinked(path) {
67
+ if (await isSymbolicLink(path)) {
68
+ throw new OpenSpecRootError(`OpenSpec planning root must not be a symbolic link: ${path}. Pass the canonical planning directory explicitly.`);
69
+ }
70
+ }
71
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../../src/core/openspec/scan/workspace.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Where the workspace is, how its paths are spelled, and the record every\n * reader of it carries.\n *\n * `Ingest` exists because the five readers below it all need the same four\n * things — the root, the mapping being checked, and the two lists they append\n * findings to — and none of them may take four parameters plus its own. It is\n * the read in progress, so the accumulators live in it: a scan that returned\n * its findings instead would have to merge five arrays whose ORDER is what the\n * `--json` contract pins.\n */\nimport { existsSync } from \"node:fs\";\nimport { realpath } from \"node:fs/promises\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { type OpenSpecMapping } from \"../model/mapping.js\";\nimport { type OpenSpecRenamedUsage, type OpenSpecUnsupportedShape, OpenSpecRootError } from \"../model/model.js\";\nimport { isDirectory, isSymbolicLink } from \"./walk.js\";\n\n/** The one read of one OpenSpec workspace, in progress. */\nexport interface Ingest {\n /** The canonical `openspec/` directory every path below is spelled relative to. */\n root: string;\n /** The mapping being graded against this workspace; empty when auditing. */\n mapping: OpenSpecMapping;\n /** Every RENAMED pair seen, resolved later against the living source. */\n renamed: OpenSpecRenamedUsage[];\n /** Shapes that block migration. Archive-scope findings go to their own list. */\n unsupported: OpenSpecUnsupportedShape[];\n}\n\nexport async function looksLikeOpenSpec(path: string): Promise<boolean> {\n return existsSync(join(path, \"config.yaml\"))\n || existsSync(join(path, \"project.md\"))\n || existsSync(join(path, \".openspec.yaml\"))\n || await isDirectory(join(path, \"specs\"))\n || await isDirectory(join(path, \"changes\"));\n}\n\nexport async function locateOpenSpecRoot(\n input: string,\n): Promise<{ inputRoot: string; root: string; kind: \"project\" | \"store\" | \"openspec-root\" }> {\n const requestedRoot = resolve(input);\n if (!await isDirectory(requestedRoot)) {\n throw new OpenSpecRootError(`OpenSpec root is missing or is not a directory: ${requestedRoot}`);\n }\n const inputRoot = await realpath(requestedRoot);\n const nested = join(inputRoot, \"openspec\");\n const storeMarker = join(inputRoot, \".openspec-store\", \"store.yaml\");\n const hasNestedShape = await looksLikeOpenSpec(nested);\n const hasDirectShape = await looksLikeOpenSpec(inputRoot);\n if (hasNestedShape && hasDirectShape) {\n throw new OpenSpecRootError(\n `Ambiguous OpenSpec root ${inputRoot}: both the directory itself and ${nested} contain OpenSpec planning shapes. Pass the intended root explicitly.`,\n );\n }\n if (hasNestedShape) {\n await assertPlanningRootNotLinked(nested);\n return { inputRoot, root: nested, kind: existsSync(storeMarker) ? \"store\" : \"project\" };\n }\n // The shape decides the root, the Store marker only decides the kind. Deciding\n // \"store\" first sent `root` to <store>/openspec for a checkout that keeps its\n // planning shape at the checkout root: a directory that does not exist reads\n // as an empty, fully compatible workspace, and apply then stages nothing.\n if (hasDirectShape) {\n const parentStoreMarker = basename(inputRoot) === \"openspec\"\n ? join(dirname(inputRoot), \".openspec-store\", \"store.yaml\")\n : \"\";\n const store = existsSync(storeMarker) || (parentStoreMarker !== \"\" && existsSync(parentStoreMarker));\n return { inputRoot, root: inputRoot, kind: store ? \"store\" : \"openspec-root\" };\n }\n // OpenSpec stores may omit empty planning directories. Keep their canonical\n // future root at <store>/openspec so paths do not change after the first spec\n // — but only when that directory is really there. Auditing a root that does\n // not exist is how a Store checkout came back `ready` over invisible content.\n if (existsSync(storeMarker)) {\n await assertPlanningRootNotLinked(nested);\n if (!await isDirectory(nested)) {\n throw new OpenSpecRootError(\n `Store checkout ${inputRoot} has no OpenSpec planning content: neither ${nested} nor config.yaml, project.md, specs/ or changes/ at the checkout root.`,\n );\n }\n return { inputRoot, root: nested, kind: \"store\" };\n }\n throw new OpenSpecRootError(\n `No OpenSpec workspace found at ${inputRoot} (expected openspec/config.yaml, specs/, changes/, project.md, or .openspec-store/store.yaml).`,\n );\n}\n\nexport async function assertPlanningRootNotLinked(path: string): Promise<void> {\n if (await isSymbolicLink(path)) {\n throw new OpenSpecRootError(\n `OpenSpec planning root must not be a symbolic link: ${path}. Pass the canonical planning directory explicitly.`,\n );\n }\n}\n"]}