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

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 (1026) hide show
  1. package/CHANGELOG.md +2548 -86
  2. package/COMPARISON.md +80 -63
  3. package/CONTRIBUTING.md +84 -0
  4. package/MIGRATING-from-OpenSpec.md +213 -54
  5. package/QUICKSTART.md +125 -0
  6. package/README.md +450 -150
  7. package/ROADMAP.md +494 -0
  8. package/SCHEMA.md +2355 -256
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +701 -0
  11. package/dist/cli.js +113 -19
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +209 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +268 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +77 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
  20. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/openapi.js +159 -0
  22. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  23. package/dist/commands/archive/plan/gate.js +317 -0
  24. package/dist/commands/archive/plan/gate.js.map +1 -0
  25. package/dist/commands/archive/plan/landscape.js +161 -0
  26. package/dist/commands/archive/plan/landscape.js.map +1 -0
  27. package/dist/commands/archive/plan/refusal.js +111 -0
  28. package/dist/commands/archive/plan/refusal.js.map +1 -0
  29. package/dist/commands/archive/plan/specs.js +237 -0
  30. package/dist/commands/archive/plan/specs.js.map +1 -0
  31. package/dist/commands/archive/plan/state.js +27 -0
  32. package/dist/commands/archive/plan/state.js.map +1 -0
  33. package/dist/commands/archive/run.js +251 -0
  34. package/dist/commands/archive/run.js.map +1 -0
  35. package/dist/commands/context/context.js +99 -0
  36. package/dist/commands/context/context.js.map +1 -0
  37. package/dist/commands/context/print.js +283 -0
  38. package/dist/commands/context/print.js.map +1 -0
  39. package/dist/commands/delta/delta.js +279 -0
  40. package/dist/commands/delta/delta.js.map +1 -0
  41. package/dist/commands/delta/print.js +205 -0
  42. package/dist/commands/delta/print.js.map +1 -0
  43. package/dist/commands/dependencies.js +9 -7
  44. package/dist/commands/dependencies.js.map +1 -1
  45. package/dist/commands/diff/diff.js +93 -0
  46. package/dist/commands/diff/diff.js.map +1 -0
  47. package/dist/commands/diff/print.js +38 -0
  48. package/dist/commands/diff/print.js.map +1 -0
  49. package/dist/commands/doctor.js +5 -4
  50. package/dist/commands/doctor.js.map +1 -1
  51. package/dist/commands/explain/explain.js +151 -0
  52. package/dist/commands/explain/explain.js.map +1 -0
  53. package/dist/commands/explore.js +29 -24
  54. package/dist/commands/explore.js.map +1 -1
  55. package/dist/commands/gate/gate.js +115 -0
  56. package/dist/commands/gate/gate.js.map +1 -0
  57. package/dist/commands/gate/print.js +54 -0
  58. package/dist/commands/gate/print.js.map +1 -0
  59. package/dist/commands/gherkin/commit.js +146 -0
  60. package/dist/commands/gherkin/commit.js.map +1 -0
  61. package/dist/commands/gherkin/gherkin.js +246 -0
  62. package/dist/commands/gherkin/gherkin.js.map +1 -0
  63. package/dist/commands/gherkin/reconcile.js +149 -0
  64. package/dist/commands/gherkin/reconcile.js.map +1 -0
  65. package/dist/commands/gherkin/render.js +77 -0
  66. package/dist/commands/gherkin/render.js.map +1 -0
  67. package/dist/commands/init/example.js +204 -0
  68. package/dist/commands/init/example.js.map +1 -0
  69. package/dist/commands/init/first-hour.js +28 -0
  70. package/dist/commands/init/first-hour.js.map +1 -0
  71. package/dist/commands/{init.js → init/init.js} +146 -71
  72. package/dist/commands/init/init.js.map +1 -0
  73. package/dist/commands/init/mcp.js +131 -0
  74. package/dist/commands/init/mcp.js.map +1 -0
  75. package/dist/commands/init/options.js +78 -0
  76. package/dist/commands/init/options.js.map +1 -0
  77. package/dist/commands/instructions.js +72 -14
  78. package/dist/commands/instructions.js.map +1 -1
  79. package/dist/commands/list/campaign/campaign.js +65 -0
  80. package/dist/commands/list/campaign/campaign.js.map +1 -0
  81. package/dist/commands/list/campaign/owners.js +65 -0
  82. package/dist/commands/list/campaign/owners.js.map +1 -0
  83. package/dist/commands/list/json.js +157 -0
  84. package/dist/commands/list/json.js.map +1 -0
  85. package/dist/commands/list/list.js +343 -0
  86. package/dist/commands/list/list.js.map +1 -0
  87. package/dist/commands/list/print.js +301 -0
  88. package/dist/commands/list/print.js.map +1 -0
  89. package/dist/commands/list/review.js +120 -0
  90. package/dist/commands/list/review.js.map +1 -0
  91. package/dist/commands/list/views.js +105 -0
  92. package/dist/commands/list/views.js.map +1 -0
  93. package/dist/commands/mcp/dispatch.js +183 -0
  94. package/dist/commands/mcp/dispatch.js.map +1 -0
  95. package/dist/commands/mcp/mcp.js +34 -0
  96. package/dist/commands/mcp/mcp.js.map +1 -0
  97. package/dist/commands/mcp/serve.js +55 -0
  98. package/dist/commands/mcp/serve.js.map +1 -0
  99. package/dist/commands/migrate-openspec/materialize/active.js +170 -0
  100. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  101. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  102. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  103. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  104. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  105. package/dist/commands/migrate-openspec/materialize/stage.js +142 -0
  106. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  107. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  108. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  109. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  110. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  111. package/dist/commands/migrate-openspec/openspec/decisions.js +91 -0
  112. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  113. package/dist/commands/migrate-openspec/openspec/error.js +19 -0
  114. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  115. package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
  116. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  117. package/dist/commands/migrate-openspec/openspec/paths.js +43 -0
  118. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  119. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  120. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  121. package/dist/commands/migrate-openspec/print.js +89 -0
  122. package/dist/commands/migrate-openspec/print.js.map +1 -0
  123. package/dist/commands/new/commit.js +76 -0
  124. package/dist/commands/new/commit.js.map +1 -0
  125. package/dist/commands/new/new.js +283 -0
  126. package/dist/commands/new/new.js.map +1 -0
  127. package/dist/commands/new/templates.js +355 -0
  128. package/dist/commands/new/templates.js.map +1 -0
  129. package/dist/commands/open.js +203 -0
  130. package/dist/commands/open.js.map +1 -0
  131. package/dist/commands/policy/format.js +152 -0
  132. package/dist/commands/policy/format.js.map +1 -0
  133. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +11 -11
  134. package/dist/commands/policy/gate.js.map +1 -0
  135. package/dist/commands/rebase/edit.js +106 -0
  136. package/dist/commands/rebase/edit.js.map +1 -0
  137. package/dist/commands/rebase/living.js +185 -0
  138. package/dist/commands/rebase/living.js.map +1 -0
  139. package/dist/commands/rebase/plan.js +245 -0
  140. package/dist/commands/rebase/plan.js.map +1 -0
  141. package/dist/commands/rebase/rebase.js +275 -0
  142. package/dist/commands/rebase/rebase.js.map +1 -0
  143. package/dist/commands/seed/commit.js +192 -0
  144. package/dist/commands/seed/commit.js.map +1 -0
  145. package/dist/commands/seed/plan.js +133 -0
  146. package/dist/commands/seed/plan.js.map +1 -0
  147. package/dist/commands/seed/seed.js +172 -0
  148. package/dist/commands/seed/seed.js.map +1 -0
  149. package/dist/commands/show/feature.js +178 -0
  150. package/dist/commands/show/feature.js.map +1 -0
  151. package/dist/commands/show/marks.js +24 -0
  152. package/dist/commands/show/marks.js.map +1 -0
  153. package/dist/commands/{show.js → show/service.js} +63 -152
  154. package/dist/commands/show/service.js.map +1 -0
  155. package/dist/commands/show/show.js +77 -0
  156. package/dist/commands/show/show.js.map +1 -0
  157. package/dist/commands/status/json.js +45 -0
  158. package/dist/commands/status/json.js.map +1 -0
  159. package/dist/commands/status/print.js +157 -0
  160. package/dist/commands/status/print.js.map +1 -0
  161. package/dist/commands/status/status.js +119 -0
  162. package/dist/commands/status/status.js.map +1 -0
  163. package/dist/commands/steps/steps.js +189 -0
  164. package/dist/commands/steps/steps.js.map +1 -0
  165. package/dist/commands/subsystem/edit.js +192 -0
  166. package/dist/commands/subsystem/edit.js.map +1 -0
  167. package/dist/commands/subsystem/move.js +265 -0
  168. package/dist/commands/subsystem/move.js.map +1 -0
  169. package/dist/commands/subsystem/query.js +115 -0
  170. package/dist/commands/subsystem/query.js.map +1 -0
  171. package/dist/commands/subsystem/subsystem.js +101 -0
  172. package/dist/commands/subsystem/subsystem.js.map +1 -0
  173. package/dist/commands/subsystem/sync.js +103 -0
  174. package/dist/commands/subsystem/sync.js.map +1 -0
  175. package/dist/commands/subsystem/txn/txn.js +94 -0
  176. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  177. package/dist/commands/subsystem/txn/views.js +70 -0
  178. package/dist/commands/subsystem/txn/views.js.map +1 -0
  179. package/dist/commands/unarchive/manifest.js +160 -0
  180. package/dist/commands/unarchive/manifest.js.map +1 -0
  181. package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
  182. package/dist/commands/unarchive/restore.js.map +1 -0
  183. package/dist/commands/unarchive/unarchive.js +67 -0
  184. package/dist/commands/unarchive/unarchive.js.map +1 -0
  185. package/dist/commands/validate/arch-coverage.js +194 -0
  186. package/dist/commands/validate/arch-coverage.js.map +1 -0
  187. package/dist/commands/validate/checks/fleet-shape.js +296 -0
  188. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  189. package/dist/commands/validate/checks/health-deps.js +55 -0
  190. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  191. package/dist/commands/validate/checks/requirements.js +254 -0
  192. package/dist/commands/validate/checks/requirements.js.map +1 -0
  193. package/dist/commands/validate/checks/sources.js +76 -0
  194. package/dist/commands/validate/checks/sources.js.map +1 -0
  195. package/dist/commands/validate/checks/vocabulary.js +31 -0
  196. package/dist/commands/validate/checks/vocabulary.js.map +1 -0
  197. package/dist/commands/validate/feature.js +216 -0
  198. package/dist/commands/validate/feature.js.map +1 -0
  199. package/dist/commands/validate/fleet/census.js +69 -0
  200. package/dist/commands/validate/fleet/census.js.map +1 -0
  201. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  202. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  203. package/dist/commands/validate/fleet/landscape.js +353 -0
  204. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  205. package/dist/commands/validate/fleet/load.js +52 -0
  206. package/dist/commands/validate/fleet/load.js.map +1 -0
  207. package/dist/commands/validate/fleet/obligations.js +236 -0
  208. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  209. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  210. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  211. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  212. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  213. package/dist/commands/validate/fleet/scorecard/print.js +63 -0
  214. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  215. package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
  216. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  217. package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
  218. package/dist/commands/validate/fleet/usecases/capability-tag.js.map +1 -0
  219. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  220. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  221. package/dist/commands/validate/fleet/usecases/requirement-tag.js +95 -0
  222. package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
  223. package/dist/commands/validate/fleet/usecases/steps.js +197 -0
  224. package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
  225. package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
  226. package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
  227. package/dist/commands/validate/fleet/views/ids.js +40 -0
  228. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  229. package/dist/commands/validate/fleet/views/stale.js +59 -0
  230. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  231. package/dist/commands/validate/links/corpus.js +92 -0
  232. package/dist/commands/validate/links/corpus.js.map +1 -0
  233. package/dist/commands/validate/links/glossary.js +75 -0
  234. package/dist/commands/validate/links/glossary.js.map +1 -0
  235. package/dist/commands/validate/report.js +269 -0
  236. package/dist/commands/validate/report.js.map +1 -0
  237. package/dist/commands/validate/service/api.js +338 -0
  238. package/dist/commands/validate/service/api.js.map +1 -0
  239. package/dist/commands/validate/service/events/events.js +219 -0
  240. package/dist/commands/validate/service/events/events.js.map +1 -0
  241. package/dist/commands/validate/service/events/message-producers.js +77 -0
  242. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  243. package/dist/commands/validate/service/evidence-pins.js +131 -0
  244. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  245. package/dist/commands/validate/service/service.js +250 -0
  246. package/dist/commands/validate/service/service.js.map +1 -0
  247. package/dist/commands/validate/service/specs.js +219 -0
  248. package/dist/commands/validate/service/specs.js.map +1 -0
  249. package/dist/commands/validate/service/spine.js +113 -0
  250. package/dist/commands/validate/service/spine.js.map +1 -0
  251. package/dist/commands/validate/validate.js +338 -0
  252. package/dist/commands/validate/validate.js.map +1 -0
  253. package/dist/commands/verify/cross/diff.js +182 -0
  254. package/dist/commands/verify/cross/diff.js.map +1 -0
  255. package/dist/commands/verify/evidence/contract.js +32 -0
  256. package/dist/commands/verify/evidence/contract.js.map +1 -0
  257. package/dist/commands/verify/evidence/pins.js +52 -0
  258. package/dist/commands/verify/evidence/pins.js.map +1 -0
  259. package/dist/commands/verify/evidence/read.js +72 -0
  260. package/dist/commands/verify/evidence/read.js.map +1 -0
  261. package/dist/commands/verify/frozen.js +241 -0
  262. package/dist/commands/verify/frozen.js.map +1 -0
  263. package/dist/commands/verify/record.js +226 -0
  264. package/dist/commands/verify/record.js.map +1 -0
  265. package/dist/commands/verify/report.js +223 -0
  266. package/dist/commands/verify/report.js.map +1 -0
  267. package/dist/commands/verify/results.js +246 -0
  268. package/dist/commands/verify/results.js.map +1 -0
  269. package/dist/commands/verify/verify.js +217 -0
  270. package/dist/commands/verify/verify.js.map +1 -0
  271. package/dist/commands/vouch/contract.js +11 -0
  272. package/dist/commands/vouch/contract.js.map +1 -0
  273. package/dist/commands/vouch/pack/contract.js +2 -0
  274. package/dist/commands/vouch/pack/contract.js.map +1 -0
  275. package/dist/commands/vouch/pack/pack.js +266 -0
  276. package/dist/commands/vouch/pack/pack.js.map +1 -0
  277. package/dist/commands/vouch/pack/print.js +271 -0
  278. package/dist/commands/vouch/pack/print.js.map +1 -0
  279. package/dist/commands/vouch/pack/sections.js +142 -0
  280. package/dist/commands/vouch/pack/sections.js.map +1 -0
  281. package/dist/commands/vouch/prompt/confirm.js +46 -0
  282. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  283. package/dist/commands/vouch/report.js +101 -0
  284. package/dist/commands/vouch/report.js.map +1 -0
  285. package/dist/commands/vouch/run.js +285 -0
  286. package/dist/commands/vouch/run.js.map +1 -0
  287. package/dist/commands/vouch/sample/plan.js +125 -0
  288. package/dist/commands/vouch/sample/plan.js.map +1 -0
  289. package/dist/commands/vouch/sample/print.js +109 -0
  290. package/dist/commands/vouch/sample/print.js.map +1 -0
  291. package/dist/commands/vouch/vet/verify.js +123 -0
  292. package/dist/commands/vouch/vet/verify.js.map +1 -0
  293. package/dist/commands/vouch/vouch.js +176 -0
  294. package/dist/commands/vouch/vouch.js.map +1 -0
  295. package/dist/core/agent/agents-md/artifacts.js +220 -0
  296. package/dist/core/agent/agents-md/artifacts.js.map +1 -0
  297. package/dist/core/agent/agents-md/command-map.js +324 -0
  298. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  299. package/dist/core/agent/agents-md/cycle.js +165 -0
  300. package/dist/core/agent/agents-md/cycle.js.map +1 -0
  301. package/dist/core/agent/agents-md/map/explain.js +34 -0
  302. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  303. package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
  304. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  305. package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
  306. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  307. package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
  308. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  309. package/dist/core/agent/agents-md/map/mcp.js +41 -0
  310. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  311. package/dist/core/agent/agents-md/map/status.js +62 -0
  312. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  313. package/dist/core/agent/agents-md/map/subsystem.js +32 -0
  314. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  315. package/dist/core/agent/agents-md/map/usecases.js +60 -0
  316. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  317. package/dist/core/agent/agents-md/refusals.js +246 -0
  318. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  319. package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
  320. package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
  321. package/dist/core/agent/agents-md/spine.js +40 -0
  322. package/dist/core/agent/agents-md/spine.js.map +1 -0
  323. package/dist/core/agent/agents-md.js +170 -0
  324. package/dist/core/agent/agents-md.js.map +1 -0
  325. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +50 -0
  326. package/dist/core/agent/agents-stamp.js.map +1 -0
  327. package/dist/core/agent/contract.js +2 -0
  328. package/dist/core/agent/contract.js.map +1 -0
  329. package/dist/core/agent/protocol.js +193 -0
  330. package/dist/core/agent/protocol.js.map +1 -0
  331. package/dist/core/agent/scaffold.js +259 -0
  332. package/dist/core/agent/scaffold.js.map +1 -0
  333. package/dist/core/agent/support/report.js +103 -0
  334. package/dist/core/agent/support/report.js.map +1 -0
  335. package/dist/core/agent/tools/dialects.js +150 -0
  336. package/dist/core/agent/tools/dialects.js.map +1 -0
  337. package/dist/core/agent/tools/registry.js +228 -0
  338. package/dist/core/agent/tools/registry.js.map +1 -0
  339. package/dist/core/agent/workflows/adopt.js +133 -0
  340. package/dist/core/agent/workflows/adopt.js.map +1 -0
  341. package/dist/core/agent/workflows/check.js +334 -0
  342. package/dist/core/agent/workflows/check.js.map +1 -0
  343. package/dist/core/agent/workflows/closing.js +262 -0
  344. package/dist/core/agent/workflows/closing.js.map +1 -0
  345. package/dist/core/agent/workflows/feature.js +105 -0
  346. package/dist/core/agent/workflows/feature.js.map +1 -0
  347. package/dist/core/agent/workflows/implement.js +105 -0
  348. package/dist/core/agent/workflows/implement.js.map +1 -0
  349. package/dist/core/agent/workflows/reference/authoring.js +209 -0
  350. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  351. package/dist/core/agent/workflows/reference/codes.js +65 -0
  352. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  353. package/dist/core/agent/workflows/reference/done-check.js +188 -0
  354. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  355. package/dist/core/agent/workflows/reference/reference.js +16 -0
  356. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  357. package/dist/core/agent/workflows/reference/spine.js +297 -0
  358. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  359. package/dist/core/asyncapi/baseline/plan.js +110 -0
  360. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  361. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  362. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  363. package/dist/core/asyncapi/depth.js +164 -0
  364. package/dist/core/asyncapi/depth.js.map +1 -0
  365. package/dist/core/asyncapi/digest.js +141 -0
  366. package/dist/core/asyncapi/digest.js.map +1 -0
  367. package/dist/core/asyncapi/merge/components.js +91 -0
  368. package/dist/core/asyncapi/merge/components.js.map +1 -0
  369. package/dist/core/asyncapi/merge/error.js +33 -0
  370. package/dist/core/asyncapi/merge/error.js.map +1 -0
  371. package/dist/core/asyncapi/merge/markers.js +308 -0
  372. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  373. package/dist/core/asyncapi/merge/merge.js +215 -0
  374. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  375. package/dist/core/asyncapi/merge/pin.js +107 -0
  376. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  377. package/dist/core/asyncapi/model.js +11 -0
  378. package/dist/core/asyncapi/model.js.map +1 -0
  379. package/dist/core/asyncapi/producers.js +50 -0
  380. package/dist/core/asyncapi/producers.js.map +1 -0
  381. package/dist/core/{asyncapi.js → asyncapi/read.js} +95 -109
  382. package/dist/core/asyncapi/read.js.map +1 -0
  383. package/dist/core/brief/brief.js +225 -0
  384. package/dist/core/brief/brief.js.map +1 -0
  385. package/dist/core/brief/checks.js +250 -0
  386. package/dist/core/brief/checks.js.map +1 -0
  387. package/dist/core/brief/landscape.js +194 -0
  388. package/dist/core/brief/landscape.js.map +1 -0
  389. package/dist/core/brief/targets.js +226 -0
  390. package/dist/core/brief/targets.js.map +1 -0
  391. package/dist/core/brief/unchecked.js +47 -0
  392. package/dist/core/brief/unchecked.js.map +1 -0
  393. package/dist/core/c4/arch.js +282 -0
  394. package/dist/core/c4/arch.js.map +1 -0
  395. package/dist/core/c4/likec4.js +88 -0
  396. package/dist/core/c4/likec4.js.map +1 -0
  397. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  398. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  399. package/dist/core/c4/parsed/specification.js +78 -0
  400. package/dist/core/c4/parsed/specification.js.map +1 -0
  401. package/dist/core/c4/parsed/values.js +57 -0
  402. package/dist/core/c4/parsed/values.js.map +1 -0
  403. package/dist/core/c4/parsed/view-ids.js +75 -0
  404. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  405. package/dist/core/c4/project/architecture.js +45 -0
  406. package/dist/core/c4/project/architecture.js.map +1 -0
  407. package/dist/core/c4/project/documents.js +58 -0
  408. package/dist/core/c4/project/documents.js.map +1 -0
  409. package/dist/core/c4/project/load.js +183 -0
  410. package/dist/core/c4/project/load.js.map +1 -0
  411. package/dist/core/c4/resolve/service.js +113 -0
  412. package/dist/core/c4/resolve/service.js.map +1 -0
  413. package/dist/core/c4/seed/fleet-file.js +201 -0
  414. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  415. package/dist/core/c4/seed/items.js +91 -0
  416. package/dist/core/c4/seed/items.js.map +1 -0
  417. package/dist/core/c4/seed/stamp.js +48 -0
  418. package/dist/core/c4/seed/stamp.js.map +1 -0
  419. package/dist/core/c4/seed/template.js +109 -0
  420. package/dist/core/c4/seed/template.js.map +1 -0
  421. package/dist/core/c4/source-mask.js +82 -0
  422. package/dist/core/c4/source-mask.js.map +1 -0
  423. package/dist/core/c4/source-scan.js +227 -0
  424. package/dist/core/c4/source-scan.js.map +1 -0
  425. package/dist/core/c4/splice/authored-source.js +101 -0
  426. package/dist/core/c4/splice/authored-source.js.map +1 -0
  427. package/dist/core/c4/splice/contract.js +10 -0
  428. package/dist/core/c4/splice/contract.js.map +1 -0
  429. package/dist/core/c4/splice/delta-blocks.js +126 -0
  430. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  431. package/dist/core/c4/splice/identity/edges.js +36 -0
  432. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  433. package/dist/core/c4/splice/landscape-merge.js +269 -0
  434. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  435. package/dist/core/c4/splice/placement.js +194 -0
  436. package/dist/core/c4/splice/placement.js.map +1 -0
  437. package/dist/core/c4/workspace.js +172 -0
  438. package/dist/core/c4/workspace.js.map +1 -0
  439. package/dist/core/capabilities/authoring/notes.js +141 -0
  440. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  441. package/dist/core/capabilities/capabilities.js +124 -0
  442. package/dist/core/capabilities/capabilities.js.map +1 -0
  443. package/dist/core/capabilities/delta/doc.js +50 -0
  444. package/dist/core/capabilities/delta/doc.js.map +1 -0
  445. package/dist/core/capabilities/delta/overlay.js +129 -0
  446. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  447. package/dist/core/capabilities/delta/summary.js +57 -0
  448. package/dist/core/capabilities/delta/summary.js.map +1 -0
  449. package/dist/core/capabilities/delta/tree.js +43 -0
  450. package/dist/core/capabilities/delta/tree.js.map +1 -0
  451. package/dist/core/capabilities/delta/uncovered.js +222 -0
  452. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  453. package/dist/core/capabilities/findings.js +342 -0
  454. package/dist/core/capabilities/findings.js.map +1 -0
  455. package/dist/core/capabilities/realizes/findings.js +181 -0
  456. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  457. package/dist/core/capabilities/realizes/join.js +143 -0
  458. package/dist/core/capabilities/realizes/join.js.map +1 -0
  459. package/dist/core/capabilities/rollup.js +199 -0
  460. package/dist/core/capabilities/rollup.js.map +1 -0
  461. package/dist/core/capabilities/tree.js +126 -0
  462. package/dist/core/capabilities/tree.js.map +1 -0
  463. package/dist/core/capabilities/usecase-join.js +277 -0
  464. package/dist/core/capabilities/usecase-join.js.map +1 -0
  465. package/dist/core/coherence/authoring/scaffold.js +177 -0
  466. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  467. package/dist/core/coherence/authoring/sentinels.js +74 -0
  468. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  469. package/dist/core/coherence/coherence.js +251 -0
  470. package/dist/core/coherence/coherence.js.map +1 -0
  471. package/dist/core/coherence/declared.js +269 -0
  472. package/dist/core/coherence/declared.js.map +1 -0
  473. package/dist/core/coherence/events/declared.js +206 -0
  474. package/dist/core/coherence/events/declared.js.map +1 -0
  475. package/dist/core/coherence/events/events.js +204 -0
  476. package/dist/core/coherence/events/events.js.map +1 -0
  477. package/dist/core/coherence/events/grades.js +166 -0
  478. package/dist/core/coherence/events/grades.js.map +1 -0
  479. package/dist/core/coherence/events/lookups.js +122 -0
  480. package/dist/core/coherence/events/lookups.js.map +1 -0
  481. package/dist/core/coherence/events/merged.js +40 -0
  482. package/dist/core/coherence/events/merged.js.map +1 -0
  483. package/dist/core/coherence/living.js +198 -0
  484. package/dist/core/coherence/living.js.map +1 -0
  485. package/dist/core/coherence/lookups.js +155 -0
  486. package/dist/core/coherence/lookups.js.map +1 -0
  487. package/dist/core/coherence/pending.js +39 -0
  488. package/dist/core/coherence/pending.js.map +1 -0
  489. package/dist/core/conflict-markers.js +60 -0
  490. package/dist/core/conflict-markers.js.map +1 -0
  491. package/dist/core/delta/claims.js +73 -0
  492. package/dist/core/delta/claims.js.map +1 -0
  493. package/dist/core/delta/delta.js +296 -0
  494. package/dist/core/delta/delta.js.map +1 -0
  495. package/dist/core/delta/document.js +177 -0
  496. package/dist/core/delta/document.js.map +1 -0
  497. package/dist/core/delta/scope.js +48 -0
  498. package/dist/core/delta/scope.js.map +1 -0
  499. package/dist/core/delta/select.js +237 -0
  500. package/dist/core/delta/select.js.map +1 -0
  501. package/dist/core/dependencies/dependencies.js +141 -0
  502. package/dist/core/dependencies/dependencies.js.map +1 -0
  503. package/dist/core/dependencies/facts.js +165 -0
  504. package/dist/core/dependencies/facts.js.map +1 -0
  505. package/dist/core/dependencies/fanin.js +88 -0
  506. package/dist/core/dependencies/fanin.js.map +1 -0
  507. package/dist/core/dependencies/graph.js +106 -0
  508. package/dist/core/dependencies/graph.js.map +1 -0
  509. package/dist/core/diff/base-git.js +148 -0
  510. package/dist/core/diff/base-git.js.map +1 -0
  511. package/dist/core/diff/base-state.js +209 -0
  512. package/dist/core/diff/base-state.js.map +1 -0
  513. package/dist/core/diff/current-state.js +96 -0
  514. package/dist/core/diff/current-state.js.map +1 -0
  515. package/dist/core/diff/scope/changed-paths.js +188 -0
  516. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  517. package/dist/core/diff/semantic.js +243 -0
  518. package/dist/core/diff/semantic.js.map +1 -0
  519. package/dist/core/diff/victims.js +247 -0
  520. package/dist/core/diff/victims.js.map +1 -0
  521. package/dist/core/docs.js +7 -64
  522. package/dist/core/docs.js.map +1 -1
  523. package/dist/core/doctor/agents.js +222 -0
  524. package/dist/core/doctor/agents.js.map +1 -0
  525. package/dist/core/doctor/config.js +135 -0
  526. package/dist/core/doctor/config.js.map +1 -0
  527. package/dist/core/doctor/doctor.js +275 -0
  528. package/dist/core/doctor/doctor.js.map +1 -0
  529. package/dist/core/doctor/report.js +13 -0
  530. package/dist/core/doctor/report.js.map +1 -0
  531. package/dist/core/doctor/residue.js +110 -0
  532. package/dist/core/doctor/residue.js.map +1 -0
  533. package/dist/core/document/apply.js +77 -0
  534. package/dist/core/document/apply.js.map +1 -0
  535. package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -2
  536. package/dist/core/document/frontmatter.js.map +1 -0
  537. package/dist/core/document/grammar/directives.js +143 -0
  538. package/dist/core/document/grammar/directives.js.map +1 -0
  539. package/dist/core/document/parse.js +263 -0
  540. package/dist/core/document/parse.js.map +1 -0
  541. package/dist/core/document/scenarios.js +221 -0
  542. package/dist/core/document/scenarios.js.map +1 -0
  543. package/dist/core/document/spec.js +241 -0
  544. package/dist/core/document/spec.js.map +1 -0
  545. package/dist/core/{config.js → envelope/config.js} +79 -18
  546. package/dist/core/envelope/config.js.map +1 -0
  547. package/dist/core/envelope/json.js +175 -0
  548. package/dist/core/envelope/json.js.map +1 -0
  549. package/dist/core/{version.js → envelope/version.js} +3 -3
  550. package/dist/core/envelope/version.js.map +1 -0
  551. package/dist/core/explain/families.js +175 -0
  552. package/dist/core/explain/families.js.map +1 -0
  553. package/dist/core/explain/fix-tables.js +178 -0
  554. package/dist/core/explain/fix-tables.js.map +1 -0
  555. package/dist/core/explain/lookup.js +181 -0
  556. package/dist/core/explain/lookup.js.map +1 -0
  557. package/dist/core/explain/refusals.js +49 -0
  558. package/dist/core/explain/refusals.js.map +1 -0
  559. package/dist/core/explain/terms.js +144 -0
  560. package/dist/core/explain/terms.js.map +1 -0
  561. package/dist/core/explore/describe.js +105 -0
  562. package/dist/core/explore/describe.js.map +1 -0
  563. package/dist/core/{explore.js → explore/explore.js} +50 -101
  564. package/dist/core/explore/explore.js.map +1 -0
  565. package/dist/core/fleet-context.js +120 -78
  566. package/dist/core/fleet-context.js.map +1 -1
  567. package/dist/core/gate/checks.js +201 -0
  568. package/dist/core/gate/checks.js.map +1 -0
  569. package/dist/core/gate/partners.js +205 -0
  570. package/dist/core/gate/partners.js.map +1 -0
  571. package/dist/core/gate/report.js +47 -0
  572. package/dist/core/gate/report.js.map +1 -0
  573. package/dist/core/gate/verification.js +113 -0
  574. package/dist/core/gate/verification.js.map +1 -0
  575. package/dist/core/gherkin/digest.js +60 -0
  576. package/dist/core/gherkin/digest.js.map +1 -0
  577. package/dist/core/gherkin/emit.js +177 -0
  578. package/dist/core/gherkin/emit.js.map +1 -0
  579. package/dist/core/gherkin/read.js +76 -0
  580. package/dist/core/gherkin/read.js.map +1 -0
  581. package/dist/core/gherkin/stale.js +234 -0
  582. package/dist/core/gherkin/stale.js.map +1 -0
  583. package/dist/core/gherkin/stamp.js +77 -0
  584. package/dist/core/gherkin/stamp.js.map +1 -0
  585. package/dist/core/gherkin/steps/catalogue.js +154 -0
  586. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  587. package/dist/core/gherkin/steps/inventory.js +98 -0
  588. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  589. package/dist/core/gherkin/steps/phrase.js +72 -0
  590. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  591. package/dist/core/glossary/delta.js +106 -0
  592. package/dist/core/glossary/delta.js.map +1 -0
  593. package/dist/core/glossary/tree.js +86 -0
  594. package/dist/core/glossary/tree.js.map +1 -0
  595. package/dist/core/kernel/concurrency.js.map +1 -0
  596. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  597. package/dist/core/kernel/document-bytes.js.map +1 -0
  598. package/dist/core/kernel/fences.js +42 -0
  599. package/dist/core/kernel/fences.js.map +1 -0
  600. package/dist/core/kernel/ids/capability.js +72 -0
  601. package/dist/core/kernel/ids/capability.js.map +1 -0
  602. package/dist/core/kernel/ids/dirs.js +33 -0
  603. package/dist/core/kernel/ids/dirs.js.map +1 -0
  604. package/dist/core/kernel/ids/feature.js +75 -0
  605. package/dist/core/kernel/ids/feature.js.map +1 -0
  606. package/dist/core/kernel/ids/service.js +156 -0
  607. package/dist/core/kernel/ids/service.js.map +1 -0
  608. package/dist/core/kernel/ids/subsystem.js +63 -0
  609. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  610. package/dist/core/{path-safety.js → kernel/path-safety.js} +18 -4
  611. package/dist/core/kernel/path-safety.js.map +1 -0
  612. package/dist/core/kernel/records.js.map +1 -0
  613. package/dist/core/links/backlinks.js +68 -0
  614. package/dist/core/links/backlinks.js.map +1 -0
  615. package/dist/core/links/case.js +74 -0
  616. package/dist/core/links/case.js.map +1 -0
  617. package/dist/core/links/corpus.js +104 -0
  618. package/dist/core/links/corpus.js.map +1 -0
  619. package/dist/core/links/findings.js +110 -0
  620. package/dist/core/links/findings.js.map +1 -0
  621. package/dist/core/links/parse.js +236 -0
  622. package/dist/core/links/parse.js.map +1 -0
  623. package/dist/core/mcp/argv.js +111 -0
  624. package/dist/core/mcp/argv.js.map +1 -0
  625. package/dist/core/mcp/author-tools.js +72 -0
  626. package/dist/core/mcp/author-tools.js.map +1 -0
  627. package/dist/core/mcp/framing.js +46 -0
  628. package/dist/core/mcp/framing.js.map +1 -0
  629. package/dist/core/mcp/protocol.js +280 -0
  630. package/dist/core/mcp/protocol.js.map +1 -0
  631. package/dist/core/mcp/tools.js +314 -0
  632. package/dist/core/mcp/tools.js.map +1 -0
  633. package/dist/core/obligations/obligations.js +106 -0
  634. package/dist/core/obligations/obligations.js.map +1 -0
  635. package/dist/core/openapi/baseline/gate.js +166 -0
  636. package/dist/core/openapi/baseline/gate.js.map +1 -0
  637. package/dist/core/openapi/baseline/plan.js +112 -0
  638. package/dist/core/openapi/baseline/plan.js.map +1 -0
  639. package/dist/core/openapi/baseline/record.js +175 -0
  640. package/dist/core/openapi/baseline/record.js.map +1 -0
  641. package/dist/core/openapi/depth.js +122 -0
  642. package/dist/core/openapi/depth.js.map +1 -0
  643. package/dist/core/openapi/digest.js +189 -0
  644. package/dist/core/openapi/digest.js.map +1 -0
  645. package/dist/core/{openapi.js → openapi/doc.js} +44 -106
  646. package/dist/core/openapi/doc.js.map +1 -0
  647. package/dist/core/openapi/merge/components.js +234 -0
  648. package/dist/core/openapi/merge/components.js.map +1 -0
  649. package/dist/core/openapi/merge/error.js +26 -0
  650. package/dist/core/openapi/merge/error.js.map +1 -0
  651. package/dist/core/openapi/merge/markers.js +208 -0
  652. package/dist/core/openapi/merge/markers.js.map +1 -0
  653. package/dist/core/openapi/merge/merge.js +256 -0
  654. package/dist/core/openapi/merge/merge.js.map +1 -0
  655. package/dist/core/openapi/merge/pin.js +128 -0
  656. package/dist/core/openapi/merge/pin.js.map +1 -0
  657. package/dist/core/openspec/decide/capabilities.js +244 -0
  658. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  659. package/dist/core/openspec/decide/dispositions.js +63 -0
  660. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  661. package/dist/core/openspec/decide/renames.js +179 -0
  662. package/dist/core/openspec/decide/renames.js.map +1 -0
  663. package/dist/core/openspec/decide/verdict.js +84 -0
  664. package/dist/core/openspec/decide/verdict.js.map +1 -0
  665. package/dist/core/openspec/inventory.js +221 -0
  666. package/dist/core/openspec/inventory.js.map +1 -0
  667. package/dist/core/openspec/model/mapping.js +76 -0
  668. package/dist/core/openspec/model/mapping.js.map +1 -0
  669. package/dist/core/openspec/model/model.js +65 -0
  670. package/dist/core/openspec/model/model.js.map +1 -0
  671. package/dist/core/openspec/scan/changes.js +235 -0
  672. package/dist/core/openspec/scan/changes.js.map +1 -0
  673. package/dist/core/openspec/scan/config.js +200 -0
  674. package/dist/core/openspec/scan/config.js.map +1 -0
  675. package/dist/core/openspec/scan/shape.js +260 -0
  676. package/dist/core/openspec/scan/shape.js.map +1 -0
  677. package/dist/core/openspec/scan/walk.js +133 -0
  678. package/dist/core/openspec/scan/walk.js.map +1 -0
  679. package/dist/core/openspec/scan/workspace.js +71 -0
  680. package/dist/core/openspec/scan/workspace.js.map +1 -0
  681. package/dist/core/owners/codeowners.js +141 -0
  682. package/dist/core/owners/codeowners.js.map +1 -0
  683. package/dist/core/pack/features.js +120 -0
  684. package/dist/core/pack/features.js.map +1 -0
  685. package/dist/core/pack/joins.js +112 -0
  686. package/dist/core/pack/joins.js.map +1 -0
  687. package/dist/core/pack/living.js +118 -0
  688. package/dist/core/pack/living.js.map +1 -0
  689. package/dist/core/pack/pack.js +76 -0
  690. package/dist/core/pack/pack.js.map +1 -0
  691. package/dist/core/permissions/permissions.js +87 -0
  692. package/dist/core/permissions/permissions.js.map +1 -0
  693. package/dist/core/projection/api.js +84 -0
  694. package/dist/core/projection/api.js.map +1 -0
  695. package/dist/core/projection/arch-slice.js +63 -0
  696. package/dist/core/projection/arch-slice.js.map +1 -0
  697. package/dist/core/projection/events.js +34 -0
  698. package/dist/core/projection/events.js.map +1 -0
  699. package/dist/core/provenance/findings.js +208 -0
  700. package/dist/core/provenance/findings.js.map +1 -0
  701. package/dist/core/provenance/git.js +225 -0
  702. package/dist/core/provenance/git.js.map +1 -0
  703. package/dist/core/provenance/gitq/moves.js +182 -0
  704. package/dist/core/provenance/gitq/moves.js.map +1 -0
  705. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  706. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  707. package/dist/core/provenance/sample/scope.js +238 -0
  708. package/dist/core/provenance/sample/scope.js.map +1 -0
  709. package/dist/core/provenance/sample/sections.js +61 -0
  710. package/dist/core/provenance/sample/sections.js.map +1 -0
  711. package/dist/core/provenance/sources.js +263 -0
  712. package/dist/core/provenance/sources.js.map +1 -0
  713. package/dist/core/provenance/stamp.js +232 -0
  714. package/dist/core/provenance/stamp.js.map +1 -0
  715. package/dist/core/provenance/walk.js +157 -0
  716. package/dist/core/provenance/walk.js.map +1 -0
  717. package/dist/core/repo/authored/paths.js +192 -0
  718. package/dist/core/repo/authored/paths.js.map +1 -0
  719. package/dist/core/repo/entries.js +126 -0
  720. package/dist/core/repo/entries.js.map +1 -0
  721. package/dist/core/repo/paths.js +236 -0
  722. package/dist/core/repo/paths.js.map +1 -0
  723. package/dist/core/repo/repo.js +248 -0
  724. package/dist/core/repo/repo.js.map +1 -0
  725. package/dist/core/repo/service-target.js +153 -0
  726. package/dist/core/repo/service-target.js.map +1 -0
  727. package/dist/core/repo/state.js +58 -0
  728. package/dist/core/repo/state.js.map +1 -0
  729. package/dist/core/repo/tree/find.js +52 -0
  730. package/dist/core/repo/tree/find.js.map +1 -0
  731. package/dist/core/repo/tree/fs.js +64 -0
  732. package/dist/core/repo/tree/fs.js.map +1 -0
  733. package/dist/core/repo/tree/marker.js +61 -0
  734. package/dist/core/repo/tree/marker.js.map +1 -0
  735. package/dist/core/repo/tree/views.js +172 -0
  736. package/dist/core/repo/tree/views.js.map +1 -0
  737. package/dist/core/repo/tree/walk.js +234 -0
  738. package/dist/core/repo/tree/walk.js.map +1 -0
  739. package/dist/core/results.js +99 -2
  740. package/dist/core/results.js.map +1 -1
  741. package/dist/core/scaffold/landscape.js +131 -0
  742. package/dist/core/scaffold/landscape.js.map +1 -0
  743. package/dist/core/scaffold/readme.js +84 -0
  744. package/dist/core/scaffold/readme.js.map +1 -0
  745. package/dist/core/staging/commit.js +241 -0
  746. package/dist/core/staging/commit.js.map +1 -0
  747. package/dist/core/staging/interrupted.js +96 -0
  748. package/dist/core/staging/interrupted.js.map +1 -0
  749. package/dist/core/staging/lock.js +206 -0
  750. package/dist/core/staging/lock.js.map +1 -0
  751. package/dist/core/staging/recovery/finding.js +35 -0
  752. package/dist/core/staging/recovery/finding.js.map +1 -0
  753. package/dist/core/staging/recovery/intent.js +98 -0
  754. package/dist/core/staging/recovery/intent.js.map +1 -0
  755. package/dist/core/staging/recovery/recover.js +126 -0
  756. package/dist/core/staging/recovery/recover.js.map +1 -0
  757. package/dist/core/staging/recovery/residue.js +62 -0
  758. package/dist/core/staging/recovery/residue.js.map +1 -0
  759. package/dist/core/staging/snapshot.js +202 -0
  760. package/dist/core/staging/snapshot.js.map +1 -0
  761. package/dist/core/staging/txn/forward.js +171 -0
  762. package/dist/core/staging/txn/forward.js.map +1 -0
  763. package/dist/core/staging/txn/journal.js +139 -0
  764. package/dist/core/staging/txn/journal.js.map +1 -0
  765. package/dist/core/staging/txn/transaction.js +75 -0
  766. package/dist/core/staging/txn/transaction.js.map +1 -0
  767. package/dist/core/staging/writes.js +113 -0
  768. package/dist/core/staging/writes.js.map +1 -0
  769. package/dist/core/status/actions/execution.js +49 -0
  770. package/dist/core/status/actions/execution.js.map +1 -0
  771. package/dist/core/status/contracts.js +102 -0
  772. package/dist/core/status/contracts.js.map +1 -0
  773. package/dist/core/status/feature/artifacts.js +171 -0
  774. package/dist/core/status/feature/artifacts.js.map +1 -0
  775. package/dist/core/status/feature/feature.js +207 -0
  776. package/dist/core/status/feature/feature.js.map +1 -0
  777. package/dist/core/status/feature/next.js +150 -0
  778. package/dist/core/status/feature/next.js.map +1 -0
  779. package/dist/core/status/feature/state.js +21 -0
  780. package/dist/core/status/feature/state.js.map +1 -0
  781. package/dist/core/status/fleet/fleet.js +187 -0
  782. package/dist/core/status/fleet/fleet.js.map +1 -0
  783. package/dist/core/status/fleet/next.js +207 -0
  784. package/dist/core/status/fleet/next.js.map +1 -0
  785. package/dist/core/status/interrupted.js +97 -0
  786. package/dist/core/status/interrupted.js.map +1 -0
  787. package/dist/core/status/report.js +31 -0
  788. package/dist/core/status/report.js.map +1 -0
  789. package/dist/core/status/scan.js +41 -0
  790. package/dist/core/status/scan.js.map +1 -0
  791. package/dist/core/status/verification.js +201 -0
  792. package/dist/core/status/verification.js.map +1 -0
  793. package/dist/core/usecases/capability.js +169 -0
  794. package/dist/core/usecases/capability.js.map +1 -0
  795. package/dist/core/usecases/delta/claims.js +116 -0
  796. package/dist/core/usecases/delta/claims.js.map +1 -0
  797. package/dist/core/usecases/delta/flows.js +103 -0
  798. package/dist/core/usecases/delta/flows.js.map +1 -0
  799. package/dist/core/usecases/delta/overlay.js +235 -0
  800. package/dist/core/usecases/delta/overlay.js.map +1 -0
  801. package/dist/core/usecases/fleet.js +137 -0
  802. package/dist/core/usecases/fleet.js.map +1 -0
  803. package/dist/core/usecases/operations.js +111 -0
  804. package/dist/core/usecases/operations.js.map +1 -0
  805. package/dist/core/usecases/place.js +44 -0
  806. package/dist/core/usecases/place.js.map +1 -0
  807. package/dist/core/usecases/touch.js +101 -0
  808. package/dist/core/usecases/touch.js.map +1 -0
  809. package/dist/core/verify/answers.js +173 -0
  810. package/dist/core/verify/answers.js.map +1 -0
  811. package/dist/core/verify/build.js +150 -0
  812. package/dist/core/verify/build.js.map +1 -0
  813. package/dist/core/verify/checklist.js +201 -0
  814. package/dist/core/verify/checklist.js.map +1 -0
  815. package/dist/core/verify/claims/identity.js +61 -0
  816. package/dist/core/verify/claims/identity.js.map +1 -0
  817. package/dist/core/verify/cross/diff.js +97 -0
  818. package/dist/core/verify/cross/diff.js.map +1 -0
  819. package/dist/core/verify/evidence/contract.js +169 -0
  820. package/dist/core/verify/evidence/contract.js.map +1 -0
  821. package/dist/core/verify/file.js +257 -0
  822. package/dist/core/verify/file.js.map +1 -0
  823. package/dist/core/verify/pins/lint.js +157 -0
  824. package/dist/core/verify/pins/lint.js.map +1 -0
  825. package/dist/core/verify/pins/pin.js +95 -0
  826. package/dist/core/verify/pins/pin.js.map +1 -0
  827. package/dist/core/verify/record.js +142 -0
  828. package/dist/core/verify/record.js.map +1 -0
  829. package/dist/core/verify/store/commit.js +89 -0
  830. package/dist/core/verify/store/commit.js.map +1 -0
  831. package/dist/core/verify/store/render.js +57 -0
  832. package/dist/core/verify/store/render.js.map +1 -0
  833. package/dist/core/vocabulary/health.js +91 -0
  834. package/dist/core/vocabulary/health.js.map +1 -0
  835. package/dist/core/vocabulary/issue.js +55 -0
  836. package/dist/core/vocabulary/issue.js.map +1 -0
  837. package/dist/core/vocabulary/maturity.js +145 -0
  838. package/dist/core/vocabulary/maturity.js.map +1 -0
  839. package/dist/core/{report.js → vocabulary/report.js} +30 -2
  840. package/dist/core/vocabulary/report.js.map +1 -0
  841. package/dist/core/vocabulary/steps.js +266 -0
  842. package/dist/core/vocabulary/steps.js.map +1 -0
  843. package/dist/core/workspace/discover.js +239 -0
  844. package/dist/core/workspace/discover.js.map +1 -0
  845. package/dist/core/workspace/render.js +52 -0
  846. package/dist/core/workspace/render.js.map +1 -0
  847. package/examples/README.md +189 -0
  848. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  849. package/examples/docs/architecture/capabilities.yaml +31 -0
  850. package/examples/docs/architecture/landscape.likec4 +280 -0
  851. package/examples/docs/architecture/obligations.yaml +23 -0
  852. package/examples/docs/architecture/permissions.yaml +50 -0
  853. package/examples/docs/architecture/subsystems.likec4 +11 -0
  854. package/examples/docs/architecture/usecases/order-notification.likec4 +65 -0
  855. package/examples/docs/capabilities/checkout/spec.md +55 -0
  856. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  857. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  858. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  859. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  860. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  861. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  862. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +129 -0
  863. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  864. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  865. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  866. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  867. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  868. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +28 -0
  869. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  870. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  871. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  872. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  873. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  874. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  875. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  876. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  877. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  878. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  879. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +70 -0
  880. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  881. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  882. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  883. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  884. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  885. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  886. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  887. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  888. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  889. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  890. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  891. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  892. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  893. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  894. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  895. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  896. package/examples/docs/glossary/order.md +15 -0
  897. package/examples/docs/glossary/payments/authorization.md +14 -0
  898. package/examples/docs/likec4.config.json +9 -0
  899. package/examples/docs/loam.json +3 -0
  900. package/examples/docs/services/checkout-web/model.likec4 +109 -0
  901. package/examples/docs/services/checkout-web/spec.md +91 -0
  902. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  903. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  904. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  905. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  906. package/examples/docs/services/order-service/arch.spec.md +127 -0
  907. package/examples/docs/services/order-service/asyncapi.yaml +108 -0
  908. package/examples/docs/services/order-service/health.yaml +57 -0
  909. package/examples/docs/services/order-service/model.likec4 +138 -0
  910. package/examples/docs/services/order-service/openapi.yaml +257 -0
  911. package/examples/docs/services/order-service/runbook.md +62 -0
  912. package/examples/docs/services/order-service/spec.md +134 -0
  913. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  914. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  915. package/examples/docs/services/payment-service/arch.spec.md +73 -0
  916. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  917. package/examples/docs/services/payment-service/health.yaml +39 -0
  918. package/examples/docs/services/payment-service/model.likec4 +67 -0
  919. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  920. package/examples/docs/services/payment-service/runbook.md +37 -0
  921. package/examples/docs/services/payment-service/spec.md +88 -0
  922. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  923. package/examples/docs/services/platform/identity-service/arch.spec.md +117 -0
  924. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  925. package/examples/docs/services/platform/identity-service/model.likec4 +83 -0
  926. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  927. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  928. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  929. package/examples/docs/services/platform/notification-service/asyncapi.yaml +199 -0
  930. package/examples/docs/services/platform/notification-service/health.yaml +35 -0
  931. package/examples/docs/services/platform/notification-service/model.likec4 +118 -0
  932. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  933. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  934. package/examples/docs/services/platform/subsystem.yaml +2 -0
  935. package/examples/fleet.yaml +57 -0
  936. package/package.json +19 -6
  937. package/dist/commands/adopt.js +0 -240
  938. package/dist/commands/adopt.js.map +0 -1
  939. package/dist/commands/archive.js +0 -1313
  940. package/dist/commands/archive.js.map +0 -1
  941. package/dist/commands/delta.js +0 -388
  942. package/dist/commands/delta.js.map +0 -1
  943. package/dist/commands/docs-repo-gate.js.map +0 -1
  944. package/dist/commands/format.js +0 -17
  945. package/dist/commands/format.js.map +0 -1
  946. package/dist/commands/gherkin.js +0 -309
  947. package/dist/commands/gherkin.js.map +0 -1
  948. package/dist/commands/init.js.map +0 -1
  949. package/dist/commands/list.js +0 -295
  950. package/dist/commands/list.js.map +0 -1
  951. package/dist/commands/migrate-openspec.js +0 -950
  952. package/dist/commands/migrate-openspec.js.map +0 -1
  953. package/dist/commands/new.js +0 -413
  954. package/dist/commands/new.js.map +0 -1
  955. package/dist/commands/rebase.js +0 -356
  956. package/dist/commands/rebase.js.map +0 -1
  957. package/dist/commands/show.js.map +0 -1
  958. package/dist/commands/status.js +0 -262
  959. package/dist/commands/status.js.map +0 -1
  960. package/dist/commands/unarchive.js.map +0 -1
  961. package/dist/commands/validate.js +0 -1773
  962. package/dist/commands/validate.js.map +0 -1
  963. package/dist/commands/verify.js +0 -775
  964. package/dist/commands/verify.js.map +0 -1
  965. package/dist/commands/vouch.js +0 -421
  966. package/dist/commands/vouch.js.map +0 -1
  967. package/dist/core/agent.js +0 -2173
  968. package/dist/core/agent.js.map +0 -1
  969. package/dist/core/agents-stamp.js.map +0 -1
  970. package/dist/core/arch.js +0 -130
  971. package/dist/core/arch.js.map +0 -1
  972. package/dist/core/asyncapi.js.map +0 -1
  973. package/dist/core/brief.js +0 -755
  974. package/dist/core/brief.js.map +0 -1
  975. package/dist/core/coherence.js +0 -577
  976. package/dist/core/coherence.js.map +0 -1
  977. package/dist/core/concurrency.js.map +0 -1
  978. package/dist/core/config.js.map +0 -1
  979. package/dist/core/delta.js +0 -476
  980. package/dist/core/delta.js.map +0 -1
  981. package/dist/core/dependencies.js +0 -356
  982. package/dist/core/dependencies.js.map +0 -1
  983. package/dist/core/doctor.js +0 -596
  984. package/dist/core/doctor.js.map +0 -1
  985. package/dist/core/document-bytes.js.map +0 -1
  986. package/dist/core/explore.js.map +0 -1
  987. package/dist/core/frontmatter.js.map +0 -1
  988. package/dist/core/gherkin.js +0 -463
  989. package/dist/core/gherkin.js.map +0 -1
  990. package/dist/core/health.js +0 -67
  991. package/dist/core/health.js.map +0 -1
  992. package/dist/core/ids.js +0 -122
  993. package/dist/core/ids.js.map +0 -1
  994. package/dist/core/issue.js +0 -9
  995. package/dist/core/issue.js.map +0 -1
  996. package/dist/core/json.js +0 -74
  997. package/dist/core/json.js.map +0 -1
  998. package/dist/core/likec4.js +0 -489
  999. package/dist/core/likec4.js.map +0 -1
  1000. package/dist/core/maturity.js +0 -66
  1001. package/dist/core/maturity.js.map +0 -1
  1002. package/dist/core/openapi-merge.js +0 -552
  1003. package/dist/core/openapi-merge.js.map +0 -1
  1004. package/dist/core/openapi.js.map +0 -1
  1005. package/dist/core/openspec-inventory.js +0 -1440
  1006. package/dist/core/openspec-inventory.js.map +0 -1
  1007. package/dist/core/path-safety.js.map +0 -1
  1008. package/dist/core/provenance.js +0 -787
  1009. package/dist/core/provenance.js.map +0 -1
  1010. package/dist/core/records.js.map +0 -1
  1011. package/dist/core/repo.js +0 -438
  1012. package/dist/core/repo.js.map +0 -1
  1013. package/dist/core/report.js.map +0 -1
  1014. package/dist/core/spec.js +0 -505
  1015. package/dist/core/spec.js.map +0 -1
  1016. package/dist/core/staging.js +0 -890
  1017. package/dist/core/staging.js.map +0 -1
  1018. package/dist/core/status.js +0 -1132
  1019. package/dist/core/status.js.map +0 -1
  1020. package/dist/core/steps.js +0 -72
  1021. package/dist/core/steps.js.map +0 -1
  1022. package/dist/core/verify.js +0 -807
  1023. package/dist/core/verify.js.map +0 -1
  1024. package/dist/core/version.js.map +0 -1
  1025. /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
  1026. /package/dist/core/{records.js → kernel/records.js} +0 -0
package/README.md CHANGED
@@ -1,41 +1,163 @@
1
1
  # loam
2
2
 
3
- **Architecture-first spec framework for microservice fleets.**
3
+ **Architecture-first semantic integrity and change governance for evolving software systems.**
4
4
 
5
5
  ![license: MIT](https://img.shields.io/badge/license-MIT-blue.svg)
6
6
  ![node: >=22.22.3](https://img.shields.io/badge/node-%3E%3D22.22.3-brightgreen.svg)
7
7
  [![CI](https://github.com/ybotok/loam/actions/workflows/ci.yml/badge.svg)](https://github.com/ybotok/loam/actions/workflows/ci.yml)
8
- <!-- once published: [![npm](https://img.shields.io/npm/v/@ybotok/loam.svg)](https://www.npmjs.com/package/@ybotok/loam) -->
8
+ [![npm](https://img.shields.io/npm/v/@ybotok/loam.svg)](https://www.npmjs.com/package/@ybotok/loam)
9
9
 
10
- > **Pre-release: `0.1.0-beta.1`.** Every command below is implemented and covered by tests; the package is not on npm yet. See [Status](#status).
10
+ > **Pre-release: `0.2.0-alpha.1`**, the first release of the 0.2 line and the newest published
11
+ > version of [`@ybotok/loam`](https://www.npmjs.com/package/@ybotok/loam). It publishes under the
12
+ > `alpha` npm dist-tag: `npm i @ybotok/loam@alpha`, or the exact version, always installs this
13
+ > line. `latest` is moved onto a release by hand once it has published, so a plain
14
+ > `npm i @ybotok/loam` may still resolve to `0.1.0-beta.3` until it is. See [Status](#status).
11
15
 
12
- `loam` gets a service's documentation and C4 architecture written **from its code**, then lets you drive cross-service features top-down: you author a **C4 delta**, `loam` projects it onto each affected service as concrete work, and `loam gherkin` turns the spec's scenarios into real, digest-stamped Gherkin `.feature` files — the acceptance skeleton that drives TDD, kept honest by `loam validate` reporting when the spec moves under it.
16
+ `loam` keeps an authored C4 model, requirements, API and event contracts, permissions, domain
17
+ vocabulary and verification evidence in explicit agreement as a system changes. The same lifecycle
18
+ governs a modular monolith, a distributed service fleet, or a hybrid of both; the CLI and filesystem
19
+ call each governed implementation boundary a `service`, but it need not be a network service.
20
+
21
+ For an existing boundary, `loam` briefs an agent to document it **by reading its code**, then checks
22
+ the result without pretending to extract architectural meaning itself. Forward changes start from
23
+ an authored C4 delta: `loam` projects it onto each affected boundary, generates digest-stamped
24
+ Gherkin, and checks that behavior, architecture, contracts and evidence still join.
13
25
 
14
26
  ## Contents
15
27
 
16
- - [Why](#why) · [Install](#install) · [Quick start](#quick-start) · [loam vs OpenSpec](#loam-vs-openspec)
17
- - [Day zero: onboarding a fleet](#day-zero-onboarding-a-fleet) · [Two flows](#two-flows) · [Principles](#principles)
18
- - [Commands](#commands) · [Command notes](#command-notes) · [Working with AI agents](#working-with-ai-agents) · [Fleet scale](#fleet-scale)
19
- - [Docs](#docs) · [Development](#development) · [Status](#status) · [Contributing](#contributing) · [Security](#security) · [License](#license)
28
+ - [Why](#why) · [System shapes](#one-lifecycle-several-system-shapes) · [Install](#install) ·
29
+ [Quick start](#quick-start) · [Commands](#commands) · [Working with AI agents](#working-with-ai-agents)
30
+ - [Docs](#docs) · [Development](#development) · [Status](#status) · [Contributing](#contributing) ·
31
+ [Security](#security) · [License](#license)
32
+ - Companion pages: [QUICKSTART.md](QUICKSTART.md) — install-to-first-change ·
33
+ [WORKFLOW.md](WORKFLOW.md) — the protocol · [SCHEMA.md](SCHEMA.md) — the reference ·
34
+ [ROADMAP.md](ROADMAP.md) · [COMPARISON.md](COMPARISON.md)
20
35
 
21
36
  ## Why
22
37
 
23
- Spec-driven development tools treat specs as business-analyst-level documents: there is no architecture layer, and even where planning is shared across repos no service topology is modelled — while a business-simple feature can span many services (e.g. 7 new + 4 changed). C4 diagrams, Gherkin and specs end up as disconnected documents that drift apart quietly. `loam` ties them with one feature-ID spine and makes C4 the center. And because a business spec will never mention the transactional outbox, architecture gets its own requirement axis — `arch.spec.md`, whose `Covers:` lines tie outbox/retry/alert obligations to the C4 elements and health signals they exercise, with coverage derived mechanically rather than trusted.
38
+ Software architecture does not live in one artifact. A business-simple feature can cross modules,
39
+ processes or services while C4 diagrams, requirements, API contracts, permissions and test evidence
40
+ drift independently. `loam` makes the authored C4 model the center and gives those artifacts
41
+ referential integrity: every join below is an exact token spelled in two places, never a heuristic
42
+ over prose.
43
+
44
+ | The join | Ties |
45
+ |---|---|
46
+ | `Operations:` ↔ OpenAPI `operationId` | a requirement to the endpoint it governs |
47
+ | `Publishes:` / `Consumes:` ↔ AsyncAPI message names | a requirement to the event spine |
48
+ | `Covers:` ↔ C4 elements, `#obl-` tags, `health.yaml` ids | an architectural obligation to what it accounts for |
49
+ | `Requires:` ↔ `architecture/permissions.yaml` | a requirement to the system-wide authorization vocabulary |
50
+ | `Realizes:` ↔ `capabilities/<cap>/spec.md` | a service requirement to the business promise it keeps |
51
+ | `#cap-` / `#req-` on a `dynamic view` ↔ a capability requirement | a cross-service use case to the promise it keeps |
52
+ | a Markdown link ↔ `glossary/<term>.md` | a document to the word it uses |
53
+
54
+ Architecture has its own requirement axis (`arch.spec.md`) because a business spec will not mention
55
+ the transactional outbox, retries or alerts.
56
+
57
+ ### One lifecycle, several system shapes
58
+
59
+ Topology changes where loam's checks pay off; it does not change the lifecycle:
60
+
61
+ - **A modular monolith is one governed boundary.** Bind one root element to one
62
+ `services/<app>/` directory and draw modules, components and their relationships beneath it.
63
+ `Covers:` can name those nested elements and edges, and a feature's `delta.likec4` can change
64
+ them through the same validate/archive transaction as any fleet change.
65
+ - **A distributed system is several governed boundaries.** Each service gets its own directory and
66
+ binding; cross-boundary edges can join to provider OpenAPI operations or AsyncAPI messages, and a
67
+ feature is projected onto every boundary it touches.
68
+ - **A hybrid uses both shapes at once.** A modular application can sit beside independently
69
+ deployed services and external systems in the same landscape. The binding, not the C4 kind or
70
+ nesting depth, decides which `services/<id>/` owns an element.
71
+
72
+ For example, the frozen `service` term can name an application while its internal modules remain
73
+ ordinary C4 elements:
74
+
75
+ ```likec4
76
+ specification {
77
+ element softwareSystem
78
+ element component
79
+ }
80
+
81
+ model {
82
+ commerce = softwareSystem 'commerce-app' {
83
+ metadata {
84
+ service 'commerce-app'
85
+ }
86
+
87
+ orders = component 'Orders module'
88
+ billing = component 'Billing module'
89
+ orders -> billing 'Reserves credit'
90
+ }
91
+ }
92
+ ```
93
+
94
+ An internal edge normally carries no `metadata { op }`: that key specifically joins a call to the
95
+ governed boundary's OpenAPI contract. An architecture requirement can instead say
96
+ `Covers: commerce.orders -> commerce.billing`. Fleet-level maturity, dependency and scorecard views
97
+ still aggregate at the bound `service`; nested elements get architecture coverage and feature
98
+ lifecycle, not a separate deployment status invented for each module.
99
+
100
+ **There is no extractor, and there will not be one.** Nothing deterministic reads a legacy service
101
+ and says what its architecture *means*, and a model that was guessed is worse than none — everyone
102
+ downstream has to re-derive it to know whether to believe it. So loam takes the half of the job that
103
+ is mechanical: it **states the work** and it **checks the result**. An agent does the reading, and
104
+ both halves are written down: the question in the brief or the checklist, the answer in `sources` or
105
+ `verification.yaml`.
106
+
107
+ ### What green means here, and what it does not
108
+
109
+ Most of this category will tell you what it checks. loam ships the other list too, in the binary:
110
+ **[`src/core/brief/unchecked.ts`](https://github.com/ybotok/loam/blob/main/src/core/brief/unchecked.ts)
111
+ is fifteen statements of what no check will ever tell you**, printed into the adoption brief beside
112
+ the checks that do run. It says, in loam's own words, that nothing here knows whether the model is
113
+ the architecture the code actually has, whether a requirement is *true*, whether an `operationId` is
114
+ the one the code serves, or whether `sources` names the files anybody read. And it says the one that
115
+ matters most: **completeness is unchecked** — forty behaviours documented as one requirement passes
116
+ every check loam has, and so does a service with one endpoint documented out of thirty.
117
+
118
+ That list exists because a check that is silent for want of anything to ask must never read as a
119
+ check that passed. Green here means *the documents agree with each other* — never that they are
120
+ true, and never that they are complete.
121
+
122
+ The same refusal runs through the evidence model. `loam verify` records who answered every claim,
123
+ and keeps two answers permanently distinguishable:
124
+
125
+ - **`verified`** — a digest-tagged scenario answered by a green test run. The digest is taken over
126
+ the scenario's *body*, so rewording a `Given` breaks the link on purpose. Tag-based coverage
127
+ (`@REQ-1234` and its relatives) survives any rewrite and goes on asserting a claim nobody
128
+ re-checked.
129
+ - **`attested`** — an agent's word, with `file:line` evidence at an attested commit. Recorded in
130
+ full, labelled on every surface, and never promoted. A feature whose scenarios rest on attestation
131
+ does not become verified because a gate would be greener if it did.
132
+
133
+ Neither gates the archive. The claim loam makes for its evidence is persistence and honest
134
+ provenance — not that every recorded judgement is true.
135
+
136
+ Files stay the source of truth. Delete `loam` and every artifact remains as Markdown, LikeC4 DSL,
137
+ Gherkin and YAML — no server, no database, no state file, three runtime dependencies. The two flows
138
+ this implies, what gates and what only advises, are in [WORKFLOW.md](WORKFLOW.md).
24
139
 
25
140
  ## Install
26
141
 
27
- **Node ≥ 22.22.3** (the `engines` floor in `package.json`) is the only prerequisite for everything loam derives from the docs repo. C4 modeling uses **[LikeC4](https://likec4.dev)** (pinned exact), an ordinary npm runtime dependency loaded in-process (TypeScript-native): no JVM, no external CLI. The one outside binary loam ever calls is **`git`**, and only inside a service repo — `verify --service` binds each attestation to that repo's HEAD and refuses (`repository-unavailable`) without one, while `vouch`'s source digest asks `git check-ignore` and treats an absent git as "nothing is ignored" rather than failing.
142
+ **Node ≥ 22.22.3** (the `engines` floor in `package.json`) is the only prerequisite for everything
143
+ loam derives from the docs repo. C4 modeling uses **[LikeC4](https://likec4.dev)** (pinned exact),
144
+ an ordinary npm runtime dependency loaded in-process (TypeScript-native): no JVM, no external CLI.
145
+ The one outside binary loam ever calls is **`git`** — read-only questions in whichever repository
146
+ the command is about (`verify --service`, `vouch`'s source digest, `subsystem move`/`history`, and
147
+ `diff --base`), plus the one blessed `git add` that stages a subsystem move's renames. Never the
148
+ network.
28
149
 
29
150
  ```bash
30
151
  npm install -g @ybotok/loam
31
152
  loam --version
32
153
  ```
33
154
 
34
- `loam doctor` is the wiring check, not the install check: run where no `loam.json` is in scope, it reports `doctor.config-missing` and exits 1 by design. Save it for after `loam init`.
155
+ `loam doctor` is the wiring check, not the install check: run where no `loam.json` is in scope, it
156
+ reports `doctor.config-missing` and exits 1 by design. Save it for after `loam init`.
35
157
 
36
158
  A per-repo dev dependency works the same way: `npm i -D @ybotok/loam`, then `npx loam …`.
37
159
 
38
- Until the package is published ([Status](#status)), install from a clone:
160
+ To work on loam itself — or to run an unreleased commit — install from a clone:
39
161
 
40
162
  ```bash
41
163
  git clone https://github.com/ybotok/loam.git && cd loam
@@ -46,170 +168,328 @@ Drop `--link` to build without a global `loam`; on Windows run `npm ci && npm ru
46
168
 
47
169
  ## Quick start
48
170
 
49
- The repo ships a small example fleet under [`examples/docs/`](examples/docs) — two services, one feature in flight. From a clone, point a throwaway `loam.json` at it and run the real commands (the file is untracked; delete it when done):
50
-
51
- ```bash
52
- echo '{ "docsDir": "examples/docs" }' > loam.json # relative, resolved against this file
53
- npm run dev -- list # what the fleet looks like
54
- npm run dev -- validate --all # the CI gate: 0 errors, 3 deliberate warnings
55
- npm run dev -- archive FEAT-101 --dry-run # the whole three-axis merge plan, writing nothing
56
- ```
57
-
58
- `test/examples.test.ts` pins the validate summary and every finding code, and the archive plan file-for-file, so those outcomes cannot drift from the code; the `list` rendering is not pinned.
171
+ For the shortest install-to-first-feature path, including the exact chat commands and local problem
172
+ report flow, use [QUICKSTART.md](QUICKSTART.md). The routes below explain the alternative starting
173
+ positions in more depth.
59
174
 
60
- To wire loam into your own repositories, start at [Day zero](#day-zero-onboarding-a-fleet).
175
+ `loam --help` ends by naming where to start and the way out, and this section is the same two
176
+ commands in the same order: **`loam init --create`** first — every other command needs the docs repo
177
+ it writes — and **`loam doctor`** whenever a later run does not do what you expected, which reports
178
+ the runtime, the resolved `docsDir`, the access, the binding, and any finding with its `fix:` line.
179
+ Each path below is that first command aimed at a different starting position; `loam diff` is the one
180
+ that needs neither.
61
181
 
62
- ## loam vs OpenSpec
182
+ ### Start from the fleet spine
63
183
 
64
- loam reads the core of [OpenSpec](https://github.com/Fission-AI/OpenSpec)'s requirement format: requirement/scenario headings and the `ADDED | MODIFIED | REMOVED` delta sections. Routine CI exercises seven representative upstream fixtures; a scheduled/manual sweep reproduces the broader compatibility result — counts *and* parse/serialize/parse stability of every requirement's content — against the full living, active and archived spec trees at the pinned OpenSpec v1.7.0 commit: **207 Markdown files, 739 requirements, 2273 scenarios** (the post-release main canary the same sweep pins is 209 / 742 / 2284). The boundary is explicit: OpenSpec `Purpose`, wrapper, and `RENAMED` semantics are not round-trippable — a `RENAMED` section is a loud `delta.unknown-section` error, not a silent drop, and `migrate-openspec` maps it rather than losing it.
184
+ The path that pays off first, because it is the only one whose checks have two sides to compare.
185
+ It needs **no requirement Markdown, no `loam adopt`, and no `loam vouch`** — just the map and the
186
+ contracts you already have.
65
187
 
66
- | | OpenSpec | loam |
67
- |---|---|---|
68
- | System model | capability specs; beta Stores share planning across repos (Git-owned planning roots, read-only references), but model no service topology | C4 landscape + one ID spine across spec / arch / API |
69
- | Executability | `/opsx:verify` asks an agent to inspect implementation and tests; advisory | digest-stamped Gherkin; a green cucumber run confirms a scenario mechanically, and a scenario confirmed on an agent's word instead is recorded as **attested, not verified** (`verify.scenario-attested`) |
70
- | Drift control | structural CLI validation plus agent-led verification on demand; no persisted digests to compare against later | persisted source/content digests + human vouch. `content.stale` is checkable fleet-wide; `sources.stale` only inside each service's own repo. Both are warnings — `--strict` is the CI escalation |
71
- | Change merge | validates prepared requirement updates, supports `RENAMED`, then writes specs sequentially | transactional 3-axis merge behind a coherence gate, digest-checked byte-level undo, and a commit journal that repairs an interrupted merge |
72
- | Agent surface | skills + commands for 34 tools at v1.7.0; `openspec update` regenerates them in place, skipping ones already current | skills for 20 tools and commands for the 19 that read them (Codex takes skills only); `--json` on every command; generated files carry a version stamp and are **never** regenerated — drift is reported (`doctor.agent-files-stale`) and repaired by hand |
73
- | Entry curve | minutes | you learn LikeC4 + frontmatter + the operationId spine first |
188
+ Write a `fleet.yaml` naming your services and who calls whom
189
+ ([`examples/fleet.yaml`](https://github.com/ybotok/loam/blob/main/examples/fleet.yaml) is a real
190
+ one), then:
74
191
 
75
- Honest boundary: for a single repo without cross-service contracts, OpenSpec is simpler *and sufficient*. The full comparison — including what loam deliberately refuses to borrow — is in [COMPARISON.md](COMPARISON.md); migration is covered by [MIGRATING-from-OpenSpec.md](MIGRATING-from-OpenSpec.md).
192
+ ```bash
193
+ loam init --docs . --create # in an empty directory: the docs repo
194
+ loam seed --from fleet.yaml # the fleet map + one services/<id>/ per service
195
+ ```
76
196
 
77
- ## Day zero: onboarding a fleet
197
+ Now do the two things only you can do:
78
198
 
79
- A fleet of ten services is **eleven repositories**: one docs repo and ten service repos, each with its own committed `loam.json`. There is no batch command and no fleet manifest, deliberately — the wiring is one file per repo, and it is reviewable. In order:
199
+ 1. **Drop each service's existing `openapi.yaml`** into `services/<id>/`. Copy the one your build
200
+ already produces — loam never generates it and never reads your code.
201
+ 2. **Name the operation on each call edge** in `architecture/landscape.likec4`:
202
+ `metadata { op 'createOrder' }`. This is the labour, and it is also the artifact nothing else
203
+ produces — a drawn arrow becomes a checked join.
80
204
 
81
- 1. **Create the docs repo.** In an empty directory that will be the shared source of truth:
205
+ ```bash
206
+ loam validate --all
207
+ ```
82
208
 
83
- ```bash
84
- loam init --docs . --create
85
- ```
209
+ That already convicts the fleet's real edges: a call naming an operation its provider does not
210
+ define is `spine.op-undefined`, an **error**, and one letter is enough — `authorisePayment` against
211
+ a contract spelling it `authorizePayment` fails here and nowhere else a team normally runs.
212
+
213
+ **Expect a red run, and read it correctly.** Five seeded services with no C4 centre report
214
+ `service.no-model` (error) five times, and `service.no-spec` (warn) five times. Those are not
215
+ misconfiguration: they are a truthful reading of a fleet where adoption has not started, and they
216
+ stay until you write those documents. The finding you came for is the spine one.
217
+ [`test/spine-first.test.ts`](https://github.com/ybotok/loam/blob/main/test/spine-first.test.ts)
218
+ pins this whole sequence against the shipped `examples/fleet.yaml`, so the recipe cannot drift from
219
+ the binary.
220
+
221
+ From here, [WORKFLOW.md's day zero](WORKFLOW.md#day-zero-onboarding-a-fleet) is the rest: bind each
222
+ service repo, adopt, grade, promote.
223
+
224
+ ### Guard the fleet's edges on every PR
225
+
226
+ Two commands, each installable on its own with no part of the workflow above adopted. **`loam diff`
227
+ exits 1 when a pull request removes an operation or an event message the fleet still consumes**,
228
+ and names the consumers. That question — *who still calls this?* — is the one a fleet answers wrong,
229
+ and it is answerable only from a document that knows the whole fleet. **`loam validate --all --base
230
+ <ref>` grades only the boundaries the branch touched**, which is what lets a strict gate go in on
231
+ the first day of adoption and tighten as the system gets written down.
232
+
233
+ ```yaml
234
+ # .github/workflows/fleet-edges.yml — in the docs repo
235
+ name: fleet edges
236
+ on: pull_request
237
+ jobs:
238
+ edges:
239
+ runs-on: ubuntu-latest
240
+ steps:
241
+ - uses: actions/checkout@v4
242
+ with: { fetch-depth: 0 } # both read the base out of git history
243
+ - uses: actions/setup-node@v4
244
+ with: { node-version: 22 }
245
+ # did you break a consumer?
246
+ - run: npx -y @ybotok/loam diff --base origin/${{ github.base_ref }}
247
+ # did you document what you touched?
248
+ - run: npx -y @ybotok/loam validate --all --base origin/${{ github.base_ref }} --strict
249
+ ```
86
250
 
87
- That scaffolds `services/`, `features/`, `architecture/landscape.likec4`, `AGENTS.md`, and the docs repo's own `loam.json` (`docsDir: "."`, plus the `agentTools` it wrote for) — so every later command run *inside* the docs repo finds the fleet. An empty directory holds no tool dot-directory to detect, so the Claude Code fallback always fires here too: six slash commands and six Agent Skills under `.claude/` ([Working with AI agents](#working-with-ai-agents)). Commit all of it.
251
+ Two gates, two different questions, and neither is the other's cheaper form. `diff` reports every
252
+ removal against the system's current consumers rather than against a rule list, which is why it
253
+ repays installation before anything else exists. `validate --base` grades the boundaries this
254
+ branch changed, at full strictness, and says out loud how much of the system that was — a run with
255
+ nothing in scope prints that it graded nothing rather than the word valid. Unscoped, neither
256
+ setting is usable on a partly-documented system: `loam validate --all` is green over boundaries
257
+ nobody has written yet, because warnings do not gate, and `--strict` over all of them is red from
258
+ the first minute of adoption until the last one is done.
88
259
 
89
- 2. **Draw what you already know** in `architecture/landscape.likec4`. It can start almost empty; it is a **required** artifact, not an optional one — `loam validate --all` reports `landscape.missing` as an error the moment `services/` holds a directory (an empty one counts, before a single document lands in it), because with no fleet map every cross-service check is blind rather than passing.
260
+ **A `--base`-scoped validate cannot see a victim boundary the change did not touch.** Remove an
261
+ operation `payment-service` owns, and `checkout-web` — whose living requirement still names it —
262
+ is not in scope, so nothing in that gate reports the broken join. That is `loam diff --base`'s
263
+ question, it stays `loam diff --base`'s, and a green scoped validate is not a statement about the
264
+ consumers of what changed. [WORKFLOW.md](WORKFLOW.md#what-actually-gates) has what each does and
265
+ does not grade — including the oasdiff invocation for the byte-level OpenAPI breaking-change
266
+ catalogue, which loam deliberately does not reimplement.
90
267
 
91
- 3. **Bind each service repo.** Once per service, in that service's own checkout, beside the docs repo:
268
+ ### Try loam on one governed system in five minutes
92
269
 
93
- ```bash
94
- loam init --docs ../docs-repo --service payment-service # no --create: it JOINS
95
- loam doctor # confirms the wiring
96
- ```
270
+ The full model may be one application or a fleet; the trial is one repository. In the codebase you
271
+ know best (after [installing](#install)):
97
272
 
98
- `--service` is the binding: without it `loam vouch` and `loam gherkin` refuse outright, and `loam verify --service --record` / `--results` refuse to attest, because none of them will write a service's documents from a repo that has not said which service it is. Reading — `loam verify --service` on its own — needs no binding, because it writes nothing. Commit the `loam.json`.
273
+ ```bash
274
+ loam init --docs loam-docs --create --service commerce-app
275
+ ```
99
276
 
100
- 4. **Adopt each service.** In its repo: `loam adopt --service <id> --json` emits the brief — every file to write, the grammar of each, what the fleet map already says, and the block the map still owes this service. An agent reads the code and writes the baseline as `draft`. `warnings[]` catches the typo case, where an id one letter off would have produced a complete, validating baseline for a service that does not exist.
277
+ One run does two things: it scaffolds a new docs repo at `loam-docs/` — `services/`, `features/`,
278
+ `architecture/landscape.likec4`, its own `AGENTS.md` and `loam.json` — and it binds this repository
279
+ to the id `commerce-app` in a committed `loam.json` beside your code (plus the slash commands and
280
+ Agent Skills for the AI tools it detects here — [Working with AI agents](#working-with-ai-agents)).
281
+ `init` ends by printing the first hour, which is this loop:
101
282
 
102
- 5. **Grade it, twice.** `loam validate --service <id> --json` in the service repo (its own axes plus `sources`, which only that repo can resolve), then `loam validate --all --json` in the docs repo — the fleet cross-check that catches a landscape edit which never landed.
283
+ ```bash
284
+ loam adopt --service commerce-app --json # the brief: an agent reads the code, writes the baseline as draft
285
+ loam validate --service commerce-app # grade the result in this repo
286
+ loam vouch --service commerce-app # you, not the agent: draft -> verified
287
+ loam status # what to do next, derived from the files
288
+ ```
103
289
 
104
- 6. **Promote it.** A human runs `loam vouch --service <id>` in the service repo: `draft → verified`, stamping the source and content digests that make later staleness detectable. `loam list --json` in the docs repo then grades the whole fleet on the presence ladder `empty → partial → documented → sourced → vouched`, and `loam list --needs-work` is the remaining worklist.
290
+ What the trial pays off on is the adopt → validate → vouch mechanics: the brief, the graded
291
+ baseline, the human promotion that makes later staleness detectable. In a modular monolith,
292
+ `arch.spec.md` and `Covers:` can already govern the nested model inside this one boundary. The
293
+ cross-boundary contract spine needs a second service — one boundary has no remote edge to join.
294
+ When a second service wants in, graduate to the full wiring:
295
+ [WORKFLOW.md's day zero](WORKFLOW.md#day-zero-onboarding-a-fleet) is the same steps, pluralized.
105
296
 
106
- Steps 3–6 repeat per service and are independent — no ordering, no lock, no shared state between two services' runs — so ten services can be onboarded by ten people in parallel. The one file they all touch is the landscape: step 2 draws it, step 4's brief tells each of them to *add* their own element to it where the map does not yet know the service, and step 5's `--all` reads it.
297
+ ### Explore the example fleet
107
298
 
108
- ## Two flows
299
+ Installed from npm rather than cloned? The example fleet ships inside the package, and one command
300
+ copies it out — through the same journaled write path every other loam writer uses, byte for byte.
301
+ It binds no repository, records no `docsDir`, and writes nothing outside the directory you name:
109
302
 
110
- ```
111
- BOOTSTRAP (once per service, reverse):
112
- code ──adopt──► brief ──agent──► C4 baseline + capability spec [truth = code]
113
-
114
- FORWARD (per feature, generative):
115
- intent → C4 delta → Gherkin (BDD) → tests → code [truth = model]
116
- ▲ │
117
- └──── done-check: verify ◄──────────┘
118
- (a checklist of the feature's own promises,
119
- answered against the code, with evidence)
303
+ ```bash
304
+ loam init --example ./loam-demo
305
+ cd loam-demo && loam validate --all # 0 errors, 10 deliberate warnings
120
306
  ```
121
307
 
122
- **There is no extractor, and there will not be one.** Nothing deterministic reads a legacy service and says what its architecture *means*, and a model that was guessed is worse than none — everyone downstream has to re-derive it to know whether to believe it. So loam takes the half of the job that is mechanical: it **states the work** and it **checks the result**. An agent does the reading.
308
+ That tree is the one the repo ships under
309
+ [`examples/docs/`](https://github.com/ybotok/loam/tree/main/examples/docs) — five services, two
310
+ features already shipped, two in flight, the event spine, the permission vocabulary, the business
311
+ tree, and two verification records that read `attested` and `verified` so the difference between
312
+ them can be seen standing.
313
+ [`examples/README.md`](https://github.com/ybotok/loam/blob/main/examples/README.md) is the guided
314
+ tour: what each service is there to show, and what every one of the ten deliberate warnings
315
+ demonstrates. From a clone, step into the fleet where it sits and run the real commands — it carries
316
+ its own committed `loam.json`, so there is nothing to write first and nothing to delete afterwards
317
+ (working from source instead of an installed binary, substitute `npx tsx ../../src/cli.ts` for
318
+ `loam`):
123
319
 
124
- The same split runs the done-check. `verify` cannot compare a generated model to the delta (two generated models of the same code disagree every run, so the diff would flap and get switched off), but it *can* derive the question set deterministically: every service the delta introduces, every operation the feature adds, every operation-linked call it draws, every scenario it wrote. The agent answers with a `file:line` — required to be non-empty in the docs-repo all-at-once form, and under `--service` resolved inside the service repo and pinned to its commit — and every answer is recorded next to the feature, marked with who gave it (`answered_by: runner` or `answered_by: agent`).
125
-
126
- **The scenario claims are where that mark carries weight.** The generated suite's digest tags ride into the cucumber JSON report, so `verify --results` answers a `scenario.tested` claim mechanically: only a green, digest-matched run confirms one, and names never match anything. But a legacy service with no runnable suite yet must still be able to record its answers, so `--record` may confirm a scenario claim too — on somebody's word. loam does not pretend those are the same thing. A record holding any of them never reads back as `verified`: complete, it reads **`verdict: "attested"`**; short of complete — an unanswered claim anywhere, or the feature moved under the answers — `unverified`. `verify` prints `verify.scenario-attested` naming each claim, `loam status` re-reports it and offers `next.verify-attested`, and the record travels into `features/archive/` saying so. `verified: true` in the JSON envelope means every scenario claim came from a test run. None of it gates anything: the notice is a warning, and `archive` does not read the record at all.
127
-
128
- ## Principles
320
+ ```bash
321
+ cd examples/docs # the tree governs itself: its loam.json says "docsDir": "."
322
+ loam list # the fleet and its maturity ladder
323
+ loam status # what to do next, derived from the files
324
+ loam validate --all # the CI gate: 0 errors, 10 deliberate warnings
325
+ loam archive FEAT-101 --dry-run # the whole three-axis merge plan, writing nothing
326
+ loam archive FEAT-112 --dry-run # an operation being retired, writing nothing
327
+ loam verify FEAT-088 # a shipped feature's done-check: attested
328
+ loam verify FEAT-120 # its pair, same check: verified
329
+ ```
129
330
 
130
- - **Files are the source of truth**; the CLI is a derived convenience. Delete `loam` and every artifact remains as Markdown / LikeC4 DSL / Gherkin / YAML. No binary, no database, no state file.
131
- - **Thin, not a platform.** One shared docs repo + a CLI. No server, no DB, no Backstage.
132
- - **Mechanical vs semantic.** Deterministic checks validate *shape* (valid DSL, resolvable IDs, coverage); an LLM writes *narrative* (the docs, the Gherkin behavior).
133
- - **loam never guesses about code.** It reads the docs repo; inside a service repo it only ever hashes or locates what a document already named — the files a `sources` list covers, the `file:line` an answer cites, the cucumber report `--results` was handed. It never parses code or derives meaning from it. Where a judgement about a codebase is needed — what this service is, whether that scenario has a test — loam states the **question**, precisely and repeatably, and an agent answers it. Both halves are written down: the question in the brief or the checklist, the answer in `sources` or `verification.yaml`.
331
+ `test/examples.test.ts` pins the validate summary and every finding code, and both archive plans
332
+ file-for-file, so those outcomes cannot drift from the code; the `list` rendering is not pinned.
134
333
 
135
334
  ## Commands
136
335
 
137
- | Command | What it does |
138
- |---|---|
139
- | `loam init --docs <dir> [--service <id>]` | Bind this repository to the single shared docs repo: write a committed local `loam.json` and, for every AI tool it detects here (Claude Code when it finds none), a command file and an Agent Skill per workflow. `--create` scaffolds the docs repo itself instead — `services/`, `features/`, `architecture/landscape.likec4` and its `AGENTS.md`. |
140
- | `loam list [services\|features]` | What is in the docs repo, and what is missing from it. |
141
- | `loam status [<FEAT>]` | Where the work stands and what to do next, as a projection over the two gates. Derived every run; writes nothing. |
142
- | `loam doctor` | Read-only preflight for runtime, config, docs-repo access, fleet roots, counts, and the current service binding. Blockers exit 1; incomplete optional bindings stay warnings. |
143
- | `loam dependencies [<FEAT>]` | Derive the active-feature dependency graph and same-identity conflicts from requirement deltas and OpenAPI operationIds. Optional focus includes transitive prerequisites. |
144
- | `loam explore [<service>...]` | Read the fleet around a change nobody has written down yet: the ring one hop out, each service's maturity and living operations, the features already in flight over the same ground, and the `loam new` line the seeds imply. `--op <id>` seeds from an operation. Writes nothing. |
145
- | `loam instructions [<workflow>] [args...]` | Print one of the six workflow protocols, `$1`/`$2` filled in — version-matched to this binary, which is what the generated command and skill files point at. Reads no config. |
146
- | `loam new <FEAT> [--title <t>] [--touches <id>] [--new-service <id>]` | Scaffold a feature: intent, C4 delta, and a requirement delta for every service named by `--touches` / `--new-service` (both repeatable). The title is optional and becomes the directory slug. |
147
- | `loam show <service\|FEAT>` | Everything loam knows about one service or feature. |
148
- | `loam adopt --service <id>` | Brief an agent to write this service's baseline into the docs repo as `draft`. Writes nothing. |
149
- | `loam delta <FEAT> [--service <id>]` | Project a feature onto one service: the intent, its requirement deltas with every requirement body and every Given/When/Then line reproduced verbatim, the endpoints it adds or retires, and the edges around it. The output doubles as a coding-agent task. |
150
- | `loam gherkin [<FEAT>] [--service <id>]` | Emit spec scenarios as digest-stamped Gherkin `.feature` files into the service repo's `<gherkinDir>/loam/`. |
151
- | `loam rebase <FEAT> [--service <id>]` | Pin the feature to the living versions it was written against, on the requirement axis and the contract axis. `--dry-run` shows what would be pinned. |
152
- | `loam validate [<id>] [--service <id>\|--feature <id>] [--all]` | Validate one service or feature, or the whole fleet in one run (the docs repo's CI gate). The positional id resolves a feature first; `--service` / `--feature` force the reading. `--strict` exits 1 on warnings too. |
153
- | `loam verify <FEAT> [--service <id>]` | The done-check: derive a checklist of the feature's own promises, and record the answers with their evidence. |
154
- | `loam vouch --service <id>` | The human promotion `draft` → `verified`: stamp a living spec against the code it was written from. Run in the service's own repo. |
155
- | `loam archive <FEAT>` | Merge a shipped feature into the living specs, API and landscape; gated on gating coherence issues, on what only the computed merge can see, and on living documents the merge cannot rewrite safely. `--approve` overrides the judgement calls, never the mechanical losses. `--dry-run` prints the plan and writes nothing. |
156
- | `loam unarchive <FEAT>` | Take that back: restore the living docs from the snapshot archive left behind, and re-open the feature. |
157
- | `loam audit-openspec <root>` | Read-only inventory of an OpenSpec checkout/workspace/Store checkout. Writes nothing; `--write-mapping <path>` emits the decision skeleton you fill in. |
158
- | `loam migrate-openspec <root> --map <path>` | Validate a completed mapping against a re-read of the source, and materialize staged migration docs. Dry-run is the default. |
159
-
160
- Every command takes `--json`: findings carry stable codes (`c4.valid`, `spine.op-undefined`, `coherence.ok` …) so an agent branches on the code, not on prose. The envelope keeps three different questions apart, each on the command that can answer it — `ok` (the command ran) on every envelope, `valid` (the docs pass) on `validate`, and `verified` (every claim is confirmed **and** every scenario claim came from a test run) on `verify`, beside `verdict`, which carries the third state, `attested`, for a record whose scenarios rest on an agent's word.
161
-
162
- ### Command notes
163
-
164
- **`loam init`** — `--docs` **joins** an existing docs repo; `--create` is required to make a new one, so a mistyped path cannot scaffold a second source of truth. `--service <id>` is what a **service** repo needs: it is the binding `vouch`, `gherkin` and `verify --service --record`/`--results` require before they will write for that service. `--tools <ids>|all` overrides the tool scan; `--no-commands` / `--no-skills` drop one delivery — and the two are exclusive, refused together, since one names the files to write and the other suppresses them. `docsDir` is stored exactly as you typed it and resolved against `loam.json`, so a relative `../docs-repo` works on every clone — and `--docs` wins only when you actually pass it, so a re-run in a wired repo keeps the pointer its committed `loam.json` already spells, `--create` included (`docsDirSource: "flag" | "config" | "default"` in `--json` says which).
165
-
166
- **`loam status`** — the question an agent has when it joins a repo halfway or loses its session. Artifacts come back `missing`/`blocked`/`draft`/`ready`/`done`, and `next[]` is ordered, each entry a stable code plus the literal command. It takes the union of what `validate --feature` errors on and what `archive` refuses to merge, so it may be redder than either and is never greener than both. There is no state file to go stale.
167
-
168
- **`loam new`** — the scaffold passes `loam validate --feature` with **zero errors**; the warning left standing is the `owner` you have to fill in yourself, and a feature that introduces a service starts on a second, `c4.uncovered`, until its `arch.spec.md` delta carries a `Covers:` line for the element the delta adds. For a requirements-only feature you delete the scaffolded `delta.likec4` yourself — `new` says so on the way out, and the feature validates clean without it.
169
-
170
- **`loam adopt`** — the brief names the target paths, the grammar of each, what the landscape already says, the checks that follow, and the ones that do not exist.
171
-
172
- **`loam gherkin`** — a feature's changed requirements, or (without a feature) the full living suite. Deterministic, digest-stamped, regeneration-owned; run in the service's own repo.
173
-
174
- **`loam rebase`** — writes `Based-On:` on every MODIFIED/REMOVED requirement and `x-loam-based-on` on every operation in the contract delta that the living docs already hold; what this feature is *adding* has nothing to pin against, and the output says so per item. On the requirement axis that stops a second feature rewriting the same requirement from landing on top of the first in silence; on the contract axis it also marks the rest of the delta as **quotation** — an `openapi.yaml` is a complete document, so without the pin the merge upserts operations you only restated and reverts whatever landed on them. Restamping is the last step of resolving a collision, not the resolution — the output says which pins moved.
175
-
176
- **`loam verify`** — `--results <report.json>` answers the scenario claims from a cucumber JSON run, digest-matched, so only a green run confirms one, and the record writes down which file it read (path, sha256, mtime). It answers *only* those claims, so on a feature with open `service.exists` / `api.exposes` claims it is passed alongside `--record` or refused (`answers-mismatch`). `--record <answers.json>` takes the agent's answers, refusing anything unevidenced — under `--service`, refusing a `file:line` that does not resolve in that repo at the attested commit — and a scenario claim answered that way makes the record `attested` rather than `verified`. A cross-service feature is recorded **once per service repo** with `--service <id>`, each run adding its own commit-bound attestation to one shared record; the `--service`-less `--record` form writes the whole record from one place and is refused (`record-federated`) once anyone else has attested.
177
-
178
- **`loam unarchive`** — it refuses rather than guesses: `snapshot-stale` when a merged file moved since (`--force` says that was meant), and `snapshot-corrupt` when a pre-image no longer hashes to what the archive recorded for it, which `--force` deliberately does **not** override — the damage there is to the undo itself.
336
+ Every command takes `--json`; findings carry stable codes (`c4.valid`, `spine.op-undefined`,
337
+ `coherence.ok` …) so an agent branches on the code, not on prose. Flags are listed in full below —
338
+ `loam <command> --help` is the same list from the binary you are running, and
339
+ [WORKFLOW.md's command notes](WORKFLOW.md#command-notes) is the per-command behavior that a table
340
+ cannot hold.
179
341
 
180
- **`loam audit-openspec` / `loam migrate-openspec`** — the audit reports capabilities, active and archived changes, counts, RENAMED and unsupported shapes, and every capability→service decision still needing a human. The migration validates your completed mapping against a re-read of the source, and with `--apply --target <empty-dir>` materializes **staged migration docs** into a separate directory. `--map` is required — there is no one-shot form.
181
-
182
- ### How `archive` protects the source of truth
183
-
184
- `archive` is the one command that rewrites the source of truth, so it takes an advisory lock on the docs repo for the whole plan-and-commit (a second writer — another `archive`, an `unarchive`, a `rebase` — refuses with `docs-busy` rather than interleaving), computes the whole merge before touching disk, commits each file through a temp file swapped in atomically after re-checking the bytes it read (a rename for an overwrite, a no-clobber `link(2)` for a create, so a file that appeared after the plan was computed is never buried), and rolls back what it already swapped if any part fails. It also records the bytes it overwrote inside the archived feature — with a digest of each pre-image, so `unarchive` can tell an intact one from an edited one — which is what makes `unarchive` an undo rather than a guess. A process **killed mid-commit** is covered too: an intent journal (`.loam-commit`) is fsynced before the first swap, and the next `archive`/`unarchive` recovers from it under the lock, rewriting each half-written file from the snapshot — an interrupted archive is undone, an interrupted unarchive is *finished*, because the merged text it was replacing is written down nowhere else — or refusing with `commit-interrupted` when a file has been edited since. `loam doctor` reports that state rather than calling the repo healthy.
185
-
186
- The gate itself comes in two kinds. Coherence, an unknown service and the OpenAPI plan are judgement calls, and `--approve` carries them; two refusals are mechanical loss and `--approve` deliberately does not — a living document still holding git conflict markers (`merge-failed`) and a living requirement that has strayed outside `## Requirements` (`living-outside-requirements`). loam's docs files must be **UTF-8** for the same reason: undecodable bytes refuse the merge (`merge-failed`, naming the file) instead of being rewritten as U+FFFD, and a non-UTF-8 `openapi.yaml` grades `openapi.invalid`. **`verify` does not gate `archive`** — coherence gates because loam *computed* it; a verdict is somebody's word about code loam never read, and a gate in front of shipping only teaches everyone that the cheapest way past it is to say yes.
187
-
188
- API retirement is explicit and reviewable: a feature marks the exact path/method operation with `x-loam-remove: true` — **inside the operation being retired, beside its `operationId`** — and removes the governing requirement in the same delta. A marker written one level up, at path level beside the methods, addresses no operation and retires nothing; archive refuses it (`openapi.remove-marker-path-level`) rather than publishing a meaningless key into the fleet's living contract. Validation refuses stale, mismatched, or unjustified markers; archive deletes the method without persisting the marker or garbage-collecting components, and reports the removals in both text and JSON. See [SCHEMA.md](SCHEMA.md) for the lifecycle contract.
342
+ | Command | Flags | What it does |
343
+ |---|---|---|
344
+ | `loam init` | `--docs <dir>` `--service <id>` `--create` `--force` `--tools <ids>` `--agent-profile <full\|service\|docs>` `--example <dir>` `--no-commands` `--no-skills` `--mcp` `--mcp-author` | Bind this repository to the single shared docs repo: a committed local `loam.json`, plus command and Agent Skill pointers for detected AI tools. Profiles narrow the six lifecycle workflows to a repo's role; the support-only `loam-report` stays in every profile. Re-running init refreshes only unchanged loam-owned pointers; edited files are preserved. `--mcp` writes the read-only host entry, while `--mcp-author` opts into the bounded authoring tools. `--create` scaffolds the docs repo; `--example` copies the packaged example and stops |
345
+ | `loam seed` | `--from <file>` | Template the fleet map and one `services/<id>/` directory per service from a tiny human-authored `fleet.yaml`. Mechanical, never a guess: a human stated every fact. Refuses once the landscape has been hand-edited |
346
+ | `loam list [services\|features\|capabilities\|glossary]` | `--archived` `--needs-work` `--review-order` `--subsystem <name>` `--owners <path>` | What is in the docs repo, and what is missing from it. `capabilities` rolls up who realizes each promise; `glossary` rolls up each term with the documents that cite it |
347
+ | `loam status [<FEAT>]` | `--service <id>` | Where the work stands and what to do next, as a projection over the two gates. Each `next[]` row has an `execution` object that says whether it is runnable, where, and what input or edit is still needed. Derived every run; writes nothing |
348
+ | `loam doctor` | — | Read-only preflight for runtime, config, docs-repo access, fleet roots, counts, and the current service binding. Blockers exit 1; incomplete optional bindings stay warnings |
349
+ | `loam dependencies [<FEAT>]` | — | The active-feature dependency graph and same-identity conflicts, derived from requirement deltas and OpenAPI operationIds |
350
+ | `loam diff` | `--base <ref>` | Semantic diff of the living docs against a base git ref of the docs repo — the review lens for a docs-repo PR, with the current consumers of every removal named. Exit 1 on a removal the fleet still consumes |
351
+ | `loam explore [<service>...]` | `--op <operationId>` `--capability <id>` `--as <FEAT>` | Read the fleet around a change nobody has written down yet: the ring one hop out, each service's maturity and living operations, the features already in flight over the same ground, and the `loam new` line the seeds imply |
352
+ | `loam context <service>` | `--feature <FEAT>` | Assemble one service's docs slice — living requirements verbatim, both contracts, the fleet edges around it, permissions, capabilities, provenance, and every active feature's delta over it — as one deterministic briefing |
353
+ | `loam steps` | `--service <id>` `--duplicates` `--json` | Inventory the step phrases of one service's scenarios: how many distinct steps its suite is written in, how few definitions cover most of them, and which phrases differ only by an article or a trailing clause. Reads the living specs, writes nothing — the work-list a team writes its step definitions from, diffed against the optional `services/<svc>/steps.yaml` catalogue when one exists |
354
+ | `loam instructions [<workflow>] [args...]` | `--no-fix-tables` | Print one of the six workflow protocols, the separate `loam-report` support protocol, or one of the four reference pages `loam-codes`, `loam-spine`, `loam-authoring` and `loam-done-check`, version-matched to this binary. Workflow `$1`/`$2` placeholders are filled; support/reference pages take no arguments. Reads no config. `--no-fix-tables` collapses the per-code fix tables to a line each, keeping the paragraph that says which scope graded them: `loam-check`'s page goes 84,151 bytes to 3,541, while a support/reference page holds no such table and comes back byte-identical |
355
+ | `loam explain [<subject>]` | `--codes` | Explain a finding code, a refusal code, or a concept term. Most finding prose is parsed at runtime from the shipped fix tables, so it cannot drift from the binary; the `doctor.*`, `next.*`, `diff.*` and `gate.*` families, which no fix table grades, are answered from a registry written beside them. Every text-mode refusal prints `<code> · loam explain <code>` on stderr and every non-`ok` finding line carries its code in parentheses, so the lookup is reachable without re-running under `--json`. Omit the subject to list the terms; `--codes` lists the whole vocabulary — 293 finding codes and 46 refusal codes, each row the same answer `explain <code> --json` gives for that one |
356
+ | `loam open` | `--root <dir>` `--out <file>` `--force` | Write a `.code-workspace` joining the docs repo and every service checkout whose committed `loam.json` binds to it. Never overwrites without `--force` |
357
+ | `loam mcp` | `--author` | Serve fourteen read tools, version-matched instruction resources and a declared envelope output schema over MCP. `--author` adds `new`, `rebase`, `gherkin` and an archive dry-run; it never exposes `vouch`, verification recording or a committing archive — [the MCP server](WORKFLOW.md#the-mcp-server) |
358
+ | `loam new <FEAT>` | `--title <text>` `--touches <id>` `--new-service <id>` `--capability <id>` | Scaffold a feature: intent, C4 delta, a requirement delta per service named by `--touches`/`--new-service`, and a capability delta per promise named by `--capability` (all repeatable) |
359
+ | `loam show <service\|FEAT>` | `--type <kind>` | Everything loam knows about one service or feature. A feature's JSON includes a semantic `review` pack: intent, exact architecture objects, API/event slices, dependencies, artifacts, verification, blockers and next actions. `--type` forces an ambiguous reading |
360
+ | `loam subsystem <verb> [names...]` | `--into <name>` `--under <name>` `--title <text>` `--description <text>` `--owner <name>` | Manage the grouping tree under `services/` — a navigable tree no identity depends on. `new`/`rm`, `move … --into`, `rename`, `list`, `history`, `sync` |
361
+ | `loam adopt` | `--service <id>` `--subsystem <name>` `--targets` | Brief an agent to write this service's baseline into the docs repo as `draft`: the target paths, the grammar of each, what the landscape already says, and the checks that follow. Writes nothing. `--targets` narrows it to what varies by service — the walk, the 37 checks and the fifteen statements of what nothing checks are the same bytes everywhere, so a `full` field names the one run that carries them: 42,873 bytes to 17,805 |
362
+ | `loam delta <FEAT>` | `--service <id>` | Project a feature onto one service: the intent, its requirement deltas with every body and Given/When/Then line verbatim, the endpoints it adds or retires, and the edges around it. Doubles as a coding-agent task |
363
+ | `loam gherkin [<FEAT>]` | `--service <id>` `--dry-run` | Emit spec scenarios as digest-stamped Gherkin `.feature` files into the service repo's `<gherkinDir>/loam/` |
364
+ | `loam rebase [<FEAT>]` | `--service <id>` `--dry-run` `--living` | Pin the feature to the living versions it was written against, on the requirement axis and the contract axis. `--living` takes no feature: it pins the living corpus's `Realizes:` entries to the capability requirements they name, which is what makes `capability.realizes-stale` able to fire later |
365
+ | `loam validate [<id>]` | `--service <id>` `--feature <id>` `--all` `--base <ref>` `--strict` `--errors-only` | Validate one service or feature, or the whole fleet in one run. JSON findings carry `locations[]`: an exact primary location when the check knows one, otherwise the narrowest proved scope. `--base` is the adoption ratchet, not a substitute for `loam diff`; `--strict` exits 1 on warnings; `--errors-only` drops the `ok` confirmations from the text view, keeping every warning |
366
+ | `loam verify <FEAT>` | `--record <file>` `--results <file>` `--contract-results <file>` `--diff-answers <files...>` `--service <id>` | The done-check: derive a checklist of the feature's own promises, and record the answers with their evidence. `--results`/`--contract-results` answer claims from a test report; `--diff-answers` cross-examines two blind answer sets |
367
+ | `loam vouch` | `--service <id>` `--yes` `--pack` `--sample <n>` | The human promotion `draft` → `verified`: stamp a living spec against the code it was written from. `--pack` prints the re-vouch reading pack; `--sample <n>` records a partial read as one. Run in the service's own repo |
368
+ | `loam gate` | `--service <id>` `--strict` | Can this service deploy? A pure query over recorded evidence for deploy pipelines outside loam's lifecycle. Executes nothing, writes nothing; errors exit 1, warnings stay advisory |
369
+ | `loam archive <FEAT>` | `--approve` `--dry-run` | Merge a shipped feature into the living specs, API, events, business tree and landscape; gated on what only the computed merge can see. `--approve` overrides the judgement calls, never the mechanical losses |
370
+ | `loam unarchive <FEAT>` | `--force` | Take that back: restore the living docs from the snapshot archive left behind, and re-open the feature |
371
+ | `loam audit-openspec <root>` | `--write-mapping <path>` | Read-only inventory of an OpenSpec checkout/workspace/Store checkout. `--write-mapping` emits the decision skeleton you fill in |
372
+ | `loam migrate-openspec <root>` | `--map <path>` `--mapping <path>` `--apply` `--target <directory>` | Validate a completed mapping against a re-read of the source, and materialize staged migration docs. Dry-run is the default |
373
+
374
+ The envelope keeps three different questions apart, each on the command that can answer it — `ok`
375
+ (the command ran) on every envelope, `valid` (the docs pass) on `validate`, and `verified` (every
376
+ claim is confirmed **and** every scenario claim came from a test run) on `verify`, beside `verdict`,
377
+ which carries the third state, `attested`, for a record whose scenarios rest on an agent's word.
378
+ Every envelope also says what answered it — `contractVersion` for the shape and `version` for the
379
+ binary — because the two move independently: a release bumps one and leaves the other alone, so a
380
+ new build never reads as a contract break, and a green run from a loam that is behind is
381
+ recognisable as one. Every success payload carries `command`, so a host holding a pile of envelopes
382
+ branches on one field instead of guessing from the presence of `valid` or `services`.
189
383
 
190
384
  ## Working with AI agents
191
385
 
192
- `loam init --create` writes `AGENTS.md` into the docs repo — the process contract, travelling with the thing it describes; a join finds it there and refuses a `--docs` target without one. Into the repo it runs in, every `init` writes the six workflow bodies (`loam-adopt`, `loam-feature`, `loam-implement`, `loam-check`, `loam-verify`, `loam-ship`), **twice each for nineteen of the twenty tools**: as a command file in the tool's own command, prompt or workflow directory, which you type — `/loam-check` for most, `/loam:check` where the tool namespaces by directory, `@loam-check` in Amazon Q's prompt library — and as an Agent Skill at `<tool-dir>/skills/loam-<x>/SKILL.md`, which the model loads by itself when the task matches the skill's description. Codex is the twentieth: it reads `.codex/skills/` and loads no custom command files, so it gets skills only rather than files nothing will ever open. One shared body, a thin per-tool wrapper; `--no-commands` and `--no-skills` each suppress one delivery.
193
-
194
- Which tools is detected from the repo: `init` scans each of the 20 tools it knows for its own marker paths — usually just its dot-directory, but Copilot's are the files *inside* `.github/`, because almost every repo has a `.github/` and almost none of them means Copilot. The twenty are Claude Code, Cursor, GitHub Copilot, Gemini CLI, opencode, Cline, Amazon Q, Antigravity, Auggie, Codex, Continue, Crush, Devin, Factory, Junie, Kilo Code, Kiro, Qwen, Roo Code and Trae. It writes for the ones it finds, and falls back to Claude Code when it finds none. `--tools <ids>|all` overrides the scan; an unknown id is refused, not skipped. What it wrote for is recorded in `loam.json` as `agentTools`, which is how `loam doctor` reports a command or skill file that a newer loam would lay down (`doctor.agent-files-missing`) without mistaking a tool nobody selected for one that fell behind — and a repo that asked for one delivery only (`--no-skills`, `--no-commands`) is not reported as missing the other.
195
-
196
- **A generated file is a pointer, not a protocol.** It carries what does not move between releases — what the workflow is for, and the verbs in order — and defers this release's flags, finding codes and fix tables to `loam instructions <workflow>`, which ships inside the binary you are about to run. That split exists because the two go stale in opposite directions and only one of them is fixable: a file written once and never regenerated will eventually describe a different loam with total confidence, while the command cannot. `loam instructions` reads no `loam.json` and no docs repo, deliberately — `loam-adopt`'s own first step is to run `loam init` when there is no config, so it cannot be the step that requires one.
197
-
198
- **Nothing is ever overwritten and nothing is ever refreshed**, and that is the whole difference from `openspec update`: your edits to a generated file outrank the template, so drift is reported and never repaired. To make that reportable at all, every generated command and skill body opens with `<!-- generated by loam vX.Y.Z -->`; `loam doctor` reads **only that line** and raises `doctor.agent-files-stale` for a file carrying no stamp or an older one. It never compares bodies — "your file differs from the template" is one step from offering to rewrite it. The fix is a human's: read the file, then bump the stamp, or delete it and re-run `loam init`. The AGENTS.md version stamp (`agents.stale`) works the same way. A repo scaffolded by an older loam keeps the files it was given, protocol text and all — nothing rewrites them, and the stamp is how you know. Running a tool loam has no adapter for? Point it at `AGENTS.md` — the commands are thin wrappers over the CLI, so any runner that can read a file and exec `loam` has everything.
199
-
200
- ## Fleet scale
201
-
202
- One docs repo, a hundred services, many teams: the docs repo bootstraps itself with `loam init --docs . --create`, ownership is CODEOWNERS, `vouch` and `archive` land through reviewed PRs, provenance runs in each service repo's own CI, and `loam list --json` grades every service on a presence-honest maturity ladder (`empty → partial → documented → sourced → vouched`). The full operating model — including `loam.json` per repo, the federated verification record, the per-service CI summary contract and the one-landscape decision — is in [SCHEMA.md](SCHEMA.md).
203
-
204
- The shape that has been measured, on a generated 120-service fleet with 400 and 800 op-linked landscape edges and 10 active features (built CLI, 8-core laptop, idle, wall clock including Node startup — of which ~0.16 s is Node itself): `loam list` **~0.45 s**, `loam validate --service <id>` — the command each service repo's CI runs — **~0.6 s**, and `loam status` **~1.3 s** — it grades every active feature's `delta.likec4`, so it costs about 0.11 s per feature *in flight* and is nearly flat in the size of the fleet (the same 120 services with one active feature answer in ~0.34 s). The fleet gate is the outlier: `loam validate --all` over the same 120 services takes **~13–14 s**, because it parses a fresh LikeC4 workspace per service rather than sharing one. That cost is fixed and linear in the number of services, and it is CPU inside the model construction, not I/O — bounded concurrency measurably does not help. It is the docs repo's own CI job and it is not on anybody's inner loop; on a machine whose cores are already busy, expect meaningfully more. `test/scale.test.ts` gates a smaller fleet — 30 services, 10 features, 24 op-linked edges — under a 110 s wall-clock ceiling: a blowup alarm sized to stay quiet inside a 64-file parallel suite, so it catches the order-of-magnitude regression an accidental per-service re-parse causes, not a two-fold one.
386
+ `loam init --create` writes `AGENTS.md` into the docs repo — the process contract, travelling with
387
+ the thing it describes; a join finds it there and refuses a `--docs` target without one. Into the
388
+ repo it runs in, every `init` writes pointers for the six workflow bodies (`loam-adopt`,
389
+ `loam-feature`, `loam-implement`, `loam-check`, `loam-verify`, `loam-ship`) plus the separate
390
+ `loam-report` support protocol, **twice each for nineteen of the
391
+ twenty-one targets**: as a command file you type — `/loam-check` for most, `/loam:check` where the
392
+ tool namespaces by directory, `@loam-check` in Amazon Q's prompt library — and as an Agent Skill
393
+ at `<tool-dir>/skills/loam-<x>/SKILL.md`, which the model loads by itself when the task matches. Two
394
+ targets are skills only: Codex reads `.codex/skills/` and loads no custom command files, and
395
+ `agents` is not a tool at all but the vendor-neutral `.agents/skills/` root that Cursor, GitHub
396
+ Copilot, Codex, Gemini CLI, Zed and Roo Code each document reading — one copy those six share
397
+ instead of six copies of the same bytes. `--no-commands` and `--no-skills` each suppress one
398
+ delivery.
399
+
400
+ **The explicit command is the recommended, predictable entry point; natural language remains a
401
+ shortcut.** A normal chat lifecycle is `/loam-feature FEAT-101 "Split payments"` to propose,
402
+ `/loam-implement FEAT-101 payment-service` in each affected checkout, `/loam-check`,
403
+ `/loam-verify FEAT-101`, then `/loam-ship FEAT-101`. Most hosts use the flat slash spelling;
404
+ Gemini namespaces it as `/loam:feature`, Amazon Q exposes `@loam-feature`, and a skills-only host
405
+ uses its explicit skill syntax such as `$loam-feature`. Saying “implement FEAT-101” may load that
406
+ same skill automatically. Both routes reach the same binary-owned protocol; after entry, the agent
407
+ runs the status/edit/validate loop rather than asking the user to type every internal command.
408
+
409
+ When the binary or agent integration behaves unexpectedly, `/loam-report` (or `$loam-report` on a
410
+ skills-only host) collects a sanitized, reproducible local report under `loam-reports/`. It records
411
+ the version, doctor/status evidence, stable codes, write state and the smallest safe reproduction;
412
+ it does not repair the repo, retry a writer, include secrets, or upload anything. The support
413
+ protocol ships in every agent profile but remains outside the six-step lifecycle.
414
+
415
+ Which tools is detected from the repo: `init` scans each of the 21 targets it knows for its own
416
+ marker paths — usually just its dot-directory, but Copilot's are the files *inside* `.github/` and
417
+ the vendor-neutral one's is `.agents/skills/` rather than `.agents/`, because almost every repo has
418
+ a `.github/`, a `.agents/` is claimed by other conventions too, and almost none of either means the
419
+ tool. It writes for the ones it finds, and falls back to Claude Code when it finds none.
420
+ `--tools <ids>|all` overrides the scan; an unknown id is refused, not skipped. `--agent-profile`
421
+ selects `full`, `service` or `docs`, so a service checkout need not install feature-authoring and
422
+ shipping entry points. `loam.json` records the tools, profile and sha256 of every pointer loam owns;
423
+ that is how `doctor` distinguishes missing managed files from workflows nobody selected.
424
+
425
+ **A generated file is a pointer, not a protocol.** It carries what does not move between releases —
426
+ what the workflow is for, and the verbs in order — and defers this release's flags, finding codes
427
+ and fix tables to `loam instructions <workflow>`, which ships inside the binary you are about to
428
+ run. That split exists because the two go stale in opposite directions and only one of them is
429
+ fixable: embedded protocol text eventually describes a different loam with total confidence, while
430
+ the command cannot. Pointing at the binary is also what makes the protocol
431
+ affordable to load: `loam instructions loam-check --no-fix-tables` prints the same page with its
432
+ per-code fix tables collapsed to a line each — 84,151 bytes down to 3,541 — and
433
+ `loam explain <code> --json` answers, in 473 bytes, whichever two or three of those rows a run
434
+ actually reported. A copy frozen into the generated file would have charged the full 84 KB every
435
+ session, and gone stale doing it. `AGENTS.md` itself was the one generated file that argument did
436
+ not reach — it was the process contract *and* the reference manual, and every session paid for all
437
+ of it — so four **reference pages** now come out of the binary instead, printed by
438
+ `loam instructions`: `loam-codes` (which codes each invocation can raise), `loam-spine` (every join
439
+ between the artifacts, and the `Based-On:` pins), `loam-authoring` (`arch.spec.md`, the generated
440
+ Gherkin suite, frontmatter) and `loam-done-check` (how `loam verify` derives its claims, and
441
+ verified versus attested). What stayed is what a reader needs to form a question at all: the layout,
442
+ the cycle, which element is which service, the validator's rules and the archive gate. The current
443
+ orientation is **8,762 bytes**, below both the 32,768-byte Codex chain limit and the smaller 12,000
444
+ workspace-rule ceiling. Detailed pages are fetched only when the task reaches them. `loam init`
445
+ writes **no file** for a reference page: a page printed on demand describes the loam you are
446
+ running, not the one that scaffolded the repository.
447
+
448
+ The code inventory is that same split applied twice, and the largest page is what it left behind.
449
+ `loam instructions loam-codes` lists which codes each invocation can raise — 331 of the 335 the
450
+ scaffolded docs name between them, the one fact no other surface carries — and no longer says what
451
+ any of them means, because `loam explain <code>` answers that from the binary actually running and a
452
+ paragraph written once at `init` cannot. Dropping the duplicated gloss came first and took the file
453
+ from 120,896 bytes to 109,399; moving the inventory off it took the remaining 79,679. The OpenSpec
454
+ migration codes keep their notes inline on the page, because they are 49 of the 51 codes
455
+ `loam explain` does not answer yet, and a pointer to an explanation that does not exist is worse
456
+ than the prose it replaced.
457
+
458
+ **Refresh is ownership-aware.** Re-running `loam init` may replace a pointer only when its bytes
459
+ still match the digest recorded when loam last wrote it. The first human edit breaks that equality
460
+ and permanently wins; loam preserves the file and `doctor` reports its stale stamp for review.
461
+ Missing pointers are created. This gives unchanged repositories current entry points without an
462
+ `openspec update`-style overwrite of team customizations.
463
+
464
+ For hosts that reach tools through MCP rather than a shell, see [the MCP server](WORKFLOW.md#the-mcp-server).
465
+ Read tools declare `readOnlyHint`; every tool declares the shared envelope output schema; the compact
466
+ orientation and all workflow/support/reference pages are MCP resources, including a compact loam-check
467
+ resource without the 223-row fix table. `loam init --mcp` writes the
468
+ read-only host entry. `--mcp-author` is a separate explicit choice that adds bounded writers while
469
+ still excluding vouch, evidence recording and a committing archive. An existing `.mcp.json` is
470
+ always preserved byte for byte, with the entry printed for manual merge.
205
471
 
206
472
  ## Docs
207
473
 
208
- - [WORKFLOW.md](WORKFLOW.md) — the working protocol: the artifact graph and its derived states, what gates and what only advises, the six workflows, and how an agent drives the whole cycle from `--json`.
209
- - [SCHEMA.md](SCHEMA.md) — the docs-repo layout, each artifact's grammar, and the decisions behind them: the coherence rules, how `archive` writes and `unarchive` undoes, operating at fleet scale.
210
- - [COMPARISON.md](COMPARISON.md) — loam vs OpenSpec, honestly: seven axes, when OpenSpec is enough, what loam refuses to borrow.
211
- - [MIGRATING-from-OpenSpec.md](MIGRATING-from-OpenSpec.md) — moving an OpenSpec repo onto loam: what maps, what is lost, what must be added.
212
- - [CHANGELOG.md](CHANGELOG.md) — what changed; one `[Unreleased]` entry so far, because nothing has been released yet.
474
+ - [QUICKSTART.md](QUICKSTART.md) — the shortest complete path from install to adoption, the first
475
+ agent-driven feature, and a local problem report when something behaves unexpectedly.
476
+ - [WORKFLOW.md](WORKFLOW.md) — the working protocol: day zero, the artifact graph and its derived
477
+ states, what gates and what only advises, the six workflows, the per-command notes, and how an
478
+ agent drives the cycle from `--json`.
479
+ - [SCHEMA.md](SCHEMA.md) — the docs-repo layout, each artifact's grammar, and the decisions behind
480
+ them: the coherence rules, how `archive` writes and `unarchive` undoes, operating at fleet scale.
481
+ - [COMPARISON.md](COMPARISON.md) — where loam fits beside architecture-as-code tools, software and
482
+ event catalogs, contract verification and diff engines, requirements traceability, and code-level
483
+ architecture checks. Each is treated as a neighbouring specialist, not an opponent loam needs to
484
+ replace.
485
+ - [MIGRATING-from-OpenSpec.md](MIGRATING-from-OpenSpec.md) — moving an OpenSpec repo onto loam: what
486
+ maps, what is lost, what must be added.
487
+ - [ROADMAP.md](ROADMAP.md) — the evidence-backed improvement plan, priorities, non-goals and exit
488
+ criteria.
489
+ - [CHANGELOG.md](CHANGELOG.md) — released beta.1–alpha.1 plus the changes on `main` under
490
+ `[Unreleased]`.
491
+ - [docs/BENCHMARKS.md](https://github.com/ybotok/loam/blob/main/docs/BENCHMARKS.md) — what a
492
+ fleet-sized run costs, with the method, the machine and the committed runs behind every number.
213
493
 
214
494
  ## Development
215
495
 
@@ -218,31 +498,51 @@ npm run setup # or: npm ci && npm run build
218
498
  npm run dev -- --help # run the CLI from source
219
499
  npm run lint
220
500
  npm run typecheck
501
+ npm run arch:check # package-level dependency graph stays acyclic
221
502
  npm test # vitest
222
503
  npm run test:coverage # full src/**/*.ts coverage with enforced thresholds
223
504
  npm run test:package # clean, pack, install the tarball, run its loam binary
224
- npm run pilot:check # the pilot harness against its own example manifest
225
- # optional, against the exact upstream checkout named in "loam vs OpenSpec" (the
505
+ # optional, against the exact upstream checkout named in MIGRATING-from-OpenSpec.md (the
226
506
  # flag matters: --baseline defaults to canary, and the sweep refuses a checkout
227
507
  # at any other HEAD):
228
508
  npm run test:openspec-corpus -- --baseline release /path/to/OpenSpec
229
509
  ```
230
510
 
231
- `npm run setup` is `bash scripts/setup.sh`, so on Windows use `npm ci && npm run build`. [CONTRIBUTING.md](CONTRIBUTING.md) has the rest — the local loop, what a reviewable change looks like, and the release posture; the pilot harness itself is documented under [`docs/pilot/`](docs/pilot).
511
+ `npm run setup` is `bash scripts/setup.sh`, so on Windows use `npm ci && npm run build`.
512
+ [CONTRIBUTING.md](CONTRIBUTING.md) has the rest — the local loop, what a reviewable change looks
513
+ like, and the release posture.
232
514
 
233
515
  ## Status
234
516
 
235
- Every command in the table is implemented, `verify --results` included — the generated suite's cucumber report feeds the done-check, closing the TDD loop mechanically. Remaining: `render` (diagrams — delegated to LikeC4's own tooling), `health` **compose**, UI-prototype generation. Composing a `health.yaml` is what is missing, not reading one: `validate` already grades its `slis:`/`alerts:` ids against the living `arch.spec.md`'s `Covers:` lines (`health.uncovered`, `health.invalid`).
236
-
237
- The release-candidate manifest is `@ybotok/loam@0.1.0-beta.1`: as of 2026-08-06 the unscoped `loam` name is taken by an unrelated GDAL wrapper, so the package ships under the maintainer's own npm user scope. The registry had no package at that scoped name when it was last checked — a registry fact this repository cannot confirm, so re-check it before tagging. Until it is published, use the clone install above rather than treating the package as published.
517
+ Every command in the table is implemented, including `verify --results` and its contract-test
518
+ sibling `verify --contract-results`, the full AsyncAPI feature lifecycle, OpenAPI path-item and
519
+ component baselines, the `architecture/permissions.yaml` authorization vocabulary, the declared- and
520
+ authored-capability axes with the `Realizes:` join, use cases graded as `dynamic view`s, the
521
+ `glossary/<term>.md` domain vocabulary checked through the links that cite it, and the
522
+ `architecture/obligations.yaml` architectural obligations checked through `#obl-` tags and
523
+ `Covers:`. Known limits, each with its owner in [ROADMAP.md](ROADMAP.md): the complete gate still
524
+ needs repeatable CI and installed-package evidence observed from an actual push. Speculative
525
+ `render`, health composition and UI generation come later. Behind that status stand **156 test files** (counted 2026-09-01): the count is graded
526
+ against a live readdir by `test/docs-facts.test.ts`, so this sentence fails the suite the moment it
527
+ trails the tree.
528
+
529
+ The package is published as [`@ybotok/loam`](https://www.npmjs.com/package/@ybotok/loam), currently
530
+ `0.2.0-alpha.1`: the unscoped `loam` name is taken by an unrelated GDAL wrapper, so the package ships
531
+ under the maintainer's own npm user scope. Releases are tag-driven and maintainer-only
532
+ ([CONTRIBUTING.md](CONTRIBUTING.md)); the version this line names is pinned to `package.json` by a
533
+ drift test, so it cannot silently trail a release.
238
534
 
239
535
  ## Contributing
240
536
 
241
- Issues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for the local loop (`lint`, `typecheck`, `test`, `test:package`) and what a reviewable change looks like here.
537
+ Issues and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for the complete local
538
+ gate and what a reviewable change looks like here.
242
539
 
243
540
  ## Security
244
541
 
245
- Please do not report a suspected vulnerability in a public issue. [SECURITY.md](SECURITY.md) says what to include and names the intended private route — GitHub Private Vulnerability Reporting, which is not switched on for the canonical repository yet, so the link there does not resolve until it is.
542
+ Do not put vulnerability details in a public issue. Report privately through
543
+ [GitHub Private Vulnerability Reporting](https://github.com/ybotok/loam/security/advisories/new),
544
+ which is enabled for this repository; [SECURITY.md](SECURITY.md) says what to include and what to
545
+ leave out.
246
546
 
247
547
  ## License
248
548