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

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 (1036) hide show
  1. package/CHANGELOG.md +2635 -86
  2. package/COMPARISON.md +80 -63
  3. package/CONTRIBUTING.md +84 -0
  4. package/MIGRATING-from-OpenSpec.md +213 -54
  5. package/QUICKSTART.md +125 -0
  6. package/README.md +450 -150
  7. package/ROADMAP.md +599 -0
  8. package/SCHEMA.md +2355 -256
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +701 -0
  11. package/dist/cli.js +113 -19
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +209 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +268 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +77 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
  20. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/openapi.js +159 -0
  22. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  23. package/dist/commands/archive/plan/gate.js +323 -0
  24. package/dist/commands/archive/plan/gate.js.map +1 -0
  25. package/dist/commands/archive/plan/landscape.js +180 -0
  26. package/dist/commands/archive/plan/landscape.js.map +1 -0
  27. package/dist/commands/archive/plan/refusal.js +111 -0
  28. package/dist/commands/archive/plan/refusal.js.map +1 -0
  29. package/dist/commands/archive/plan/specs.js +237 -0
  30. package/dist/commands/archive/plan/specs.js.map +1 -0
  31. package/dist/commands/archive/plan/state.js +27 -0
  32. package/dist/commands/archive/plan/state.js.map +1 -0
  33. package/dist/commands/archive/run.js +252 -0
  34. package/dist/commands/archive/run.js.map +1 -0
  35. package/dist/commands/context/context.js +99 -0
  36. package/dist/commands/context/context.js.map +1 -0
  37. package/dist/commands/context/print.js +283 -0
  38. package/dist/commands/context/print.js.map +1 -0
  39. package/dist/commands/delta/delta.js +279 -0
  40. package/dist/commands/delta/delta.js.map +1 -0
  41. package/dist/commands/delta/print.js +205 -0
  42. package/dist/commands/delta/print.js.map +1 -0
  43. package/dist/commands/dependencies.js +9 -7
  44. package/dist/commands/dependencies.js.map +1 -1
  45. package/dist/commands/diff/diff.js +93 -0
  46. package/dist/commands/diff/diff.js.map +1 -0
  47. package/dist/commands/diff/print.js +38 -0
  48. package/dist/commands/diff/print.js.map +1 -0
  49. package/dist/commands/doctor.js +5 -4
  50. package/dist/commands/doctor.js.map +1 -1
  51. package/dist/commands/explain/explain.js +151 -0
  52. package/dist/commands/explain/explain.js.map +1 -0
  53. package/dist/commands/explore.js +29 -24
  54. package/dist/commands/explore.js.map +1 -1
  55. package/dist/commands/gate/gate.js +115 -0
  56. package/dist/commands/gate/gate.js.map +1 -0
  57. package/dist/commands/gate/print.js +54 -0
  58. package/dist/commands/gate/print.js.map +1 -0
  59. package/dist/commands/gherkin/commit.js +146 -0
  60. package/dist/commands/gherkin/commit.js.map +1 -0
  61. package/dist/commands/gherkin/gherkin.js +246 -0
  62. package/dist/commands/gherkin/gherkin.js.map +1 -0
  63. package/dist/commands/gherkin/reconcile.js +149 -0
  64. package/dist/commands/gherkin/reconcile.js.map +1 -0
  65. package/dist/commands/gherkin/render.js +77 -0
  66. package/dist/commands/gherkin/render.js.map +1 -0
  67. package/dist/commands/init/example.js +204 -0
  68. package/dist/commands/init/example.js.map +1 -0
  69. package/dist/commands/init/first-hour.js +28 -0
  70. package/dist/commands/init/first-hour.js.map +1 -0
  71. package/dist/commands/{init.js → init/init.js} +146 -71
  72. package/dist/commands/init/init.js.map +1 -0
  73. package/dist/commands/init/mcp.js +131 -0
  74. package/dist/commands/init/mcp.js.map +1 -0
  75. package/dist/commands/init/options.js +78 -0
  76. package/dist/commands/init/options.js.map +1 -0
  77. package/dist/commands/instructions.js +72 -14
  78. package/dist/commands/instructions.js.map +1 -1
  79. package/dist/commands/list/campaign/campaign.js +65 -0
  80. package/dist/commands/list/campaign/campaign.js.map +1 -0
  81. package/dist/commands/list/campaign/owners.js +65 -0
  82. package/dist/commands/list/campaign/owners.js.map +1 -0
  83. package/dist/commands/list/json.js +157 -0
  84. package/dist/commands/list/json.js.map +1 -0
  85. package/dist/commands/list/list.js +343 -0
  86. package/dist/commands/list/list.js.map +1 -0
  87. package/dist/commands/list/print.js +301 -0
  88. package/dist/commands/list/print.js.map +1 -0
  89. package/dist/commands/list/review.js +120 -0
  90. package/dist/commands/list/review.js.map +1 -0
  91. package/dist/commands/list/views.js +105 -0
  92. package/dist/commands/list/views.js.map +1 -0
  93. package/dist/commands/mcp/dispatch.js +183 -0
  94. package/dist/commands/mcp/dispatch.js.map +1 -0
  95. package/dist/commands/mcp/mcp.js +34 -0
  96. package/dist/commands/mcp/mcp.js.map +1 -0
  97. package/dist/commands/mcp/serve.js +55 -0
  98. package/dist/commands/mcp/serve.js.map +1 -0
  99. package/dist/commands/migrate-openspec/materialize/active.js +170 -0
  100. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  101. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  102. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  103. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  104. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  105. package/dist/commands/migrate-openspec/materialize/stage.js +142 -0
  106. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  107. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  108. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  109. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  110. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  111. package/dist/commands/migrate-openspec/openspec/decisions.js +91 -0
  112. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  113. package/dist/commands/migrate-openspec/openspec/error.js +19 -0
  114. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  115. package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
  116. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  117. package/dist/commands/migrate-openspec/openspec/paths.js +43 -0
  118. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  119. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  120. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  121. package/dist/commands/migrate-openspec/print.js +89 -0
  122. package/dist/commands/migrate-openspec/print.js.map +1 -0
  123. package/dist/commands/new/commit.js +76 -0
  124. package/dist/commands/new/commit.js.map +1 -0
  125. package/dist/commands/new/new.js +283 -0
  126. package/dist/commands/new/new.js.map +1 -0
  127. package/dist/commands/new/templates.js +355 -0
  128. package/dist/commands/new/templates.js.map +1 -0
  129. package/dist/commands/open.js +203 -0
  130. package/dist/commands/open.js.map +1 -0
  131. package/dist/commands/policy/format.js +152 -0
  132. package/dist/commands/policy/format.js.map +1 -0
  133. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +11 -11
  134. package/dist/commands/policy/gate.js.map +1 -0
  135. package/dist/commands/rebase/edit.js +106 -0
  136. package/dist/commands/rebase/edit.js.map +1 -0
  137. package/dist/commands/rebase/living.js +185 -0
  138. package/dist/commands/rebase/living.js.map +1 -0
  139. package/dist/commands/rebase/plan.js +245 -0
  140. package/dist/commands/rebase/plan.js.map +1 -0
  141. package/dist/commands/rebase/rebase.js +275 -0
  142. package/dist/commands/rebase/rebase.js.map +1 -0
  143. package/dist/commands/seed/commit.js +192 -0
  144. package/dist/commands/seed/commit.js.map +1 -0
  145. package/dist/commands/seed/plan.js +133 -0
  146. package/dist/commands/seed/plan.js.map +1 -0
  147. package/dist/commands/seed/seed.js +172 -0
  148. package/dist/commands/seed/seed.js.map +1 -0
  149. package/dist/commands/show/feature.js +178 -0
  150. package/dist/commands/show/feature.js.map +1 -0
  151. package/dist/commands/show/marks.js +24 -0
  152. package/dist/commands/show/marks.js.map +1 -0
  153. package/dist/commands/{show.js → show/service.js} +63 -152
  154. package/dist/commands/show/service.js.map +1 -0
  155. package/dist/commands/show/show.js +77 -0
  156. package/dist/commands/show/show.js.map +1 -0
  157. package/dist/commands/status/json.js +45 -0
  158. package/dist/commands/status/json.js.map +1 -0
  159. package/dist/commands/status/print.js +157 -0
  160. package/dist/commands/status/print.js.map +1 -0
  161. package/dist/commands/status/status.js +119 -0
  162. package/dist/commands/status/status.js.map +1 -0
  163. package/dist/commands/steps/steps.js +189 -0
  164. package/dist/commands/steps/steps.js.map +1 -0
  165. package/dist/commands/subsystem/edit.js +192 -0
  166. package/dist/commands/subsystem/edit.js.map +1 -0
  167. package/dist/commands/subsystem/move.js +265 -0
  168. package/dist/commands/subsystem/move.js.map +1 -0
  169. package/dist/commands/subsystem/query.js +115 -0
  170. package/dist/commands/subsystem/query.js.map +1 -0
  171. package/dist/commands/subsystem/subsystem.js +101 -0
  172. package/dist/commands/subsystem/subsystem.js.map +1 -0
  173. package/dist/commands/subsystem/sync.js +103 -0
  174. package/dist/commands/subsystem/sync.js.map +1 -0
  175. package/dist/commands/subsystem/txn/txn.js +94 -0
  176. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  177. package/dist/commands/subsystem/txn/views.js +70 -0
  178. package/dist/commands/subsystem/txn/views.js.map +1 -0
  179. package/dist/commands/unarchive/manifest.js +160 -0
  180. package/dist/commands/unarchive/manifest.js.map +1 -0
  181. package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
  182. package/dist/commands/unarchive/restore.js.map +1 -0
  183. package/dist/commands/unarchive/unarchive.js +67 -0
  184. package/dist/commands/unarchive/unarchive.js.map +1 -0
  185. package/dist/commands/validate/arch-coverage.js +204 -0
  186. package/dist/commands/validate/arch-coverage.js.map +1 -0
  187. package/dist/commands/validate/checks/fleet-shape.js +296 -0
  188. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  189. package/dist/commands/validate/checks/health-deps.js +55 -0
  190. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  191. package/dist/commands/validate/checks/requirements.js +254 -0
  192. package/dist/commands/validate/checks/requirements.js.map +1 -0
  193. package/dist/commands/validate/checks/sources.js +76 -0
  194. package/dist/commands/validate/checks/sources.js.map +1 -0
  195. package/dist/commands/validate/checks/vocabulary.js +31 -0
  196. package/dist/commands/validate/checks/vocabulary.js.map +1 -0
  197. package/dist/commands/validate/feature.js +216 -0
  198. package/dist/commands/validate/feature.js.map +1 -0
  199. package/dist/commands/validate/fleet/census.js +69 -0
  200. package/dist/commands/validate/fleet/census.js.map +1 -0
  201. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  202. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  203. package/dist/commands/validate/fleet/landscape.js +353 -0
  204. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  205. package/dist/commands/validate/fleet/load.js +52 -0
  206. package/dist/commands/validate/fleet/load.js.map +1 -0
  207. package/dist/commands/validate/fleet/obligations.js +270 -0
  208. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  209. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  210. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  211. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  212. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  213. package/dist/commands/validate/fleet/scorecard/print.js +63 -0
  214. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  215. package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
  216. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  217. package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
  218. package/dist/commands/validate/fleet/usecases/capability-tag.js.map +1 -0
  219. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  220. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  221. package/dist/commands/validate/fleet/usecases/requirement-tag.js +95 -0
  222. package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
  223. package/dist/commands/validate/fleet/usecases/steps.js +197 -0
  224. package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
  225. package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
  226. package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
  227. package/dist/commands/validate/fleet/views/ids.js +40 -0
  228. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  229. package/dist/commands/validate/fleet/views/stale.js +59 -0
  230. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  231. package/dist/commands/validate/links/corpus.js +92 -0
  232. package/dist/commands/validate/links/corpus.js.map +1 -0
  233. package/dist/commands/validate/links/glossary.js +75 -0
  234. package/dist/commands/validate/links/glossary.js.map +1 -0
  235. package/dist/commands/validate/report.js +269 -0
  236. package/dist/commands/validate/report.js.map +1 -0
  237. package/dist/commands/validate/service/api.js +338 -0
  238. package/dist/commands/validate/service/api.js.map +1 -0
  239. package/dist/commands/validate/service/events/events.js +219 -0
  240. package/dist/commands/validate/service/events/events.js.map +1 -0
  241. package/dist/commands/validate/service/events/message-producers.js +77 -0
  242. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  243. package/dist/commands/validate/service/evidence-pins.js +131 -0
  244. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  245. package/dist/commands/validate/service/service.js +251 -0
  246. package/dist/commands/validate/service/service.js.map +1 -0
  247. package/dist/commands/validate/service/specs.js +251 -0
  248. package/dist/commands/validate/service/specs.js.map +1 -0
  249. package/dist/commands/validate/service/spine.js +113 -0
  250. package/dist/commands/validate/service/spine.js.map +1 -0
  251. package/dist/commands/validate/validate.js +338 -0
  252. package/dist/commands/validate/validate.js.map +1 -0
  253. package/dist/commands/verify/cross/diff.js +182 -0
  254. package/dist/commands/verify/cross/diff.js.map +1 -0
  255. package/dist/commands/verify/evidence/contract.js +32 -0
  256. package/dist/commands/verify/evidence/contract.js.map +1 -0
  257. package/dist/commands/verify/evidence/pins.js +52 -0
  258. package/dist/commands/verify/evidence/pins.js.map +1 -0
  259. package/dist/commands/verify/evidence/read.js +72 -0
  260. package/dist/commands/verify/evidence/read.js.map +1 -0
  261. package/dist/commands/verify/frozen.js +241 -0
  262. package/dist/commands/verify/frozen.js.map +1 -0
  263. package/dist/commands/verify/record.js +226 -0
  264. package/dist/commands/verify/record.js.map +1 -0
  265. package/dist/commands/verify/report.js +223 -0
  266. package/dist/commands/verify/report.js.map +1 -0
  267. package/dist/commands/verify/results.js +246 -0
  268. package/dist/commands/verify/results.js.map +1 -0
  269. package/dist/commands/verify/verify.js +217 -0
  270. package/dist/commands/verify/verify.js.map +1 -0
  271. package/dist/commands/vouch/contract.js +11 -0
  272. package/dist/commands/vouch/contract.js.map +1 -0
  273. package/dist/commands/vouch/pack/contract.js +2 -0
  274. package/dist/commands/vouch/pack/contract.js.map +1 -0
  275. package/dist/commands/vouch/pack/pack.js +266 -0
  276. package/dist/commands/vouch/pack/pack.js.map +1 -0
  277. package/dist/commands/vouch/pack/print.js +271 -0
  278. package/dist/commands/vouch/pack/print.js.map +1 -0
  279. package/dist/commands/vouch/pack/sections.js +142 -0
  280. package/dist/commands/vouch/pack/sections.js.map +1 -0
  281. package/dist/commands/vouch/prompt/confirm.js +46 -0
  282. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  283. package/dist/commands/vouch/report.js +101 -0
  284. package/dist/commands/vouch/report.js.map +1 -0
  285. package/dist/commands/vouch/run.js +285 -0
  286. package/dist/commands/vouch/run.js.map +1 -0
  287. package/dist/commands/vouch/sample/plan.js +125 -0
  288. package/dist/commands/vouch/sample/plan.js.map +1 -0
  289. package/dist/commands/vouch/sample/print.js +109 -0
  290. package/dist/commands/vouch/sample/print.js.map +1 -0
  291. package/dist/commands/vouch/vet/verify.js +123 -0
  292. package/dist/commands/vouch/vet/verify.js.map +1 -0
  293. package/dist/commands/vouch/vouch.js +176 -0
  294. package/dist/commands/vouch/vouch.js.map +1 -0
  295. package/dist/core/agent/agents-md/artifacts.js +220 -0
  296. package/dist/core/agent/agents-md/artifacts.js.map +1 -0
  297. package/dist/core/agent/agents-md/command-map.js +324 -0
  298. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  299. package/dist/core/agent/agents-md/cycle.js +165 -0
  300. package/dist/core/agent/agents-md/cycle.js.map +1 -0
  301. package/dist/core/agent/agents-md/map/explain.js +34 -0
  302. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  303. package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
  304. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  305. package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
  306. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  307. package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
  308. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  309. package/dist/core/agent/agents-md/map/mcp.js +41 -0
  310. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  311. package/dist/core/agent/agents-md/map/status.js +62 -0
  312. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  313. package/dist/core/agent/agents-md/map/subsystem.js +32 -0
  314. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  315. package/dist/core/agent/agents-md/map/usecases.js +60 -0
  316. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  317. package/dist/core/agent/agents-md/refusals.js +246 -0
  318. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  319. package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
  320. package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
  321. package/dist/core/agent/agents-md/spine.js +40 -0
  322. package/dist/core/agent/agents-md/spine.js.map +1 -0
  323. package/dist/core/agent/agents-md.js +170 -0
  324. package/dist/core/agent/agents-md.js.map +1 -0
  325. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +50 -0
  326. package/dist/core/agent/agents-stamp.js.map +1 -0
  327. package/dist/core/agent/contract.js +2 -0
  328. package/dist/core/agent/contract.js.map +1 -0
  329. package/dist/core/agent/protocol.js +193 -0
  330. package/dist/core/agent/protocol.js.map +1 -0
  331. package/dist/core/agent/scaffold.js +259 -0
  332. package/dist/core/agent/scaffold.js.map +1 -0
  333. package/dist/core/agent/support/report.js +103 -0
  334. package/dist/core/agent/support/report.js.map +1 -0
  335. package/dist/core/agent/tools/dialects.js +150 -0
  336. package/dist/core/agent/tools/dialects.js.map +1 -0
  337. package/dist/core/agent/tools/registry.js +228 -0
  338. package/dist/core/agent/tools/registry.js.map +1 -0
  339. package/dist/core/agent/workflows/adopt.js +133 -0
  340. package/dist/core/agent/workflows/adopt.js.map +1 -0
  341. package/dist/core/agent/workflows/check.js +337 -0
  342. package/dist/core/agent/workflows/check.js.map +1 -0
  343. package/dist/core/agent/workflows/closing.js +262 -0
  344. package/dist/core/agent/workflows/closing.js.map +1 -0
  345. package/dist/core/agent/workflows/feature.js +105 -0
  346. package/dist/core/agent/workflows/feature.js.map +1 -0
  347. package/dist/core/agent/workflows/implement.js +105 -0
  348. package/dist/core/agent/workflows/implement.js.map +1 -0
  349. package/dist/core/agent/workflows/reference/authoring.js +209 -0
  350. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  351. package/dist/core/agent/workflows/reference/codes.js +65 -0
  352. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  353. package/dist/core/agent/workflows/reference/done-check.js +188 -0
  354. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  355. package/dist/core/agent/workflows/reference/reference.js +16 -0
  356. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  357. package/dist/core/agent/workflows/reference/spine.js +297 -0
  358. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  359. package/dist/core/asyncapi/baseline/plan.js +110 -0
  360. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  361. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  362. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  363. package/dist/core/asyncapi/depth.js +164 -0
  364. package/dist/core/asyncapi/depth.js.map +1 -0
  365. package/dist/core/asyncapi/digest.js +141 -0
  366. package/dist/core/asyncapi/digest.js.map +1 -0
  367. package/dist/core/asyncapi/merge/components.js +91 -0
  368. package/dist/core/asyncapi/merge/components.js.map +1 -0
  369. package/dist/core/asyncapi/merge/error.js +33 -0
  370. package/dist/core/asyncapi/merge/error.js.map +1 -0
  371. package/dist/core/asyncapi/merge/markers.js +308 -0
  372. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  373. package/dist/core/asyncapi/merge/merge.js +215 -0
  374. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  375. package/dist/core/asyncapi/merge/pin.js +107 -0
  376. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  377. package/dist/core/asyncapi/model.js +11 -0
  378. package/dist/core/asyncapi/model.js.map +1 -0
  379. package/dist/core/asyncapi/producers.js +50 -0
  380. package/dist/core/asyncapi/producers.js.map +1 -0
  381. package/dist/core/{asyncapi.js → asyncapi/read.js} +95 -109
  382. package/dist/core/asyncapi/read.js.map +1 -0
  383. package/dist/core/brief/brief.js +225 -0
  384. package/dist/core/brief/brief.js.map +1 -0
  385. package/dist/core/brief/checks.js +250 -0
  386. package/dist/core/brief/checks.js.map +1 -0
  387. package/dist/core/brief/landscape.js +194 -0
  388. package/dist/core/brief/landscape.js.map +1 -0
  389. package/dist/core/brief/targets.js +226 -0
  390. package/dist/core/brief/targets.js.map +1 -0
  391. package/dist/core/brief/unchecked.js +48 -0
  392. package/dist/core/brief/unchecked.js.map +1 -0
  393. package/dist/core/c4/arch.js +174 -0
  394. package/dist/core/c4/arch.js.map +1 -0
  395. package/dist/core/c4/likec4.js +90 -0
  396. package/dist/core/c4/likec4.js.map +1 -0
  397. package/dist/core/c4/parsed/deployment.js +158 -0
  398. package/dist/core/c4/parsed/deployment.js.map +1 -0
  399. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  400. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  401. package/dist/core/c4/parsed/specification.js +78 -0
  402. package/dist/core/c4/parsed/specification.js.map +1 -0
  403. package/dist/core/c4/parsed/values.js +57 -0
  404. package/dist/core/c4/parsed/values.js.map +1 -0
  405. package/dist/core/c4/parsed/view-ids.js +75 -0
  406. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  407. package/dist/core/c4/project/architecture.js +45 -0
  408. package/dist/core/c4/project/architecture.js.map +1 -0
  409. package/dist/core/c4/project/documents.js +58 -0
  410. package/dist/core/c4/project/documents.js.map +1 -0
  411. package/dist/core/c4/project/load.js +187 -0
  412. package/dist/core/c4/project/load.js.map +1 -0
  413. package/dist/core/c4/project/staged.js +220 -0
  414. package/dist/core/c4/project/staged.js.map +1 -0
  415. package/dist/core/c4/resolve/service.js +159 -0
  416. package/dist/core/c4/resolve/service.js.map +1 -0
  417. package/dist/core/c4/resolve/steps.js +144 -0
  418. package/dist/core/c4/resolve/steps.js.map +1 -0
  419. package/dist/core/c4/seed/fleet-file.js +201 -0
  420. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  421. package/dist/core/c4/seed/items.js +91 -0
  422. package/dist/core/c4/seed/items.js.map +1 -0
  423. package/dist/core/c4/seed/stamp.js +48 -0
  424. package/dist/core/c4/seed/stamp.js.map +1 -0
  425. package/dist/core/c4/seed/template.js +109 -0
  426. package/dist/core/c4/seed/template.js.map +1 -0
  427. package/dist/core/c4/source-mask.js +82 -0
  428. package/dist/core/c4/source-mask.js.map +1 -0
  429. package/dist/core/c4/source-scan.js +227 -0
  430. package/dist/core/c4/source-scan.js.map +1 -0
  431. package/dist/core/c4/splice/authored-source.js +101 -0
  432. package/dist/core/c4/splice/authored-source.js.map +1 -0
  433. package/dist/core/c4/splice/contract.js +10 -0
  434. package/dist/core/c4/splice/contract.js.map +1 -0
  435. package/dist/core/c4/splice/delta-blocks.js +139 -0
  436. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  437. package/dist/core/c4/splice/identity/edges.js +36 -0
  438. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  439. package/dist/core/c4/splice/landscape-merge.js +269 -0
  440. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  441. package/dist/core/c4/splice/placement.js +194 -0
  442. package/dist/core/c4/splice/placement.js.map +1 -0
  443. package/dist/core/c4/workspace.js +174 -0
  444. package/dist/core/c4/workspace.js.map +1 -0
  445. package/dist/core/capabilities/authoring/notes.js +141 -0
  446. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  447. package/dist/core/capabilities/capabilities.js +124 -0
  448. package/dist/core/capabilities/capabilities.js.map +1 -0
  449. package/dist/core/capabilities/delta/doc.js +50 -0
  450. package/dist/core/capabilities/delta/doc.js.map +1 -0
  451. package/dist/core/capabilities/delta/overlay.js +129 -0
  452. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  453. package/dist/core/capabilities/delta/summary.js +57 -0
  454. package/dist/core/capabilities/delta/summary.js.map +1 -0
  455. package/dist/core/capabilities/delta/tree.js +43 -0
  456. package/dist/core/capabilities/delta/tree.js.map +1 -0
  457. package/dist/core/capabilities/delta/uncovered.js +222 -0
  458. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  459. package/dist/core/capabilities/findings.js +342 -0
  460. package/dist/core/capabilities/findings.js.map +1 -0
  461. package/dist/core/capabilities/realizes/findings.js +181 -0
  462. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  463. package/dist/core/capabilities/realizes/join.js +143 -0
  464. package/dist/core/capabilities/realizes/join.js.map +1 -0
  465. package/dist/core/capabilities/rollup.js +199 -0
  466. package/dist/core/capabilities/rollup.js.map +1 -0
  467. package/dist/core/capabilities/tree.js +126 -0
  468. package/dist/core/capabilities/tree.js.map +1 -0
  469. package/dist/core/capabilities/usecase-join.js +277 -0
  470. package/dist/core/capabilities/usecase-join.js.map +1 -0
  471. package/dist/core/coherence/authoring/scaffold.js +177 -0
  472. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  473. package/dist/core/coherence/authoring/sentinels.js +74 -0
  474. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  475. package/dist/core/coherence/coherence.js +287 -0
  476. package/dist/core/coherence/coherence.js.map +1 -0
  477. package/dist/core/coherence/declared.js +269 -0
  478. package/dist/core/coherence/declared.js.map +1 -0
  479. package/dist/core/coherence/events/declared.js +206 -0
  480. package/dist/core/coherence/events/declared.js.map +1 -0
  481. package/dist/core/coherence/events/events.js +204 -0
  482. package/dist/core/coherence/events/events.js.map +1 -0
  483. package/dist/core/coherence/events/grades.js +166 -0
  484. package/dist/core/coherence/events/grades.js.map +1 -0
  485. package/dist/core/coherence/events/lookups.js +122 -0
  486. package/dist/core/coherence/events/lookups.js.map +1 -0
  487. package/dist/core/coherence/events/merged.js +40 -0
  488. package/dist/core/coherence/events/merged.js.map +1 -0
  489. package/dist/core/coherence/living.js +198 -0
  490. package/dist/core/coherence/living.js.map +1 -0
  491. package/dist/core/coherence/lookups.js +155 -0
  492. package/dist/core/coherence/lookups.js.map +1 -0
  493. package/dist/core/coherence/pending.js +39 -0
  494. package/dist/core/coherence/pending.js.map +1 -0
  495. package/dist/core/conflict-markers.js +60 -0
  496. package/dist/core/conflict-markers.js.map +1 -0
  497. package/dist/core/delta/claims.js +73 -0
  498. package/dist/core/delta/claims.js.map +1 -0
  499. package/dist/core/delta/delta.js +296 -0
  500. package/dist/core/delta/delta.js.map +1 -0
  501. package/dist/core/delta/document.js +177 -0
  502. package/dist/core/delta/document.js.map +1 -0
  503. package/dist/core/delta/scope.js +48 -0
  504. package/dist/core/delta/scope.js.map +1 -0
  505. package/dist/core/delta/select.js +237 -0
  506. package/dist/core/delta/select.js.map +1 -0
  507. package/dist/core/dependencies/dependencies.js +141 -0
  508. package/dist/core/dependencies/dependencies.js.map +1 -0
  509. package/dist/core/dependencies/facts.js +165 -0
  510. package/dist/core/dependencies/facts.js.map +1 -0
  511. package/dist/core/dependencies/fanin.js +88 -0
  512. package/dist/core/dependencies/fanin.js.map +1 -0
  513. package/dist/core/dependencies/graph.js +106 -0
  514. package/dist/core/dependencies/graph.js.map +1 -0
  515. package/dist/core/deployment/delta.js +188 -0
  516. package/dist/core/deployment/delta.js.map +1 -0
  517. package/dist/core/deployment/objects.js +145 -0
  518. package/dist/core/deployment/objects.js.map +1 -0
  519. package/dist/core/diff/base-git.js +148 -0
  520. package/dist/core/diff/base-git.js.map +1 -0
  521. package/dist/core/diff/base-state.js +209 -0
  522. package/dist/core/diff/base-state.js.map +1 -0
  523. package/dist/core/diff/current-state.js +96 -0
  524. package/dist/core/diff/current-state.js.map +1 -0
  525. package/dist/core/diff/scope/changed-paths.js +188 -0
  526. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  527. package/dist/core/diff/semantic.js +243 -0
  528. package/dist/core/diff/semantic.js.map +1 -0
  529. package/dist/core/diff/victims.js +247 -0
  530. package/dist/core/diff/victims.js.map +1 -0
  531. package/dist/core/docs.js +7 -64
  532. package/dist/core/docs.js.map +1 -1
  533. package/dist/core/doctor/agents.js +222 -0
  534. package/dist/core/doctor/agents.js.map +1 -0
  535. package/dist/core/doctor/config.js +135 -0
  536. package/dist/core/doctor/config.js.map +1 -0
  537. package/dist/core/doctor/doctor.js +275 -0
  538. package/dist/core/doctor/doctor.js.map +1 -0
  539. package/dist/core/doctor/report.js +13 -0
  540. package/dist/core/doctor/report.js.map +1 -0
  541. package/dist/core/doctor/residue.js +110 -0
  542. package/dist/core/doctor/residue.js.map +1 -0
  543. package/dist/core/document/apply.js +77 -0
  544. package/dist/core/document/apply.js.map +1 -0
  545. package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -2
  546. package/dist/core/document/frontmatter.js.map +1 -0
  547. package/dist/core/document/grammar/directives.js +143 -0
  548. package/dist/core/document/grammar/directives.js.map +1 -0
  549. package/dist/core/document/parse.js +263 -0
  550. package/dist/core/document/parse.js.map +1 -0
  551. package/dist/core/document/scenarios.js +221 -0
  552. package/dist/core/document/scenarios.js.map +1 -0
  553. package/dist/core/document/spec.js +241 -0
  554. package/dist/core/document/spec.js.map +1 -0
  555. package/dist/core/{config.js → envelope/config.js} +79 -18
  556. package/dist/core/envelope/config.js.map +1 -0
  557. package/dist/core/envelope/json.js +175 -0
  558. package/dist/core/envelope/json.js.map +1 -0
  559. package/dist/core/{version.js → envelope/version.js} +3 -3
  560. package/dist/core/envelope/version.js.map +1 -0
  561. package/dist/core/explain/families.js +175 -0
  562. package/dist/core/explain/families.js.map +1 -0
  563. package/dist/core/explain/fix-tables.js +178 -0
  564. package/dist/core/explain/fix-tables.js.map +1 -0
  565. package/dist/core/explain/lookup.js +181 -0
  566. package/dist/core/explain/lookup.js.map +1 -0
  567. package/dist/core/explain/refusals.js +49 -0
  568. package/dist/core/explain/refusals.js.map +1 -0
  569. package/dist/core/explain/terms.js +144 -0
  570. package/dist/core/explain/terms.js.map +1 -0
  571. package/dist/core/explore/describe.js +105 -0
  572. package/dist/core/explore/describe.js.map +1 -0
  573. package/dist/core/{explore.js → explore/explore.js} +50 -101
  574. package/dist/core/explore/explore.js.map +1 -0
  575. package/dist/core/fleet-context.js +120 -78
  576. package/dist/core/fleet-context.js.map +1 -1
  577. package/dist/core/gate/checks.js +201 -0
  578. package/dist/core/gate/checks.js.map +1 -0
  579. package/dist/core/gate/partners.js +205 -0
  580. package/dist/core/gate/partners.js.map +1 -0
  581. package/dist/core/gate/report.js +47 -0
  582. package/dist/core/gate/report.js.map +1 -0
  583. package/dist/core/gate/verification.js +113 -0
  584. package/dist/core/gate/verification.js.map +1 -0
  585. package/dist/core/gherkin/digest.js +60 -0
  586. package/dist/core/gherkin/digest.js.map +1 -0
  587. package/dist/core/gherkin/emit.js +177 -0
  588. package/dist/core/gherkin/emit.js.map +1 -0
  589. package/dist/core/gherkin/read.js +76 -0
  590. package/dist/core/gherkin/read.js.map +1 -0
  591. package/dist/core/gherkin/stale.js +234 -0
  592. package/dist/core/gherkin/stale.js.map +1 -0
  593. package/dist/core/gherkin/stamp.js +77 -0
  594. package/dist/core/gherkin/stamp.js.map +1 -0
  595. package/dist/core/gherkin/steps/catalogue.js +154 -0
  596. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  597. package/dist/core/gherkin/steps/inventory.js +98 -0
  598. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  599. package/dist/core/gherkin/steps/phrase.js +72 -0
  600. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  601. package/dist/core/glossary/delta.js +106 -0
  602. package/dist/core/glossary/delta.js.map +1 -0
  603. package/dist/core/glossary/tree.js +86 -0
  604. package/dist/core/glossary/tree.js.map +1 -0
  605. package/dist/core/kernel/concurrency.js.map +1 -0
  606. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  607. package/dist/core/kernel/document-bytes.js.map +1 -0
  608. package/dist/core/kernel/fences.js +42 -0
  609. package/dist/core/kernel/fences.js.map +1 -0
  610. package/dist/core/kernel/ids/capability.js +72 -0
  611. package/dist/core/kernel/ids/capability.js.map +1 -0
  612. package/dist/core/kernel/ids/dirs.js +33 -0
  613. package/dist/core/kernel/ids/dirs.js.map +1 -0
  614. package/dist/core/kernel/ids/feature.js +75 -0
  615. package/dist/core/kernel/ids/feature.js.map +1 -0
  616. package/dist/core/kernel/ids/service.js +156 -0
  617. package/dist/core/kernel/ids/service.js.map +1 -0
  618. package/dist/core/kernel/ids/subsystem.js +63 -0
  619. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  620. package/dist/core/{path-safety.js → kernel/path-safety.js} +18 -4
  621. package/dist/core/kernel/path-safety.js.map +1 -0
  622. package/dist/core/kernel/records.js.map +1 -0
  623. package/dist/core/links/backlinks.js +68 -0
  624. package/dist/core/links/backlinks.js.map +1 -0
  625. package/dist/core/links/case.js +74 -0
  626. package/dist/core/links/case.js.map +1 -0
  627. package/dist/core/links/corpus.js +104 -0
  628. package/dist/core/links/corpus.js.map +1 -0
  629. package/dist/core/links/findings.js +110 -0
  630. package/dist/core/links/findings.js.map +1 -0
  631. package/dist/core/links/parse.js +236 -0
  632. package/dist/core/links/parse.js.map +1 -0
  633. package/dist/core/mcp/argv.js +111 -0
  634. package/dist/core/mcp/argv.js.map +1 -0
  635. package/dist/core/mcp/author-tools.js +72 -0
  636. package/dist/core/mcp/author-tools.js.map +1 -0
  637. package/dist/core/mcp/framing.js +46 -0
  638. package/dist/core/mcp/framing.js.map +1 -0
  639. package/dist/core/mcp/protocol.js +280 -0
  640. package/dist/core/mcp/protocol.js.map +1 -0
  641. package/dist/core/mcp/tools.js +314 -0
  642. package/dist/core/mcp/tools.js.map +1 -0
  643. package/dist/core/obligations/obligations.js +106 -0
  644. package/dist/core/obligations/obligations.js.map +1 -0
  645. package/dist/core/openapi/baseline/gate.js +166 -0
  646. package/dist/core/openapi/baseline/gate.js.map +1 -0
  647. package/dist/core/openapi/baseline/plan.js +112 -0
  648. package/dist/core/openapi/baseline/plan.js.map +1 -0
  649. package/dist/core/openapi/baseline/record.js +175 -0
  650. package/dist/core/openapi/baseline/record.js.map +1 -0
  651. package/dist/core/openapi/depth.js +122 -0
  652. package/dist/core/openapi/depth.js.map +1 -0
  653. package/dist/core/openapi/digest.js +189 -0
  654. package/dist/core/openapi/digest.js.map +1 -0
  655. package/dist/core/{openapi.js → openapi/doc.js} +44 -106
  656. package/dist/core/openapi/doc.js.map +1 -0
  657. package/dist/core/openapi/merge/components.js +234 -0
  658. package/dist/core/openapi/merge/components.js.map +1 -0
  659. package/dist/core/openapi/merge/error.js +26 -0
  660. package/dist/core/openapi/merge/error.js.map +1 -0
  661. package/dist/core/openapi/merge/markers.js +208 -0
  662. package/dist/core/openapi/merge/markers.js.map +1 -0
  663. package/dist/core/openapi/merge/merge.js +256 -0
  664. package/dist/core/openapi/merge/merge.js.map +1 -0
  665. package/dist/core/openapi/merge/pin.js +128 -0
  666. package/dist/core/openapi/merge/pin.js.map +1 -0
  667. package/dist/core/openspec/decide/capabilities.js +244 -0
  668. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  669. package/dist/core/openspec/decide/dispositions.js +63 -0
  670. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  671. package/dist/core/openspec/decide/renames.js +179 -0
  672. package/dist/core/openspec/decide/renames.js.map +1 -0
  673. package/dist/core/openspec/decide/verdict.js +84 -0
  674. package/dist/core/openspec/decide/verdict.js.map +1 -0
  675. package/dist/core/openspec/inventory.js +221 -0
  676. package/dist/core/openspec/inventory.js.map +1 -0
  677. package/dist/core/openspec/model/mapping.js +76 -0
  678. package/dist/core/openspec/model/mapping.js.map +1 -0
  679. package/dist/core/openspec/model/model.js +65 -0
  680. package/dist/core/openspec/model/model.js.map +1 -0
  681. package/dist/core/openspec/scan/changes.js +235 -0
  682. package/dist/core/openspec/scan/changes.js.map +1 -0
  683. package/dist/core/openspec/scan/config.js +200 -0
  684. package/dist/core/openspec/scan/config.js.map +1 -0
  685. package/dist/core/openspec/scan/shape.js +260 -0
  686. package/dist/core/openspec/scan/shape.js.map +1 -0
  687. package/dist/core/openspec/scan/walk.js +133 -0
  688. package/dist/core/openspec/scan/walk.js.map +1 -0
  689. package/dist/core/openspec/scan/workspace.js +71 -0
  690. package/dist/core/openspec/scan/workspace.js.map +1 -0
  691. package/dist/core/owners/codeowners.js +141 -0
  692. package/dist/core/owners/codeowners.js.map +1 -0
  693. package/dist/core/pack/features.js +120 -0
  694. package/dist/core/pack/features.js.map +1 -0
  695. package/dist/core/pack/joins.js +112 -0
  696. package/dist/core/pack/joins.js.map +1 -0
  697. package/dist/core/pack/living.js +137 -0
  698. package/dist/core/pack/living.js.map +1 -0
  699. package/dist/core/pack/pack.js +76 -0
  700. package/dist/core/pack/pack.js.map +1 -0
  701. package/dist/core/permissions/permissions.js +87 -0
  702. package/dist/core/permissions/permissions.js.map +1 -0
  703. package/dist/core/projection/api.js +84 -0
  704. package/dist/core/projection/api.js.map +1 -0
  705. package/dist/core/projection/arch-slice.js +63 -0
  706. package/dist/core/projection/arch-slice.js.map +1 -0
  707. package/dist/core/projection/events.js +34 -0
  708. package/dist/core/projection/events.js.map +1 -0
  709. package/dist/core/provenance/findings.js +208 -0
  710. package/dist/core/provenance/findings.js.map +1 -0
  711. package/dist/core/provenance/git.js +225 -0
  712. package/dist/core/provenance/git.js.map +1 -0
  713. package/dist/core/provenance/gitq/moves.js +182 -0
  714. package/dist/core/provenance/gitq/moves.js.map +1 -0
  715. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  716. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  717. package/dist/core/provenance/sample/scope.js +238 -0
  718. package/dist/core/provenance/sample/scope.js.map +1 -0
  719. package/dist/core/provenance/sample/sections.js +61 -0
  720. package/dist/core/provenance/sample/sections.js.map +1 -0
  721. package/dist/core/provenance/sources.js +263 -0
  722. package/dist/core/provenance/sources.js.map +1 -0
  723. package/dist/core/provenance/stamp.js +232 -0
  724. package/dist/core/provenance/stamp.js.map +1 -0
  725. package/dist/core/provenance/walk.js +157 -0
  726. package/dist/core/provenance/walk.js.map +1 -0
  727. package/dist/core/repo/authored/paths.js +210 -0
  728. package/dist/core/repo/authored/paths.js.map +1 -0
  729. package/dist/core/repo/entries.js +126 -0
  730. package/dist/core/repo/entries.js.map +1 -0
  731. package/dist/core/repo/paths.js +277 -0
  732. package/dist/core/repo/paths.js.map +1 -0
  733. package/dist/core/repo/repo.js +248 -0
  734. package/dist/core/repo/repo.js.map +1 -0
  735. package/dist/core/repo/service-target.js +153 -0
  736. package/dist/core/repo/service-target.js.map +1 -0
  737. package/dist/core/repo/state.js +58 -0
  738. package/dist/core/repo/state.js.map +1 -0
  739. package/dist/core/repo/tree/find.js +52 -0
  740. package/dist/core/repo/tree/find.js.map +1 -0
  741. package/dist/core/repo/tree/fs.js +64 -0
  742. package/dist/core/repo/tree/fs.js.map +1 -0
  743. package/dist/core/repo/tree/marker.js +61 -0
  744. package/dist/core/repo/tree/marker.js.map +1 -0
  745. package/dist/core/repo/tree/views.js +172 -0
  746. package/dist/core/repo/tree/views.js.map +1 -0
  747. package/dist/core/repo/tree/walk.js +234 -0
  748. package/dist/core/repo/tree/walk.js.map +1 -0
  749. package/dist/core/results.js +99 -2
  750. package/dist/core/results.js.map +1 -1
  751. package/dist/core/scaffold/landscape.js +131 -0
  752. package/dist/core/scaffold/landscape.js.map +1 -0
  753. package/dist/core/scaffold/readme.js +84 -0
  754. package/dist/core/scaffold/readme.js.map +1 -0
  755. package/dist/core/staging/commit.js +241 -0
  756. package/dist/core/staging/commit.js.map +1 -0
  757. package/dist/core/staging/interrupted.js +96 -0
  758. package/dist/core/staging/interrupted.js.map +1 -0
  759. package/dist/core/staging/lock.js +206 -0
  760. package/dist/core/staging/lock.js.map +1 -0
  761. package/dist/core/staging/recovery/finding.js +35 -0
  762. package/dist/core/staging/recovery/finding.js.map +1 -0
  763. package/dist/core/staging/recovery/intent.js +98 -0
  764. package/dist/core/staging/recovery/intent.js.map +1 -0
  765. package/dist/core/staging/recovery/recover.js +126 -0
  766. package/dist/core/staging/recovery/recover.js.map +1 -0
  767. package/dist/core/staging/recovery/residue.js +62 -0
  768. package/dist/core/staging/recovery/residue.js.map +1 -0
  769. package/dist/core/staging/snapshot.js +202 -0
  770. package/dist/core/staging/snapshot.js.map +1 -0
  771. package/dist/core/staging/txn/forward.js +171 -0
  772. package/dist/core/staging/txn/forward.js.map +1 -0
  773. package/dist/core/staging/txn/journal.js +139 -0
  774. package/dist/core/staging/txn/journal.js.map +1 -0
  775. package/dist/core/staging/txn/transaction.js +75 -0
  776. package/dist/core/staging/txn/transaction.js.map +1 -0
  777. package/dist/core/staging/writes.js +113 -0
  778. package/dist/core/staging/writes.js.map +1 -0
  779. package/dist/core/status/actions/execution.js +49 -0
  780. package/dist/core/status/actions/execution.js.map +1 -0
  781. package/dist/core/status/contracts.js +102 -0
  782. package/dist/core/status/contracts.js.map +1 -0
  783. package/dist/core/status/feature/artifacts.js +196 -0
  784. package/dist/core/status/feature/artifacts.js.map +1 -0
  785. package/dist/core/status/feature/feature.js +207 -0
  786. package/dist/core/status/feature/feature.js.map +1 -0
  787. package/dist/core/status/feature/next.js +150 -0
  788. package/dist/core/status/feature/next.js.map +1 -0
  789. package/dist/core/status/feature/state.js +21 -0
  790. package/dist/core/status/feature/state.js.map +1 -0
  791. package/dist/core/status/fleet/fleet.js +197 -0
  792. package/dist/core/status/fleet/fleet.js.map +1 -0
  793. package/dist/core/status/fleet/next.js +207 -0
  794. package/dist/core/status/fleet/next.js.map +1 -0
  795. package/dist/core/status/interrupted.js +97 -0
  796. package/dist/core/status/interrupted.js.map +1 -0
  797. package/dist/core/status/report.js +31 -0
  798. package/dist/core/status/report.js.map +1 -0
  799. package/dist/core/status/scan.js +41 -0
  800. package/dist/core/status/scan.js.map +1 -0
  801. package/dist/core/status/verification.js +201 -0
  802. package/dist/core/status/verification.js.map +1 -0
  803. package/dist/core/usecases/capability.js +169 -0
  804. package/dist/core/usecases/capability.js.map +1 -0
  805. package/dist/core/usecases/delta/claims.js +116 -0
  806. package/dist/core/usecases/delta/claims.js.map +1 -0
  807. package/dist/core/usecases/delta/flows.js +103 -0
  808. package/dist/core/usecases/delta/flows.js.map +1 -0
  809. package/dist/core/usecases/delta/overlay.js +72 -0
  810. package/dist/core/usecases/delta/overlay.js.map +1 -0
  811. package/dist/core/usecases/fleet.js +137 -0
  812. package/dist/core/usecases/fleet.js.map +1 -0
  813. package/dist/core/usecases/operations.js +111 -0
  814. package/dist/core/usecases/operations.js.map +1 -0
  815. package/dist/core/usecases/place.js +44 -0
  816. package/dist/core/usecases/place.js.map +1 -0
  817. package/dist/core/usecases/touch.js +101 -0
  818. package/dist/core/usecases/touch.js.map +1 -0
  819. package/dist/core/verify/answers.js +173 -0
  820. package/dist/core/verify/answers.js.map +1 -0
  821. package/dist/core/verify/build.js +150 -0
  822. package/dist/core/verify/build.js.map +1 -0
  823. package/dist/core/verify/checklist.js +201 -0
  824. package/dist/core/verify/checklist.js.map +1 -0
  825. package/dist/core/verify/claims/identity.js +61 -0
  826. package/dist/core/verify/claims/identity.js.map +1 -0
  827. package/dist/core/verify/cross/diff.js +97 -0
  828. package/dist/core/verify/cross/diff.js.map +1 -0
  829. package/dist/core/verify/evidence/contract.js +169 -0
  830. package/dist/core/verify/evidence/contract.js.map +1 -0
  831. package/dist/core/verify/file.js +257 -0
  832. package/dist/core/verify/file.js.map +1 -0
  833. package/dist/core/verify/pins/lint.js +157 -0
  834. package/dist/core/verify/pins/lint.js.map +1 -0
  835. package/dist/core/verify/pins/pin.js +95 -0
  836. package/dist/core/verify/pins/pin.js.map +1 -0
  837. package/dist/core/verify/record.js +142 -0
  838. package/dist/core/verify/record.js.map +1 -0
  839. package/dist/core/verify/store/commit.js +89 -0
  840. package/dist/core/verify/store/commit.js.map +1 -0
  841. package/dist/core/verify/store/render.js +57 -0
  842. package/dist/core/verify/store/render.js.map +1 -0
  843. package/dist/core/vocabulary/health.js +91 -0
  844. package/dist/core/vocabulary/health.js.map +1 -0
  845. package/dist/core/vocabulary/issue.js +58 -0
  846. package/dist/core/vocabulary/issue.js.map +1 -0
  847. package/dist/core/vocabulary/maturity.js +145 -0
  848. package/dist/core/vocabulary/maturity.js.map +1 -0
  849. package/dist/core/{report.js → vocabulary/report.js} +30 -2
  850. package/dist/core/vocabulary/report.js.map +1 -0
  851. package/dist/core/vocabulary/steps.js +266 -0
  852. package/dist/core/vocabulary/steps.js.map +1 -0
  853. package/dist/core/workspace/discover.js +239 -0
  854. package/dist/core/workspace/discover.js.map +1 -0
  855. package/dist/core/workspace/render.js +52 -0
  856. package/dist/core/workspace/render.js.map +1 -0
  857. package/examples/README.md +189 -0
  858. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  859. package/examples/docs/architecture/capabilities.yaml +31 -0
  860. package/examples/docs/architecture/landscape.likec4 +280 -0
  861. package/examples/docs/architecture/obligations.yaml +23 -0
  862. package/examples/docs/architecture/permissions.yaml +50 -0
  863. package/examples/docs/architecture/subsystems.likec4 +11 -0
  864. package/examples/docs/architecture/usecases/order-notification.likec4 +65 -0
  865. package/examples/docs/capabilities/checkout/spec.md +55 -0
  866. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  867. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  868. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  869. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  870. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  871. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  872. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +129 -0
  873. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  874. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  875. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  876. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  877. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  878. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +28 -0
  879. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  880. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  881. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  882. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  883. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  884. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  885. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  886. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  887. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  888. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  889. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +70 -0
  890. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  891. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  892. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  893. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  894. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  895. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  896. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  897. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  898. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  899. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  900. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  901. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  902. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  903. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  904. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  905. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  906. package/examples/docs/glossary/order.md +15 -0
  907. package/examples/docs/glossary/payments/authorization.md +14 -0
  908. package/examples/docs/likec4.config.json +9 -0
  909. package/examples/docs/loam.json +3 -0
  910. package/examples/docs/services/checkout-web/model.likec4 +109 -0
  911. package/examples/docs/services/checkout-web/spec.md +91 -0
  912. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  913. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  914. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  915. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  916. package/examples/docs/services/order-service/arch.spec.md +127 -0
  917. package/examples/docs/services/order-service/asyncapi.yaml +108 -0
  918. package/examples/docs/services/order-service/health.yaml +57 -0
  919. package/examples/docs/services/order-service/model.likec4 +138 -0
  920. package/examples/docs/services/order-service/openapi.yaml +257 -0
  921. package/examples/docs/services/order-service/runbook.md +62 -0
  922. package/examples/docs/services/order-service/spec.md +134 -0
  923. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  924. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  925. package/examples/docs/services/payment-service/arch.spec.md +73 -0
  926. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  927. package/examples/docs/services/payment-service/health.yaml +39 -0
  928. package/examples/docs/services/payment-service/model.likec4 +67 -0
  929. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  930. package/examples/docs/services/payment-service/runbook.md +37 -0
  931. package/examples/docs/services/payment-service/spec.md +88 -0
  932. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  933. package/examples/docs/services/platform/identity-service/arch.spec.md +117 -0
  934. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  935. package/examples/docs/services/platform/identity-service/model.likec4 +83 -0
  936. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  937. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  938. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  939. package/examples/docs/services/platform/notification-service/asyncapi.yaml +199 -0
  940. package/examples/docs/services/platform/notification-service/health.yaml +35 -0
  941. package/examples/docs/services/platform/notification-service/model.likec4 +118 -0
  942. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  943. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  944. package/examples/docs/services/platform/subsystem.yaml +2 -0
  945. package/examples/fleet.yaml +57 -0
  946. package/package.json +19 -6
  947. package/dist/commands/adopt.js +0 -240
  948. package/dist/commands/adopt.js.map +0 -1
  949. package/dist/commands/archive.js +0 -1313
  950. package/dist/commands/archive.js.map +0 -1
  951. package/dist/commands/delta.js +0 -388
  952. package/dist/commands/delta.js.map +0 -1
  953. package/dist/commands/docs-repo-gate.js.map +0 -1
  954. package/dist/commands/format.js +0 -17
  955. package/dist/commands/format.js.map +0 -1
  956. package/dist/commands/gherkin.js +0 -309
  957. package/dist/commands/gherkin.js.map +0 -1
  958. package/dist/commands/init.js.map +0 -1
  959. package/dist/commands/list.js +0 -295
  960. package/dist/commands/list.js.map +0 -1
  961. package/dist/commands/migrate-openspec.js +0 -950
  962. package/dist/commands/migrate-openspec.js.map +0 -1
  963. package/dist/commands/new.js +0 -413
  964. package/dist/commands/new.js.map +0 -1
  965. package/dist/commands/rebase.js +0 -356
  966. package/dist/commands/rebase.js.map +0 -1
  967. package/dist/commands/show.js.map +0 -1
  968. package/dist/commands/status.js +0 -262
  969. package/dist/commands/status.js.map +0 -1
  970. package/dist/commands/unarchive.js.map +0 -1
  971. package/dist/commands/validate.js +0 -1773
  972. package/dist/commands/validate.js.map +0 -1
  973. package/dist/commands/verify.js +0 -775
  974. package/dist/commands/verify.js.map +0 -1
  975. package/dist/commands/vouch.js +0 -421
  976. package/dist/commands/vouch.js.map +0 -1
  977. package/dist/core/agent.js +0 -2173
  978. package/dist/core/agent.js.map +0 -1
  979. package/dist/core/agents-stamp.js.map +0 -1
  980. package/dist/core/arch.js +0 -130
  981. package/dist/core/arch.js.map +0 -1
  982. package/dist/core/asyncapi.js.map +0 -1
  983. package/dist/core/brief.js +0 -755
  984. package/dist/core/brief.js.map +0 -1
  985. package/dist/core/coherence.js +0 -577
  986. package/dist/core/coherence.js.map +0 -1
  987. package/dist/core/concurrency.js.map +0 -1
  988. package/dist/core/config.js.map +0 -1
  989. package/dist/core/delta.js +0 -476
  990. package/dist/core/delta.js.map +0 -1
  991. package/dist/core/dependencies.js +0 -356
  992. package/dist/core/dependencies.js.map +0 -1
  993. package/dist/core/doctor.js +0 -596
  994. package/dist/core/doctor.js.map +0 -1
  995. package/dist/core/document-bytes.js.map +0 -1
  996. package/dist/core/explore.js.map +0 -1
  997. package/dist/core/frontmatter.js.map +0 -1
  998. package/dist/core/gherkin.js +0 -463
  999. package/dist/core/gherkin.js.map +0 -1
  1000. package/dist/core/health.js +0 -67
  1001. package/dist/core/health.js.map +0 -1
  1002. package/dist/core/ids.js +0 -122
  1003. package/dist/core/ids.js.map +0 -1
  1004. package/dist/core/issue.js +0 -9
  1005. package/dist/core/issue.js.map +0 -1
  1006. package/dist/core/json.js +0 -74
  1007. package/dist/core/json.js.map +0 -1
  1008. package/dist/core/likec4.js +0 -489
  1009. package/dist/core/likec4.js.map +0 -1
  1010. package/dist/core/maturity.js +0 -66
  1011. package/dist/core/maturity.js.map +0 -1
  1012. package/dist/core/openapi-merge.js +0 -552
  1013. package/dist/core/openapi-merge.js.map +0 -1
  1014. package/dist/core/openapi.js.map +0 -1
  1015. package/dist/core/openspec-inventory.js +0 -1440
  1016. package/dist/core/openspec-inventory.js.map +0 -1
  1017. package/dist/core/path-safety.js.map +0 -1
  1018. package/dist/core/provenance.js +0 -787
  1019. package/dist/core/provenance.js.map +0 -1
  1020. package/dist/core/records.js.map +0 -1
  1021. package/dist/core/repo.js +0 -438
  1022. package/dist/core/repo.js.map +0 -1
  1023. package/dist/core/report.js.map +0 -1
  1024. package/dist/core/spec.js +0 -505
  1025. package/dist/core/spec.js.map +0 -1
  1026. package/dist/core/staging.js +0 -890
  1027. package/dist/core/staging.js.map +0 -1
  1028. package/dist/core/status.js +0 -1132
  1029. package/dist/core/status.js.map +0 -1
  1030. package/dist/core/steps.js +0 -72
  1031. package/dist/core/steps.js.map +0 -1
  1032. package/dist/core/verify.js +0 -807
  1033. package/dist/core/verify.js.map +0 -1
  1034. package/dist/core/version.js.map +0 -1
  1035. /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
  1036. /package/dist/core/{records.js → kernel/records.js} +0 -0
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Is this migration ready, and what does the answer look like?
3
+ *
4
+ * Readiness is one judgement over everything the scan and the decisions found,
5
+ * and it lives in one function so the six conditions can be read together. Five
6
+ * of them are human decisions and the sixth is the corpus itself; a migration
7
+ * that satisfied five of six used to read as "nearly ready", which is not a
8
+ * state `--apply` may act on.
9
+ *
10
+ * The per-axis `readiness` block exists so an agent can say WHICH of the six is
11
+ * open without re-deriving it from the issue list — the same information, but
12
+ * the derivation is here rather than in every reader.
13
+ */
14
+ import { compareIds } from "../../repo/entries.js";
15
+ import {} from "../model/mapping.js";
16
+ import { OPENSPEC_BASELINES, } from "../model/model.js";
17
+ import { sortIssues } from "../scan/changes.js";
18
+ export function inventoryVerdict(found) {
19
+ const { located, inventoryDigest, config, storeMetadataPath, livingCounts, capabilities, active, archived, renamed, blockers, archiveDiagnostics, artifacts, mappingDecisions, changeDecisions, mappingIssues, artifactDecisions, } = found;
20
+ const { inputRoot, root } = located;
21
+ mappingIssues.sort((a, b) => compareIds(a.key, b.key) || compareIds(a.code, b.code));
22
+ renamed.sort((a, b) => compareIds(a.path, b.path) || a.line - b.line || compareIds(a.key, b.key));
23
+ sortIssues(blockers);
24
+ sortIssues(archiveDiagnostics);
25
+ const livingIssueCount = blockers.filter((item) => item.scope === "workspace" || item.scope === "living").length;
26
+ const activeIssueCount = blockers.filter((item) => item.scope === "active").length;
27
+ const needsMapping = mappingDecisions.filter((decision) => decision.status === "needsMapping");
28
+ const needsChangeMapping = changeDecisions.filter((decision) => decision.status === "needsFeature");
29
+ const needsDisposition = artifactDecisions.filter((decision) => decision.status === "needsDisposition");
30
+ const unresolvedActiveRenames = renamed.filter((rename) => rename.scope === "active" && rename.status === "needsIdentity");
31
+ const mechanicallyCompatible = livingIssueCount === 0 && activeIssueCount === 0;
32
+ const ready = mechanicallyCompatible
33
+ && needsMapping.length === 0
34
+ && needsChangeMapping.length === 0
35
+ && unresolvedActiveRenames.length === 0
36
+ && needsDisposition.length === 0
37
+ && mappingIssues.length === 0;
38
+ return {
39
+ baselines: OPENSPEC_BASELINES,
40
+ inputRoot,
41
+ root,
42
+ inventoryDigest,
43
+ workspace: {
44
+ kind: located.kind,
45
+ config,
46
+ storeMetadataPath,
47
+ },
48
+ ready,
49
+ mechanicallyCompatible,
50
+ readiness: {
51
+ living: { compatible: livingIssueCount === 0, issueCount: livingIssueCount },
52
+ active: { compatible: activeIssueCount === 0, issueCount: activeIssueCount },
53
+ sourceCurrent: !mappingIssues.some((item) => item.code.startsWith("mapping.source-")),
54
+ mappingsResolved: needsMapping.length === 0 && !mappingIssues.some((item) => item.code === "mapping.unknown-capability"
55
+ || item.code === "mapping.unknown-requirement"
56
+ || item.code.startsWith("mapping.requirement-")
57
+ || item.code === "mapping.service-allocation-empty"),
58
+ changesResolved: needsChangeMapping.length === 0 && !mappingIssues.some((item) => item.code === "mapping.unknown-change"
59
+ || item.code === "mapping.change-title-missing"
60
+ || item.code.startsWith("mapping.feature-id-")),
61
+ renamesResolved: unresolvedActiveRenames.length === 0 && !mappingIssues.some((item) => item.code.includes("rename") || item.code.includes("requirement-id")),
62
+ dispositionsResolved: needsDisposition.length === 0 && !mappingIssues.some((item) => item.code.includes("artifact")),
63
+ migrationReady: ready,
64
+ },
65
+ living: { ...livingCounts, capabilities },
66
+ changes: {
67
+ active,
68
+ archived,
69
+ counts: { active: active.length, archived: archived.length },
70
+ },
71
+ renamed,
72
+ unsupported: blockers,
73
+ archiveDiagnostics,
74
+ mappingDecisions,
75
+ needsMapping,
76
+ changeDecisions,
77
+ needsChangeMapping,
78
+ mappingIssues,
79
+ artifacts,
80
+ artifactDecisions,
81
+ needsDisposition,
82
+ };
83
+ }
84
+ //# sourceMappingURL=verdict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict.js","sourceRoot":"","sources":["../../../../src/core/openspec/decide/verdict.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Is this migration ready, and what does the answer look like?\n *\n * Readiness is one judgement over everything the scan and the decisions found,\n * and it lives in one function so the six conditions can be read together. Five\n * of them are human decisions and the sixth is the corpus itself; a migration\n * that satisfied five of six used to read as \"nearly ready\", which is not a\n * state `--apply` may act on.\n *\n * The per-axis `readiness` block exists so an agent can say WHICH of the six is\n * open without re-deriving it from the issue list — the same information, but\n * the derivation is here rather than in every reader.\n */\nimport { compareIds } from \"../../repo/entries.js\";\nimport {\n type OpenSpecMapping,\n type CapabilityMappingDecision,\n type OpenSpecChangeDecision,\n type OpenSpecMappingIssue,\n} from \"../model/mapping.js\";\nimport {\n OPENSPEC_BASELINES,\n type OpenSpecArtifact,\n type OpenSpecArtifactDecision,\n type OpenSpecCapability,\n type OpenSpecChange,\n type OpenSpecCounts,\n type OpenSpecInventory,\n type OpenSpecRenamedUsage,\n type OpenSpecUnsupportedShape,\n} from \"../model/model.js\";\nimport { sortIssues } from \"../scan/changes.js\";\n\n/** Everything a finished read produced, before it is graded into a verdict. */\nexport interface Findings {\n located: { inputRoot: string; root: string; kind: OpenSpecInventory[\"workspace\"][\"kind\"] };\n mapping: OpenSpecMapping;\n inventoryDigest: string;\n config: OpenSpecInventory[\"workspace\"][\"config\"];\n storeMetadataPath: string | null;\n livingCounts: OpenSpecCounts;\n capabilities: OpenSpecCapability[];\n active: OpenSpecChange[];\n archived: OpenSpecChange[];\n renamed: OpenSpecRenamedUsage[];\n blockers: OpenSpecUnsupportedShape[];\n archiveDiagnostics: OpenSpecUnsupportedShape[];\n artifacts: OpenSpecArtifact[];\n mappingDecisions: CapabilityMappingDecision[];\n changeDecisions: OpenSpecChangeDecision[];\n mappingIssues: OpenSpecMappingIssue[];\n artifactDecisions: OpenSpecArtifactDecision[];\n}\n\nexport function inventoryVerdict(found: Findings): OpenSpecInventory {\n const {\n located, inventoryDigest, config, storeMetadataPath, livingCounts, capabilities,\n active, archived, renamed, blockers, archiveDiagnostics, artifacts,\n mappingDecisions, changeDecisions, mappingIssues, artifactDecisions,\n } = found;\n const { inputRoot, root } = located;\n mappingIssues.sort((a, b) => compareIds(a.key, b.key) || compareIds(a.code, b.code));\n\n renamed.sort((a, b) => compareIds(a.path, b.path) || a.line - b.line || compareIds(a.key, b.key));\n sortIssues(blockers);\n sortIssues(archiveDiagnostics);\n const livingIssueCount = blockers.filter((item) => item.scope === \"workspace\" || item.scope === \"living\").length;\n const activeIssueCount = blockers.filter((item) => item.scope === \"active\").length;\n const needsMapping = mappingDecisions.filter((decision) => decision.status === \"needsMapping\");\n const needsChangeMapping = changeDecisions.filter((decision) => decision.status === \"needsFeature\");\n const needsDisposition = artifactDecisions.filter((decision) => decision.status === \"needsDisposition\");\n const unresolvedActiveRenames = renamed.filter(\n (rename) => rename.scope === \"active\" && rename.status === \"needsIdentity\",\n );\n const mechanicallyCompatible = livingIssueCount === 0 && activeIssueCount === 0;\n const ready = mechanicallyCompatible\n && needsMapping.length === 0\n && needsChangeMapping.length === 0\n && unresolvedActiveRenames.length === 0\n && needsDisposition.length === 0\n && mappingIssues.length === 0;\n\n return {\n baselines: OPENSPEC_BASELINES,\n inputRoot,\n root,\n inventoryDigest,\n workspace: {\n kind: located.kind,\n config,\n storeMetadataPath,\n },\n ready,\n mechanicallyCompatible,\n readiness: {\n living: { compatible: livingIssueCount === 0, issueCount: livingIssueCount },\n active: { compatible: activeIssueCount === 0, issueCount: activeIssueCount },\n sourceCurrent: !mappingIssues.some((item) => item.code.startsWith(\"mapping.source-\")),\n mappingsResolved: needsMapping.length === 0 && !mappingIssues.some((item) =>\n item.code === \"mapping.unknown-capability\"\n || item.code === \"mapping.unknown-requirement\"\n || item.code.startsWith(\"mapping.requirement-\")\n || item.code === \"mapping.service-allocation-empty\"),\n changesResolved: needsChangeMapping.length === 0 && !mappingIssues.some((item) =>\n item.code === \"mapping.unknown-change\"\n || item.code === \"mapping.change-title-missing\"\n || item.code.startsWith(\"mapping.feature-id-\")),\n renamesResolved: unresolvedActiveRenames.length === 0 && !mappingIssues.some((item) => item.code.includes(\"rename\") || item.code.includes(\"requirement-id\")),\n dispositionsResolved: needsDisposition.length === 0 && !mappingIssues.some((item) => item.code.includes(\"artifact\")),\n migrationReady: ready,\n },\n living: { ...livingCounts, capabilities },\n changes: {\n active,\n archived,\n counts: { active: active.length, archived: archived.length },\n },\n renamed,\n unsupported: blockers,\n archiveDiagnostics,\n mappingDecisions,\n needsMapping,\n changeDecisions,\n needsChangeMapping,\n mappingIssues,\n artifacts,\n artifactDecisions,\n needsDisposition,\n };\n}\n"]}
@@ -0,0 +1,221 @@
1
+ /**
2
+ * One whole OpenSpec workspace, read and graded in one pass.
3
+ *
4
+ * The order below is the contract: everything is SCANNED before anything is
5
+ * DECIDED, because a decision graded against a half-read corpus is worse than
6
+ * no decision — it reads as reviewed. So this module locates the root, walks
7
+ * it, reads every document through `./scan/`, and only then hands the result to
8
+ * `./decide/`, which is the half a human's mapping can change.
9
+ *
10
+ * The digest is taken over the non-archive artifacts only. It binds a mapping
11
+ * to the truth it was reviewed against, and frozen archive history is neither
12
+ * migrated nor allowed to block readiness — covering it meant a colleague's typo
13
+ * fix under `changes/archive/` killed a completed mapping, with no `--force` and
14
+ * no indication of which file had moved.
15
+ */
16
+ import { isUtf8 } from "node:buffer";
17
+ import { existsSync } from "node:fs";
18
+ import { readFile } from "node:fs/promises";
19
+ import { basename, dirname, join } from "node:path";
20
+ import { compareIds } from "../repo/entries.js";
21
+ import { parseRequirements } from "../document/parse.js";
22
+ import { emptyMapping } from "./model/mapping.js";
23
+ import {} from "./model/model.js";
24
+ import { locateOpenSpecRoot } from "./scan/workspace.js";
25
+ import { digestInventory, hiddenSubdirs, isSymbolicLink, portable, sourceInventoryPath, subdirs, walkFiles, walkSymlinks, } from "./scan/walk.js";
26
+ import { inspectSpecFile, issue } from "./scan/shape.js";
27
+ import { inspectConfig } from "./scan/config.js";
28
+ import { artifactFor, artifactScope, inventoryChanges } from "./scan/changes.js";
29
+ import { capabilityDecisions } from "./decide/capabilities.js";
30
+ import { resolveRenames } from "./decide/renames.js";
31
+ import { artifactDispositions } from "./decide/dispositions.js";
32
+ import { inventoryVerdict } from "./decide/verdict.js";
33
+ import { isDirectory } from "./scan/walk.js";
34
+ import { addCounts } from "./scan/shape.js";
35
+ import {} from "./model/model.js";
36
+ export async function inventoryOpenSpec(input, options = {}) {
37
+ const located = await locateOpenSpecRoot(input);
38
+ const { inputRoot, root } = located;
39
+ const mapping = emptyMapping(options.mapping);
40
+ const renamed = [];
41
+ const blockers = [];
42
+ // The read in progress. Every reader below appends to these two lists rather
43
+ // than returning findings, because the ORDER they land in is what the `--json`
44
+ // contract pins — five arrays merged afterwards would be a different report.
45
+ const ingest = { root, mapping, renamed, unsupported: blockers };
46
+ const archiveDiagnostics = [];
47
+ for (const absolute of await walkSymlinks(root)) {
48
+ const path = portable(root, absolute);
49
+ const scope = artifactScope(path);
50
+ issue(scope === "archive" ? archiveDiagnostics : blockers, scope, {
51
+ code: "openspec.symlink-unsupported",
52
+ path: path,
53
+ message: "Symbolic links are not followed by migration inventory; replace this link with an in-tree regular file or directory.",
54
+ });
55
+ }
56
+ const config = await inspectConfig(root, blockers);
57
+ const specsRoot = join(root, "specs");
58
+ const changesRoot = join(root, "changes");
59
+ const inputStoreMetadata = join(inputRoot, ".openspec-store", "store.yaml");
60
+ const parentStoreMetadata = basename(root) === "openspec"
61
+ ? join(dirname(root), ".openspec-store", "store.yaml")
62
+ : inputStoreMetadata;
63
+ const storeMetadata = existsSync(inputStoreMetadata) ? inputStoreMetadata : parentStoreMetadata;
64
+ const storeMetadataExists = existsSync(storeMetadata);
65
+ const storeMetadataSymlink = storeMetadataExists && await isSymbolicLink(storeMetadata);
66
+ if (storeMetadataSymlink) {
67
+ issue(blockers, "workspace", {
68
+ code: "openspec.symlink-unsupported",
69
+ path: sourceInventoryPath(root, storeMetadata),
70
+ message: "Symbolic Store metadata is not followed; replace it with an in-tree regular file.",
71
+ });
72
+ }
73
+ const hasModernEmptyShape = config !== null || (storeMetadataExists && !storeMetadataSymlink);
74
+ if (!await isDirectory(specsRoot) && !hasModernEmptyShape) {
75
+ issue(blockers, "living", {
76
+ code: "openspec.specs-missing",
77
+ path: "specs",
78
+ message: "Living specs/ directory is missing.",
79
+ });
80
+ }
81
+ if (config !== null && config.store !== null && !await isDirectory(specsRoot) && !await isDirectory(changesRoot)) {
82
+ issue(blockers, "workspace", {
83
+ code: "openspec.external-store-pointer",
84
+ path: "config.yaml",
85
+ message: `Planning is externalized to Store '${config.store}'; audit that registered Store checkout directly.`,
86
+ });
87
+ }
88
+ const capabilities = [];
89
+ const livingRequirements = new Map();
90
+ const livingCounts = { specFiles: 0, requirements: 0, scenarios: 0 };
91
+ const livingTree = await walkFiles(specsRoot);
92
+ const livingFiles = livingTree.filter((path) => basename(path) === "spec.md");
93
+ // The living twin of openspec.nonstandard-change-spec. Selecting living specs
94
+ // by exact basename is right, but without the mirror a mis-cased or renamed
95
+ // file simply disappears: specs/payments/Spec.md audited as a clean, empty
96
+ // corpus while the identical shape under a change was reported.
97
+ for (const file of livingTree.filter((path) => /\.md$/i.test(path) && basename(path) !== "spec.md" && basename(path) !== "design.md")) {
98
+ blockers.push({
99
+ code: "openspec.nonstandard-living-spec",
100
+ path: portable(root, file),
101
+ message: "Markdown under specs/ is named neither spec.md nor design.md, so no capability reads it.",
102
+ scope: "living",
103
+ });
104
+ }
105
+ for (const specFile of livingFiles) {
106
+ const id = portable(specsRoot, dirname(specFile));
107
+ const inspected = await inspectSpecFile(ingest, specFile, "living", null);
108
+ livingRequirements.set(id, inspected.requirements);
109
+ const capability = { id, files: [inspected.path], ...inspected.counts };
110
+ capabilities.push(capability);
111
+ addCounts(livingCounts, inspected.counts);
112
+ }
113
+ capabilities.sort((a, b) => compareIds(a.id, b.id));
114
+ const activeIds = (await subdirs(changesRoot)).filter((id) => id !== "archive");
115
+ const archiveRoot = join(changesRoot, "archive");
116
+ const archivedIds = await subdirs(archiveRoot);
117
+ for (const id of await hiddenSubdirs(changesRoot)) {
118
+ blockers.push({
119
+ code: "openspec.hidden-change-directory",
120
+ path: portable(root, join(changesRoot, id)),
121
+ message: "A dot-prefixed change directory is not enumerated as a change, so nothing under it is migrated; rename it or move it out of changes/.",
122
+ scope: "active",
123
+ });
124
+ }
125
+ for (const id of await hiddenSubdirs(archiveRoot)) {
126
+ archiveDiagnostics.push({
127
+ code: "openspec.hidden-change-directory",
128
+ path: portable(root, join(archiveRoot, id)),
129
+ message: "A dot-prefixed archive directory is not enumerated as a change; frozen history is retained read-only where it is.",
130
+ scope: "archive",
131
+ });
132
+ }
133
+ const fallbackSchema = config?.schema ?? "spec-driven";
134
+ const active = await inventoryChanges(ingest, {
135
+ base: changesRoot,
136
+ ids: activeIds,
137
+ scope: "active",
138
+ fallbackSchema,
139
+ findings: blockers,
140
+ });
141
+ const archived = await inventoryChanges(ingest, {
142
+ base: archiveRoot,
143
+ ids: archivedIds,
144
+ scope: "archive",
145
+ fallbackSchema,
146
+ findings: archiveDiagnostics,
147
+ });
148
+ // Last-resort backstop under the whole "audited past the corpus" family, and
149
+ // the one check that does not depend on root selection being right: an
150
+ // inventory that read no living spec AND no active change describes nothing,
151
+ // so no verdict over it can be `ready`. That is exactly the shape the Store
152
+ // misdetection produced — ready, mechanically compatible, zero capabilities,
153
+ // zero unsupported shapes — where the failure verdict was more confident than
154
+ // any success verdict. A greenfield workspace whose only requirements live
155
+ // under changes/ has an active change and is not caught here.
156
+ if (livingCounts.specFiles === 0 && active.length === 0) {
157
+ blockers.push({
158
+ code: "openspec.workspace-empty",
159
+ path: ".",
160
+ message: `Planning root ${root} holds no living spec and no active change; there is nothing to migrate, so confirm this is the directory that really holds the corpus.`,
161
+ scope: "workspace",
162
+ });
163
+ }
164
+ const artifactFiles = await walkFiles(root);
165
+ if (storeMetadataExists && !storeMetadataSymlink && !artifactFiles.includes(storeMetadata)) {
166
+ artifactFiles.push(storeMetadata);
167
+ }
168
+ for (const absolute of artifactFiles) {
169
+ const bytes = await readFile(absolute);
170
+ if (isUtf8(bytes))
171
+ continue;
172
+ const rootPath = portable(root, absolute);
173
+ const artifactPath = sourceInventoryPath(root, absolute);
174
+ const scope = absolute === storeMetadata ? "workspace" : artifactScope(rootPath);
175
+ issue(scope === "archive" ? archiveDiagnostics : blockers, scope, {
176
+ code: "openspec.non-utf8-artifact",
177
+ path: artifactPath,
178
+ message: "Migration can preserve only valid UTF-8 authored artifacts; convert this file to UTF-8 before apply.",
179
+ });
180
+ }
181
+ // The digest binds a mapping to the truth it was reviewed against, and frozen
182
+ // archive history is neither migrated nor allowed to block readiness. Covering
183
+ // it meant a colleague's typo fix under changes/archive/ killed a completed
184
+ // mapping, with no --force and no indication of which file moved.
185
+ const inventoryDigest = await digestInventory(root, artifactFiles.filter((absolute) => artifactScope(portable(root, absolute)) !== "archive"));
186
+ const artifacts = artifactFiles
187
+ .map((path) => artifactFor(root, path))
188
+ .sort((a, b) => compareIds(a.path, b.path));
189
+ const { mappingIssues, mappingDecisions, changeDecisions, routing } = capabilityDecisions({
190
+ root,
191
+ mapping,
192
+ // An audit grades no source binding: there is no mapping to bind yet.
193
+ bound: options.mapping !== undefined,
194
+ inventoryDigest,
195
+ livingRequirements,
196
+ active,
197
+ renamed,
198
+ });
199
+ resolveRenames({ root, mapping, bound: options.mapping !== undefined, inventoryDigest, livingRequirements, active, renamed }, routing, mappingIssues);
200
+ const artifactDecisions = artifactDispositions(artifacts, mapping, new Set(active.map((change) => change.id)), mappingIssues);
201
+ return inventoryVerdict({
202
+ located,
203
+ mapping,
204
+ inventoryDigest,
205
+ config,
206
+ storeMetadataPath: storeMetadataExists ? sourceInventoryPath(root, storeMetadata) : null,
207
+ livingCounts,
208
+ capabilities,
209
+ active,
210
+ archived,
211
+ renamed,
212
+ blockers,
213
+ archiveDiagnostics,
214
+ artifacts,
215
+ mappingDecisions,
216
+ changeDecisions,
217
+ mappingIssues,
218
+ artifactDecisions,
219
+ });
220
+ }
221
+ //# sourceMappingURL=inventory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inventory.js","sourceRoot":"","sources":["../../../src/core/openspec/inventory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One whole OpenSpec workspace, read and graded in one pass.\n *\n * The order below is the contract: everything is SCANNED before anything is\n * DECIDED, because a decision graded against a half-read corpus is worse than\n * no decision — it reads as reviewed. So this module locates the root, walks\n * it, reads every document through `./scan/`, and only then hands the result to\n * `./decide/`, which is the half a human's mapping can change.\n *\n * The digest is taken over the non-archive artifacts only. It binds a mapping\n * to the truth it was reviewed against, and frozen archive history is neither\n * migrated nor allowed to block readiness — covering it meant a colleague's typo\n * fix under `changes/archive/` killed a completed mapping, with no `--force` and\n * no indication of which file had moved.\n */\nimport { isUtf8 } from \"node:buffer\";\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { compareIds } from \"../repo/entries.js\";\nimport { parseRequirements } from \"../document/parse.js\";\nimport { emptyMapping, type OpenSpecMapping } from \"./model/mapping.js\";\nimport { type OpenSpecInventory, type OpenSpecRenamedUsage, type OpenSpecUnsupportedShape } from \"./model/model.js\";\nimport { locateOpenSpecRoot, type Ingest } from \"./scan/workspace.js\";\nimport {\n digestInventory,\n hiddenSubdirs,\n isSymbolicLink,\n portable,\n sourceInventoryPath,\n subdirs,\n walkFiles,\n walkSymlinks,\n} from \"./scan/walk.js\";\nimport { inspectSpecFile, issue } from \"./scan/shape.js\";\nimport { inspectConfig } from \"./scan/config.js\";\nimport { artifactFor, artifactScope, inventoryChanges } from \"./scan/changes.js\";\nimport { capabilityDecisions } from \"./decide/capabilities.js\";\nimport { resolveRenames } from \"./decide/renames.js\";\nimport { artifactDispositions } from \"./decide/dispositions.js\";\nimport { inventoryVerdict } from \"./decide/verdict.js\";\nimport { isDirectory } from \"./scan/walk.js\";\nimport { addCounts } from \"./scan/shape.js\";\nimport { type OpenSpecCapability, type OpenSpecCounts } from \"./model/model.js\";\n\nexport async function inventoryOpenSpec(\n input: string,\n options: { mapping?: OpenSpecMapping } = {},\n): Promise<OpenSpecInventory> {\n const located = await locateOpenSpecRoot(input);\n const { inputRoot, root } = located;\n const mapping = emptyMapping(options.mapping);\n const renamed: OpenSpecRenamedUsage[] = [];\n const blockers: OpenSpecUnsupportedShape[] = [];\n // The read in progress. Every reader below appends to these two lists rather\n // than returning findings, because the ORDER they land in is what the `--json`\n // contract pins — five arrays merged afterwards would be a different report.\n const ingest: Ingest = { root, mapping, renamed, unsupported: blockers };\n const archiveDiagnostics: OpenSpecUnsupportedShape[] = [];\n for (const absolute of await walkSymlinks(root)) {\n const path = portable(root, absolute);\n const scope = artifactScope(path);\n issue(scope === \"archive\" ? archiveDiagnostics : blockers, scope, {\n code: \"openspec.symlink-unsupported\",\n path: path,\n message: \"Symbolic links are not followed by migration inventory; replace this link with an in-tree regular file or directory.\",\n });\n }\n const config = await inspectConfig(root, blockers);\n const specsRoot = join(root, \"specs\");\n const changesRoot = join(root, \"changes\");\n const inputStoreMetadata = join(inputRoot, \".openspec-store\", \"store.yaml\");\n const parentStoreMetadata = basename(root) === \"openspec\"\n ? join(dirname(root), \".openspec-store\", \"store.yaml\")\n : inputStoreMetadata;\n const storeMetadata = existsSync(inputStoreMetadata) ? inputStoreMetadata : parentStoreMetadata;\n const storeMetadataExists = existsSync(storeMetadata);\n const storeMetadataSymlink = storeMetadataExists && await isSymbolicLink(storeMetadata);\n if (storeMetadataSymlink) {\n issue(blockers, \"workspace\", {\n code: \"openspec.symlink-unsupported\",\n path: sourceInventoryPath(root, storeMetadata),\n message: \"Symbolic Store metadata is not followed; replace it with an in-tree regular file.\",\n });\n }\n const hasModernEmptyShape = config !== null || (storeMetadataExists && !storeMetadataSymlink);\n if (!await isDirectory(specsRoot) && !hasModernEmptyShape) {\n issue(blockers, \"living\", {\n code: \"openspec.specs-missing\",\n path: \"specs\",\n message: \"Living specs/ directory is missing.\",\n });\n }\n if (config !== null && config.store !== null && !await isDirectory(specsRoot) && !await isDirectory(changesRoot)) {\n issue(blockers, \"workspace\", {\n code: \"openspec.external-store-pointer\",\n path: \"config.yaml\",\n message: `Planning is externalized to Store '${config.store}'; audit that registered Store checkout directly.`,\n });\n }\n\n const capabilities: OpenSpecCapability[] = [];\n const livingRequirements = new Map<string, ReturnType<typeof parseRequirements>>();\n const livingCounts: OpenSpecCounts = { specFiles: 0, requirements: 0, scenarios: 0 };\n const livingTree = await walkFiles(specsRoot);\n const livingFiles = livingTree.filter((path) => basename(path) === \"spec.md\");\n // The living twin of openspec.nonstandard-change-spec. Selecting living specs\n // by exact basename is right, but without the mirror a mis-cased or renamed\n // file simply disappears: specs/payments/Spec.md audited as a clean, empty\n // corpus while the identical shape under a change was reported.\n for (const file of livingTree.filter((path) =>\n /\\.md$/i.test(path) && basename(path) !== \"spec.md\" && basename(path) !== \"design.md\")) {\n blockers.push({\n code: \"openspec.nonstandard-living-spec\",\n path: portable(root, file),\n message: \"Markdown under specs/ is named neither spec.md nor design.md, so no capability reads it.\",\n scope: \"living\",\n });\n }\n for (const specFile of livingFiles) {\n const id = portable(specsRoot, dirname(specFile));\n const inspected = await inspectSpecFile(ingest, specFile, \"living\", null);\n livingRequirements.set(id, inspected.requirements);\n const capability = { id, files: [inspected.path], ...inspected.counts };\n capabilities.push(capability);\n addCounts(livingCounts, inspected.counts);\n }\n capabilities.sort((a, b) => compareIds(a.id, b.id));\n\n const activeIds = (await subdirs(changesRoot)).filter((id) => id !== \"archive\");\n const archiveRoot = join(changesRoot, \"archive\");\n const archivedIds = await subdirs(archiveRoot);\n for (const id of await hiddenSubdirs(changesRoot)) {\n blockers.push({\n code: \"openspec.hidden-change-directory\",\n path: portable(root, join(changesRoot, id)),\n message: \"A dot-prefixed change directory is not enumerated as a change, so nothing under it is migrated; rename it or move it out of changes/.\",\n scope: \"active\",\n });\n }\n for (const id of await hiddenSubdirs(archiveRoot)) {\n archiveDiagnostics.push({\n code: \"openspec.hidden-change-directory\",\n path: portable(root, join(archiveRoot, id)),\n message: \"A dot-prefixed archive directory is not enumerated as a change; frozen history is retained read-only where it is.\",\n scope: \"archive\",\n });\n }\n const fallbackSchema = config?.schema ?? \"spec-driven\";\n const active = await inventoryChanges(ingest, {\n base: changesRoot,\n ids: activeIds,\n scope: \"active\",\n fallbackSchema,\n findings: blockers,\n });\n const archived = await inventoryChanges(ingest, {\n base: archiveRoot,\n ids: archivedIds,\n scope: \"archive\",\n fallbackSchema,\n findings: archiveDiagnostics,\n });\n\n // Last-resort backstop under the whole \"audited past the corpus\" family, and\n // the one check that does not depend on root selection being right: an\n // inventory that read no living spec AND no active change describes nothing,\n // so no verdict over it can be `ready`. That is exactly the shape the Store\n // misdetection produced — ready, mechanically compatible, zero capabilities,\n // zero unsupported shapes — where the failure verdict was more confident than\n // any success verdict. A greenfield workspace whose only requirements live\n // under changes/ has an active change and is not caught here.\n if (livingCounts.specFiles === 0 && active.length === 0) {\n blockers.push({\n code: \"openspec.workspace-empty\",\n path: \".\",\n message: `Planning root ${root} holds no living spec and no active change; there is nothing to migrate, so confirm this is the directory that really holds the corpus.`,\n scope: \"workspace\",\n });\n }\n\n const artifactFiles = await walkFiles(root);\n if (storeMetadataExists && !storeMetadataSymlink && !artifactFiles.includes(storeMetadata)) {\n artifactFiles.push(storeMetadata);\n }\n for (const absolute of artifactFiles) {\n const bytes = await readFile(absolute);\n if (isUtf8(bytes)) continue;\n const rootPath = portable(root, absolute);\n const artifactPath = sourceInventoryPath(root, absolute);\n const scope = absolute === storeMetadata ? \"workspace\" : artifactScope(rootPath);\n issue(scope === \"archive\" ? archiveDiagnostics : blockers, scope, {\n code: \"openspec.non-utf8-artifact\",\n path: artifactPath,\n message: \"Migration can preserve only valid UTF-8 authored artifacts; convert this file to UTF-8 before apply.\",\n });\n }\n // The digest binds a mapping to the truth it was reviewed against, and frozen\n // archive history is neither migrated nor allowed to block readiness. Covering\n // it meant a colleague's typo fix under changes/archive/ killed a completed\n // mapping, with no --force and no indication of which file moved.\n const inventoryDigest = await digestInventory(\n root,\n artifactFiles.filter((absolute) => artifactScope(portable(root, absolute)) !== \"archive\"),\n );\n const artifacts = artifactFiles\n .map((path) => artifactFor(root, path))\n .sort((a, b) => compareIds(a.path, b.path));\n\n const { mappingIssues, mappingDecisions, changeDecisions, routing } = capabilityDecisions({\n root,\n mapping,\n // An audit grades no source binding: there is no mapping to bind yet.\n bound: options.mapping !== undefined,\n inventoryDigest,\n livingRequirements,\n active,\n renamed,\n });\n resolveRenames(\n { root, mapping, bound: options.mapping !== undefined, inventoryDigest, livingRequirements, active, renamed },\n routing,\n mappingIssues,\n );\n const artifactDecisions = artifactDispositions(\n artifacts,\n mapping,\n new Set(active.map((change) => change.id)),\n mappingIssues,\n );\n\n return inventoryVerdict({\n located,\n mapping,\n inventoryDigest,\n config,\n storeMetadataPath: storeMetadataExists ? sourceInventoryPath(root, storeMetadata) : null,\n livingCounts,\n capabilities,\n active,\n archived,\n renamed,\n blockers,\n archiveDiagnostics,\n artifacts,\n mappingDecisions,\n changeDecisions,\n mappingIssues,\n artifactDecisions,\n });\n}\n"]}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The human decisions an audit asks for, and the blank form it hands over.
3
+ *
4
+ * Separate from `./model.ts` because these are the only shapes a PERSON edits.
5
+ * The skeleton is generated from a finished inventory rather than from the
6
+ * workspace, so every slot in it is a decision the audit actually reached — a
7
+ * form with a field nothing grades is a form somebody fills in for nothing.
8
+ */
9
+ import { dictionary } from "../../kernel/records.js";
10
+ import {} from "./model.js";
11
+ import {} from "./model.js";
12
+ export function emptyMapping(mapping) {
13
+ if (mapping === undefined) {
14
+ return {
15
+ source: null,
16
+ capabilities: dictionary(),
17
+ changes: dictionary(),
18
+ renames: dictionary(),
19
+ artifacts: dictionary(),
20
+ };
21
+ }
22
+ // Keep the core inventory tolerant of programmatic v0 callers while the CLI
23
+ // parser enforces the complete v1 document, including explicit `changes`.
24
+ return {
25
+ source: mapping.source ?? null,
26
+ capabilities: mapping.capabilities ?? dictionary(),
27
+ changes: mapping.changes ?? dictionary(),
28
+ renames: mapping.renames ?? dictionary(),
29
+ artifacts: mapping.artifacts ?? dictionary(),
30
+ };
31
+ }
32
+ export function createOpenSpecMappingSkeleton(inventory) {
33
+ return {
34
+ version: 1,
35
+ source: { root: inventory.root, inventoryDigest: inventory.inventoryDigest },
36
+ capabilities: Object.fromEntries(inventory.mappingDecisions.map((decision) => [
37
+ decision.capability,
38
+ {
39
+ services: decision.services,
40
+ suggestedServices: [decision.suggestedService],
41
+ requirementServices: decision.requirementServices,
42
+ },
43
+ ])),
44
+ changes: Object.fromEntries(inventory.changeDecisions.map((decision) => [
45
+ decision.change,
46
+ {
47
+ feature: null,
48
+ suggestedFeature: decision.suggestedFeature,
49
+ title: decision.title,
50
+ },
51
+ ])),
52
+ renames: Object.fromEntries(inventory.renamed
53
+ .filter((rename) => rename.scope === "active")
54
+ .map((rename) => [rename.key, {
55
+ from: rename.from,
56
+ to: rename.to,
57
+ existingRequirementId: rename.existingRequirementId,
58
+ // The identity the inventory settled on, which is the field the
59
+ // skeleton is asking a human to fill in. `existingRequirementId` is
60
+ // the living source's own id and happens to equal it on the only path
61
+ // that reaches here today — but a caller that audits WITH a mapping
62
+ // would have a settled id and no existing one, and the skeleton would
63
+ // hand that decision back as unmade.
64
+ requirementId: rename.requirementId,
65
+ }])),
66
+ artifacts: Object.fromEntries(inventory.artifactDecisions.map((decision) => [
67
+ decision.path,
68
+ {
69
+ kind: decision.kind,
70
+ disposition: null,
71
+ suggestedDisposition: decision.suggestedDisposition,
72
+ },
73
+ ])),
74
+ };
75
+ }
76
+ //# sourceMappingURL=mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapping.js","sourceRoot":"","sources":["../../../../src/core/openspec/model/mapping.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAA0B,MAAM,YAAY,CAAC;AACpD,OAAO,EAAoC,MAAM,YAAY,CAAC;AA4G9D,MAAM,UAAU,YAAY,CAAC,OAAyB;IACpD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,UAAU,EAAE;YAC1B,OAAO,EAAE,UAAU,EAAE;YACrB,OAAO,EAAE,UAAU,EAAE;YACrB,SAAS,EAAE,UAAU,EAAE;SACxB,CAAC;IACJ,CAAC;IACD,4EAA4E;IAC5E,0EAA0E;IAC1E,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI;QAC9B,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,UAAU,EAAE;QAClD,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,UAAU,EAAE;QACxC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,UAAU,EAAE;QACxC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,UAAU,EAAE;KAC7C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,SAA4B;IACxE,OAAO;QACL,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,eAAe,EAAE,SAAS,CAAC,eAAe,EAAE;QAC5E,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC5E,QAAQ,CAAC,UAAU;YACnB;gBACE,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,iBAAiB,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBAC9C,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB;aAClD;SACF,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;YACtE,QAAQ,CAAC,MAAM;YACf;gBACE,OAAO,EAAE,IAAI;gBACb,gBAAgB,EAAE,QAAQ,CAAC,gBAAgB;gBAC3C,KAAK,EAAE,QAAQ,CAAC,KAAK;aACtB;SACF,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,CAAC,WAAW,CACzB,SAAS,CAAC,OAAO;aACd,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC;aAC7C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE;gBAC5B,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;gBACnD,gEAAgE;gBAChE,oEAAoE;gBACpE,sEAAsE;gBACtE,oEAAoE;gBACpE,sEAAsE;gBACtE,qCAAqC;gBACrC,aAAa,EAAE,MAAM,CAAC,aAAa;aACpC,CAAC,CAAC,CACN;QACD,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC1E,QAAQ,CAAC,IAAI;YACb;gBACE,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,WAAW,EAAE,IAAI;gBACjB,oBAAoB,EAAE,QAAQ,CAAC,oBAAoB;aACpD;SACF,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC","sourcesContent":["/**\n * The human decisions an audit asks for, and the blank form it hands over.\n *\n * Separate from `./model.ts` because these are the only shapes a PERSON edits.\n * The skeleton is generated from a finished inventory rather than from the\n * workspace, so every slot in it is a decision the audit actually reached — a\n * form with a field nothing grades is a form somebody fills in for nothing.\n */\nimport { dictionary } from \"../../kernel/records.js\";\nimport { type OpenSpecInventory } from \"./model.js\";\nimport { type OpenSpecArtifactDisposition } from \"./model.js\";\n\nexport interface CapabilityMappingDecision {\n capability: string;\n /** Backward-compatible convenience for consumers that only understand one owner. */\n service: string | null;\n /** One capability may need to be split across multiple loam services. */\n services: string[];\n /** Required only when a capability is split across more than one service. */\n requirementServices: Record<string, string[]>;\n suggestedService: string;\n hasLivingSpec: boolean;\n activeChanges: string[];\n status: \"needsMapping\" | \"mapped\";\n}\n\nexport interface OpenSpecCapabilityMapping {\n services: string[];\n requirementServices: Record<string, string[]>;\n}\n\nexport interface OpenSpecChangeMapping {\n feature: string | null;\n title: string;\n}\n\nexport interface OpenSpecChangeDecision {\n change: string;\n feature: string | null;\n title: string;\n suggestedFeature: string;\n suggestedTitle: string;\n status: \"needsFeature\" | \"mapped\";\n}\n\nexport interface OpenSpecMapping {\n source: { root: string; inventoryDigest: string } | null;\n capabilities: Record<string, OpenSpecCapabilityMapping>;\n changes: Record<string, OpenSpecChangeMapping>;\n renames: Record<string, string>;\n /**\n * Whatever a human wrote, not what the type wishes they had written. Declaring\n * this as the disposition union meant the parser had to assert its way into\n * it, so an unrecognised disposition arrived typed as a valid one and only\n * `mapping.invalid-artifact-disposition` — a check downstream of the parse —\n * stood between it and code comparing it against a literal. The union is\n * recovered where it is needed, through `isOpenSpecArtifactDisposition`.\n */\n artifacts: Record<string, string>;\n}\n\nexport interface OpenSpecMappingIssue {\n code:\n | \"mapping.source-missing\"\n | \"mapping.source-root-mismatch\"\n | \"mapping.source-digest-mismatch\"\n | \"mapping.unknown-capability\"\n | \"mapping.unknown-requirement\"\n | \"mapping.requirement-allocation-missing\"\n | \"mapping.requirement-service-unknown\"\n | \"mapping.service-allocation-empty\"\n | \"mapping.unknown-change\"\n | \"mapping.change-title-missing\"\n | \"mapping.feature-id-invalid\"\n | \"mapping.feature-id-duplicate\"\n | \"mapping.unknown-rename\"\n | \"mapping.invalid-requirement-id\"\n | \"mapping.rename-source-missing\"\n | \"mapping.rename-source-ambiguous\"\n | \"mapping.rename-source-id-invalid\"\n | \"mapping.rename-target-conflict\"\n | \"mapping.rename-existing-id-conflict\"\n | \"mapping.rename-id-conflict\"\n | \"mapping.rename-double-source\"\n | \"mapping.rename-double-target\"\n | \"mapping.rename-chain\"\n | \"mapping.unknown-artifact\"\n | \"mapping.invalid-artifact-disposition\";\n key: string;\n message: string;\n}\n\nexport interface OpenSpecMappingSkeleton {\n version: 1;\n source: { root: string; inventoryDigest: string };\n capabilities: Record<string, {\n services: string[];\n suggestedServices: string[];\n requirementServices: Record<string, string[]>;\n }>;\n changes: Record<string, {\n feature: null;\n suggestedFeature: string;\n title: string;\n }>;\n renames: Record<string, {\n from: string | null;\n to: string | null;\n existingRequirementId: string | null;\n requirementId: string | null;\n }>;\n artifacts: Record<string, {\n kind: \"proposal\" | \"tasks\" | \"change-design\";\n disposition: null;\n suggestedDisposition: OpenSpecArtifactDisposition;\n }>;\n}\n\nexport function emptyMapping(mapping?: OpenSpecMapping): OpenSpecMapping {\n if (mapping === undefined) {\n return {\n source: null,\n capabilities: dictionary(),\n changes: dictionary(),\n renames: dictionary(),\n artifacts: dictionary(),\n };\n }\n // Keep the core inventory tolerant of programmatic v0 callers while the CLI\n // parser enforces the complete v1 document, including explicit `changes`.\n return {\n source: mapping.source ?? null,\n capabilities: mapping.capabilities ?? dictionary(),\n changes: mapping.changes ?? dictionary(),\n renames: mapping.renames ?? dictionary(),\n artifacts: mapping.artifacts ?? dictionary(),\n };\n}\n\nexport function createOpenSpecMappingSkeleton(inventory: OpenSpecInventory): OpenSpecMappingSkeleton {\n return {\n version: 1,\n source: { root: inventory.root, inventoryDigest: inventory.inventoryDigest },\n capabilities: Object.fromEntries(inventory.mappingDecisions.map((decision) => [\n decision.capability,\n {\n services: decision.services,\n suggestedServices: [decision.suggestedService],\n requirementServices: decision.requirementServices,\n },\n ])),\n changes: Object.fromEntries(inventory.changeDecisions.map((decision) => [\n decision.change,\n {\n feature: null,\n suggestedFeature: decision.suggestedFeature,\n title: decision.title,\n },\n ])),\n renames: Object.fromEntries(\n inventory.renamed\n .filter((rename) => rename.scope === \"active\")\n .map((rename) => [rename.key, {\n from: rename.from,\n to: rename.to,\n existingRequirementId: rename.existingRequirementId,\n // The identity the inventory settled on, which is the field the\n // skeleton is asking a human to fill in. `existingRequirementId` is\n // the living source's own id and happens to equal it on the only path\n // that reaches here today — but a caller that audits WITH a mapping\n // would have a settled id and no existing one, and the skeleton would\n // hand that decision back as unmade.\n requirementId: rename.requirementId,\n }]),\n ),\n artifacts: Object.fromEntries(inventory.artifactDecisions.map((decision) => [\n decision.path,\n {\n kind: decision.kind,\n disposition: null,\n suggestedDisposition: decision.suggestedDisposition,\n },\n ])),\n };\n}\n"]}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * What an OpenSpec workspace IS, as loam models it.
3
+ *
4
+ * `core/openspec-inventory.ts` was the one foreign model in this codebase and
5
+ * this package is still it: OpenSpec's vocabulary — capabilities, changes,
6
+ * RENAMED pairs, `.openspec.yaml` — is named here and nowhere else, and nothing
7
+ * outside `commands/migrate-openspec/` may import an `OpenSpec*` type. That
8
+ * quarantine is the point of the package, not a side effect of its size.
9
+ *
10
+ * Types only, plus the one error the root search throws. Every module below
11
+ * fills these in; none of them redefines one.
12
+ */
13
+ import {} from "./mapping.js";
14
+ /**
15
+ * The upstream commits this binary's OpenSpec compatibility is measured against:
16
+ * `release` is the certified current release, swept file by file by the corpus
17
+ * gate (`scripts/check-openspec-corpus.ts`) and vendored as the seven verbatim
18
+ * fixtures. `mainCanary` is the older post-v1.7 canary, kept as a regression pin
19
+ * rather than as a claim about where `main` points today — at the time of the
20
+ * v1.9.0 pin, `main` and the release tag were the same commit.
21
+ */
22
+ export const OPENSPEC_BASELINES = Object.freeze({
23
+ release: Object.freeze({
24
+ version: "1.9.0",
25
+ ref: "v1.9.0",
26
+ commit: "2826b8889e5223a9a8095d4428b60b56597e1020",
27
+ }),
28
+ mainCanary: Object.freeze({
29
+ ref: "main",
30
+ commit: "45cca5db6137ed209117cc70510eb3e057fb981b",
31
+ }),
32
+ });
33
+ /**
34
+ * The dispositions as values, not only as a type, because a mapping file names
35
+ * one as a plain string and the parse boundary has to be able to ask whether
36
+ * that string is one of these. A hand-written second spelling of the same list
37
+ * is how a disposition added here would go on being unrecognised where it is
38
+ * read from somebody else's YAML.
39
+ */
40
+ export const OPENSPEC_ARTIFACT_DISPOSITIONS = [
41
+ "translate-project-context",
42
+ "record-external-planning-root",
43
+ "remove-after-cutover",
44
+ "map-requirements",
45
+ "review-as-service-adr",
46
+ "translate-change-metadata",
47
+ "convert-to-intent",
48
+ "preserve-as-legacy-checklist",
49
+ "review-as-feature-adr",
50
+ "map-delta",
51
+ "review-custom-workflow",
52
+ "retain-read-only",
53
+ "manual-review",
54
+ ];
55
+ /** Whether an authored string names a disposition this codebase actually defines. */
56
+ export function isOpenSpecArtifactDisposition(value) {
57
+ return OPENSPEC_ARTIFACT_DISPOSITIONS.includes(value);
58
+ }
59
+ export class OpenSpecRootError extends Error {
60
+ constructor(message) {
61
+ super(message);
62
+ this.name = "OpenSpecRootError";
63
+ }
64
+ }
65
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../src/core/openspec/model/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAIN,MAAM,cAAc,CAAC;AAEtB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9C,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;QACrB,OAAO,EAAE,OAAO;QAChB,GAAG,EAAE,QAAQ;QACb,MAAM,EAAE,0CAA0C;KACnD,CAAC;IACF,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC;QACxB,GAAG,EAAE,MAAM;QACX,MAAM,EAAE,0CAA0C;KACnD,CAAC;CACH,CAAC,CAAC;AA4EH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,2BAA2B;IAC3B,+BAA+B;IAC/B,sBAAsB;IACtB,kBAAkB;IAClB,uBAAuB;IACvB,2BAA2B;IAC3B,mBAAmB;IACnB,8BAA8B;IAC9B,uBAAuB;IACvB,WAAW;IACX,wBAAwB;IACxB,kBAAkB;IAClB,eAAe;CACP,CAAC;AAGX,qFAAqF;AACrF,MAAM,UAAU,6BAA6B,CAAC,KAAa;IACzD,OAAQ,8BAAoD,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC/E,CAAC;AA8ED,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF","sourcesContent":["/**\n * What an OpenSpec workspace IS, as loam models it.\n *\n * `core/openspec-inventory.ts` was the one foreign model in this codebase and\n * this package is still it: OpenSpec's vocabulary — capabilities, changes,\n * RENAMED pairs, `.openspec.yaml` — is named here and nowhere else, and nothing\n * outside `commands/migrate-openspec/` may import an `OpenSpec*` type. That\n * quarantine is the point of the package, not a side effect of its size.\n *\n * Types only, plus the one error the root search throws. Every module below\n * fills these in; none of them redefines one.\n */\nimport {\n type CapabilityMappingDecision,\n type OpenSpecChangeDecision,\n type OpenSpecMappingIssue,\n} from \"./mapping.js\";\n\n/**\n * The upstream commits this binary's OpenSpec compatibility is measured against:\n * `release` is the certified current release, swept file by file by the corpus\n * gate (`scripts/check-openspec-corpus.ts`) and vendored as the seven verbatim\n * fixtures. `mainCanary` is the older post-v1.7 canary, kept as a regression pin\n * rather than as a claim about where `main` points today — at the time of the\n * v1.9.0 pin, `main` and the release tag were the same commit.\n */\nexport const OPENSPEC_BASELINES = Object.freeze({\n release: Object.freeze({\n version: \"1.9.0\",\n ref: \"v1.9.0\",\n commit: \"2826b8889e5223a9a8095d4428b60b56597e1020\",\n }),\n mainCanary: Object.freeze({\n ref: \"main\",\n commit: \"45cca5db6137ed209117cc70510eb3e057fb981b\",\n }),\n});\n\nexport interface OpenSpecCounts {\n specFiles: number;\n requirements: number;\n scenarios: number;\n}\n\nexport interface OpenSpecCapability extends OpenSpecCounts {\n /** Nested capability ids retain their complete relative directory, e.g. payments/refunds. */\n id: string;\n files: string[];\n}\n\nexport interface OpenSpecChangeMetadata {\n path: string | null;\n schema: string | null;\n skipSpecs: boolean;\n created: string | null;\n fields: string[];\n}\n\nexport interface OpenSpecChangeSpec extends OpenSpecCounts {\n capability: string;\n path: string;\n requirementNames: string[];\n}\n\nexport interface OpenSpecChange extends OpenSpecCounts {\n id: string;\n files: string[];\n specs: OpenSpecChangeSpec[];\n artifacts: string[];\n metadata: OpenSpecChangeMetadata;\n}\n\nexport type OpenSpecIssueScope = \"workspace\" | \"living\" | \"active\" | \"archive\";\n\nexport interface OpenSpecRenamedUsage {\n /** Stable key used by the mapping file. */\n key: string;\n path: string;\n line: number;\n scope: \"active\" | \"archive\";\n changeId: string;\n capability: string;\n from: string | null;\n to: string | null;\n existingRequirementId: string | null;\n requirementId: string | null;\n status: \"needsIdentity\" | \"mapped\";\n}\n\nexport interface OpenSpecUnsupportedShape {\n code: string;\n path: string;\n message: string;\n scope: OpenSpecIssueScope;\n}\n\nexport type OpenSpecArtifactScope = \"workspace\" | \"living\" | \"active\" | \"archive\";\nexport type OpenSpecArtifactKind =\n | \"config\"\n | \"store-metadata\"\n | \"project-context\"\n | \"agent-instructions\"\n | \"living-spec\"\n | \"living-design\"\n | \"change-metadata\"\n | \"proposal\"\n | \"tasks\"\n | \"change-design\"\n | \"delta-spec\"\n | \"custom-schema\"\n | \"schema-template\"\n | \"other\";\n/**\n * The dispositions as values, not only as a type, because a mapping file names\n * one as a plain string and the parse boundary has to be able to ask whether\n * that string is one of these. A hand-written second spelling of the same list\n * is how a disposition added here would go on being unrecognised where it is\n * read from somebody else's YAML.\n */\nexport const OPENSPEC_ARTIFACT_DISPOSITIONS = [\n \"translate-project-context\",\n \"record-external-planning-root\",\n \"remove-after-cutover\",\n \"map-requirements\",\n \"review-as-service-adr\",\n \"translate-change-metadata\",\n \"convert-to-intent\",\n \"preserve-as-legacy-checklist\",\n \"review-as-feature-adr\",\n \"map-delta\",\n \"review-custom-workflow\",\n \"retain-read-only\",\n \"manual-review\",\n] as const;\nexport type OpenSpecArtifactDisposition = (typeof OPENSPEC_ARTIFACT_DISPOSITIONS)[number];\n\n/** Whether an authored string names a disposition this codebase actually defines. */\nexport function isOpenSpecArtifactDisposition(value: string): value is OpenSpecArtifactDisposition {\n return (OPENSPEC_ARTIFACT_DISPOSITIONS as readonly string[]).includes(value);\n}\n\nexport interface OpenSpecArtifact {\n /** Workspace-relative, so store metadata outside openspec/ remains representable. */\n path: string;\n scope: OpenSpecArtifactScope;\n kind: OpenSpecArtifactKind;\n disposition: OpenSpecArtifactDisposition;\n changeId?: string;\n capability?: string;\n}\n\nexport interface OpenSpecArtifactDecision {\n path: string;\n kind: \"proposal\" | \"tasks\" | \"change-design\";\n suggestedDisposition: OpenSpecArtifactDisposition;\n /**\n * What the mapping selected, verbatim. This is the field the invalid-value\n * report is written from, so it has to be able to hold the invalid value —\n * narrowing it to the union would only mean asserting one back into it.\n */\n disposition: string | null;\n status: \"needsDisposition\" | \"mapped\";\n}\n\nexport interface OpenSpecConfigSummary {\n path: string;\n schema: string | null;\n store: string | null;\n hasContext: boolean;\n ruleArtifacts: string[];\n references: string[];\n}\n\nexport interface OpenSpecInventory {\n baselines: typeof OPENSPEC_BASELINES;\n inputRoot: string;\n root: string;\n /** SHA-256 over every inventoried OpenSpec source path and byte sequence. */\n inventoryDigest: string;\n workspace: {\n kind: \"project\" | \"store\" | \"openspec-root\";\n config: OpenSpecConfigSummary | null;\n storeMetadataPath: string | null;\n };\n ready: boolean;\n mechanicallyCompatible: boolean;\n readiness: {\n living: { compatible: boolean; issueCount: number };\n active: { compatible: boolean; issueCount: number };\n sourceCurrent: boolean;\n mappingsResolved: boolean;\n changesResolved: boolean;\n renamesResolved: boolean;\n dispositionsResolved: boolean;\n migrationReady: boolean;\n };\n living: OpenSpecCounts & { capabilities: OpenSpecCapability[] };\n changes: {\n active: OpenSpecChange[];\n archived: OpenSpecChange[];\n counts: { active: number; archived: number };\n };\n renamed: OpenSpecRenamedUsage[];\n /** Living/active blockers only. Frozen archive history never blocks migration readiness. */\n unsupported: OpenSpecUnsupportedShape[];\n /** Historical anomalies are retained for review, but are not migration blockers. */\n archiveDiagnostics: OpenSpecUnsupportedShape[];\n mappingDecisions: CapabilityMappingDecision[];\n needsMapping: CapabilityMappingDecision[];\n changeDecisions: OpenSpecChangeDecision[];\n needsChangeMapping: OpenSpecChangeDecision[];\n mappingIssues: OpenSpecMappingIssue[];\n artifacts: OpenSpecArtifact[];\n artifactDecisions: OpenSpecArtifactDecision[];\n needsDisposition: OpenSpecArtifactDecision[];\n}\n\nexport class OpenSpecRootError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OpenSpecRootError\";\n }\n}\n"]}