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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1256) hide show
  1. package/CHANGELOG.md +5992 -82
  2. package/COMPARISON.md +168 -63
  3. package/CONTRIBUTING.md +121 -0
  4. package/MIGRATING-from-OpenSpec.md +238 -55
  5. package/QUICKSTART.md +302 -0
  6. package/README.md +653 -144
  7. package/ROADMAP.md +1035 -0
  8. package/SCHEMA.md +3916 -263
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +927 -0
  11. package/dist/cli.js +133 -21
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +204 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +309 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +74 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/closing.js +42 -0
  20. package/dist/commands/archive/closing.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/asyncapi.js +172 -0
  22. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  23. package/dist/commands/archive/plan/contracts/consumers.js +56 -0
  24. package/dist/commands/archive/plan/contracts/consumers.js.map +1 -0
  25. package/dist/commands/archive/plan/contracts/openapi.js +193 -0
  26. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  27. package/dist/commands/archive/plan/contracts/verdict-lines.js +103 -0
  28. package/dist/commands/archive/plan/contracts/verdict-lines.js.map +1 -0
  29. package/dist/commands/archive/plan/document/head.js +151 -0
  30. package/dist/commands/archive/plan/document/head.js.map +1 -0
  31. package/dist/commands/archive/plan/document/links.js +284 -0
  32. package/dist/commands/archive/plan/document/links.js.map +1 -0
  33. package/dist/commands/archive/plan/document/run.js +136 -0
  34. package/dist/commands/archive/plan/document/run.js.map +1 -0
  35. package/dist/commands/archive/plan/gate.js +319 -0
  36. package/dist/commands/archive/plan/gate.js.map +1 -0
  37. package/dist/commands/archive/plan/landscape.js +298 -0
  38. package/dist/commands/archive/plan/landscape.js.map +1 -0
  39. package/dist/commands/archive/plan/model/extending.js +85 -0
  40. package/dist/commands/archive/plan/model/extending.js.map +1 -0
  41. package/dist/commands/archive/plan/refusal.js +106 -0
  42. package/dist/commands/archive/plan/refusal.js.map +1 -0
  43. package/dist/commands/archive/plan/specs.js +318 -0
  44. package/dist/commands/archive/plan/specs.js.map +1 -0
  45. package/dist/commands/archive/plan/state.js +30 -0
  46. package/dist/commands/archive/plan/state.js.map +1 -0
  47. package/dist/commands/archive/run.js +355 -0
  48. package/dist/commands/archive/run.js.map +1 -0
  49. package/dist/commands/archive/shipped.js +49 -0
  50. package/dist/commands/archive/shipped.js.map +1 -0
  51. package/dist/commands/context/context.js +166 -0
  52. package/dist/commands/context/context.js.map +1 -0
  53. package/dist/commands/context/print.js +305 -0
  54. package/dist/commands/context/print.js.map +1 -0
  55. package/dist/commands/delta/delta.js +367 -0
  56. package/dist/commands/delta/delta.js.map +1 -0
  57. package/dist/commands/delta/print.js +221 -0
  58. package/dist/commands/delta/print.js.map +1 -0
  59. package/dist/commands/dependencies.js +6 -8
  60. package/dist/commands/dependencies.js.map +1 -1
  61. package/dist/commands/diff/diff.js +86 -0
  62. package/dist/commands/diff/diff.js.map +1 -0
  63. package/dist/commands/diff/print.js +38 -0
  64. package/dist/commands/diff/print.js.map +1 -0
  65. package/dist/commands/doctor.js +65 -5
  66. package/dist/commands/doctor.js.map +1 -1
  67. package/dist/commands/explain/explain.js +227 -0
  68. package/dist/commands/explain/explain.js.map +1 -0
  69. package/dist/commands/explore.js +39 -28
  70. package/dist/commands/explore.js.map +1 -1
  71. package/dist/commands/gate/gate.js +152 -0
  72. package/dist/commands/gate/gate.js.map +1 -0
  73. package/dist/commands/gate/print.js +66 -0
  74. package/dist/commands/gate/print.js.map +1 -0
  75. package/dist/commands/gherkin/commit.js +105 -0
  76. package/dist/commands/gherkin/commit.js.map +1 -0
  77. package/dist/commands/gherkin/gherkin.js +262 -0
  78. package/dist/commands/gherkin/gherkin.js.map +1 -0
  79. package/dist/commands/gherkin/reconcile.js +146 -0
  80. package/dist/commands/gherkin/reconcile.js.map +1 -0
  81. package/dist/commands/gherkin/render.js +77 -0
  82. package/dist/commands/gherkin/render.js.map +1 -0
  83. package/dist/commands/init/example.js +204 -0
  84. package/dist/commands/init/example.js.map +1 -0
  85. package/dist/commands/init/first-hour.js +72 -0
  86. package/dist/commands/init/first-hour.js.map +1 -0
  87. package/dist/commands/{init.js → init/init.js} +142 -71
  88. package/dist/commands/init/init.js.map +1 -0
  89. package/dist/commands/init/mcp.js +131 -0
  90. package/dist/commands/init/mcp.js.map +1 -0
  91. package/dist/commands/init/options.js +78 -0
  92. package/dist/commands/init/options.js.map +1 -0
  93. package/dist/commands/instructions.js +72 -14
  94. package/dist/commands/instructions.js.map +1 -1
  95. package/dist/commands/list/campaign/campaign.js +63 -0
  96. package/dist/commands/list/campaign/campaign.js.map +1 -0
  97. package/dist/commands/list/campaign/owners.js +65 -0
  98. package/dist/commands/list/campaign/owners.js.map +1 -0
  99. package/dist/commands/list/json.js +155 -0
  100. package/dist/commands/list/json.js.map +1 -0
  101. package/dist/commands/list/list.js +358 -0
  102. package/dist/commands/list/list.js.map +1 -0
  103. package/dist/commands/list/print.js +344 -0
  104. package/dist/commands/list/print.js.map +1 -0
  105. package/dist/commands/list/review.js +120 -0
  106. package/dist/commands/list/review.js.map +1 -0
  107. package/dist/commands/list/suites/suites.js +140 -0
  108. package/dist/commands/list/suites/suites.js.map +1 -0
  109. package/dist/commands/list/views.js +108 -0
  110. package/dist/commands/list/views.js.map +1 -0
  111. package/dist/commands/mcp/dispatch.js +238 -0
  112. package/dist/commands/mcp/dispatch.js.map +1 -0
  113. package/dist/commands/mcp/mcp.js +75 -0
  114. package/dist/commands/mcp/mcp.js.map +1 -0
  115. package/dist/commands/mcp/serve.js +55 -0
  116. package/dist/commands/mcp/serve.js.map +1 -0
  117. package/dist/commands/migrate-openspec/materialize/active.js +175 -0
  118. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  119. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  120. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  121. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  122. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  123. package/dist/commands/migrate-openspec/materialize/stage.js +143 -0
  124. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  125. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  126. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  127. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  128. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  129. package/dist/commands/migrate-openspec/openspec/decisions.js +86 -0
  130. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  131. package/dist/commands/migrate-openspec/openspec/error.js +18 -0
  132. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  133. package/dist/commands/migrate-openspec/openspec/mapping.js +162 -0
  134. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  135. package/dist/commands/migrate-openspec/openspec/paths.js +40 -0
  136. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  137. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  138. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  139. package/dist/commands/migrate-openspec/print.js +89 -0
  140. package/dist/commands/migrate-openspec/print.js.map +1 -0
  141. package/dist/commands/new/capability-template.js +118 -0
  142. package/dist/commands/new/capability-template.js.map +1 -0
  143. package/dist/commands/new/commit.js +62 -0
  144. package/dist/commands/new/commit.js.map +1 -0
  145. package/dist/commands/new/modifies.js +206 -0
  146. package/dist/commands/new/modifies.js.map +1 -0
  147. package/dist/commands/new/new.js +328 -0
  148. package/dist/commands/new/new.js.map +1 -0
  149. package/dist/commands/new/templates.js +279 -0
  150. package/dist/commands/new/templates.js.map +1 -0
  151. package/dist/commands/open.js +199 -0
  152. package/dist/commands/open.js.map +1 -0
  153. package/dist/commands/policy/format.js +152 -0
  154. package/dist/commands/policy/format.js.map +1 -0
  155. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +38 -11
  156. package/dist/commands/policy/gate.js.map +1 -0
  157. package/dist/commands/rebase/edit.js +106 -0
  158. package/dist/commands/rebase/edit.js.map +1 -0
  159. package/dist/commands/rebase/living.js +185 -0
  160. package/dist/commands/rebase/living.js.map +1 -0
  161. package/dist/commands/rebase/plan.js +245 -0
  162. package/dist/commands/rebase/plan.js.map +1 -0
  163. package/dist/commands/rebase/rebase.js +300 -0
  164. package/dist/commands/rebase/rebase.js.map +1 -0
  165. package/dist/commands/seed/commit.js +221 -0
  166. package/dist/commands/seed/commit.js.map +1 -0
  167. package/dist/commands/seed/plan.js +278 -0
  168. package/dist/commands/seed/plan.js.map +1 -0
  169. package/dist/commands/seed/seed.js +174 -0
  170. package/dist/commands/seed/seed.js.map +1 -0
  171. package/dist/commands/show/feature.js +182 -0
  172. package/dist/commands/show/feature.js.map +1 -0
  173. package/dist/commands/show/introduced.js +157 -0
  174. package/dist/commands/show/introduced.js.map +1 -0
  175. package/dist/commands/show/marks.js +53 -0
  176. package/dist/commands/show/marks.js.map +1 -0
  177. package/dist/commands/show/service.js +239 -0
  178. package/dist/commands/show/service.js.map +1 -0
  179. package/dist/commands/show/show.js +87 -0
  180. package/dist/commands/show/show.js.map +1 -0
  181. package/dist/commands/status/fleet-next.js +90 -0
  182. package/dist/commands/status/fleet-next.js.map +1 -0
  183. package/dist/commands/status/json.js +47 -0
  184. package/dist/commands/status/json.js.map +1 -0
  185. package/dist/commands/status/print.js +209 -0
  186. package/dist/commands/status/print.js.map +1 -0
  187. package/dist/commands/status/status.js +115 -0
  188. package/dist/commands/status/status.js.map +1 -0
  189. package/dist/commands/steps/steps.js +269 -0
  190. package/dist/commands/steps/steps.js.map +1 -0
  191. package/dist/commands/subsystem/edit.js +192 -0
  192. package/dist/commands/subsystem/edit.js.map +1 -0
  193. package/dist/commands/subsystem/move.js +325 -0
  194. package/dist/commands/subsystem/move.js.map +1 -0
  195. package/dist/commands/subsystem/query.js +113 -0
  196. package/dist/commands/subsystem/query.js.map +1 -0
  197. package/dist/commands/subsystem/subsystem.js +98 -0
  198. package/dist/commands/subsystem/subsystem.js.map +1 -0
  199. package/dist/commands/subsystem/sync.js +318 -0
  200. package/dist/commands/subsystem/sync.js.map +1 -0
  201. package/dist/commands/subsystem/txn/exclude.js +132 -0
  202. package/dist/commands/subsystem/txn/exclude.js.map +1 -0
  203. package/dist/commands/subsystem/txn/links.js +128 -0
  204. package/dist/commands/subsystem/txn/links.js.map +1 -0
  205. package/dist/commands/subsystem/txn/report.js +174 -0
  206. package/dist/commands/subsystem/txn/report.js.map +1 -0
  207. package/dist/commands/subsystem/txn/txn.js +196 -0
  208. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  209. package/dist/commands/subsystem/txn/views.js +249 -0
  210. package/dist/commands/subsystem/txn/views.js.map +1 -0
  211. package/dist/commands/tasks/actions.js +107 -0
  212. package/dist/commands/tasks/actions.js.map +1 -0
  213. package/dist/commands/tasks/render.js +253 -0
  214. package/dist/commands/tasks/render.js.map +1 -0
  215. package/dist/commands/tasks/tasks.js +119 -0
  216. package/dist/commands/tasks/tasks.js.map +1 -0
  217. package/dist/commands/unarchive/manifest.js +176 -0
  218. package/dist/commands/unarchive/manifest.js.map +1 -0
  219. package/dist/commands/unarchive/restore.js +254 -0
  220. package/dist/commands/unarchive/restore.js.map +1 -0
  221. package/dist/commands/unarchive/unarchive.js +59 -0
  222. package/dist/commands/unarchive/unarchive.js.map +1 -0
  223. package/dist/commands/validate/arch-coverage.js +245 -0
  224. package/dist/commands/validate/arch-coverage.js.map +1 -0
  225. package/dist/commands/validate/checks/fleet-shape.js +204 -0
  226. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  227. package/dist/commands/validate/checks/health-deps.js +58 -0
  228. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  229. package/dist/commands/validate/checks/introduced.js +102 -0
  230. package/dist/commands/validate/checks/introduced.js.map +1 -0
  231. package/dist/commands/validate/checks/requirements.js +264 -0
  232. package/dist/commands/validate/checks/requirements.js.map +1 -0
  233. package/dist/commands/validate/checks/sources.js +85 -0
  234. package/dist/commands/validate/checks/sources.js.map +1 -0
  235. package/dist/commands/validate/coverage/covers-after.js +105 -0
  236. package/dist/commands/validate/coverage/covers-after.js.map +1 -0
  237. package/dist/commands/validate/feature.js +222 -0
  238. package/dist/commands/validate/feature.js.map +1 -0
  239. package/dist/commands/validate/fleet/census.js +93 -0
  240. package/dist/commands/validate/fleet/census.js.map +1 -0
  241. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  242. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  243. package/dist/commands/validate/fleet/landscape.js +371 -0
  244. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  245. package/dist/commands/validate/fleet/load.js +118 -0
  246. package/dist/commands/validate/fleet/load.js.map +1 -0
  247. package/dist/commands/validate/fleet/map/attest.js +98 -0
  248. package/dist/commands/validate/fleet/map/attest.js.map +1 -0
  249. package/dist/commands/validate/fleet/map/bindings.js +107 -0
  250. package/dist/commands/validate/fleet/map/bindings.js.map +1 -0
  251. package/dist/commands/validate/fleet/map/consumers.js +244 -0
  252. package/dist/commands/validate/fleet/map/consumers.js.map +1 -0
  253. package/dist/commands/validate/fleet/map/isolation.js +116 -0
  254. package/dist/commands/validate/fleet/map/isolation.js.map +1 -0
  255. package/dist/commands/validate/fleet/map/usecases.js +54 -0
  256. package/dist/commands/validate/fleet/map/usecases.js.map +1 -0
  257. package/dist/commands/validate/fleet/obligations.js +266 -0
  258. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  259. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  260. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  261. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  262. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  263. package/dist/commands/validate/fleet/scorecard/print.js +71 -0
  264. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  265. package/dist/commands/validate/fleet/scorecard/scorecard.js +162 -0
  266. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  267. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  268. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  269. package/dist/commands/validate/fleet/views/fleet-project.js +217 -0
  270. package/dist/commands/validate/fleet/views/fleet-project.js.map +1 -0
  271. package/dist/commands/validate/fleet/views/ids.js +75 -0
  272. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  273. package/dist/commands/validate/fleet/views/projects.js +278 -0
  274. package/dist/commands/validate/fleet/views/projects.js.map +1 -0
  275. package/dist/commands/validate/fleet/views/root-documents.js +83 -0
  276. package/dist/commands/validate/fleet/views/root-documents.js.map +1 -0
  277. package/dist/commands/validate/fleet/views/stale.js +52 -0
  278. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  279. package/dist/commands/validate/links/corpus.js +89 -0
  280. package/dist/commands/validate/links/corpus.js.map +1 -0
  281. package/dist/commands/validate/links/glossary.js +75 -0
  282. package/dist/commands/validate/links/glossary.js.map +1 -0
  283. package/dist/commands/validate/render/repeats.js +63 -0
  284. package/dist/commands/validate/render/repeats.js.map +1 -0
  285. package/dist/commands/validate/render/rollups.js +115 -0
  286. package/dist/commands/validate/render/rollups.js.map +1 -0
  287. package/dist/commands/validate/render/text.js +199 -0
  288. package/dist/commands/validate/render/text.js.map +1 -0
  289. package/dist/commands/validate/report.js +145 -0
  290. package/dist/commands/validate/report.js.map +1 -0
  291. package/dist/commands/validate/scope.js +113 -0
  292. package/dist/commands/validate/scope.js.map +1 -0
  293. package/dist/commands/validate/service/api.js +252 -0
  294. package/dist/commands/validate/service/api.js.map +1 -0
  295. package/dist/commands/validate/service/contracts/generated.js +134 -0
  296. package/dist/commands/validate/service/contracts/generated.js.map +1 -0
  297. package/dist/commands/validate/service/events/events.js +241 -0
  298. package/dist/commands/validate/service/events/events.js.map +1 -0
  299. package/dist/commands/validate/service/events/message-producers.js +77 -0
  300. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  301. package/dist/commands/validate/service/evidence-pins.js +177 -0
  302. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  303. package/dist/commands/validate/service/model/diverged.js +226 -0
  304. package/dist/commands/validate/service/model/diverged.js.map +1 -0
  305. package/dist/commands/validate/service/model/grade.js +163 -0
  306. package/dist/commands/validate/service/model/grade.js.map +1 -0
  307. package/dist/commands/validate/service/service.js +310 -0
  308. package/dist/commands/validate/service/service.js.map +1 -0
  309. package/dist/commands/validate/service/specs.js +279 -0
  310. package/dist/commands/validate/service/specs.js.map +1 -0
  311. package/dist/commands/validate/service/spine.js +148 -0
  312. package/dist/commands/validate/service/spine.js.map +1 -0
  313. package/dist/commands/validate/service/usecases/tags.js +113 -0
  314. package/dist/commands/validate/service/usecases/tags.js.map +1 -0
  315. package/dist/commands/validate/service/usecases/usecases.js +209 -0
  316. package/dist/commands/validate/service/usecases/usecases.js.map +1 -0
  317. package/dist/commands/validate/validate.js +363 -0
  318. package/dist/commands/validate/validate.js.map +1 -0
  319. package/dist/commands/verify/cross/diff.js +178 -0
  320. package/dist/commands/verify/cross/diff.js.map +1 -0
  321. package/dist/commands/verify/evidence/contract.js +32 -0
  322. package/dist/commands/verify/evidence/contract.js.map +1 -0
  323. package/dist/commands/verify/evidence/pins.js +52 -0
  324. package/dist/commands/verify/evidence/pins.js.map +1 -0
  325. package/dist/commands/verify/evidence/read.js +81 -0
  326. package/dist/commands/verify/evidence/read.js.map +1 -0
  327. package/dist/commands/verify/frozen.js +263 -0
  328. package/dist/commands/verify/frozen.js.map +1 -0
  329. package/dist/commands/verify/record.js +278 -0
  330. package/dist/commands/verify/record.js.map +1 -0
  331. package/dist/commands/verify/report.js +206 -0
  332. package/dist/commands/verify/report.js.map +1 -0
  333. package/dist/commands/verify/results.js +328 -0
  334. package/dist/commands/verify/results.js.map +1 -0
  335. package/dist/commands/verify/verify.js +220 -0
  336. package/dist/commands/verify/verify.js.map +1 -0
  337. package/dist/commands/vouch/contract.js +11 -0
  338. package/dist/commands/vouch/contract.js.map +1 -0
  339. package/dist/commands/vouch/pack/contract.js +2 -0
  340. package/dist/commands/vouch/pack/contract.js.map +1 -0
  341. package/dist/commands/vouch/pack/pack.js +266 -0
  342. package/dist/commands/vouch/pack/pack.js.map +1 -0
  343. package/dist/commands/vouch/pack/print.js +266 -0
  344. package/dist/commands/vouch/pack/print.js.map +1 -0
  345. package/dist/commands/vouch/pack/sections.js +141 -0
  346. package/dist/commands/vouch/pack/sections.js.map +1 -0
  347. package/dist/commands/vouch/prompt/confirm.js +46 -0
  348. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  349. package/dist/commands/vouch/report.js +101 -0
  350. package/dist/commands/vouch/report.js.map +1 -0
  351. package/dist/commands/vouch/run.js +230 -0
  352. package/dist/commands/vouch/run.js.map +1 -0
  353. package/dist/commands/vouch/sample/plan.js +111 -0
  354. package/dist/commands/vouch/sample/plan.js.map +1 -0
  355. package/dist/commands/vouch/sample/print.js +109 -0
  356. package/dist/commands/vouch/sample/print.js.map +1 -0
  357. package/dist/commands/vouch/vet/verify.js +155 -0
  358. package/dist/commands/vouch/vet/verify.js.map +1 -0
  359. package/dist/commands/vouch/vouch.js +169 -0
  360. package/dist/commands/vouch/vouch.js.map +1 -0
  361. package/dist/core/agent/agents-md/command-map.js +299 -0
  362. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  363. package/dist/core/agent/agents-md/map/explain.js +46 -0
  364. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  365. package/dist/core/agent/agents-md/map/lenses/context.js +50 -0
  366. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  367. package/dist/core/agent/agents-md/map/lenses/diff.js +59 -0
  368. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  369. package/dist/core/agent/agents-md/map/lenses/gate.js +65 -0
  370. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  371. package/dist/core/agent/agents-md/map/mcp.js +44 -0
  372. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  373. package/dist/core/agent/agents-md/map/status.js +78 -0
  374. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  375. package/dist/core/agent/agents-md/map/subsystem.js +104 -0
  376. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  377. package/dist/core/agent/agents-md/map/usecases.js +138 -0
  378. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  379. package/dist/core/agent/agents-md/refusals.js +273 -0
  380. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  381. package/dist/core/agent/agents-md.js +203 -0
  382. package/dist/core/agent/agents-md.js.map +1 -0
  383. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +60 -0
  384. package/dist/core/agent/agents-stamp.js.map +1 -0
  385. package/dist/core/agent/contract.js +2 -0
  386. package/dist/core/agent/contract.js.map +1 -0
  387. package/dist/core/agent/protocol.js +193 -0
  388. package/dist/core/agent/protocol.js.map +1 -0
  389. package/dist/core/agent/scaffold.js +254 -0
  390. package/dist/core/agent/scaffold.js.map +1 -0
  391. package/dist/core/agent/support/report.js +144 -0
  392. package/dist/core/agent/support/report.js.map +1 -0
  393. package/dist/core/agent/tools/dialects.js +151 -0
  394. package/dist/core/agent/tools/dialects.js.map +1 -0
  395. package/dist/core/agent/tools/registry.js +193 -0
  396. package/dist/core/agent/tools/registry.js.map +1 -0
  397. package/dist/core/agent/workflows/adopt.js +280 -0
  398. package/dist/core/agent/workflows/adopt.js.map +1 -0
  399. package/dist/core/agent/workflows/check.js +373 -0
  400. package/dist/core/agent/workflows/check.js.map +1 -0
  401. package/dist/core/agent/workflows/closing.js +323 -0
  402. package/dist/core/agent/workflows/closing.js.map +1 -0
  403. package/dist/core/agent/workflows/feature.js +220 -0
  404. package/dist/core/agent/workflows/feature.js.map +1 -0
  405. package/dist/core/agent/workflows/implement.js +188 -0
  406. package/dist/core/agent/workflows/implement.js.map +1 -0
  407. package/dist/core/agent/workflows/reference/authoring.js +311 -0
  408. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  409. package/dist/core/agent/workflows/reference/codes.js +67 -0
  410. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  411. package/dist/core/agent/workflows/reference/done-check.js +210 -0
  412. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  413. package/dist/core/agent/workflows/reference/drawing/drawing.js +253 -0
  414. package/dist/core/agent/workflows/reference/drawing/drawing.js.map +1 -0
  415. package/dist/core/agent/workflows/reference/reference.js +19 -0
  416. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  417. package/dist/core/agent/workflows/reference/spine.js +338 -0
  418. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  419. package/dist/core/asyncapi/baseline/plan.js +43 -0
  420. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  421. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  422. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  423. package/dist/core/asyncapi/depth.js +164 -0
  424. package/dist/core/asyncapi/depth.js.map +1 -0
  425. package/dist/core/asyncapi/digest.js +146 -0
  426. package/dist/core/asyncapi/digest.js.map +1 -0
  427. package/dist/core/asyncapi/merge/components.js +92 -0
  428. package/dist/core/asyncapi/merge/components.js.map +1 -0
  429. package/dist/core/asyncapi/merge/error.js +38 -0
  430. package/dist/core/asyncapi/merge/error.js.map +1 -0
  431. package/dist/core/asyncapi/merge/markers.js +290 -0
  432. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  433. package/dist/core/asyncapi/merge/merge.js +195 -0
  434. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  435. package/dist/core/asyncapi/merge/pin.js +83 -0
  436. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  437. package/dist/core/asyncapi/model.js +11 -0
  438. package/dist/core/asyncapi/model.js.map +1 -0
  439. package/dist/core/asyncapi/producers.js +50 -0
  440. package/dist/core/asyncapi/producers.js.map +1 -0
  441. package/dist/core/asyncapi/read.js +263 -0
  442. package/dist/core/asyncapi/read.js.map +1 -0
  443. package/dist/core/brief/brief.js +285 -0
  444. package/dist/core/brief/brief.js.map +1 -0
  445. package/dist/core/brief/checks.js +385 -0
  446. package/dist/core/brief/checks.js.map +1 -0
  447. package/dist/core/brief/landscape.js +273 -0
  448. package/dist/core/brief/landscape.js.map +1 -0
  449. package/dist/core/brief/map/extend.js +84 -0
  450. package/dist/core/brief/map/extend.js.map +1 -0
  451. package/dist/core/brief/map/owed.js +266 -0
  452. package/dist/core/brief/map/owed.js.map +1 -0
  453. package/dist/core/brief/targets.js +304 -0
  454. package/dist/core/brief/targets.js.map +1 -0
  455. package/dist/core/brief/unchecked.js +58 -0
  456. package/dist/core/brief/unchecked.js.map +1 -0
  457. package/dist/core/c4/arch.js +190 -0
  458. package/dist/core/c4/arch.js.map +1 -0
  459. package/dist/core/c4/direction/direction.js +114 -0
  460. package/dist/core/c4/direction/direction.js.map +1 -0
  461. package/dist/core/c4/likec4.js +243 -0
  462. package/dist/core/c4/likec4.js.map +1 -0
  463. package/dist/core/c4/locate/unlocated.js +150 -0
  464. package/dist/core/c4/locate/unlocated.js.map +1 -0
  465. package/dist/core/c4/parsed/deployment.js +160 -0
  466. package/dist/core/c4/parsed/deployment.js.map +1 -0
  467. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  468. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  469. package/dist/core/c4/parsed/specification.js +78 -0
  470. package/dist/core/c4/parsed/specification.js.map +1 -0
  471. package/dist/core/c4/parsed/values.js +110 -0
  472. package/dist/core/c4/parsed/values.js.map +1 -0
  473. package/dist/core/c4/parsed/view-ids.js +113 -0
  474. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  475. package/dist/core/c4/prefetch/fleet.js +134 -0
  476. package/dist/core/c4/prefetch/fleet.js.map +1 -0
  477. package/dist/core/c4/project/architecture.js +161 -0
  478. package/dist/core/c4/project/architecture.js.map +1 -0
  479. package/dist/core/c4/project/batch.js +140 -0
  480. package/dist/core/c4/project/batch.js.map +1 -0
  481. package/dist/core/c4/project/documents.js +89 -0
  482. package/dist/core/c4/project/documents.js.map +1 -0
  483. package/dist/core/c4/project/load.js +219 -0
  484. package/dist/core/c4/project/load.js.map +1 -0
  485. package/dist/core/c4/project/staged.js +277 -0
  486. package/dist/core/c4/project/staged.js.map +1 -0
  487. package/dist/core/c4/resolve/attested.js +0 -0
  488. package/dist/core/c4/resolve/attested.js.map +1 -0
  489. package/dist/core/c4/resolve/external.js +51 -0
  490. package/dist/core/c4/resolve/external.js.map +1 -0
  491. package/dist/core/c4/resolve/service.js +174 -0
  492. package/dist/core/c4/resolve/service.js.map +1 -0
  493. package/dist/core/c4/resolve/steps.js +290 -0
  494. package/dist/core/c4/resolve/steps.js.map +1 -0
  495. package/dist/core/c4/resolve/systems.js +154 -0
  496. package/dist/core/c4/resolve/systems.js.map +1 -0
  497. package/dist/core/c4/root-project/exclude.js +352 -0
  498. package/dist/core/c4/root-project/exclude.js.map +1 -0
  499. package/dist/core/c4/seed/fleet-file.js +201 -0
  500. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  501. package/dist/core/c4/seed/items.js +91 -0
  502. package/dist/core/c4/seed/items.js.map +1 -0
  503. package/dist/core/c4/seed/stamp.js +48 -0
  504. package/dist/core/c4/seed/stamp.js.map +1 -0
  505. package/dist/core/c4/seed/template.js +173 -0
  506. package/dist/core/c4/seed/template.js.map +1 -0
  507. package/dist/core/c4/service-model/created/models.js +96 -0
  508. package/dist/core/c4/service-model/created/models.js.map +1 -0
  509. package/dist/core/c4/service-model/documents.js +47 -0
  510. package/dist/core/c4/service-model/documents.js.map +1 -0
  511. package/dist/core/c4/service-model/fleet/extending.js +82 -0
  512. package/dist/core/c4/service-model/fleet/extending.js.map +1 -0
  513. package/dist/core/c4/service-model/load.js +165 -0
  514. package/dist/core/c4/service-model/load.js.map +1 -0
  515. package/dist/core/c4/service-model/renderer.js +128 -0
  516. package/dist/core/c4/service-model/renderer.js.map +1 -0
  517. package/dist/core/c4/service-model/shape.js +106 -0
  518. package/dist/core/c4/service-model/shape.js.map +1 -0
  519. package/dist/core/c4/service-model/slice.js +188 -0
  520. package/dist/core/c4/service-model/slice.js.map +1 -0
  521. package/dist/core/c4/source-mask.js +369 -0
  522. package/dist/core/c4/source-mask.js.map +1 -0
  523. package/dist/core/c4/source-scan.js +308 -0
  524. package/dist/core/c4/source-scan.js.map +1 -0
  525. package/dist/core/c4/splice/authored-source.js +167 -0
  526. package/dist/core/c4/splice/authored-source.js.map +1 -0
  527. package/dist/core/c4/splice/contract.js +30 -0
  528. package/dist/core/c4/splice/contract.js.map +1 -0
  529. package/dist/core/c4/splice/delta-blocks.js +126 -0
  530. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  531. package/dist/core/c4/splice/identity/declared.js +87 -0
  532. package/dist/core/c4/splice/identity/declared.js.map +1 -0
  533. package/dist/core/c4/splice/identity/edges.js +73 -0
  534. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  535. package/dist/core/c4/splice/identity/existing.js +80 -0
  536. package/dist/core/c4/splice/identity/existing.js.map +1 -0
  537. package/dist/core/c4/splice/identity/interior.js +80 -0
  538. package/dist/core/c4/splice/identity/interior.js.map +1 -0
  539. package/dist/core/c4/splice/identity/owner.js +50 -0
  540. package/dist/core/c4/splice/identity/owner.js.map +1 -0
  541. package/dist/core/c4/splice/landscape-merge.js +337 -0
  542. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  543. package/dist/core/c4/splice/model/merge.js +151 -0
  544. package/dist/core/c4/splice/model/merge.js.map +1 -0
  545. package/dist/core/c4/splice/placement.js +298 -0
  546. package/dist/core/c4/splice/placement.js.map +1 -0
  547. package/dist/core/c4/splice/text/spot.js +131 -0
  548. package/dist/core/c4/splice/text/spot.js.map +1 -0
  549. package/dist/core/c4/workspace.js +166 -0
  550. package/dist/core/c4/workspace.js.map +1 -0
  551. package/dist/core/capabilities/authoring/notes.js +141 -0
  552. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  553. package/dist/core/capabilities/capabilities.js +124 -0
  554. package/dist/core/capabilities/capabilities.js.map +1 -0
  555. package/dist/core/capabilities/delta/doc.js +47 -0
  556. package/dist/core/capabilities/delta/doc.js.map +1 -0
  557. package/dist/core/capabilities/delta/overlay.js +129 -0
  558. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  559. package/dist/core/capabilities/delta/summary.js +57 -0
  560. package/dist/core/capabilities/delta/summary.js.map +1 -0
  561. package/dist/core/capabilities/delta/tree.js +43 -0
  562. package/dist/core/capabilities/delta/tree.js.map +1 -0
  563. package/dist/core/capabilities/delta/uncovered.js +222 -0
  564. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  565. package/dist/core/capabilities/findings.js +338 -0
  566. package/dist/core/capabilities/findings.js.map +1 -0
  567. package/dist/core/capabilities/realizes/findings.js +174 -0
  568. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  569. package/dist/core/capabilities/realizes/join.js +123 -0
  570. package/dist/core/capabilities/realizes/join.js.map +1 -0
  571. package/dist/core/capabilities/rollup.js +205 -0
  572. package/dist/core/capabilities/rollup.js.map +1 -0
  573. package/dist/core/capabilities/tree.js +104 -0
  574. package/dist/core/capabilities/tree.js.map +1 -0
  575. package/dist/core/capabilities/usecase-join.js +267 -0
  576. package/dist/core/capabilities/usecase-join.js.map +1 -0
  577. package/dist/core/coherence/authoring/scaffold.js +185 -0
  578. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  579. package/dist/core/coherence/authoring/sentinels.js +75 -0
  580. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  581. package/dist/core/coherence/calls/called.js +52 -0
  582. package/dist/core/coherence/calls/called.js.map +1 -0
  583. package/dist/core/coherence/coherence.js +332 -0
  584. package/dist/core/coherence/coherence.js.map +1 -0
  585. package/dist/core/coherence/consumed/operations.js +70 -0
  586. package/dist/core/coherence/consumed/operations.js.map +1 -0
  587. package/dist/core/coherence/consumed/refusal.js +38 -0
  588. package/dist/core/coherence/consumed/refusal.js.map +1 -0
  589. package/dist/core/coherence/covers/health.js +85 -0
  590. package/dist/core/coherence/covers/health.js.map +1 -0
  591. package/dist/core/coherence/declared.js +295 -0
  592. package/dist/core/coherence/declared.js.map +1 -0
  593. package/dist/core/coherence/events/declared.js +191 -0
  594. package/dist/core/coherence/events/declared.js.map +1 -0
  595. package/dist/core/coherence/events/events.js +335 -0
  596. package/dist/core/coherence/events/events.js.map +1 -0
  597. package/dist/core/coherence/events/grades.js +189 -0
  598. package/dist/core/coherence/events/grades.js.map +1 -0
  599. package/dist/core/coherence/events/lookups.js +63 -0
  600. package/dist/core/coherence/events/lookups.js.map +1 -0
  601. package/dist/core/coherence/events/produced.js +100 -0
  602. package/dist/core/coherence/events/produced.js.map +1 -0
  603. package/dist/core/coherence/living.js +198 -0
  604. package/dist/core/coherence/living.js.map +1 -0
  605. package/dist/core/coherence/lookups.js +95 -0
  606. package/dist/core/coherence/lookups.js.map +1 -0
  607. package/dist/core/coherence/pending.js +39 -0
  608. package/dist/core/coherence/pending.js.map +1 -0
  609. package/dist/core/coherence/retired/archived.js +285 -0
  610. package/dist/core/coherence/retired/archived.js.map +1 -0
  611. package/dist/core/coherence/retired/event-pair.js +62 -0
  612. package/dist/core/coherence/retired/event-pair.js.map +1 -0
  613. package/dist/core/coherence/retired/merged.js +79 -0
  614. package/dist/core/coherence/retired/merged.js.map +1 -0
  615. package/dist/core/coherence/retired/retirement.js +49 -0
  616. package/dist/core/coherence/retired/retirement.js.map +1 -0
  617. package/dist/core/coherence/retired/revival/arrivals.js +131 -0
  618. package/dist/core/coherence/retired/revival/arrivals.js.map +1 -0
  619. package/dist/core/coherence/retired/revival/revived.js +297 -0
  620. package/dist/core/coherence/retired/revival/revived.js.map +1 -0
  621. package/dist/core/conflict-markers.js +60 -0
  622. package/dist/core/conflict-markers.js.map +1 -0
  623. package/dist/core/consumers/after.js +113 -0
  624. package/dist/core/consumers/after.js.map +1 -0
  625. package/dist/core/consumers/consumers.js +296 -0
  626. package/dist/core/consumers/consumers.js.map +1 -0
  627. package/dist/core/consumers/current.js +211 -0
  628. package/dist/core/consumers/current.js.map +1 -0
  629. package/dist/core/consumers/scan.js +46 -0
  630. package/dist/core/consumers/scan.js.map +1 -0
  631. package/dist/core/consumers/state.js +27 -0
  632. package/dist/core/consumers/state.js.map +1 -0
  633. package/dist/core/delta/claims.js +73 -0
  634. package/dist/core/delta/claims.js.map +1 -0
  635. package/dist/core/delta/delta.js +341 -0
  636. package/dist/core/delta/delta.js.map +1 -0
  637. package/dist/core/delta/document.js +177 -0
  638. package/dist/core/delta/document.js.map +1 -0
  639. package/dist/core/delta/scope.js +48 -0
  640. package/dist/core/delta/scope.js.map +1 -0
  641. package/dist/core/delta/select.js +237 -0
  642. package/dist/core/delta/select.js.map +1 -0
  643. package/dist/core/dependencies/dependencies.js +141 -0
  644. package/dist/core/dependencies/dependencies.js.map +1 -0
  645. package/dist/core/dependencies/facts.js +165 -0
  646. package/dist/core/dependencies/facts.js.map +1 -0
  647. package/dist/core/dependencies/fanin.js +88 -0
  648. package/dist/core/dependencies/fanin.js.map +1 -0
  649. package/dist/core/dependencies/graph.js +106 -0
  650. package/dist/core/dependencies/graph.js.map +1 -0
  651. package/dist/core/deployment/delta.js +191 -0
  652. package/dist/core/deployment/delta.js.map +1 -0
  653. package/dist/core/deployment/objects.js +145 -0
  654. package/dist/core/deployment/objects.js.map +1 -0
  655. package/dist/core/diff/base-git.js +230 -0
  656. package/dist/core/diff/base-git.js.map +1 -0
  657. package/dist/core/diff/base-state.js +237 -0
  658. package/dist/core/diff/base-state.js.map +1 -0
  659. package/dist/core/diff/joins.js +136 -0
  660. package/dist/core/diff/joins.js.map +1 -0
  661. package/dist/core/diff/scope/changed-paths.js +204 -0
  662. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  663. package/dist/core/diff/scope/edges.js +82 -0
  664. package/dist/core/diff/scope/edges.js.map +1 -0
  665. package/dist/core/diff/semantic.js +312 -0
  666. package/dist/core/diff/semantic.js.map +1 -0
  667. package/dist/core/docs.js +37 -85
  668. package/dist/core/docs.js.map +1 -1
  669. package/dist/core/doctor/agents.js +238 -0
  670. package/dist/core/doctor/agents.js.map +1 -0
  671. package/dist/core/doctor/config.js +139 -0
  672. package/dist/core/doctor/config.js.map +1 -0
  673. package/dist/core/doctor/doctor.js +355 -0
  674. package/dist/core/doctor/doctor.js.map +1 -0
  675. package/dist/core/doctor/report.js +13 -0
  676. package/dist/core/doctor/report.js.map +1 -0
  677. package/dist/core/doctor/reports/scan.js +242 -0
  678. package/dist/core/doctor/reports/scan.js.map +1 -0
  679. package/dist/core/doctor/residue.js +110 -0
  680. package/dist/core/doctor/residue.js.map +1 -0
  681. package/dist/core/document/apply.js +224 -0
  682. package/dist/core/document/apply.js.map +1 -0
  683. package/dist/core/{frontmatter.js → document/frontmatter.js} +103 -2
  684. package/dist/core/document/frontmatter.js.map +1 -0
  685. package/dist/core/document/grammar/directives.js +143 -0
  686. package/dist/core/document/grammar/directives.js.map +1 -0
  687. package/dist/core/document/parse.js +286 -0
  688. package/dist/core/document/parse.js.map +1 -0
  689. package/dist/core/document/scenarios.js +238 -0
  690. package/dist/core/document/scenarios.js.map +1 -0
  691. package/dist/core/document/spec.js +234 -0
  692. package/dist/core/document/spec.js.map +1 -0
  693. package/dist/core/{config.js → envelope/config.js} +89 -18
  694. package/dist/core/envelope/config.js.map +1 -0
  695. package/dist/core/envelope/json.js +209 -0
  696. package/dist/core/envelope/json.js.map +1 -0
  697. package/dist/core/{version.js → envelope/version.js} +3 -3
  698. package/dist/core/envelope/version.js.map +1 -0
  699. package/dist/core/explain/families.js +180 -0
  700. package/dist/core/explain/families.js.map +1 -0
  701. package/dist/core/explain/fix-tables.js +178 -0
  702. package/dist/core/explain/fix-tables.js.map +1 -0
  703. package/dist/core/explain/lookup.js +194 -0
  704. package/dist/core/explain/lookup.js.map +1 -0
  705. package/dist/core/explain/refusals.js +49 -0
  706. package/dist/core/explain/refusals.js.map +1 -0
  707. package/dist/core/explain/terms/documents.js +227 -0
  708. package/dist/core/explain/terms/documents.js.map +1 -0
  709. package/dist/core/explain/terms/done-check.js +144 -0
  710. package/dist/core/explain/terms/done-check.js.map +1 -0
  711. package/dist/core/explain/terms/entry.js +14 -0
  712. package/dist/core/explain/terms/entry.js.map +1 -0
  713. package/dist/core/explain/terms/stages.js +71 -0
  714. package/dist/core/explain/terms/stages.js.map +1 -0
  715. package/dist/core/explain/terms/tasks.js +97 -0
  716. package/dist/core/explain/terms/tasks.js.map +1 -0
  717. package/dist/core/explain/terms.js +103 -0
  718. package/dist/core/explain/terms.js.map +1 -0
  719. package/dist/core/explore/describe.js +105 -0
  720. package/dist/core/explore/describe.js.map +1 -0
  721. package/dist/core/explore/explore.js +204 -0
  722. package/dist/core/explore/explore.js.map +1 -0
  723. package/dist/core/fleet-context.js +174 -146
  724. package/dist/core/fleet-context.js.map +1 -1
  725. package/dist/core/gate/checks.js +208 -0
  726. package/dist/core/gate/checks.js.map +1 -0
  727. package/dist/core/gate/partners.js +246 -0
  728. package/dist/core/gate/partners.js.map +1 -0
  729. package/dist/core/gate/report.js +47 -0
  730. package/dist/core/gate/report.js.map +1 -0
  731. package/dist/core/gate/verification.js +176 -0
  732. package/dist/core/gate/verification.js.map +1 -0
  733. package/dist/core/gherkin/digest.js +60 -0
  734. package/dist/core/gherkin/digest.js.map +1 -0
  735. package/dist/core/gherkin/emit.js +177 -0
  736. package/dist/core/gherkin/emit.js.map +1 -0
  737. package/dist/core/gherkin/read.js +76 -0
  738. package/dist/core/gherkin/read.js.map +1 -0
  739. package/dist/core/gherkin/stale.js +210 -0
  740. package/dist/core/gherkin/stale.js.map +1 -0
  741. package/dist/core/gherkin/stamp.js +77 -0
  742. package/dist/core/gherkin/stamp.js.map +1 -0
  743. package/dist/core/gherkin/steps/catalogue.js +154 -0
  744. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  745. package/dist/core/gherkin/steps/inventory.js +98 -0
  746. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  747. package/dist/core/gherkin/steps/phrase.js +72 -0
  748. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  749. package/dist/core/glossary/delta.js +109 -0
  750. package/dist/core/glossary/delta.js.map +1 -0
  751. package/dist/core/glossary/tree.js +73 -0
  752. package/dist/core/glossary/tree.js.map +1 -0
  753. package/dist/core/{concurrency.js → kernel/concurrency.js} +19 -0
  754. package/dist/core/kernel/concurrency.js.map +1 -0
  755. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  756. package/dist/core/kernel/document-bytes.js.map +1 -0
  757. package/dist/core/kernel/fences.js +42 -0
  758. package/dist/core/kernel/fences.js.map +1 -0
  759. package/dist/core/kernel/ids/capability.js +72 -0
  760. package/dist/core/kernel/ids/capability.js.map +1 -0
  761. package/dist/core/kernel/ids/dirs.js +33 -0
  762. package/dist/core/kernel/ids/dirs.js.map +1 -0
  763. package/dist/core/kernel/ids/feature.js +75 -0
  764. package/dist/core/kernel/ids/feature.js.map +1 -0
  765. package/dist/core/kernel/ids/fqn/ancestors.js +65 -0
  766. package/dist/core/kernel/ids/fqn/ancestors.js.map +1 -0
  767. package/dist/core/kernel/ids/service.js +156 -0
  768. package/dist/core/kernel/ids/service.js.map +1 -0
  769. package/dist/core/kernel/ids/subsystem.js +63 -0
  770. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  771. package/dist/core/{path-safety.js → kernel/path-safety.js} +56 -4
  772. package/dist/core/kernel/path-safety.js.map +1 -0
  773. package/dist/core/{records.js → kernel/records.js} +11 -0
  774. package/dist/core/kernel/records.js.map +1 -0
  775. package/dist/core/links/backlinks.js +66 -0
  776. package/dist/core/links/backlinks.js.map +1 -0
  777. package/dist/core/links/case.js +74 -0
  778. package/dist/core/links/case.js.map +1 -0
  779. package/dist/core/links/corpus.js +118 -0
  780. package/dist/core/links/corpus.js.map +1 -0
  781. package/dist/core/links/findings.js +110 -0
  782. package/dist/core/links/findings.js.map +1 -0
  783. package/dist/core/links/parse.js +265 -0
  784. package/dist/core/links/parse.js.map +1 -0
  785. package/dist/core/mcp/argv.js +212 -0
  786. package/dist/core/mcp/argv.js.map +1 -0
  787. package/dist/core/mcp/author-tools.js +73 -0
  788. package/dist/core/mcp/author-tools.js.map +1 -0
  789. package/dist/core/mcp/framing.js +46 -0
  790. package/dist/core/mcp/framing.js.map +1 -0
  791. package/dist/core/mcp/protocol.js +280 -0
  792. package/dist/core/mcp/protocol.js.map +1 -0
  793. package/dist/core/mcp/tools.js +324 -0
  794. package/dist/core/mcp/tools.js.map +1 -0
  795. package/dist/core/obligations/obligations.js +106 -0
  796. package/dist/core/obligations/obligations.js.map +1 -0
  797. package/dist/core/openapi/baseline/gate.js +207 -0
  798. package/dist/core/openapi/baseline/gate.js.map +1 -0
  799. package/dist/core/openapi/baseline/plan.js +142 -0
  800. package/dist/core/openapi/baseline/plan.js.map +1 -0
  801. package/dist/core/openapi/baseline/record.js +174 -0
  802. package/dist/core/openapi/baseline/record.js.map +1 -0
  803. package/dist/core/openapi/contract-text.js +33 -0
  804. package/dist/core/openapi/contract-text.js.map +1 -0
  805. package/dist/core/openapi/contract-tree.js +301 -0
  806. package/dist/core/openapi/contract-tree.js.map +1 -0
  807. package/dist/core/openapi/depth.js +136 -0
  808. package/dist/core/openapi/depth.js.map +1 -0
  809. package/dist/core/openapi/digest.js +239 -0
  810. package/dist/core/openapi/digest.js.map +1 -0
  811. package/dist/core/{openapi.js → openapi/doc.js} +54 -108
  812. package/dist/core/openapi/doc.js.map +1 -0
  813. package/dist/core/openapi/merge/components.js +199 -0
  814. package/dist/core/openapi/merge/components.js.map +1 -0
  815. package/dist/core/openapi/merge/error.js +16 -0
  816. package/dist/core/openapi/merge/error.js.map +1 -0
  817. package/dist/core/openapi/merge/markers.js +204 -0
  818. package/dist/core/openapi/merge/markers.js.map +1 -0
  819. package/dist/core/openapi/merge/merge.js +232 -0
  820. package/dist/core/openapi/merge/merge.js.map +1 -0
  821. package/dist/core/openapi/merge/pin.js +110 -0
  822. package/dist/core/openapi/merge/pin.js.map +1 -0
  823. package/dist/core/openspec/decide/capabilities.js +244 -0
  824. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  825. package/dist/core/openspec/decide/dispositions.js +63 -0
  826. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  827. package/dist/core/openspec/decide/renames.js +179 -0
  828. package/dist/core/openspec/decide/renames.js.map +1 -0
  829. package/dist/core/openspec/decide/verdict.js +84 -0
  830. package/dist/core/openspec/decide/verdict.js.map +1 -0
  831. package/dist/core/openspec/inventory.js +220 -0
  832. package/dist/core/openspec/inventory.js.map +1 -0
  833. package/dist/core/openspec/model/mapping.js +78 -0
  834. package/dist/core/openspec/model/mapping.js.map +1 -0
  835. package/dist/core/openspec/model/model.js +70 -0
  836. package/dist/core/openspec/model/model.js.map +1 -0
  837. package/dist/core/openspec/scan/changes.js +241 -0
  838. package/dist/core/openspec/scan/changes.js.map +1 -0
  839. package/dist/core/openspec/scan/config.js +191 -0
  840. package/dist/core/openspec/scan/config.js.map +1 -0
  841. package/dist/core/openspec/scan/shape.js +304 -0
  842. package/dist/core/openspec/scan/shape.js.map +1 -0
  843. package/dist/core/openspec/scan/walk.js +116 -0
  844. package/dist/core/openspec/scan/walk.js.map +1 -0
  845. package/dist/core/openspec/scan/workspace.js +71 -0
  846. package/dist/core/openspec/scan/workspace.js.map +1 -0
  847. package/dist/core/owners/codeowners.js +141 -0
  848. package/dist/core/owners/codeowners.js.map +1 -0
  849. package/dist/core/pack/features.js +120 -0
  850. package/dist/core/pack/features.js.map +1 -0
  851. package/dist/core/pack/joins.js +112 -0
  852. package/dist/core/pack/joins.js.map +1 -0
  853. package/dist/core/pack/living.js +157 -0
  854. package/dist/core/pack/living.js.map +1 -0
  855. package/dist/core/pack/pack.js +120 -0
  856. package/dist/core/pack/pack.js.map +1 -0
  857. package/dist/core/permissions/permissions.js +87 -0
  858. package/dist/core/permissions/permissions.js.map +1 -0
  859. package/dist/core/projection/api.js +84 -0
  860. package/dist/core/projection/api.js.map +1 -0
  861. package/dist/core/projection/arch-slice.js +63 -0
  862. package/dist/core/projection/arch-slice.js.map +1 -0
  863. package/dist/core/projection/events.js +34 -0
  864. package/dist/core/projection/events.js.map +1 -0
  865. package/dist/core/projection/introduced.js +14 -0
  866. package/dist/core/projection/introduced.js.map +1 -0
  867. package/dist/core/provenance/findings.js +244 -0
  868. package/dist/core/provenance/findings.js.map +1 -0
  869. package/dist/core/provenance/git.js +201 -0
  870. package/dist/core/provenance/git.js.map +1 -0
  871. package/dist/core/provenance/gitq/moves.js +139 -0
  872. package/dist/core/provenance/gitq/moves.js.map +1 -0
  873. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  874. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  875. package/dist/core/provenance/sample/scope.js +238 -0
  876. package/dist/core/provenance/sample/scope.js.map +1 -0
  877. package/dist/core/provenance/sample/sections.js +61 -0
  878. package/dist/core/provenance/sample/sections.js.map +1 -0
  879. package/dist/core/provenance/sources.js +280 -0
  880. package/dist/core/provenance/sources.js.map +1 -0
  881. package/dist/core/provenance/stamp.js +220 -0
  882. package/dist/core/provenance/stamp.js.map +1 -0
  883. package/dist/core/provenance/walk.js +157 -0
  884. package/dist/core/provenance/walk.js.map +1 -0
  885. package/dist/core/repo/authored/paths.js +210 -0
  886. package/dist/core/repo/authored/paths.js.map +1 -0
  887. package/dist/core/repo/entries.js +126 -0
  888. package/dist/core/repo/entries.js.map +1 -0
  889. package/dist/core/repo/paths.js +322 -0
  890. package/dist/core/repo/paths.js.map +1 -0
  891. package/dist/core/repo/repo.js +308 -0
  892. package/dist/core/repo/repo.js.map +1 -0
  893. package/dist/core/repo/service-target.js +153 -0
  894. package/dist/core/repo/service-target.js.map +1 -0
  895. package/dist/core/repo/state.js +58 -0
  896. package/dist/core/repo/state.js.map +1 -0
  897. package/dist/core/repo/tree/find.js +61 -0
  898. package/dist/core/repo/tree/find.js.map +1 -0
  899. package/dist/core/repo/tree/fs.js +90 -0
  900. package/dist/core/repo/tree/fs.js.map +1 -0
  901. package/dist/core/repo/tree/marker.js +61 -0
  902. package/dist/core/repo/tree/marker.js.map +1 -0
  903. package/dist/core/repo/tree/render/body.js +258 -0
  904. package/dist/core/repo/tree/render/body.js.map +1 -0
  905. package/dist/core/repo/tree/render/projects.js +182 -0
  906. package/dist/core/repo/tree/render/projects.js.map +1 -0
  907. package/dist/core/repo/tree/render/service/header.js +125 -0
  908. package/dist/core/repo/tree/render/service/header.js.map +1 -0
  909. package/dist/core/repo/tree/render/service/peers.js +28 -0
  910. package/dist/core/repo/tree/render/service/peers.js.map +1 -0
  911. package/dist/core/repo/tree/render/service/view-id.js +67 -0
  912. package/dist/core/repo/tree/render/service/view-id.js.map +1 -0
  913. package/dist/core/repo/tree/render/service/views.js +78 -0
  914. package/dist/core/repo/tree/render/service/views.js.map +1 -0
  915. package/dist/core/repo/tree/render/stale.js +42 -0
  916. package/dist/core/repo/tree/render/stale.js.map +1 -0
  917. package/dist/core/repo/tree/render/text.js +84 -0
  918. package/dist/core/repo/tree/render/text.js.map +1 -0
  919. package/dist/core/repo/tree/render/views.js +293 -0
  920. package/dist/core/repo/tree/render/views.js.map +1 -0
  921. package/dist/core/repo/tree/walk.js +255 -0
  922. package/dist/core/repo/tree/walk.js.map +1 -0
  923. package/dist/core/results.js +146 -14
  924. package/dist/core/results.js.map +1 -1
  925. package/dist/core/scaffold/landscape.js +239 -0
  926. package/dist/core/scaffold/landscape.js.map +1 -0
  927. package/dist/core/scaffold/legacy.js +271 -0
  928. package/dist/core/scaffold/legacy.js.map +1 -0
  929. package/dist/core/scaffold/readme.js +84 -0
  930. package/dist/core/scaffold/readme.js.map +1 -0
  931. package/dist/core/staging/commit.js +252 -0
  932. package/dist/core/staging/commit.js.map +1 -0
  933. package/dist/core/staging/interrupted.js +96 -0
  934. package/dist/core/staging/interrupted.js.map +1 -0
  935. package/dist/core/staging/lock.js +268 -0
  936. package/dist/core/staging/lock.js.map +1 -0
  937. package/dist/core/staging/recovery/finding.js +35 -0
  938. package/dist/core/staging/recovery/finding.js.map +1 -0
  939. package/dist/core/staging/recovery/intent.js +95 -0
  940. package/dist/core/staging/recovery/intent.js.map +1 -0
  941. package/dist/core/staging/recovery/recover.js +204 -0
  942. package/dist/core/staging/recovery/recover.js.map +1 -0
  943. package/dist/core/staging/recovery/residue.js +62 -0
  944. package/dist/core/staging/recovery/residue.js.map +1 -0
  945. package/dist/core/staging/snapshot/manifest.js +188 -0
  946. package/dist/core/staging/snapshot/manifest.js.map +1 -0
  947. package/dist/core/staging/snapshot/snapshot.js +196 -0
  948. package/dist/core/staging/snapshot/snapshot.js.map +1 -0
  949. package/dist/core/staging/txn/forward.js +181 -0
  950. package/dist/core/staging/txn/forward.js.map +1 -0
  951. package/dist/core/staging/txn/journal.js +139 -0
  952. package/dist/core/staging/txn/journal.js.map +1 -0
  953. package/dist/core/staging/txn/transaction.js +75 -0
  954. package/dist/core/staging/txn/transaction.js.map +1 -0
  955. package/dist/core/staging/writes.js +113 -0
  956. package/dist/core/staging/writes.js.map +1 -0
  957. package/dist/core/status/actions/execution.js +60 -0
  958. package/dist/core/status/actions/execution.js.map +1 -0
  959. package/dist/core/status/contracts.js +126 -0
  960. package/dist/core/status/contracts.js.map +1 -0
  961. package/dist/core/status/feature/artifacts.js +196 -0
  962. package/dist/core/status/feature/artifacts.js.map +1 -0
  963. package/dist/core/status/feature/feature.js +214 -0
  964. package/dist/core/status/feature/feature.js.map +1 -0
  965. package/dist/core/status/feature/next.js +163 -0
  966. package/dist/core/status/feature/next.js.map +1 -0
  967. package/dist/core/status/feature/state.js +21 -0
  968. package/dist/core/status/feature/state.js.map +1 -0
  969. package/dist/core/status/feature/words.js +96 -0
  970. package/dist/core/status/feature/words.js.map +1 -0
  971. package/dist/core/status/fleet/fleet.js +216 -0
  972. package/dist/core/status/fleet/fleet.js.map +1 -0
  973. package/dist/core/status/fleet/next.js +302 -0
  974. package/dist/core/status/fleet/next.js.map +1 -0
  975. package/dist/core/status/interrupted.js +97 -0
  976. package/dist/core/status/interrupted.js.map +1 -0
  977. package/dist/core/status/report.js +31 -0
  978. package/dist/core/status/report.js.map +1 -0
  979. package/dist/core/status/scan.js +41 -0
  980. package/dist/core/status/scan.js.map +1 -0
  981. package/dist/core/status/verification.js +216 -0
  982. package/dist/core/status/verification.js.map +1 -0
  983. package/dist/core/tasks/packet.js +199 -0
  984. package/dist/core/tasks/packet.js.map +1 -0
  985. package/dist/core/tasks/record.js +43 -0
  986. package/dist/core/tasks/record.js.map +1 -0
  987. package/dist/core/tasks/sources.js +181 -0
  988. package/dist/core/tasks/sources.js.map +1 -0
  989. package/dist/core/tasks/stamps.js +76 -0
  990. package/dist/core/tasks/stamps.js.map +1 -0
  991. package/dist/core/tasks/unit.js +0 -0
  992. package/dist/core/tasks/unit.js.map +1 -0
  993. package/dist/core/usecases/capability.js +166 -0
  994. package/dist/core/usecases/capability.js.map +1 -0
  995. package/dist/core/usecases/delta/claims.js +140 -0
  996. package/dist/core/usecases/delta/claims.js.map +1 -0
  997. package/dist/core/usecases/delta/flows.js +101 -0
  998. package/dist/core/usecases/delta/flows.js.map +1 -0
  999. package/dist/core/usecases/delta/modified.js +315 -0
  1000. package/dist/core/usecases/delta/modified.js.map +1 -0
  1001. package/dist/core/usecases/delta/overlay.js +76 -0
  1002. package/dist/core/usecases/delta/overlay.js.map +1 -0
  1003. package/dist/core/usecases/fleet.js +296 -0
  1004. package/dist/core/usecases/fleet.js.map +1 -0
  1005. package/dist/core/usecases/grade/capability-tag.js +93 -0
  1006. package/dist/core/usecases/grade/capability-tag.js.map +1 -0
  1007. package/dist/core/usecases/grade/feature.js +88 -0
  1008. package/dist/core/usecases/grade/feature.js.map +1 -0
  1009. package/dist/core/usecases/grade/requirement-tag.js +94 -0
  1010. package/dist/core/usecases/grade/requirement-tag.js.map +1 -0
  1011. package/dist/core/usecases/grade/steps.js +266 -0
  1012. package/dist/core/usecases/grade/steps.js.map +1 -0
  1013. package/dist/core/usecases/grade/usecases.js +112 -0
  1014. package/dist/core/usecases/grade/usecases.js.map +1 -0
  1015. package/dist/core/usecases/operations.js +123 -0
  1016. package/dist/core/usecases/operations.js.map +1 -0
  1017. package/dist/core/usecases/place.js +44 -0
  1018. package/dist/core/usecases/place.js.map +1 -0
  1019. package/dist/core/usecases/service/exclude.js +119 -0
  1020. package/dist/core/usecases/service/exclude.js.map +1 -0
  1021. package/dist/core/usecases/service/flows.js +164 -0
  1022. package/dist/core/usecases/service/flows.js.map +1 -0
  1023. package/dist/core/usecases/suites/participants.js +83 -0
  1024. package/dist/core/usecases/suites/participants.js.map +1 -0
  1025. package/dist/core/usecases/suites/suites.js +45 -0
  1026. package/dist/core/usecases/suites/suites.js.map +1 -0
  1027. package/dist/core/usecases/touch.js +101 -0
  1028. package/dist/core/usecases/touch.js.map +1 -0
  1029. package/dist/core/verify/answers.js +180 -0
  1030. package/dist/core/verify/answers.js.map +1 -0
  1031. package/dist/core/verify/build.js +170 -0
  1032. package/dist/core/verify/build.js.map +1 -0
  1033. package/dist/core/verify/checklist.js +259 -0
  1034. package/dist/core/verify/checklist.js.map +1 -0
  1035. package/dist/core/verify/claims/identity.js +61 -0
  1036. package/dist/core/verify/claims/identity.js.map +1 -0
  1037. package/dist/core/verify/cross/diff.js +97 -0
  1038. package/dist/core/verify/cross/diff.js.map +1 -0
  1039. package/dist/core/verify/evidence/contract.js +169 -0
  1040. package/dist/core/verify/evidence/contract.js.map +1 -0
  1041. package/dist/core/verify/location.js +67 -0
  1042. package/dist/core/verify/location.js.map +1 -0
  1043. package/dist/core/verify/pins/lint.js +158 -0
  1044. package/dist/core/verify/pins/lint.js.map +1 -0
  1045. package/dist/core/verify/pins/pin.js +95 -0
  1046. package/dist/core/verify/pins/pin.js.map +1 -0
  1047. package/dist/core/verify/read/file.js +224 -0
  1048. package/dist/core/verify/read/file.js.map +1 -0
  1049. package/dist/core/verify/read/shape.js +169 -0
  1050. package/dist/core/verify/read/shape.js.map +1 -0
  1051. package/dist/core/verify/read/union.js +105 -0
  1052. package/dist/core/verify/read/union.js.map +1 -0
  1053. package/dist/core/verify/record.js +165 -0
  1054. package/dist/core/verify/record.js.map +1 -0
  1055. package/dist/core/verify/store/commit.js +99 -0
  1056. package/dist/core/verify/store/commit.js.map +1 -0
  1057. package/dist/core/verify/store/render.js +61 -0
  1058. package/dist/core/verify/store/render.js.map +1 -0
  1059. package/dist/core/vocabulary/health.js +91 -0
  1060. package/dist/core/vocabulary/health.js.map +1 -0
  1061. package/dist/core/vocabulary/issue.js +59 -0
  1062. package/dist/core/vocabulary/issue.js.map +1 -0
  1063. package/dist/core/vocabulary/maturity.js +216 -0
  1064. package/dist/core/vocabulary/maturity.js.map +1 -0
  1065. package/dist/core/vocabulary/report.js +90 -0
  1066. package/dist/core/vocabulary/report.js.map +1 -0
  1067. package/dist/core/vocabulary/steps.js +266 -0
  1068. package/dist/core/vocabulary/steps.js.map +1 -0
  1069. package/dist/core/workspace/discover.js +239 -0
  1070. package/dist/core/workspace/discover.js.map +1 -0
  1071. package/dist/core/workspace/render.js +52 -0
  1072. package/dist/core/workspace/render.js.map +1 -0
  1073. package/examples/README.md +232 -0
  1074. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  1075. package/examples/docs/architecture/capabilities.yaml +31 -0
  1076. package/examples/docs/architecture/landscape.likec4 +336 -0
  1077. package/examples/docs/architecture/obligations.yaml +23 -0
  1078. package/examples/docs/architecture/permissions.yaml +50 -0
  1079. package/examples/docs/architecture/services.likec4 +70 -0
  1080. package/examples/docs/architecture/subsystems.likec4 +18 -0
  1081. package/examples/docs/architecture/usecases/order-notification.likec4 +74 -0
  1082. package/examples/docs/capabilities/checkout/spec.md +55 -0
  1083. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  1084. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  1085. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  1086. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  1087. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  1088. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  1089. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +132 -0
  1090. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  1091. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  1092. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  1093. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  1094. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  1095. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +31 -0
  1096. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  1097. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  1098. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  1099. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  1100. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  1101. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  1102. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  1103. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  1104. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  1105. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  1106. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +73 -0
  1107. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  1108. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  1109. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  1110. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  1111. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  1112. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  1113. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  1114. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  1115. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  1116. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  1117. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  1118. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  1119. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  1120. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  1121. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  1122. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  1123. package/examples/docs/glossary/order.md +15 -0
  1124. package/examples/docs/glossary/payments/authorization.md +14 -0
  1125. package/examples/docs/likec4.config.json +8 -0
  1126. package/examples/docs/loam.json +3 -0
  1127. package/examples/docs/services/checkout-web/model.likec4 +92 -0
  1128. package/examples/docs/services/checkout-web/spec.md +91 -0
  1129. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  1130. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  1131. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  1132. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  1133. package/examples/docs/services/order-service/arch.spec.md +134 -0
  1134. package/examples/docs/services/order-service/asyncapi.yaml +109 -0
  1135. package/examples/docs/services/order-service/health.yaml +57 -0
  1136. package/examples/docs/services/order-service/model.likec4 +126 -0
  1137. package/examples/docs/services/order-service/openapi.yaml +257 -0
  1138. package/examples/docs/services/order-service/runbook.md +62 -0
  1139. package/examples/docs/services/order-service/spec.md +134 -0
  1140. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  1141. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  1142. package/examples/docs/services/payment-service/arch.spec.md +76 -0
  1143. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  1144. package/examples/docs/services/payment-service/health.yaml +39 -0
  1145. package/examples/docs/services/payment-service/model.likec4 +68 -0
  1146. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  1147. package/examples/docs/services/payment-service/runbook.md +37 -0
  1148. package/examples/docs/services/payment-service/spec.md +88 -0
  1149. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  1150. package/examples/docs/services/platform/identity-service/arch.spec.md +120 -0
  1151. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  1152. package/examples/docs/services/platform/identity-service/model.likec4 +81 -0
  1153. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  1154. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  1155. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  1156. package/examples/docs/services/platform/notification-service/asyncapi.yaml +200 -0
  1157. package/examples/docs/services/platform/notification-service/health.yaml +40 -0
  1158. package/examples/docs/services/platform/notification-service/model.likec4 +97 -0
  1159. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  1160. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  1161. package/examples/docs/services/platform/subsystem.yaml +2 -0
  1162. package/examples/fleet.yaml +57 -0
  1163. package/package.json +19 -6
  1164. package/dist/commands/adopt.js +0 -240
  1165. package/dist/commands/adopt.js.map +0 -1
  1166. package/dist/commands/archive.js +0 -1313
  1167. package/dist/commands/archive.js.map +0 -1
  1168. package/dist/commands/delta.js +0 -388
  1169. package/dist/commands/delta.js.map +0 -1
  1170. package/dist/commands/docs-repo-gate.js.map +0 -1
  1171. package/dist/commands/format.js +0 -17
  1172. package/dist/commands/format.js.map +0 -1
  1173. package/dist/commands/gherkin.js +0 -309
  1174. package/dist/commands/gherkin.js.map +0 -1
  1175. package/dist/commands/init.js.map +0 -1
  1176. package/dist/commands/list.js +0 -295
  1177. package/dist/commands/list.js.map +0 -1
  1178. package/dist/commands/migrate-openspec.js +0 -950
  1179. package/dist/commands/migrate-openspec.js.map +0 -1
  1180. package/dist/commands/new.js +0 -413
  1181. package/dist/commands/new.js.map +0 -1
  1182. package/dist/commands/rebase.js +0 -356
  1183. package/dist/commands/rebase.js.map +0 -1
  1184. package/dist/commands/show.js +0 -320
  1185. package/dist/commands/show.js.map +0 -1
  1186. package/dist/commands/status.js +0 -262
  1187. package/dist/commands/status.js.map +0 -1
  1188. package/dist/commands/unarchive.js +0 -317
  1189. package/dist/commands/unarchive.js.map +0 -1
  1190. package/dist/commands/validate.js +0 -1773
  1191. package/dist/commands/validate.js.map +0 -1
  1192. package/dist/commands/verify.js +0 -775
  1193. package/dist/commands/verify.js.map +0 -1
  1194. package/dist/commands/vouch.js +0 -421
  1195. package/dist/commands/vouch.js.map +0 -1
  1196. package/dist/core/agent.js +0 -2173
  1197. package/dist/core/agent.js.map +0 -1
  1198. package/dist/core/agents-stamp.js.map +0 -1
  1199. package/dist/core/arch.js +0 -130
  1200. package/dist/core/arch.js.map +0 -1
  1201. package/dist/core/asyncapi.js +0 -253
  1202. package/dist/core/asyncapi.js.map +0 -1
  1203. package/dist/core/brief.js +0 -755
  1204. package/dist/core/brief.js.map +0 -1
  1205. package/dist/core/coherence.js +0 -577
  1206. package/dist/core/coherence.js.map +0 -1
  1207. package/dist/core/concurrency.js.map +0 -1
  1208. package/dist/core/config.js.map +0 -1
  1209. package/dist/core/delta.js +0 -476
  1210. package/dist/core/delta.js.map +0 -1
  1211. package/dist/core/dependencies.js +0 -356
  1212. package/dist/core/dependencies.js.map +0 -1
  1213. package/dist/core/doctor.js +0 -596
  1214. package/dist/core/doctor.js.map +0 -1
  1215. package/dist/core/document-bytes.js.map +0 -1
  1216. package/dist/core/explore.js +0 -225
  1217. package/dist/core/explore.js.map +0 -1
  1218. package/dist/core/frontmatter.js.map +0 -1
  1219. package/dist/core/gherkin.js +0 -463
  1220. package/dist/core/gherkin.js.map +0 -1
  1221. package/dist/core/health.js +0 -67
  1222. package/dist/core/health.js.map +0 -1
  1223. package/dist/core/ids.js +0 -122
  1224. package/dist/core/ids.js.map +0 -1
  1225. package/dist/core/issue.js +0 -9
  1226. package/dist/core/issue.js.map +0 -1
  1227. package/dist/core/json.js +0 -74
  1228. package/dist/core/json.js.map +0 -1
  1229. package/dist/core/likec4.js +0 -489
  1230. package/dist/core/likec4.js.map +0 -1
  1231. package/dist/core/maturity.js +0 -66
  1232. package/dist/core/maturity.js.map +0 -1
  1233. package/dist/core/openapi-merge.js +0 -552
  1234. package/dist/core/openapi-merge.js.map +0 -1
  1235. package/dist/core/openapi.js.map +0 -1
  1236. package/dist/core/openspec-inventory.js +0 -1440
  1237. package/dist/core/openspec-inventory.js.map +0 -1
  1238. package/dist/core/path-safety.js.map +0 -1
  1239. package/dist/core/provenance.js +0 -787
  1240. package/dist/core/provenance.js.map +0 -1
  1241. package/dist/core/records.js.map +0 -1
  1242. package/dist/core/repo.js +0 -438
  1243. package/dist/core/repo.js.map +0 -1
  1244. package/dist/core/report.js +0 -47
  1245. package/dist/core/report.js.map +0 -1
  1246. package/dist/core/spec.js +0 -505
  1247. package/dist/core/spec.js.map +0 -1
  1248. package/dist/core/staging.js +0 -890
  1249. package/dist/core/staging.js.map +0 -1
  1250. package/dist/core/status.js +0 -1132
  1251. package/dist/core/status.js.map +0 -1
  1252. package/dist/core/steps.js +0 -72
  1253. package/dist/core/steps.js.map +0 -1
  1254. package/dist/core/verify.js +0 -807
  1255. package/dist/core/verify.js.map +0 -1
  1256. package/dist/core/version.js.map +0 -1
@@ -0,0 +1,141 @@
1
+ /**
2
+ * A deliberately small CODEOWNERS reader: directory-pattern rules only,
3
+ * parsed fail-closed, matched mechanically — the join behind
4
+ * `loam list --owners <path>`. loam does not grow an ownership model of its
5
+ * own (SCHEMA.md: ownership is CODEOWNERS); this module only reads back, as
6
+ * data, what the forge's file already says.
7
+ *
8
+ * Three postures, and the line between them is the module's whole design:
9
+ *
10
+ * - A rule the subset UNDERSTANDS — a plain directory path, optionally
11
+ * anchored with a leading `/`, optionally ending `/`, `/*` or `/**` — is
12
+ * matched, last match winning, GitHub's own precedence. An OWNER-LESS rule
13
+ * with such a pattern is understood too: it CLEARS ownership for what it
14
+ * matches, exactly as the forge reads it — skipping it would fail in the
15
+ * dangerous direction, leaving the earlier broad rule's team holding a
16
+ * service the forge explicitly took off their plate.
17
+ * - A rule the subset RECOGNISES but does not implement — any other wildcard
18
+ * use, `*` and `*.md` above all — is SKIPPED and reported, never guessed
19
+ * at: an attribution computed from a half-understood pattern would file
20
+ * services under teams the forge never named. Skipping only ever
21
+ * UNDER-attributes (a service reads unowned, honestly listed), never the
22
+ * reverse. The caller surfaces `skipped` beside the join.
23
+ * - A line that cannot be read as `pattern owner…` at all refuses as data
24
+ * (`{ ok: false, line }`): silently dropping lines of a corrupted file
25
+ * would grade it as a thin one — the same fail-closed rule the answers
26
+ * reader applies to the other user-named file (`answers-unreadable`).
27
+ *
28
+ * Matching is by path SEGMENTS: a rule matches a service directory when the
29
+ * pattern's segments appear as one contiguous run in the service's
30
+ * docs-repo-relative directory segments — starting at the root when the
31
+ * pattern is anchored, at any depth when it is not. Two deliberate
32
+ * divergences from gitignore semantics, both pinned by
33
+ * test/list-campaign.test.ts so they are documented behaviour, not accident:
34
+ * a slash-containing pattern WITHOUT a leading `/` (`services/payments/`)
35
+ * matches at any depth here, where the forge would anchor it to the root —
36
+ * a BROADER attribution, since a rule can match at a depth GitHub would
37
+ * not, though the segments still have to appear verbatim; and a trailing
38
+ * `/*` is read as the directory itself (services anywhere beneath match),
39
+ * where GitHub would stop at direct children. One rule for all spellings
40
+ * keeps the subset explainable in a sentence.
41
+ *
42
+ * Pure on purpose: content arrives as a string, and nothing here touches the
43
+ * filesystem or prints, so the command layer owns the read and the
44
+ * `owners-unreadable` refusal (core never prints — AGENTS.md).
45
+ */
46
+ /**
47
+ * What an owner token may look like: `@user`, `@org/team`, or an email — the
48
+ * three forms GitHub's own syntax accepts. Anything else in owner position is
49
+ * a corrupted line, not a rule, and the whole parse refuses with its number.
50
+ */
51
+ const OWNER_TOKEN = /^@[^\s@/]+(?:\/[^\s@/]+)?$|^[^\s@]+@[^\s@]+\.[^\s@]+$/;
52
+ export function parseCodeowners(content) {
53
+ const rules = [];
54
+ const skipped = [];
55
+ // A UTF-8 BOM would otherwise glue itself onto the first pattern and turn
56
+ // an anchored rule silently unanchored.
57
+ const lines = content.replace(/^\uFEFF/, "").split(/\r?\n/);
58
+ for (const [index, raw] of lines.entries()) {
59
+ const line = index + 1;
60
+ const text = raw.trim();
61
+ if (text === "" || text.startsWith("#"))
62
+ continue;
63
+ // A trailing comment is dropped from its `#` token on. Owners precede any
64
+ // comment, so nothing a comment says can change the rule it annotates —
65
+ // and the `#` token cannot be index 0, because a line whose first token
66
+ // starts with `#` took the comment branch above.
67
+ const tokens = text.split(/\s+/);
68
+ const hash = tokens.findIndex((token) => token.startsWith("#"));
69
+ const effective = hash === -1 ? tokens : tokens.slice(0, hash);
70
+ const pattern = effective[0];
71
+ const owners = effective.slice(1);
72
+ const bad = owners.find((token) => !OWNER_TOKEN.test(token));
73
+ if (bad !== undefined) {
74
+ return { ok: false, line, problem: `'${bad}' is not an owner (@user, @org/team or an email address)` };
75
+ }
76
+ const read = readPattern(pattern);
77
+ if (read === null) {
78
+ skipped.push({ line, pattern });
79
+ continue;
80
+ }
81
+ // `owners` may be empty: an owner-less in-subset rule is GitHub's
82
+ // ownership-clearing form, and last-match-wins performs the clear for
83
+ // free — a matching empty rule overwrites the earlier team with nobody.
84
+ rules.push({ line, pattern, ...read, owners });
85
+ }
86
+ return { ok: true, rules, skipped };
87
+ }
88
+ /** The pattern grammar of the implemented subset, or null when outside it. */
89
+ function readPattern(pattern) {
90
+ const trimmed = pattern.endsWith("/**")
91
+ ? pattern.slice(0, -3)
92
+ : pattern.endsWith("/*")
93
+ ? pattern.slice(0, -2)
94
+ : pattern;
95
+ // Any wildcard, character class, negation or escape elsewhere in the
96
+ // pattern is real CODEOWNERS syntax this subset does not implement.
97
+ if (/[*?[\]!\\]/.test(trimmed))
98
+ return null;
99
+ const anchored = trimmed.startsWith("/");
100
+ const body = (anchored ? trimmed.slice(1) : trimmed).replace(/\/$/, "");
101
+ if (body === "")
102
+ return null;
103
+ const segments = body.split("/");
104
+ if (segments.some((segment) => segment === ""))
105
+ return null;
106
+ return { anchored, segments };
107
+ }
108
+ /**
109
+ * The owners of the LAST rule matching this directory, or `[]` for an
110
+ * unowned one — later rules override earlier ones, GitHub's own precedence,
111
+ * so a specific team can reclaim a corner of a broadly-owned tree. `dir` is
112
+ * the service's docs-repo-relative directory split on `/`
113
+ * (`["services", "payments", "pay-a"]`).
114
+ */
115
+ export function ownersFor(dir, rules) {
116
+ let owners = [];
117
+ for (const rule of rules) {
118
+ if (matches(dir, rule))
119
+ owners = rule.owners;
120
+ }
121
+ return owners;
122
+ }
123
+ /**
124
+ * A directory pattern names a directory, and covers the service AT that
125
+ * directory and every service beneath it — which is exactly "the pattern's
126
+ * segments appear as a contiguous run in the service's own segments".
127
+ */
128
+ function matches(dir, rule) {
129
+ const last = dir.length - rule.segments.length;
130
+ if (last < 0)
131
+ return false;
132
+ const startsAt = (from) => rule.segments.every((segment, i) => dir[from + i] === segment);
133
+ if (rule.anchored)
134
+ return startsAt(0);
135
+ for (let from = 0; from <= last; from += 1) {
136
+ if (startsAt(from))
137
+ return true;
138
+ }
139
+ return false;
140
+ }
141
+ //# sourceMappingURL=codeowners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeowners.js","sourceRoot":"","sources":["../../../src/core/owners/codeowners.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A deliberately small CODEOWNERS reader: directory-pattern rules only,\n * parsed fail-closed, matched mechanically — the join behind\n * `loam list --owners <path>`. loam does not grow an ownership model of its\n * own (SCHEMA.md: ownership is CODEOWNERS); this module only reads back, as\n * data, what the forge's file already says.\n *\n * Three postures, and the line between them is the module's whole design:\n *\n * - A rule the subset UNDERSTANDS — a plain directory path, optionally\n * anchored with a leading `/`, optionally ending `/`, `/*` or `/**` — is\n * matched, last match winning, GitHub's own precedence. An OWNER-LESS rule\n * with such a pattern is understood too: it CLEARS ownership for what it\n * matches, exactly as the forge reads it — skipping it would fail in the\n * dangerous direction, leaving the earlier broad rule's team holding a\n * service the forge explicitly took off their plate.\n * - A rule the subset RECOGNISES but does not implement — any other wildcard\n * use, `*` and `*.md` above all — is SKIPPED and reported, never guessed\n * at: an attribution computed from a half-understood pattern would file\n * services under teams the forge never named. Skipping only ever\n * UNDER-attributes (a service reads unowned, honestly listed), never the\n * reverse. The caller surfaces `skipped` beside the join.\n * - A line that cannot be read as `pattern owner…` at all refuses as data\n * (`{ ok: false, line }`): silently dropping lines of a corrupted file\n * would grade it as a thin one — the same fail-closed rule the answers\n * reader applies to the other user-named file (`answers-unreadable`).\n *\n * Matching is by path SEGMENTS: a rule matches a service directory when the\n * pattern's segments appear as one contiguous run in the service's\n * docs-repo-relative directory segments — starting at the root when the\n * pattern is anchored, at any depth when it is not. Two deliberate\n * divergences from gitignore semantics, both pinned by\n * test/list-campaign.test.ts so they are documented behaviour, not accident:\n * a slash-containing pattern WITHOUT a leading `/` (`services/payments/`)\n * matches at any depth here, where the forge would anchor it to the root —\n * a BROADER attribution, since a rule can match at a depth GitHub would\n * not, though the segments still have to appear verbatim; and a trailing\n * `/*` is read as the directory itself (services anywhere beneath match),\n * where GitHub would stop at direct children. One rule for all spellings\n * keeps the subset explainable in a sentence.\n *\n * Pure on purpose: content arrives as a string, and nothing here touches the\n * filesystem or prints, so the command layer owns the read and the\n * `owners-unreadable` refusal (core never prints — AGENTS.md).\n */\n\n/** One rule the implemented subset accepted, in file order. */\nexport interface OwnersRule {\n /** 1-based line number in the file, for messages and reports. */\n readonly line: number;\n /** The pattern exactly as written, for reporting. */\n readonly pattern: string;\n /** True when the pattern began with `/` — matched from the repo root only. */\n readonly anchored: boolean;\n /** The pattern's path segments, leading `/`, trailing `/`, `/*`, `/**` stripped. */\n readonly segments: readonly string[];\n readonly owners: readonly string[];\n}\n\n/** A recognised rule outside the implemented subset — reported, never guessed. */\nexport interface SkippedRule {\n readonly line: number;\n readonly pattern: string;\n}\n\nexport type ParsedCodeowners =\n | { readonly ok: true; readonly rules: readonly OwnersRule[]; readonly skipped: readonly SkippedRule[] }\n | { readonly ok: false; readonly line: number; readonly problem: string };\n\n/**\n * What an owner token may look like: `@user`, `@org/team`, or an email — the\n * three forms GitHub's own syntax accepts. Anything else in owner position is\n * a corrupted line, not a rule, and the whole parse refuses with its number.\n */\nconst OWNER_TOKEN = /^@[^\\s@/]+(?:\\/[^\\s@/]+)?$|^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport function parseCodeowners(content: string): ParsedCodeowners {\n const rules: OwnersRule[] = [];\n const skipped: SkippedRule[] = [];\n // A UTF-8 BOM would otherwise glue itself onto the first pattern and turn\n // an anchored rule silently unanchored.\n const lines = content.replace(/^\\uFEFF/, \"\").split(/\\r?\\n/);\n for (const [index, raw] of lines.entries()) {\n const line = index + 1;\n const text = raw.trim();\n if (text === \"\" || text.startsWith(\"#\")) continue;\n // A trailing comment is dropped from its `#` token on. Owners precede any\n // comment, so nothing a comment says can change the rule it annotates —\n // and the `#` token cannot be index 0, because a line whose first token\n // starts with `#` took the comment branch above.\n const tokens = text.split(/\\s+/);\n const hash = tokens.findIndex((token) => token.startsWith(\"#\"));\n const effective = hash === -1 ? tokens : tokens.slice(0, hash);\n const pattern = effective[0]!;\n const owners = effective.slice(1);\n const bad = owners.find((token) => !OWNER_TOKEN.test(token));\n if (bad !== undefined) {\n return { ok: false, line, problem: `'${bad}' is not an owner (@user, @org/team or an email address)` };\n }\n const read = readPattern(pattern);\n if (read === null) {\n skipped.push({ line, pattern });\n continue;\n }\n // `owners` may be empty: an owner-less in-subset rule is GitHub's\n // ownership-clearing form, and last-match-wins performs the clear for\n // free — a matching empty rule overwrites the earlier team with nobody.\n rules.push({ line, pattern, ...read, owners });\n }\n return { ok: true, rules, skipped };\n}\n\n/** The pattern grammar of the implemented subset, or null when outside it. */\nfunction readPattern(pattern: string): { anchored: boolean; segments: string[] } | null {\n const trimmed = pattern.endsWith(\"/**\")\n ? pattern.slice(0, -3)\n : pattern.endsWith(\"/*\")\n ? pattern.slice(0, -2)\n : pattern;\n // Any wildcard, character class, negation or escape elsewhere in the\n // pattern is real CODEOWNERS syntax this subset does not implement.\n if (/[*?[\\]!\\\\]/.test(trimmed)) return null;\n const anchored = trimmed.startsWith(\"/\");\n const body = (anchored ? trimmed.slice(1) : trimmed).replace(/\\/$/, \"\");\n if (body === \"\") return null;\n const segments = body.split(\"/\");\n if (segments.some((segment) => segment === \"\")) return null;\n return { anchored, segments };\n}\n\n/**\n * The owners of the LAST rule matching this directory, or `[]` for an\n * unowned one — later rules override earlier ones, GitHub's own precedence,\n * so a specific team can reclaim a corner of a broadly-owned tree. `dir` is\n * the service's docs-repo-relative directory split on `/`\n * (`[\"services\", \"payments\", \"pay-a\"]`).\n */\nexport function ownersFor(dir: readonly string[], rules: readonly OwnersRule[]): readonly string[] {\n let owners: readonly string[] = [];\n for (const rule of rules) {\n if (matches(dir, rule)) owners = rule.owners;\n }\n return owners;\n}\n\n/**\n * A directory pattern names a directory, and covers the service AT that\n * directory and every service beneath it — which is exactly \"the pattern's\n * segments appear as a contiguous run in the service's own segments\".\n */\nfunction matches(dir: readonly string[], rule: OwnersRule): boolean {\n const last = dir.length - rule.segments.length;\n if (last < 0) return false;\n const startsAt = (from: number): boolean =>\n rule.segments.every((segment, i) => dir[from + i] === segment);\n if (rule.anchored) return startsAt(0);\n for (let from = 0; from <= last; from += 1) {\n if (startsAt(from)) return true;\n }\n return false;\n}\n"]}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * The in-flight section of one service's context pack: every active feature
3
+ * whose delta touches the service, projected onto it exactly the way
4
+ * `loam delta` projects — same helpers (`core/projection/`), same known-set,
5
+ * same shapes — so the pack and the brief can never disagree about what a
6
+ * feature changes here.
7
+ *
8
+ * THE BUSINESS CORPUS IS DELIBERATELY EXCLUDED, and it is the one place this
9
+ * module and `loam delta` are allowed to differ. `loam delta` gained a
10
+ * `capabilities` section — the promises a feature changes, and the
11
+ * `Realizes: <capability>#<id>` entry each one is addressed by — because it is
12
+ * read by a person about to author a requirement. A context pack is not that:
13
+ * it is ONE SERVICE'S slice, assembled to be copied into that service's own
14
+ * repository, and a capability delta names no service. Including it would make
15
+ * a service repository's briefing depend on the fleet's business corpus — the
16
+ * first such dependency anywhere in loam, and the exact inversion of the rule
17
+ * this axis is built on, that neither corpus is derived from the other
18
+ * (`core/capabilities/rollup.ts` states it: "TWO CORPORA MEET HERE, and neither
19
+ * is derived from the other"). A service that wants to know which promise its
20
+ * requirement keeps reads the `Realizes:` line on the requirement itself, which
21
+ * IS in the pack, because it is part of the service's own document.
22
+ *
23
+ * That is an exclusion by design, not an omission waiting to be filled: adding
24
+ * the section later is a product decision about what a service repository is
25
+ * allowed to depend on, and it needs to be argued in those terms rather than
26
+ * landed as a missing field.
27
+ */
28
+ import { existsSync } from "node:fs";
29
+ import { FleetContext } from "../fleet-context.js";
30
+ import {} from "../c4/likec4.js";
31
+ import { repoPath } from "../envelope/json.js";
32
+ import { stripFrontmatter } from "../document/frontmatter.js";
33
+ import { inOrder } from "../kernel/concurrency.js";
34
+ import { apiChanges } from "../projection/api.js";
35
+ import { eventChanges } from "../projection/events.js";
36
+ import { archSlice, introducedServices } from "../projection/arch-slice.js";
37
+ import { compareIds } from "../repo/entries.js";
38
+ import { featurePaths, featureSpecPaths } from "../repo/paths.js";
39
+ import { packRequirement } from "./living.js";
40
+ export async function buildFeatures(req) {
41
+ const { docsDir, entry, feature, context } = req;
42
+ // `--feature` narrows to the one feature and includes it even when it does
43
+ // not touch the service — a known feature projects onto any living service
44
+ // (delta's stance), and the empty sections plus the feature's own `services`
45
+ // list ARE the answer. The default is every active feature, and "touches"
46
+ // needs each one's C4 delta: a feature that introduces this service draws no
47
+ // specs/<svc>/ directory yet.
48
+ const candidates = feature !== null ? [feature] : await context.listFeatures(docsDir);
49
+ // Batch-parse the deltas through the shared workspace before the pool walks
50
+ // them: `prefetchLikeC4` seeds the memo, so the loop below hits it instead
51
+ // of opening one Langium workspace per feature. Accelerator only — a
52
+ // batch-infrastructure failure degrades silently to per-path loads, so no
53
+ // answer in the pack can ever depend on tmpdir writability.
54
+ await context.prefetchLikeC4(candidates.filter((f) => f.has.delta).map((f) => featurePaths(f.dir).delta));
55
+ // Through the pool: each delta load holds a LikeC4/Langium workspace, and an
56
+ // unbounded fan-out over the features in flight is the memory shape the pool
57
+ // exists to cap. Results come back in input order, which listFeatures already
58
+ // sorted with compareIds — the pack's feature order is that order.
59
+ const loaded = await inOrder(candidates, async (f) => {
60
+ const deltaDoc = f.has.delta ? await context.loadLikeC4(featurePaths(f.dir).delta) : null;
61
+ const services = [...new Set([...f.services, ...introducedServices(deltaDoc, f.id)])].sort(compareIds);
62
+ return { entry: f, deltaDoc, services };
63
+ });
64
+ // A feature whose delta does not parse names no services — `services` above
65
+ // is only its specs/ list — so "does it touch this one?" has no answer. It
66
+ // is INCLUDED, with its errors riding in `architecture.errors` (a hole the
67
+ // command turns into exit 1), because dropping it makes the feature vanish
68
+ // from every service's pack at exit 0: an agent then works in the service
69
+ // believing nothing is in flight, which is the vacuously-green trap again,
70
+ // one document up.
71
+ const deltaUnread = (l) => l.deltaDoc !== null && l.deltaDoc.errors.length > 0;
72
+ const included = feature !== null
73
+ ? loaded
74
+ : loaded.filter((l) => l.services.includes(entry.id) || deltaUnread(l));
75
+ // The living∪feature known-set delta.ts builds, so a container-targeted edge
76
+ // resolves to the same owner here and there.
77
+ const living = (await context.listServices(docsDir)).map((s) => s.id);
78
+ return inOrder(included, (l) => projectFeature({ docsDir, service: entry.id, living, context, loaded: l }));
79
+ }
80
+ async function projectFeature(req) {
81
+ const { docsDir, service, living, context, loaded } = req;
82
+ const { entry: f, deltaDoc, services } = loaded;
83
+ const paths = featurePaths(f.dir);
84
+ const specPaths = featureSpecPaths(f.dir, service);
85
+ // Independent reads, fanned out; the contract projections carry their own
86
+ // readability flags, so nothing here throws for a document that merely does
87
+ // not parse — an unparseable delta is a HOLE the pack reports and the
88
+ // command turns into exit 1, never a refusal.
89
+ const [intentText, reqs, archReqs, api, events] = await Promise.all([
90
+ f.has.intent ? context.readText(paths.intent) : null,
91
+ existsSync(specPaths.spec) ? context.readRequirements(specPaths.spec) : [],
92
+ existsSync(specPaths.archSpec) ? context.readRequirements(specPaths.archSpec) : [],
93
+ apiChanges(specPaths.openapi),
94
+ eventChanges(specPaths.asyncapi),
95
+ ]);
96
+ return {
97
+ feature: f.id,
98
+ path: repoPath(docsDir, f.dir),
99
+ services,
100
+ intent: intentText === null ? null : stripFrontmatter(intentText).trim(),
101
+ requirements: reqs.map(packRequirement),
102
+ archRequirements: archReqs.map(packRequirement),
103
+ ...apiSplit(api),
104
+ events,
105
+ architecture: archSlice(deltaDoc, service, f.id, new Set([...living, ...services])),
106
+ };
107
+ }
108
+ /**
109
+ * The delta payload's split shape, kept verbatim: `api` stays exactly the
110
+ * operations array `loam delta` emits, and the document's readability rides
111
+ * alongside as its own key — a consumer indexing one must not have to learn a
112
+ * second shape here.
113
+ */
114
+ function apiSplit(api) {
115
+ return {
116
+ api: api.changes,
117
+ openapi: { unreadable: api.unreadable, ...(api.error === undefined ? {} : { error: api.error }) },
118
+ };
119
+ }
120
+ //# sourceMappingURL=features.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.js","sourceRoot":"","sources":["../../../src/core/pack/features.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The in-flight section of one service's context pack: every active feature\n * whose delta touches the service, projected onto it exactly the way\n * `loam delta` projects — same helpers (`core/projection/`), same known-set,\n * same shapes — so the pack and the brief can never disagree about what a\n * feature changes here.\n *\n * THE BUSINESS CORPUS IS DELIBERATELY EXCLUDED, and it is the one place this\n * module and `loam delta` are allowed to differ. `loam delta` gained a\n * `capabilities` section — the promises a feature changes, and the\n * `Realizes: <capability>#<id>` entry each one is addressed by — because it is\n * read by a person about to author a requirement. A context pack is not that:\n * it is ONE SERVICE'S slice, assembled to be copied into that service's own\n * repository, and a capability delta names no service. Including it would make\n * a service repository's briefing depend on the fleet's business corpus — the\n * first such dependency anywhere in loam, and the exact inversion of the rule\n * this axis is built on, that neither corpus is derived from the other\n * (`core/capabilities/rollup.ts` states it: \"TWO CORPORA MEET HERE, and neither\n * is derived from the other\"). A service that wants to know which promise its\n * requirement keeps reads the `Realizes:` line on the requirement itself, which\n * IS in the pack, because it is part of the service's own document.\n *\n * That is an exclusion by design, not an omission waiting to be filled: adding\n * the section later is a product decision about what a service repository is\n * allowed to depend on, and it needs to be argued in those terms rather than\n * landed as a missing field.\n */\nimport { existsSync } from \"node:fs\";\nimport { FleetContext } from \"../fleet-context.js\";\nimport { type LoadedDoc } from \"../c4/likec4.js\";\nimport { repoPath } from \"../envelope/json.js\";\nimport { stripFrontmatter } from \"../document/frontmatter.js\";\nimport { inOrder } from \"../kernel/concurrency.js\";\nimport { apiChanges, type ApiChange, type ApiSlice } from \"../projection/api.js\";\nimport { eventChanges, type EventSlice } from \"../projection/events.js\";\nimport { archSlice, introducedServices, type ArchSlice } from \"../projection/arch-slice.js\";\nimport { compareIds, type FeatureEntry, type ServiceEntry } from \"../repo/entries.js\";\nimport { featurePaths, featureSpecPaths } from \"../repo/paths.js\";\nimport { packRequirement, type PackRequirement } from \"./living.js\";\nimport type { DocsDir } from \"../kernel/ids/dirs.js\";\n\n/** One active feature's projection onto the pack's service — `loam delta`'s shapes, verbatim. */\nexport interface PackFeature {\n feature: string;\n path: string;\n /** Every service the feature speaks about: its spec deltas plus what its C4 delta introduces. */\n services: string[];\n intent: string | null;\n requirements: PackRequirement[];\n archRequirements: PackRequirement[];\n api: ApiChange[];\n openapi: { unreadable: boolean; error?: string };\n events: EventSlice;\n architecture: ArchSlice;\n}\n\nexport interface FeaturesRequest {\n docsDir: DocsDir;\n entry: ServiceEntry;\n /** The one feature `--feature` named, or null for every touching feature. */\n feature: FeatureEntry | null;\n context: FleetContext;\n}\n\n/** A feature with its delta loaded and its full service list derived. */\ninterface LoadedFeature {\n entry: FeatureEntry;\n deltaDoc: LoadedDoc | null;\n services: string[];\n}\n\nexport async function buildFeatures(req: FeaturesRequest): Promise<PackFeature[]> {\n const { docsDir, entry, feature, context } = req;\n\n // `--feature` narrows to the one feature and includes it even when it does\n // not touch the service — a known feature projects onto any living service\n // (delta's stance), and the empty sections plus the feature's own `services`\n // list ARE the answer. The default is every active feature, and \"touches\"\n // needs each one's C4 delta: a feature that introduces this service draws no\n // specs/<svc>/ directory yet.\n const candidates = feature !== null ? [feature] : await context.listFeatures(docsDir);\n // Batch-parse the deltas through the shared workspace before the pool walks\n // them: `prefetchLikeC4` seeds the memo, so the loop below hits it instead\n // of opening one Langium workspace per feature. Accelerator only — a\n // batch-infrastructure failure degrades silently to per-path loads, so no\n // answer in the pack can ever depend on tmpdir writability.\n await context.prefetchLikeC4(\n candidates.filter((f) => f.has.delta).map((f) => featurePaths(f.dir).delta),\n );\n // Through the pool: each delta load holds a LikeC4/Langium workspace, and an\n // unbounded fan-out over the features in flight is the memory shape the pool\n // exists to cap. Results come back in input order, which listFeatures already\n // sorted with compareIds — the pack's feature order is that order.\n const loaded: LoadedFeature[] = await inOrder(candidates, async (f) => {\n const deltaDoc = f.has.delta ? await context.loadLikeC4(featurePaths(f.dir).delta) : null;\n const services = [...new Set([...f.services, ...introducedServices(deltaDoc, f.id)])].sort(\n compareIds,\n );\n return { entry: f, deltaDoc, services };\n });\n // A feature whose delta does not parse names no services — `services` above\n // is only its specs/ list — so \"does it touch this one?\" has no answer. It\n // is INCLUDED, with its errors riding in `architecture.errors` (a hole the\n // command turns into exit 1), because dropping it makes the feature vanish\n // from every service's pack at exit 0: an agent then works in the service\n // believing nothing is in flight, which is the vacuously-green trap again,\n // one document up.\n const deltaUnread = (l: LoadedFeature): boolean =>\n l.deltaDoc !== null && l.deltaDoc.errors.length > 0;\n const included =\n feature !== null\n ? loaded\n : loaded.filter((l) => l.services.includes(entry.id) || deltaUnread(l));\n\n // The living∪feature known-set delta.ts builds, so a container-targeted edge\n // resolves to the same owner here and there.\n const living = (await context.listServices(docsDir)).map((s) => s.id);\n return inOrder(included, (l) => projectFeature({ docsDir, service: entry.id, living, context, loaded: l }));\n}\n\ninterface ProjectRequest {\n docsDir: DocsDir;\n service: ServiceEntry[\"id\"];\n living: string[];\n context: FleetContext;\n loaded: LoadedFeature;\n}\n\nasync function projectFeature(req: ProjectRequest): Promise<PackFeature> {\n const { docsDir, service, living, context, loaded } = req;\n const { entry: f, deltaDoc, services } = loaded;\n const paths = featurePaths(f.dir);\n const specPaths = featureSpecPaths(f.dir, service);\n\n // Independent reads, fanned out; the contract projections carry their own\n // readability flags, so nothing here throws for a document that merely does\n // not parse — an unparseable delta is a HOLE the pack reports and the\n // command turns into exit 1, never a refusal.\n const [intentText, reqs, archReqs, api, events] = await Promise.all([\n f.has.intent ? context.readText(paths.intent) : null,\n existsSync(specPaths.spec) ? context.readRequirements(specPaths.spec) : [],\n existsSync(specPaths.archSpec) ? context.readRequirements(specPaths.archSpec) : [],\n apiChanges(specPaths.openapi),\n eventChanges(specPaths.asyncapi),\n ]);\n\n return {\n feature: f.id,\n path: repoPath(docsDir, f.dir),\n services,\n intent: intentText === null ? null : stripFrontmatter(intentText).trim(),\n requirements: reqs.map(packRequirement),\n archRequirements: archReqs.map(packRequirement),\n ...apiSplit(api),\n events,\n architecture: archSlice(deltaDoc, service, f.id, new Set([...living, ...services])),\n };\n}\n\n/**\n * The delta payload's split shape, kept verbatim: `api` stays exactly the\n * operations array `loam delta` emits, and the document's readability rides\n * alongside as its own key — a consumer indexing one must not have to learn a\n * second shape here.\n */\nfunction apiSplit(api: ApiSlice): { api: ApiChange[]; openapi: { unreadable: boolean; error?: string } } {\n return {\n api: api.changes,\n openapi: { unreadable: api.unreadable, ...(api.error === undefined ? {} : { error: api.error }) },\n };\n}\n"]}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * The three fleet-vocabulary joins in one service's context pack: the
3
+ * permissions its requirements gate on, the capabilities they realize, and the
4
+ * business flows it is a hop of. All three resolve a per-service fact against a
5
+ * fleet document, which is what separates them from `./living.ts` — that module
6
+ * never has to look past the service's own directory and the fleet map.
7
+ *
8
+ * The use-case join is the newest and the one whose absence was loudest: an
9
+ * agent briefed on a service was told which capabilities its requirements
10
+ * realize and never told that step 4 of Checkout calls it. The capability is the
11
+ * label; the flow is the caller.
12
+ */
13
+ import { FleetContext } from "../fleet-context.js";
14
+ import { capabilityRollup } from "../capabilities/rollup.js";
15
+ import { repoPath } from "../envelope/json.js";
16
+ import { readVocabulary } from "../permissions/permissions.js";
17
+ import { compareIds } from "../repo/entries.js";
18
+ import { permissionsPath, servicePathsAt, SPEC_AXES } from "../repo/paths.js";
19
+ import { existsSync } from "node:fs";
20
+ import { readUseCases } from "../usecases/fleet.js";
21
+ import { flowsClaiming } from "../usecases/capability.js";
22
+ import { flowsTouching } from "../usecases/touch.js";
23
+ export async function buildJoins(req) {
24
+ const { docsDir, entry, context } = req;
25
+ const paths = servicePathsAt(entry.dir);
26
+ // The same two spec reads `living.ts` makes — memoized on the shared
27
+ // context, so whichever module asks first pays the I/O once and the two
28
+ // cannot read two different versions of one file. Fanned out because the
29
+ // axes are independent; SPEC_AXES order (spec before arch-spec) is preserved
30
+ // by Promise.all, which is what keeps `wanted` deterministic.
31
+ const perAxis = await Promise.all(SPEC_AXES.map((axis) => existsSync(paths[axis.key]) ? context.readRequirements(paths[axis.key]) : Promise.resolve([])));
32
+ const active = perAxis.flat().filter((r) => r.kind !== "REMOVED");
33
+ // One vocabulary parse per pack — the pack asks about one service, so this
34
+ // is once per invocation, not the per-service re-parse fleet-context.ts's
35
+ // stats comment warns against copying.
36
+ const vocab = await readVocabulary(permissionsPath(docsDir));
37
+ const wanted = [...new Set(active.flatMap((r) => r.requires))].sort(compareIds);
38
+ const permissions = wanted.map((id) => {
39
+ const decl = vocab.byId.get(id);
40
+ if (decl === undefined)
41
+ return { id, declared: false };
42
+ return {
43
+ id,
44
+ declared: true,
45
+ subject: decl.subject,
46
+ name: decl.name,
47
+ ...(decl.description === undefined ? {} : { description: decl.description }),
48
+ ...(decl.ownedBy === undefined ? {} : { ownedBy: decl.ownedBy }),
49
+ enforcedBy: decl.enforcedBy,
50
+ };
51
+ });
52
+ // One rollup pass through the shared context cache, exactly as explore seeds
53
+ // capabilities — the reader is injected because fleet-context.ts imports the
54
+ // capabilities package and an import back would be a package cycle.
55
+ const entries = await context.listServices(docsDir);
56
+ const capVocab = await context.capabilities(docsDir);
57
+ const unread = [];
58
+ const rows = await capabilityRollup({
59
+ services: entries,
60
+ vocab: capVocab,
61
+ read: (p) => context.readRequirements(p).catch(() => {
62
+ // Unreadable means "this file's realizations are unknown", never "the
63
+ // pack is unanswerable": the rollup walks EVERY service's spec files,
64
+ // so without this per-read containment one sibling's bad encoding
65
+ // refused every other service's briefing — and only once the fleet
66
+ // declared its first capability, which is exactly the moment the walk
67
+ // starts. The miss travels as `capabilitiesUnread` and is graded as a
68
+ // hole; the target's own copy of the same rejection still refuses the
69
+ // pack through `living.ts`'s uncontained read.
70
+ unread.push(repoPath(docsDir, p));
71
+ return [];
72
+ }),
73
+ });
74
+ // One use-case scan for the whole pack, feeding both joins below. It gates
75
+ // its own load, so a docs repo whose architecture/ never mentions the reserved
76
+ // tag prefix costs a readdir here rather than a LikeC4 workspace — the same
77
+ // discipline `loam delta` needs and this pack inherits for free.
78
+ const known = new Set(entries.map((e) => e.id));
79
+ const scan = await readUseCases({ docsDir, known });
80
+ const capabilities = rows
81
+ .filter((row) => row.services.includes(entry.id))
82
+ .map((row) => ({
83
+ id: row.id,
84
+ ...(row.description === undefined ? {} : { description: row.description }),
85
+ ...(row.owner === undefined ? {} : { owner: row.owner }),
86
+ requirements: [
87
+ ...new Set(row.realizedBy.filter((r) => r.service === entry.id).map((r) => r.requirement)),
88
+ ],
89
+ useCases: flowsClaiming(scan, row.id),
90
+ }));
91
+ return {
92
+ permissions,
93
+ permissionsVocabulary: {
94
+ present: vocab.present,
95
+ ...(vocab.invalid === undefined ? {} : { invalid: vocab.invalid }),
96
+ },
97
+ capabilities,
98
+ capabilitiesVocabulary: {
99
+ present: capVocab.present,
100
+ ...(capVocab.invalid === undefined ? {} : { invalid: capVocab.invalid }),
101
+ },
102
+ // The rollup awaits each read in its own walk order, so the push order is
103
+ // already deterministic; sorted anyway, because the CONTRACT is the sorted
104
+ // list, not the walk.
105
+ capabilitiesUnread: [...unread].sort(compareIds),
106
+ useCaseSteps: flowsTouching(scan, new Set([entry.id])),
107
+ useCaseScan: scan.kind === "read"
108
+ ? { unreadable: false }
109
+ : { unreadable: true, ...(scan.errors[0] === undefined ? {} : { error: scan.errors[0] }) },
110
+ };
111
+ }
112
+ //# sourceMappingURL=joins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"joins.js","sourceRoot":"","sources":["../../../src/core/pack/joins.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The three fleet-vocabulary joins in one service's context pack: the\n * permissions its requirements gate on, the capabilities they realize, and the\n * business flows it is a hop of. All three resolve a per-service fact against a\n * fleet document, which is what separates them from `./living.ts` — that module\n * never has to look past the service's own directory and the fleet map.\n *\n * The use-case join is the newest and the one whose absence was loudest: an\n * agent briefed on a service was told which capabilities its requirements\n * realize and never told that step 4 of Checkout calls it. The capability is the\n * label; the flow is the caller.\n */\nimport { FleetContext } from \"../fleet-context.js\";\nimport { capabilityRollup } from \"../capabilities/rollup.js\";\nimport { repoPath } from \"../envelope/json.js\";\nimport { readVocabulary } from \"../permissions/permissions.js\";\nimport { compareIds, type ServiceEntry } from \"../repo/entries.js\";\nimport { permissionsPath, servicePathsAt, SPEC_AXES } from \"../repo/paths.js\";\nimport { existsSync } from \"node:fs\";\nimport { readUseCases } from \"../usecases/fleet.js\";\nimport { flowsClaiming, type ClaimingFlow } from \"../usecases/capability.js\";\nimport { flowsTouching, type TouchedUseCase } from \"../usecases/touch.js\";\nimport type { Requirement } from \"../document/spec.js\";\nimport type { DocsDir } from \"../kernel/ids/dirs.js\";\n\n/**\n * One `Requires:` entry, resolved against `architecture/permissions.yaml`.\n * A discriminated pair rather than optional-field soup: the declared variant\n * carries what the vocabulary says, the undeclared one carries only the claim\n * — inventing an empty `enforcedBy` for a permission nobody declared would be\n * a statement about a declaration that does not exist. Undeclared entries are\n * carried, never refused: explore's \"every miss is a field\" ethos, and\n * `permissions.unknown` is `validate`'s finding to make.\n */\nexport type PackPermission =\n | {\n id: string;\n declared: true;\n subject: string;\n name: string;\n description?: string;\n ownedBy?: string;\n enforcedBy: string[];\n }\n | { id: string; declared: false };\n\n/** One declared capability this service realizes part of, with the realizing requirement names. */\nexport interface PackCapability {\n id: string;\n description?: string;\n owner?: string;\n /** This service's realizing requirement names, in the rollup's own (file, requirement) order. */\n requirements: string[];\n /**\n * The declared `dynamic view`s that CLAIM this capability, fleet-wide — not\n * only the ones this service is a hop of.\n *\n * Fleet-wide is the deliberate half. A capability is realized by several\n * services and drawn as one flow, so the flow a reader needs in order to\n * understand what this service's requirements are FOR is usually one where\n * this service appears at a single hop, or at none yet. `useCaseSteps` below\n * is the narrower answer — where this service actually appears — and the two\n * are different questions on purpose.\n *\n * Empty when nothing claims it, and empty when `useCaseScan` says nobody could\n * look; that ambiguity is why the scan's health rides beside it.\n */\n useCases: ClaimingFlow[];\n}\n\nexport interface JoinsSlice {\n permissions: PackPermission[];\n /**\n * Whether the vocabulary itself could be read — beside the entries it\n * resolves, so `declared: false` over a broken file is legible as the\n * file's fault. `invalid` is a HOLE (`packHoles`): every entry above then\n * reports `declared: false` because nobody could look, not because the\n * claim is wrong, and exit 0 over that would be a positive false claim.\n */\n permissionsVocabulary: { present: boolean; invalid?: string };\n capabilities: PackCapability[];\n /** The capability vocabulary's own health — `permissionsVocabulary`'s twin, and a hole for the same reason: an unreadable file empties `capabilities` above, and \"(none realized here)\" over a parse failure is the vacuously-green trap. */\n capabilitiesVocabulary: { present: boolean; invalid?: string };\n /**\n * Repo-relative paths of OTHER services' spec files the capability rollup\n * could not read. The rollup walks the whole fleet, so an unreadable\n * sibling must degrade (recorded here, graded as a hole) rather than refuse\n * — one service's briefing must never be hostage to another service's\n * encoding. The TARGET's own documents keep their refusal: `living.ts`\n * reads them without this containment.\n */\n capabilitiesUnread: string[];\n /**\n * The declared business flows this service is a hop of, and only the hops that\n * mention it — `core/usecases/touch.ts`'s endpoint join, so a flow drawn for\n * work not yet done still answers.\n */\n useCaseSteps: TouchedUseCase[];\n /**\n * The use-case axis's own health — `permissionsVocabulary`'s twin, and a hole\n * for the same reason. An `architecture/` that does not parse empties BOTH\n * `useCaseSteps` and every `PackCapability.useCases` above while looking\n * exactly like a fleet that draws no flows, and \"no business flow depends on\n * this service\" is the single most misleading thing this pack could say about\n * a directory nobody opened.\n */\n useCaseScan: { unreadable: boolean; error?: string };\n}\n\nexport interface JoinsRequest {\n docsDir: DocsDir;\n entry: ServiceEntry;\n context: FleetContext;\n}\n\nexport async function buildJoins(req: JoinsRequest): Promise<JoinsSlice> {\n const { docsDir, entry, context } = req;\n const paths = servicePathsAt(entry.dir);\n\n // The same two spec reads `living.ts` makes — memoized on the shared\n // context, so whichever module asks first pays the I/O once and the two\n // cannot read two different versions of one file. Fanned out because the\n // axes are independent; SPEC_AXES order (spec before arch-spec) is preserved\n // by Promise.all, which is what keeps `wanted` deterministic.\n const perAxis: Requirement[][] = await Promise.all(\n SPEC_AXES.map((axis) =>\n existsSync(paths[axis.key]) ? context.readRequirements(paths[axis.key]) : Promise.resolve([]),\n ),\n );\n const active = perAxis.flat().filter((r) => r.kind !== \"REMOVED\");\n\n // One vocabulary parse per pack — the pack asks about one service, so this\n // is once per invocation, not the per-service re-parse fleet-context.ts's\n // stats comment warns against copying.\n const vocab = await readVocabulary(permissionsPath(docsDir));\n const wanted = [...new Set(active.flatMap((r) => r.requires))].sort(compareIds);\n const permissions: PackPermission[] = wanted.map((id) => {\n const decl = vocab.byId.get(id);\n if (decl === undefined) return { id, declared: false };\n return {\n id,\n declared: true,\n subject: decl.subject,\n name: decl.name,\n ...(decl.description === undefined ? {} : { description: decl.description }),\n ...(decl.ownedBy === undefined ? {} : { ownedBy: decl.ownedBy }),\n enforcedBy: decl.enforcedBy,\n };\n });\n\n // One rollup pass through the shared context cache, exactly as explore seeds\n // capabilities — the reader is injected because fleet-context.ts imports the\n // capabilities package and an import back would be a package cycle.\n const entries = await context.listServices(docsDir);\n const capVocab = await context.capabilities(docsDir);\n const unread: string[] = [];\n const rows = await capabilityRollup({\n services: entries,\n vocab: capVocab,\n read: (p) =>\n context.readRequirements(p).catch(() => {\n // Unreadable means \"this file's realizations are unknown\", never \"the\n // pack is unanswerable\": the rollup walks EVERY service's spec files,\n // so without this per-read containment one sibling's bad encoding\n // refused every other service's briefing — and only once the fleet\n // declared its first capability, which is exactly the moment the walk\n // starts. The miss travels as `capabilitiesUnread` and is graded as a\n // hole; the target's own copy of the same rejection still refuses the\n // pack through `living.ts`'s uncontained read.\n unread.push(repoPath(docsDir, p));\n return [];\n }),\n });\n // One use-case scan for the whole pack, feeding both joins below. It gates\n // its own load, so a docs repo whose architecture/ never mentions the reserved\n // tag prefix costs a readdir here rather than a LikeC4 workspace — the same\n // discipline `loam delta` needs and this pack inherits for free.\n const known = new Set(entries.map((e) => e.id));\n const scan = await readUseCases({ docsDir, known });\n const capabilities: PackCapability[] = rows\n .filter((row) => row.services.includes(entry.id))\n .map((row) => ({\n id: row.id,\n ...(row.description === undefined ? {} : { description: row.description }),\n ...(row.owner === undefined ? {} : { owner: row.owner }),\n requirements: [\n ...new Set(row.realizedBy.filter((r) => r.service === entry.id).map((r) => r.requirement)),\n ],\n useCases: flowsClaiming(scan, row.id),\n }));\n\n return {\n permissions,\n permissionsVocabulary: {\n present: vocab.present,\n ...(vocab.invalid === undefined ? {} : { invalid: vocab.invalid }),\n },\n capabilities,\n capabilitiesVocabulary: {\n present: capVocab.present,\n ...(capVocab.invalid === undefined ? {} : { invalid: capVocab.invalid }),\n },\n // The rollup awaits each read in its own walk order, so the push order is\n // already deterministic; sorted anyway, because the CONTRACT is the sorted\n // list, not the walk.\n capabilitiesUnread: [...unread].sort(compareIds),\n useCaseSteps: flowsTouching(scan, new Set([entry.id])),\n useCaseScan:\n scan.kind === \"read\"\n ? { unreadable: false }\n : { unreadable: true, ...(scan.errors[0] === undefined ? {} : { error: scan.errors[0] }) },\n };\n}\n"]}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * The living slice of one service's context pack: its requirements verbatim,
3
+ * its two contracts, its provenance, its maturity, and the fleet edges around
4
+ * it — everything the docs repo says about the service TODAY, before any
5
+ * feature in flight is consulted.
6
+ *
7
+ * Split from `./pack.ts` because it answers about the LIVING documents while
8
+ * `./features.ts` answers about the deltas over them — two phases of one
9
+ * briefing, and the line limit is what asked the question.
10
+ */
11
+ import { existsSync } from "node:fs";
12
+ import { FleetContext } from "../fleet-context.js";
13
+ import { brokenDocumentPaths } from "../c4/likec4.js";
14
+ import { serviceResolver } from "../c4/resolve/service.js";
15
+ import { repoPath } from "../envelope/json.js";
16
+ import { listField, parseFrontmatter, stringField } from "../document/frontmatter.js";
17
+ import { scopeText } from "../provenance/sample/scope.js";
18
+ import {} from "../document/spec.js";
19
+ import { landscapeEvidence, maturityGaps, serviceMaturity, } from "../vocabulary/maturity.js";
20
+ import {} from "../repo/entries.js";
21
+ import { landscapePath, servicePathsAt } from "../repo/paths.js";
22
+ import { NO_DEPLOYMENT } from "../c4/parsed/deployment.js";
23
+ import { serviceTopology } from "../deployment/objects.js";
24
+ export function packRequirement(r) {
25
+ return {
26
+ kind: r.kind,
27
+ ...(r.id === undefined ? {} : { id: r.id }),
28
+ name: r.name,
29
+ text: r.text.join("\n").trim(),
30
+ operations: r.operations,
31
+ covers: r.covers,
32
+ requires: r.requires,
33
+ capabilities: r.capabilities,
34
+ publishes: r.publishes,
35
+ consumes: r.consumes,
36
+ scenarios: r.scenarios.map((s) => ({ name: s.name, lines: s.lines })),
37
+ };
38
+ }
39
+ export async function buildLiving(req) {
40
+ const { docsDir, entry, context } = req;
41
+ const paths = servicePathsAt(entry.dir);
42
+ // Independent reads, fanned out together; each is memoized on the shared
43
+ // context, so anything `./joins.ts` or `./features.ts` re-asks is free.
44
+ const [reqs, archReqs, api, events, specText, archText, land] = await Promise.all([
45
+ entry.has.spec ? context.readRequirements(paths.spec) : [],
46
+ existsSync(paths.archSpec) ? context.readRequirements(paths.archSpec) : [],
47
+ context.readOpenapi(paths.openapi),
48
+ context.readAsyncapi(paths.asyncapi),
49
+ entry.has.spec ? context.readText(paths.spec) : null,
50
+ // Both headers, exactly as `show` reads both (commands/show/service.ts):
51
+ // a memo hit on the same read the requirements above already paid for.
52
+ existsSync(paths.archSpec) ? context.readText(paths.archSpec) : null,
53
+ // The `architecture/` PROJECT, never `architecture/landscape.likec4` alone.
54
+ // The map is a project — the landscape merged with every use case, palette
55
+ // and second `model { }` block beside it — and reading one file of it made
56
+ // this pack answer differently from `loam adopt` about the same tree
57
+ // (review finding F26, reproduced: with a broken `architecture/palette.likec4`
58
+ // beside a landscape that parses, `adopt --service order-service` reported
59
+ // `parses: false` and refused to say anything about the map, while `context
60
+ // order-service` reported `parses: true` and listed its edges). The brief's
61
+ // own banner (core/brief/landscape.ts) already named this module as the
62
+ // reader that disagreed. Whichever answer is right, an agent handed both
63
+ // has no way to tell — and the renderer's answer is the project's.
64
+ //
65
+ // `present` stays a fact about the FILE (`existsSync` below), so a repo
66
+ // with no landscape is still "absent" rather than "empty project".
67
+ existsSync(landscapePath(docsDir)) ? context.architecture(docsDir) : null,
68
+ ]);
69
+ const present = land !== null;
70
+ const parses = land !== null && land.errors.length === 0;
71
+ const elements = parses ? land.elements : [];
72
+ // Edges are filed under the service an element is BOUND to, with the
73
+ // enumerated fleet riding in — the same resolution `show`, `explore` and
74
+ // `validate` use, so no two commands can disagree about who calls whom.
75
+ const known = new Set((await context.listServices(docsDir)).map((s) => s.id));
76
+ const svcOf = serviceResolver(elements, known);
77
+ // The partition, the modelled probe and the apiExpected rule are ONE shared
78
+ // derivation (core/vocabulary/maturity.ts `landscapeEvidence`) — the same
79
+ // one explore's describe uses, so the pack and explore cannot spell the same
80
+ // rule two ways. They are handed the same DOCUMENTS as well: `explore` reads
81
+ // the `architecture/` project too (core/explore/explore.ts), which it did not
82
+ // when this slice moved off the single file — for a while the two differed by
83
+ // input on a fleet whose sibling document is broken, which is a disagreement
84
+ // no reader of both could resolve.
85
+ const { inbound, outbound, modelled, apiExpected } = landscapeEvidence({
86
+ id: entry.id,
87
+ parses,
88
+ relationships: parses ? land.relationships : [],
89
+ elementIds: elements.map((e) => e.id),
90
+ svcOf,
91
+ });
92
+ // Where this service RUNS, from the landscape's own deployment model. The
93
+ // pack's reader is an agent about to write the implementation, and until this
94
+ // slice existed it described a service's calls and contracts while saying
95
+ // nothing whatever about its topology — so a failover got written against a
96
+ // map nobody had read. Empty for every fleet that draws none, which is the
97
+ // axis's opt-in and not a finding.
98
+ //
99
+ // Read off the PROJECT, for the reason `validate/service/specs.ts` pays the
100
+ // same load: `architecture/` is one LikeC4 project and a fleet's
101
+ // `deployment { }` block is ordinarily a file beside the landscape, not
102
+ // inside it. A single-file read would report "this service runs nowhere" over
103
+ // a repo that draws it, which is the one answer a briefing must never give.
104
+ // This used to be a SECOND load, made only when the landscape file itself
105
+ // declared no topology; `land` is that project now, so the fallback would be
106
+ // the same document parsed twice.
107
+ const topology = parses ? (land.deployment ?? NO_DEPLOYMENT) : NO_DEPLOYMENT;
108
+ const deployment = serviceTopology(topology, elements, known, entry.id);
109
+ const input = { entry, archSpec: existsSync(paths.archSpec), apiExpected };
110
+ const header = (text) => text === null ? { present: false, malformed: false, data: {}, body: "" } : parseFrontmatter(text);
111
+ const fm = header(specText);
112
+ const governs = (op) => reqs.filter((r) => r.operations.includes(op)).map((r) => r.name);
113
+ const sent = new Set(events.sent);
114
+ const received = new Set(events.received);
115
+ return {
116
+ maturity: serviceMaturity(input),
117
+ missing: maturityGaps(input),
118
+ frontmatter: {
119
+ status: stringField(fm, "status") ?? null,
120
+ owner: stringField(fm, "owner") ?? null,
121
+ last_verified: stringField(fm, "last_verified") ?? null,
122
+ // Through `scopeText`, not `stringField`: a scope whose value is not
123
+ // text is still a stamped partial read, and this pack is read by an
124
+ // agent that will otherwise take `status: verified` at face value.
125
+ vouch_scope: scopeText(fm),
126
+ sources: listField(fm, "sources"),
127
+ },
128
+ archSpec: { vouch_scope: scopeText(header(archText)) },
129
+ landscape: { present, parses, broken: land === null ? [] : brokenDocumentPaths(docsDir, land.errors), modelled, inbound, outbound },
130
+ deployment,
131
+ requirements: reqs.map(packRequirement),
132
+ archRequirements: archReqs.map(packRequirement),
133
+ openapi: { unreadable: api.unreadable, ...(api.error === undefined ? {} : { error: api.error }) },
134
+ // Document order — a fact of the file, hence of the state. `x-loam-remove`
135
+ // markers are filtered exactly as `show` filters them: they are deletion
136
+ // markers from a delta, not operations anybody can call.
137
+ operations: api.ops
138
+ .filter((o) => !o.remove)
139
+ .map((o) => ({ id: o.id, method: o.method.toUpperCase(), path: o.path, governedBy: governs(o.id) })),
140
+ asyncapi: { unreadable: events.unreadable, ...(events.error === undefined ? {} : { error: events.error }) },
141
+ messages: events.messages
142
+ .filter((m) => m.remove !== true)
143
+ .map((m) => ({
144
+ name: m.name,
145
+ slot: m.slot,
146
+ direction: sent.has(m.name) ? "send" : received.has(m.name) ? "receive" : null,
147
+ })),
148
+ pointers: {
149
+ runbook: { present: entry.has.runbook, path: repoPath(docsDir, paths.runbook) },
150
+ health: { present: entry.has.health, path: repoPath(docsDir, paths.health) },
151
+ // The enumeration already counted the ADRs; a second readdir here could
152
+ // only disagree with it.
153
+ adrs: { count: entry.adrs, path: repoPath(docsDir, paths.adrsDir) },
154
+ },
155
+ };
156
+ }
157
+ //# sourceMappingURL=living.js.map