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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1036) hide show
  1. package/CHANGELOG.md +2635 -86
  2. package/COMPARISON.md +80 -63
  3. package/CONTRIBUTING.md +84 -0
  4. package/MIGRATING-from-OpenSpec.md +213 -54
  5. package/QUICKSTART.md +125 -0
  6. package/README.md +450 -150
  7. package/ROADMAP.md +599 -0
  8. package/SCHEMA.md +2355 -256
  9. package/SECURITY.md +21 -3
  10. package/WORKFLOW.md +701 -0
  11. package/dist/cli.js +113 -19
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/adopt/adopt.js +209 -0
  14. package/dist/commands/adopt/adopt.js.map +1 -0
  15. package/dist/commands/adopt/render.js +268 -0
  16. package/dist/commands/adopt/render.js.map +1 -0
  17. package/dist/commands/archive/archive.js +77 -0
  18. package/dist/commands/archive/archive.js.map +1 -0
  19. package/dist/commands/archive/plan/contracts/asyncapi.js +178 -0
  20. package/dist/commands/archive/plan/contracts/asyncapi.js.map +1 -0
  21. package/dist/commands/archive/plan/contracts/openapi.js +159 -0
  22. package/dist/commands/archive/plan/contracts/openapi.js.map +1 -0
  23. package/dist/commands/archive/plan/gate.js +323 -0
  24. package/dist/commands/archive/plan/gate.js.map +1 -0
  25. package/dist/commands/archive/plan/landscape.js +180 -0
  26. package/dist/commands/archive/plan/landscape.js.map +1 -0
  27. package/dist/commands/archive/plan/refusal.js +111 -0
  28. package/dist/commands/archive/plan/refusal.js.map +1 -0
  29. package/dist/commands/archive/plan/specs.js +237 -0
  30. package/dist/commands/archive/plan/specs.js.map +1 -0
  31. package/dist/commands/archive/plan/state.js +27 -0
  32. package/dist/commands/archive/plan/state.js.map +1 -0
  33. package/dist/commands/archive/run.js +252 -0
  34. package/dist/commands/archive/run.js.map +1 -0
  35. package/dist/commands/context/context.js +99 -0
  36. package/dist/commands/context/context.js.map +1 -0
  37. package/dist/commands/context/print.js +283 -0
  38. package/dist/commands/context/print.js.map +1 -0
  39. package/dist/commands/delta/delta.js +279 -0
  40. package/dist/commands/delta/delta.js.map +1 -0
  41. package/dist/commands/delta/print.js +205 -0
  42. package/dist/commands/delta/print.js.map +1 -0
  43. package/dist/commands/dependencies.js +9 -7
  44. package/dist/commands/dependencies.js.map +1 -1
  45. package/dist/commands/diff/diff.js +93 -0
  46. package/dist/commands/diff/diff.js.map +1 -0
  47. package/dist/commands/diff/print.js +38 -0
  48. package/dist/commands/diff/print.js.map +1 -0
  49. package/dist/commands/doctor.js +5 -4
  50. package/dist/commands/doctor.js.map +1 -1
  51. package/dist/commands/explain/explain.js +151 -0
  52. package/dist/commands/explain/explain.js.map +1 -0
  53. package/dist/commands/explore.js +29 -24
  54. package/dist/commands/explore.js.map +1 -1
  55. package/dist/commands/gate/gate.js +115 -0
  56. package/dist/commands/gate/gate.js.map +1 -0
  57. package/dist/commands/gate/print.js +54 -0
  58. package/dist/commands/gate/print.js.map +1 -0
  59. package/dist/commands/gherkin/commit.js +146 -0
  60. package/dist/commands/gherkin/commit.js.map +1 -0
  61. package/dist/commands/gherkin/gherkin.js +246 -0
  62. package/dist/commands/gherkin/gherkin.js.map +1 -0
  63. package/dist/commands/gherkin/reconcile.js +149 -0
  64. package/dist/commands/gherkin/reconcile.js.map +1 -0
  65. package/dist/commands/gherkin/render.js +77 -0
  66. package/dist/commands/gherkin/render.js.map +1 -0
  67. package/dist/commands/init/example.js +204 -0
  68. package/dist/commands/init/example.js.map +1 -0
  69. package/dist/commands/init/first-hour.js +28 -0
  70. package/dist/commands/init/first-hour.js.map +1 -0
  71. package/dist/commands/{init.js → init/init.js} +146 -71
  72. package/dist/commands/init/init.js.map +1 -0
  73. package/dist/commands/init/mcp.js +131 -0
  74. package/dist/commands/init/mcp.js.map +1 -0
  75. package/dist/commands/init/options.js +78 -0
  76. package/dist/commands/init/options.js.map +1 -0
  77. package/dist/commands/instructions.js +72 -14
  78. package/dist/commands/instructions.js.map +1 -1
  79. package/dist/commands/list/campaign/campaign.js +65 -0
  80. package/dist/commands/list/campaign/campaign.js.map +1 -0
  81. package/dist/commands/list/campaign/owners.js +65 -0
  82. package/dist/commands/list/campaign/owners.js.map +1 -0
  83. package/dist/commands/list/json.js +157 -0
  84. package/dist/commands/list/json.js.map +1 -0
  85. package/dist/commands/list/list.js +343 -0
  86. package/dist/commands/list/list.js.map +1 -0
  87. package/dist/commands/list/print.js +301 -0
  88. package/dist/commands/list/print.js.map +1 -0
  89. package/dist/commands/list/review.js +120 -0
  90. package/dist/commands/list/review.js.map +1 -0
  91. package/dist/commands/list/views.js +105 -0
  92. package/dist/commands/list/views.js.map +1 -0
  93. package/dist/commands/mcp/dispatch.js +183 -0
  94. package/dist/commands/mcp/dispatch.js.map +1 -0
  95. package/dist/commands/mcp/mcp.js +34 -0
  96. package/dist/commands/mcp/mcp.js.map +1 -0
  97. package/dist/commands/mcp/serve.js +55 -0
  98. package/dist/commands/mcp/serve.js.map +1 -0
  99. package/dist/commands/migrate-openspec/materialize/active.js +170 -0
  100. package/dist/commands/migrate-openspec/materialize/active.js.map +1 -0
  101. package/dist/commands/migrate-openspec/materialize/feature.js +41 -0
  102. package/dist/commands/migrate-openspec/materialize/feature.js.map +1 -0
  103. package/dist/commands/migrate-openspec/materialize/living.js +62 -0
  104. package/dist/commands/migrate-openspec/materialize/living.js.map +1 -0
  105. package/dist/commands/migrate-openspec/materialize/stage.js +142 -0
  106. package/dist/commands/migrate-openspec/materialize/stage.js.map +1 -0
  107. package/dist/commands/migrate-openspec/materialize/target.js +219 -0
  108. package/dist/commands/migrate-openspec/materialize/target.js.map +1 -0
  109. package/dist/commands/migrate-openspec/migrate-openspec.js +142 -0
  110. package/dist/commands/migrate-openspec/migrate-openspec.js.map +1 -0
  111. package/dist/commands/migrate-openspec/openspec/decisions.js +91 -0
  112. package/dist/commands/migrate-openspec/openspec/decisions.js.map +1 -0
  113. package/dist/commands/migrate-openspec/openspec/error.js +19 -0
  114. package/dist/commands/migrate-openspec/openspec/error.js.map +1 -0
  115. package/dist/commands/migrate-openspec/openspec/mapping.js +170 -0
  116. package/dist/commands/migrate-openspec/openspec/mapping.js.map +1 -0
  117. package/dist/commands/migrate-openspec/openspec/paths.js +43 -0
  118. package/dist/commands/migrate-openspec/openspec/paths.js.map +1 -0
  119. package/dist/commands/migrate-openspec/openspec/read.js +49 -0
  120. package/dist/commands/migrate-openspec/openspec/read.js.map +1 -0
  121. package/dist/commands/migrate-openspec/print.js +89 -0
  122. package/dist/commands/migrate-openspec/print.js.map +1 -0
  123. package/dist/commands/new/commit.js +76 -0
  124. package/dist/commands/new/commit.js.map +1 -0
  125. package/dist/commands/new/new.js +283 -0
  126. package/dist/commands/new/new.js.map +1 -0
  127. package/dist/commands/new/templates.js +355 -0
  128. package/dist/commands/new/templates.js.map +1 -0
  129. package/dist/commands/open.js +203 -0
  130. package/dist/commands/open.js.map +1 -0
  131. package/dist/commands/policy/format.js +152 -0
  132. package/dist/commands/policy/format.js.map +1 -0
  133. package/dist/commands/{docs-repo-gate.js → policy/gate.js} +11 -11
  134. package/dist/commands/policy/gate.js.map +1 -0
  135. package/dist/commands/rebase/edit.js +106 -0
  136. package/dist/commands/rebase/edit.js.map +1 -0
  137. package/dist/commands/rebase/living.js +185 -0
  138. package/dist/commands/rebase/living.js.map +1 -0
  139. package/dist/commands/rebase/plan.js +245 -0
  140. package/dist/commands/rebase/plan.js.map +1 -0
  141. package/dist/commands/rebase/rebase.js +275 -0
  142. package/dist/commands/rebase/rebase.js.map +1 -0
  143. package/dist/commands/seed/commit.js +192 -0
  144. package/dist/commands/seed/commit.js.map +1 -0
  145. package/dist/commands/seed/plan.js +133 -0
  146. package/dist/commands/seed/plan.js.map +1 -0
  147. package/dist/commands/seed/seed.js +172 -0
  148. package/dist/commands/seed/seed.js.map +1 -0
  149. package/dist/commands/show/feature.js +178 -0
  150. package/dist/commands/show/feature.js.map +1 -0
  151. package/dist/commands/show/marks.js +24 -0
  152. package/dist/commands/show/marks.js.map +1 -0
  153. package/dist/commands/{show.js → show/service.js} +63 -152
  154. package/dist/commands/show/service.js.map +1 -0
  155. package/dist/commands/show/show.js +77 -0
  156. package/dist/commands/show/show.js.map +1 -0
  157. package/dist/commands/status/json.js +45 -0
  158. package/dist/commands/status/json.js.map +1 -0
  159. package/dist/commands/status/print.js +157 -0
  160. package/dist/commands/status/print.js.map +1 -0
  161. package/dist/commands/status/status.js +119 -0
  162. package/dist/commands/status/status.js.map +1 -0
  163. package/dist/commands/steps/steps.js +189 -0
  164. package/dist/commands/steps/steps.js.map +1 -0
  165. package/dist/commands/subsystem/edit.js +192 -0
  166. package/dist/commands/subsystem/edit.js.map +1 -0
  167. package/dist/commands/subsystem/move.js +265 -0
  168. package/dist/commands/subsystem/move.js.map +1 -0
  169. package/dist/commands/subsystem/query.js +115 -0
  170. package/dist/commands/subsystem/query.js.map +1 -0
  171. package/dist/commands/subsystem/subsystem.js +101 -0
  172. package/dist/commands/subsystem/subsystem.js.map +1 -0
  173. package/dist/commands/subsystem/sync.js +103 -0
  174. package/dist/commands/subsystem/sync.js.map +1 -0
  175. package/dist/commands/subsystem/txn/txn.js +94 -0
  176. package/dist/commands/subsystem/txn/txn.js.map +1 -0
  177. package/dist/commands/subsystem/txn/views.js +70 -0
  178. package/dist/commands/subsystem/txn/views.js.map +1 -0
  179. package/dist/commands/unarchive/manifest.js +160 -0
  180. package/dist/commands/unarchive/manifest.js.map +1 -0
  181. package/dist/commands/{unarchive.js → unarchive/restore.js} +47 -160
  182. package/dist/commands/unarchive/restore.js.map +1 -0
  183. package/dist/commands/unarchive/unarchive.js +67 -0
  184. package/dist/commands/unarchive/unarchive.js.map +1 -0
  185. package/dist/commands/validate/arch-coverage.js +204 -0
  186. package/dist/commands/validate/arch-coverage.js.map +1 -0
  187. package/dist/commands/validate/checks/fleet-shape.js +296 -0
  188. package/dist/commands/validate/checks/fleet-shape.js.map +1 -0
  189. package/dist/commands/validate/checks/health-deps.js +55 -0
  190. package/dist/commands/validate/checks/health-deps.js.map +1 -0
  191. package/dist/commands/validate/checks/requirements.js +254 -0
  192. package/dist/commands/validate/checks/requirements.js.map +1 -0
  193. package/dist/commands/validate/checks/sources.js +76 -0
  194. package/dist/commands/validate/checks/sources.js.map +1 -0
  195. package/dist/commands/validate/checks/vocabulary.js +31 -0
  196. package/dist/commands/validate/checks/vocabulary.js.map +1 -0
  197. package/dist/commands/validate/feature.js +216 -0
  198. package/dist/commands/validate/feature.js.map +1 -0
  199. package/dist/commands/validate/fleet/census.js +69 -0
  200. package/dist/commands/validate/fleet/census.js.map +1 -0
  201. package/dist/commands/validate/fleet/kind-tags.js +39 -0
  202. package/dist/commands/validate/fleet/kind-tags.js.map +1 -0
  203. package/dist/commands/validate/fleet/landscape.js +353 -0
  204. package/dist/commands/validate/fleet/landscape.js.map +1 -0
  205. package/dist/commands/validate/fleet/load.js +52 -0
  206. package/dist/commands/validate/fleet/load.js.map +1 -0
  207. package/dist/commands/validate/fleet/obligations.js +270 -0
  208. package/dist/commands/validate/fleet/obligations.js.map +1 -0
  209. package/dist/commands/validate/fleet/scorecard/adoption.js +102 -0
  210. package/dist/commands/validate/fleet/scorecard/adoption.js.map +1 -0
  211. package/dist/commands/validate/fleet/scorecard/contracts.js +98 -0
  212. package/dist/commands/validate/fleet/scorecard/contracts.js.map +1 -0
  213. package/dist/commands/validate/fleet/scorecard/print.js +63 -0
  214. package/dist/commands/validate/fleet/scorecard/print.js.map +1 -0
  215. package/dist/commands/validate/fleet/scorecard/scorecard.js +156 -0
  216. package/dist/commands/validate/fleet/scorecard/scorecard.js.map +1 -0
  217. package/dist/commands/validate/fleet/usecases/capability-tag.js +94 -0
  218. package/dist/commands/validate/fleet/usecases/capability-tag.js.map +1 -0
  219. package/dist/commands/validate/fleet/usecases/place.js +13 -0
  220. package/dist/commands/validate/fleet/usecases/place.js.map +1 -0
  221. package/dist/commands/validate/fleet/usecases/requirement-tag.js +95 -0
  222. package/dist/commands/validate/fleet/usecases/requirement-tag.js.map +1 -0
  223. package/dist/commands/validate/fleet/usecases/steps.js +197 -0
  224. package/dist/commands/validate/fleet/usecases/steps.js.map +1 -0
  225. package/dist/commands/validate/fleet/usecases/usecases.js +99 -0
  226. package/dist/commands/validate/fleet/usecases/usecases.js.map +1 -0
  227. package/dist/commands/validate/fleet/views/ids.js +40 -0
  228. package/dist/commands/validate/fleet/views/ids.js.map +1 -0
  229. package/dist/commands/validate/fleet/views/stale.js +59 -0
  230. package/dist/commands/validate/fleet/views/stale.js.map +1 -0
  231. package/dist/commands/validate/links/corpus.js +92 -0
  232. package/dist/commands/validate/links/corpus.js.map +1 -0
  233. package/dist/commands/validate/links/glossary.js +75 -0
  234. package/dist/commands/validate/links/glossary.js.map +1 -0
  235. package/dist/commands/validate/report.js +269 -0
  236. package/dist/commands/validate/report.js.map +1 -0
  237. package/dist/commands/validate/service/api.js +338 -0
  238. package/dist/commands/validate/service/api.js.map +1 -0
  239. package/dist/commands/validate/service/events/events.js +219 -0
  240. package/dist/commands/validate/service/events/events.js.map +1 -0
  241. package/dist/commands/validate/service/events/message-producers.js +77 -0
  242. package/dist/commands/validate/service/events/message-producers.js.map +1 -0
  243. package/dist/commands/validate/service/evidence-pins.js +131 -0
  244. package/dist/commands/validate/service/evidence-pins.js.map +1 -0
  245. package/dist/commands/validate/service/service.js +251 -0
  246. package/dist/commands/validate/service/service.js.map +1 -0
  247. package/dist/commands/validate/service/specs.js +251 -0
  248. package/dist/commands/validate/service/specs.js.map +1 -0
  249. package/dist/commands/validate/service/spine.js +113 -0
  250. package/dist/commands/validate/service/spine.js.map +1 -0
  251. package/dist/commands/validate/validate.js +338 -0
  252. package/dist/commands/validate/validate.js.map +1 -0
  253. package/dist/commands/verify/cross/diff.js +182 -0
  254. package/dist/commands/verify/cross/diff.js.map +1 -0
  255. package/dist/commands/verify/evidence/contract.js +32 -0
  256. package/dist/commands/verify/evidence/contract.js.map +1 -0
  257. package/dist/commands/verify/evidence/pins.js +52 -0
  258. package/dist/commands/verify/evidence/pins.js.map +1 -0
  259. package/dist/commands/verify/evidence/read.js +72 -0
  260. package/dist/commands/verify/evidence/read.js.map +1 -0
  261. package/dist/commands/verify/frozen.js +241 -0
  262. package/dist/commands/verify/frozen.js.map +1 -0
  263. package/dist/commands/verify/record.js +226 -0
  264. package/dist/commands/verify/record.js.map +1 -0
  265. package/dist/commands/verify/report.js +223 -0
  266. package/dist/commands/verify/report.js.map +1 -0
  267. package/dist/commands/verify/results.js +246 -0
  268. package/dist/commands/verify/results.js.map +1 -0
  269. package/dist/commands/verify/verify.js +217 -0
  270. package/dist/commands/verify/verify.js.map +1 -0
  271. package/dist/commands/vouch/contract.js +11 -0
  272. package/dist/commands/vouch/contract.js.map +1 -0
  273. package/dist/commands/vouch/pack/contract.js +2 -0
  274. package/dist/commands/vouch/pack/contract.js.map +1 -0
  275. package/dist/commands/vouch/pack/pack.js +266 -0
  276. package/dist/commands/vouch/pack/pack.js.map +1 -0
  277. package/dist/commands/vouch/pack/print.js +271 -0
  278. package/dist/commands/vouch/pack/print.js.map +1 -0
  279. package/dist/commands/vouch/pack/sections.js +142 -0
  280. package/dist/commands/vouch/pack/sections.js.map +1 -0
  281. package/dist/commands/vouch/prompt/confirm.js +46 -0
  282. package/dist/commands/vouch/prompt/confirm.js.map +1 -0
  283. package/dist/commands/vouch/report.js +101 -0
  284. package/dist/commands/vouch/report.js.map +1 -0
  285. package/dist/commands/vouch/run.js +285 -0
  286. package/dist/commands/vouch/run.js.map +1 -0
  287. package/dist/commands/vouch/sample/plan.js +125 -0
  288. package/dist/commands/vouch/sample/plan.js.map +1 -0
  289. package/dist/commands/vouch/sample/print.js +109 -0
  290. package/dist/commands/vouch/sample/print.js.map +1 -0
  291. package/dist/commands/vouch/vet/verify.js +123 -0
  292. package/dist/commands/vouch/vet/verify.js.map +1 -0
  293. package/dist/commands/vouch/vouch.js +176 -0
  294. package/dist/commands/vouch/vouch.js.map +1 -0
  295. package/dist/core/agent/agents-md/artifacts.js +220 -0
  296. package/dist/core/agent/agents-md/artifacts.js.map +1 -0
  297. package/dist/core/agent/agents-md/command-map.js +324 -0
  298. package/dist/core/agent/agents-md/command-map.js.map +1 -0
  299. package/dist/core/agent/agents-md/cycle.js +165 -0
  300. package/dist/core/agent/agents-md/cycle.js.map +1 -0
  301. package/dist/core/agent/agents-md/map/explain.js +34 -0
  302. package/dist/core/agent/agents-md/map/explain.js.map +1 -0
  303. package/dist/core/agent/agents-md/map/lenses/context.js +41 -0
  304. package/dist/core/agent/agents-md/map/lenses/context.js.map +1 -0
  305. package/dist/core/agent/agents-md/map/lenses/diff.js +46 -0
  306. package/dist/core/agent/agents-md/map/lenses/diff.js.map +1 -0
  307. package/dist/core/agent/agents-md/map/lenses/gate.js +57 -0
  308. package/dist/core/agent/agents-md/map/lenses/gate.js.map +1 -0
  309. package/dist/core/agent/agents-md/map/mcp.js +41 -0
  310. package/dist/core/agent/agents-md/map/mcp.js.map +1 -0
  311. package/dist/core/agent/agents-md/map/status.js +62 -0
  312. package/dist/core/agent/agents-md/map/status.js.map +1 -0
  313. package/dist/core/agent/agents-md/map/subsystem.js +32 -0
  314. package/dist/core/agent/agents-md/map/subsystem.js.map +1 -0
  315. package/dist/core/agent/agents-md/map/usecases.js +60 -0
  316. package/dist/core/agent/agents-md/map/usecases.js.map +1 -0
  317. package/dist/core/agent/agents-md/refusals.js +246 -0
  318. package/dist/core/agent/agents-md/refusals.js.map +1 -0
  319. package/dist/core/agent/agents-md/shipped/archive-gate.js +98 -0
  320. package/dist/core/agent/agents-md/shipped/archive-gate.js.map +1 -0
  321. package/dist/core/agent/agents-md/spine.js +40 -0
  322. package/dist/core/agent/agents-md/spine.js.map +1 -0
  323. package/dist/core/agent/agents-md.js +170 -0
  324. package/dist/core/agent/agents-md.js.map +1 -0
  325. package/dist/core/{agents-stamp.js → agent/agents-stamp.js} +50 -0
  326. package/dist/core/agent/agents-stamp.js.map +1 -0
  327. package/dist/core/agent/contract.js +2 -0
  328. package/dist/core/agent/contract.js.map +1 -0
  329. package/dist/core/agent/protocol.js +193 -0
  330. package/dist/core/agent/protocol.js.map +1 -0
  331. package/dist/core/agent/scaffold.js +259 -0
  332. package/dist/core/agent/scaffold.js.map +1 -0
  333. package/dist/core/agent/support/report.js +103 -0
  334. package/dist/core/agent/support/report.js.map +1 -0
  335. package/dist/core/agent/tools/dialects.js +150 -0
  336. package/dist/core/agent/tools/dialects.js.map +1 -0
  337. package/dist/core/agent/tools/registry.js +228 -0
  338. package/dist/core/agent/tools/registry.js.map +1 -0
  339. package/dist/core/agent/workflows/adopt.js +133 -0
  340. package/dist/core/agent/workflows/adopt.js.map +1 -0
  341. package/dist/core/agent/workflows/check.js +337 -0
  342. package/dist/core/agent/workflows/check.js.map +1 -0
  343. package/dist/core/agent/workflows/closing.js +262 -0
  344. package/dist/core/agent/workflows/closing.js.map +1 -0
  345. package/dist/core/agent/workflows/feature.js +105 -0
  346. package/dist/core/agent/workflows/feature.js.map +1 -0
  347. package/dist/core/agent/workflows/implement.js +105 -0
  348. package/dist/core/agent/workflows/implement.js.map +1 -0
  349. package/dist/core/agent/workflows/reference/authoring.js +209 -0
  350. package/dist/core/agent/workflows/reference/authoring.js.map +1 -0
  351. package/dist/core/agent/workflows/reference/codes.js +65 -0
  352. package/dist/core/agent/workflows/reference/codes.js.map +1 -0
  353. package/dist/core/agent/workflows/reference/done-check.js +188 -0
  354. package/dist/core/agent/workflows/reference/done-check.js.map +1 -0
  355. package/dist/core/agent/workflows/reference/reference.js +16 -0
  356. package/dist/core/agent/workflows/reference/reference.js.map +1 -0
  357. package/dist/core/agent/workflows/reference/spine.js +297 -0
  358. package/dist/core/agent/workflows/reference/spine.js.map +1 -0
  359. package/dist/core/asyncapi/baseline/plan.js +110 -0
  360. package/dist/core/asyncapi/baseline/plan.js.map +1 -0
  361. package/dist/core/asyncapi/baseline/surfaces.js +54 -0
  362. package/dist/core/asyncapi/baseline/surfaces.js.map +1 -0
  363. package/dist/core/asyncapi/depth.js +164 -0
  364. package/dist/core/asyncapi/depth.js.map +1 -0
  365. package/dist/core/asyncapi/digest.js +141 -0
  366. package/dist/core/asyncapi/digest.js.map +1 -0
  367. package/dist/core/asyncapi/merge/components.js +91 -0
  368. package/dist/core/asyncapi/merge/components.js.map +1 -0
  369. package/dist/core/asyncapi/merge/error.js +33 -0
  370. package/dist/core/asyncapi/merge/error.js.map +1 -0
  371. package/dist/core/asyncapi/merge/markers.js +308 -0
  372. package/dist/core/asyncapi/merge/markers.js.map +1 -0
  373. package/dist/core/asyncapi/merge/merge.js +215 -0
  374. package/dist/core/asyncapi/merge/merge.js.map +1 -0
  375. package/dist/core/asyncapi/merge/pin.js +107 -0
  376. package/dist/core/asyncapi/merge/pin.js.map +1 -0
  377. package/dist/core/asyncapi/model.js +11 -0
  378. package/dist/core/asyncapi/model.js.map +1 -0
  379. package/dist/core/asyncapi/producers.js +50 -0
  380. package/dist/core/asyncapi/producers.js.map +1 -0
  381. package/dist/core/{asyncapi.js → asyncapi/read.js} +95 -109
  382. package/dist/core/asyncapi/read.js.map +1 -0
  383. package/dist/core/brief/brief.js +225 -0
  384. package/dist/core/brief/brief.js.map +1 -0
  385. package/dist/core/brief/checks.js +250 -0
  386. package/dist/core/brief/checks.js.map +1 -0
  387. package/dist/core/brief/landscape.js +194 -0
  388. package/dist/core/brief/landscape.js.map +1 -0
  389. package/dist/core/brief/targets.js +226 -0
  390. package/dist/core/brief/targets.js.map +1 -0
  391. package/dist/core/brief/unchecked.js +48 -0
  392. package/dist/core/brief/unchecked.js.map +1 -0
  393. package/dist/core/c4/arch.js +174 -0
  394. package/dist/core/c4/arch.js.map +1 -0
  395. package/dist/core/c4/likec4.js +90 -0
  396. package/dist/core/c4/likec4.js.map +1 -0
  397. package/dist/core/c4/parsed/deployment.js +158 -0
  398. package/dist/core/c4/parsed/deployment.js.map +1 -0
  399. package/dist/core/c4/parsed/dynamic-views.js +132 -0
  400. package/dist/core/c4/parsed/dynamic-views.js.map +1 -0
  401. package/dist/core/c4/parsed/specification.js +78 -0
  402. package/dist/core/c4/parsed/specification.js.map +1 -0
  403. package/dist/core/c4/parsed/values.js +57 -0
  404. package/dist/core/c4/parsed/values.js.map +1 -0
  405. package/dist/core/c4/parsed/view-ids.js +75 -0
  406. package/dist/core/c4/parsed/view-ids.js.map +1 -0
  407. package/dist/core/c4/project/architecture.js +45 -0
  408. package/dist/core/c4/project/architecture.js.map +1 -0
  409. package/dist/core/c4/project/documents.js +58 -0
  410. package/dist/core/c4/project/documents.js.map +1 -0
  411. package/dist/core/c4/project/load.js +187 -0
  412. package/dist/core/c4/project/load.js.map +1 -0
  413. package/dist/core/c4/project/staged.js +220 -0
  414. package/dist/core/c4/project/staged.js.map +1 -0
  415. package/dist/core/c4/resolve/service.js +159 -0
  416. package/dist/core/c4/resolve/service.js.map +1 -0
  417. package/dist/core/c4/resolve/steps.js +144 -0
  418. package/dist/core/c4/resolve/steps.js.map +1 -0
  419. package/dist/core/c4/seed/fleet-file.js +201 -0
  420. package/dist/core/c4/seed/fleet-file.js.map +1 -0
  421. package/dist/core/c4/seed/items.js +91 -0
  422. package/dist/core/c4/seed/items.js.map +1 -0
  423. package/dist/core/c4/seed/stamp.js +48 -0
  424. package/dist/core/c4/seed/stamp.js.map +1 -0
  425. package/dist/core/c4/seed/template.js +109 -0
  426. package/dist/core/c4/seed/template.js.map +1 -0
  427. package/dist/core/c4/source-mask.js +82 -0
  428. package/dist/core/c4/source-mask.js.map +1 -0
  429. package/dist/core/c4/source-scan.js +227 -0
  430. package/dist/core/c4/source-scan.js.map +1 -0
  431. package/dist/core/c4/splice/authored-source.js +101 -0
  432. package/dist/core/c4/splice/authored-source.js.map +1 -0
  433. package/dist/core/c4/splice/contract.js +10 -0
  434. package/dist/core/c4/splice/contract.js.map +1 -0
  435. package/dist/core/c4/splice/delta-blocks.js +139 -0
  436. package/dist/core/c4/splice/delta-blocks.js.map +1 -0
  437. package/dist/core/c4/splice/identity/edges.js +36 -0
  438. package/dist/core/c4/splice/identity/edges.js.map +1 -0
  439. package/dist/core/c4/splice/landscape-merge.js +269 -0
  440. package/dist/core/c4/splice/landscape-merge.js.map +1 -0
  441. package/dist/core/c4/splice/placement.js +194 -0
  442. package/dist/core/c4/splice/placement.js.map +1 -0
  443. package/dist/core/c4/workspace.js +174 -0
  444. package/dist/core/c4/workspace.js.map +1 -0
  445. package/dist/core/capabilities/authoring/notes.js +141 -0
  446. package/dist/core/capabilities/authoring/notes.js.map +1 -0
  447. package/dist/core/capabilities/capabilities.js +124 -0
  448. package/dist/core/capabilities/capabilities.js.map +1 -0
  449. package/dist/core/capabilities/delta/doc.js +50 -0
  450. package/dist/core/capabilities/delta/doc.js.map +1 -0
  451. package/dist/core/capabilities/delta/overlay.js +129 -0
  452. package/dist/core/capabilities/delta/overlay.js.map +1 -0
  453. package/dist/core/capabilities/delta/summary.js +57 -0
  454. package/dist/core/capabilities/delta/summary.js.map +1 -0
  455. package/dist/core/capabilities/delta/tree.js +43 -0
  456. package/dist/core/capabilities/delta/tree.js.map +1 -0
  457. package/dist/core/capabilities/delta/uncovered.js +222 -0
  458. package/dist/core/capabilities/delta/uncovered.js.map +1 -0
  459. package/dist/core/capabilities/findings.js +342 -0
  460. package/dist/core/capabilities/findings.js.map +1 -0
  461. package/dist/core/capabilities/realizes/findings.js +181 -0
  462. package/dist/core/capabilities/realizes/findings.js.map +1 -0
  463. package/dist/core/capabilities/realizes/join.js +143 -0
  464. package/dist/core/capabilities/realizes/join.js.map +1 -0
  465. package/dist/core/capabilities/rollup.js +199 -0
  466. package/dist/core/capabilities/rollup.js.map +1 -0
  467. package/dist/core/capabilities/tree.js +126 -0
  468. package/dist/core/capabilities/tree.js.map +1 -0
  469. package/dist/core/capabilities/usecase-join.js +277 -0
  470. package/dist/core/capabilities/usecase-join.js.map +1 -0
  471. package/dist/core/coherence/authoring/scaffold.js +177 -0
  472. package/dist/core/coherence/authoring/scaffold.js.map +1 -0
  473. package/dist/core/coherence/authoring/sentinels.js +74 -0
  474. package/dist/core/coherence/authoring/sentinels.js.map +1 -0
  475. package/dist/core/coherence/coherence.js +287 -0
  476. package/dist/core/coherence/coherence.js.map +1 -0
  477. package/dist/core/coherence/declared.js +269 -0
  478. package/dist/core/coherence/declared.js.map +1 -0
  479. package/dist/core/coherence/events/declared.js +206 -0
  480. package/dist/core/coherence/events/declared.js.map +1 -0
  481. package/dist/core/coherence/events/events.js +204 -0
  482. package/dist/core/coherence/events/events.js.map +1 -0
  483. package/dist/core/coherence/events/grades.js +166 -0
  484. package/dist/core/coherence/events/grades.js.map +1 -0
  485. package/dist/core/coherence/events/lookups.js +122 -0
  486. package/dist/core/coherence/events/lookups.js.map +1 -0
  487. package/dist/core/coherence/events/merged.js +40 -0
  488. package/dist/core/coherence/events/merged.js.map +1 -0
  489. package/dist/core/coherence/living.js +198 -0
  490. package/dist/core/coherence/living.js.map +1 -0
  491. package/dist/core/coherence/lookups.js +155 -0
  492. package/dist/core/coherence/lookups.js.map +1 -0
  493. package/dist/core/coherence/pending.js +39 -0
  494. package/dist/core/coherence/pending.js.map +1 -0
  495. package/dist/core/conflict-markers.js +60 -0
  496. package/dist/core/conflict-markers.js.map +1 -0
  497. package/dist/core/delta/claims.js +73 -0
  498. package/dist/core/delta/claims.js.map +1 -0
  499. package/dist/core/delta/delta.js +296 -0
  500. package/dist/core/delta/delta.js.map +1 -0
  501. package/dist/core/delta/document.js +177 -0
  502. package/dist/core/delta/document.js.map +1 -0
  503. package/dist/core/delta/scope.js +48 -0
  504. package/dist/core/delta/scope.js.map +1 -0
  505. package/dist/core/delta/select.js +237 -0
  506. package/dist/core/delta/select.js.map +1 -0
  507. package/dist/core/dependencies/dependencies.js +141 -0
  508. package/dist/core/dependencies/dependencies.js.map +1 -0
  509. package/dist/core/dependencies/facts.js +165 -0
  510. package/dist/core/dependencies/facts.js.map +1 -0
  511. package/dist/core/dependencies/fanin.js +88 -0
  512. package/dist/core/dependencies/fanin.js.map +1 -0
  513. package/dist/core/dependencies/graph.js +106 -0
  514. package/dist/core/dependencies/graph.js.map +1 -0
  515. package/dist/core/deployment/delta.js +188 -0
  516. package/dist/core/deployment/delta.js.map +1 -0
  517. package/dist/core/deployment/objects.js +145 -0
  518. package/dist/core/deployment/objects.js.map +1 -0
  519. package/dist/core/diff/base-git.js +148 -0
  520. package/dist/core/diff/base-git.js.map +1 -0
  521. package/dist/core/diff/base-state.js +209 -0
  522. package/dist/core/diff/base-state.js.map +1 -0
  523. package/dist/core/diff/current-state.js +96 -0
  524. package/dist/core/diff/current-state.js.map +1 -0
  525. package/dist/core/diff/scope/changed-paths.js +188 -0
  526. package/dist/core/diff/scope/changed-paths.js.map +1 -0
  527. package/dist/core/diff/semantic.js +243 -0
  528. package/dist/core/diff/semantic.js.map +1 -0
  529. package/dist/core/diff/victims.js +247 -0
  530. package/dist/core/diff/victims.js.map +1 -0
  531. package/dist/core/docs.js +7 -64
  532. package/dist/core/docs.js.map +1 -1
  533. package/dist/core/doctor/agents.js +222 -0
  534. package/dist/core/doctor/agents.js.map +1 -0
  535. package/dist/core/doctor/config.js +135 -0
  536. package/dist/core/doctor/config.js.map +1 -0
  537. package/dist/core/doctor/doctor.js +275 -0
  538. package/dist/core/doctor/doctor.js.map +1 -0
  539. package/dist/core/doctor/report.js +13 -0
  540. package/dist/core/doctor/report.js.map +1 -0
  541. package/dist/core/doctor/residue.js +110 -0
  542. package/dist/core/doctor/residue.js.map +1 -0
  543. package/dist/core/document/apply.js +77 -0
  544. package/dist/core/document/apply.js.map +1 -0
  545. package/dist/core/{frontmatter.js → document/frontmatter.js} +48 -2
  546. package/dist/core/document/frontmatter.js.map +1 -0
  547. package/dist/core/document/grammar/directives.js +143 -0
  548. package/dist/core/document/grammar/directives.js.map +1 -0
  549. package/dist/core/document/parse.js +263 -0
  550. package/dist/core/document/parse.js.map +1 -0
  551. package/dist/core/document/scenarios.js +221 -0
  552. package/dist/core/document/scenarios.js.map +1 -0
  553. package/dist/core/document/spec.js +241 -0
  554. package/dist/core/document/spec.js.map +1 -0
  555. package/dist/core/{config.js → envelope/config.js} +79 -18
  556. package/dist/core/envelope/config.js.map +1 -0
  557. package/dist/core/envelope/json.js +175 -0
  558. package/dist/core/envelope/json.js.map +1 -0
  559. package/dist/core/{version.js → envelope/version.js} +3 -3
  560. package/dist/core/envelope/version.js.map +1 -0
  561. package/dist/core/explain/families.js +175 -0
  562. package/dist/core/explain/families.js.map +1 -0
  563. package/dist/core/explain/fix-tables.js +178 -0
  564. package/dist/core/explain/fix-tables.js.map +1 -0
  565. package/dist/core/explain/lookup.js +181 -0
  566. package/dist/core/explain/lookup.js.map +1 -0
  567. package/dist/core/explain/refusals.js +49 -0
  568. package/dist/core/explain/refusals.js.map +1 -0
  569. package/dist/core/explain/terms.js +144 -0
  570. package/dist/core/explain/terms.js.map +1 -0
  571. package/dist/core/explore/describe.js +105 -0
  572. package/dist/core/explore/describe.js.map +1 -0
  573. package/dist/core/{explore.js → explore/explore.js} +50 -101
  574. package/dist/core/explore/explore.js.map +1 -0
  575. package/dist/core/fleet-context.js +120 -78
  576. package/dist/core/fleet-context.js.map +1 -1
  577. package/dist/core/gate/checks.js +201 -0
  578. package/dist/core/gate/checks.js.map +1 -0
  579. package/dist/core/gate/partners.js +205 -0
  580. package/dist/core/gate/partners.js.map +1 -0
  581. package/dist/core/gate/report.js +47 -0
  582. package/dist/core/gate/report.js.map +1 -0
  583. package/dist/core/gate/verification.js +113 -0
  584. package/dist/core/gate/verification.js.map +1 -0
  585. package/dist/core/gherkin/digest.js +60 -0
  586. package/dist/core/gherkin/digest.js.map +1 -0
  587. package/dist/core/gherkin/emit.js +177 -0
  588. package/dist/core/gherkin/emit.js.map +1 -0
  589. package/dist/core/gherkin/read.js +76 -0
  590. package/dist/core/gherkin/read.js.map +1 -0
  591. package/dist/core/gherkin/stale.js +234 -0
  592. package/dist/core/gherkin/stale.js.map +1 -0
  593. package/dist/core/gherkin/stamp.js +77 -0
  594. package/dist/core/gherkin/stamp.js.map +1 -0
  595. package/dist/core/gherkin/steps/catalogue.js +154 -0
  596. package/dist/core/gherkin/steps/catalogue.js.map +1 -0
  597. package/dist/core/gherkin/steps/inventory.js +98 -0
  598. package/dist/core/gherkin/steps/inventory.js.map +1 -0
  599. package/dist/core/gherkin/steps/phrase.js +72 -0
  600. package/dist/core/gherkin/steps/phrase.js.map +1 -0
  601. package/dist/core/glossary/delta.js +106 -0
  602. package/dist/core/glossary/delta.js.map +1 -0
  603. package/dist/core/glossary/tree.js +86 -0
  604. package/dist/core/glossary/tree.js.map +1 -0
  605. package/dist/core/kernel/concurrency.js.map +1 -0
  606. package/dist/core/{document-bytes.js → kernel/document-bytes.js} +1 -1
  607. package/dist/core/kernel/document-bytes.js.map +1 -0
  608. package/dist/core/kernel/fences.js +42 -0
  609. package/dist/core/kernel/fences.js.map +1 -0
  610. package/dist/core/kernel/ids/capability.js +72 -0
  611. package/dist/core/kernel/ids/capability.js.map +1 -0
  612. package/dist/core/kernel/ids/dirs.js +33 -0
  613. package/dist/core/kernel/ids/dirs.js.map +1 -0
  614. package/dist/core/kernel/ids/feature.js +75 -0
  615. package/dist/core/kernel/ids/feature.js.map +1 -0
  616. package/dist/core/kernel/ids/service.js +156 -0
  617. package/dist/core/kernel/ids/service.js.map +1 -0
  618. package/dist/core/kernel/ids/subsystem.js +63 -0
  619. package/dist/core/kernel/ids/subsystem.js.map +1 -0
  620. package/dist/core/{path-safety.js → kernel/path-safety.js} +18 -4
  621. package/dist/core/kernel/path-safety.js.map +1 -0
  622. package/dist/core/kernel/records.js.map +1 -0
  623. package/dist/core/links/backlinks.js +68 -0
  624. package/dist/core/links/backlinks.js.map +1 -0
  625. package/dist/core/links/case.js +74 -0
  626. package/dist/core/links/case.js.map +1 -0
  627. package/dist/core/links/corpus.js +104 -0
  628. package/dist/core/links/corpus.js.map +1 -0
  629. package/dist/core/links/findings.js +110 -0
  630. package/dist/core/links/findings.js.map +1 -0
  631. package/dist/core/links/parse.js +236 -0
  632. package/dist/core/links/parse.js.map +1 -0
  633. package/dist/core/mcp/argv.js +111 -0
  634. package/dist/core/mcp/argv.js.map +1 -0
  635. package/dist/core/mcp/author-tools.js +72 -0
  636. package/dist/core/mcp/author-tools.js.map +1 -0
  637. package/dist/core/mcp/framing.js +46 -0
  638. package/dist/core/mcp/framing.js.map +1 -0
  639. package/dist/core/mcp/protocol.js +280 -0
  640. package/dist/core/mcp/protocol.js.map +1 -0
  641. package/dist/core/mcp/tools.js +314 -0
  642. package/dist/core/mcp/tools.js.map +1 -0
  643. package/dist/core/obligations/obligations.js +106 -0
  644. package/dist/core/obligations/obligations.js.map +1 -0
  645. package/dist/core/openapi/baseline/gate.js +166 -0
  646. package/dist/core/openapi/baseline/gate.js.map +1 -0
  647. package/dist/core/openapi/baseline/plan.js +112 -0
  648. package/dist/core/openapi/baseline/plan.js.map +1 -0
  649. package/dist/core/openapi/baseline/record.js +175 -0
  650. package/dist/core/openapi/baseline/record.js.map +1 -0
  651. package/dist/core/openapi/depth.js +122 -0
  652. package/dist/core/openapi/depth.js.map +1 -0
  653. package/dist/core/openapi/digest.js +189 -0
  654. package/dist/core/openapi/digest.js.map +1 -0
  655. package/dist/core/{openapi.js → openapi/doc.js} +44 -106
  656. package/dist/core/openapi/doc.js.map +1 -0
  657. package/dist/core/openapi/merge/components.js +234 -0
  658. package/dist/core/openapi/merge/components.js.map +1 -0
  659. package/dist/core/openapi/merge/error.js +26 -0
  660. package/dist/core/openapi/merge/error.js.map +1 -0
  661. package/dist/core/openapi/merge/markers.js +208 -0
  662. package/dist/core/openapi/merge/markers.js.map +1 -0
  663. package/dist/core/openapi/merge/merge.js +256 -0
  664. package/dist/core/openapi/merge/merge.js.map +1 -0
  665. package/dist/core/openapi/merge/pin.js +128 -0
  666. package/dist/core/openapi/merge/pin.js.map +1 -0
  667. package/dist/core/openspec/decide/capabilities.js +244 -0
  668. package/dist/core/openspec/decide/capabilities.js.map +1 -0
  669. package/dist/core/openspec/decide/dispositions.js +63 -0
  670. package/dist/core/openspec/decide/dispositions.js.map +1 -0
  671. package/dist/core/openspec/decide/renames.js +179 -0
  672. package/dist/core/openspec/decide/renames.js.map +1 -0
  673. package/dist/core/openspec/decide/verdict.js +84 -0
  674. package/dist/core/openspec/decide/verdict.js.map +1 -0
  675. package/dist/core/openspec/inventory.js +221 -0
  676. package/dist/core/openspec/inventory.js.map +1 -0
  677. package/dist/core/openspec/model/mapping.js +76 -0
  678. package/dist/core/openspec/model/mapping.js.map +1 -0
  679. package/dist/core/openspec/model/model.js +65 -0
  680. package/dist/core/openspec/model/model.js.map +1 -0
  681. package/dist/core/openspec/scan/changes.js +235 -0
  682. package/dist/core/openspec/scan/changes.js.map +1 -0
  683. package/dist/core/openspec/scan/config.js +200 -0
  684. package/dist/core/openspec/scan/config.js.map +1 -0
  685. package/dist/core/openspec/scan/shape.js +260 -0
  686. package/dist/core/openspec/scan/shape.js.map +1 -0
  687. package/dist/core/openspec/scan/walk.js +133 -0
  688. package/dist/core/openspec/scan/walk.js.map +1 -0
  689. package/dist/core/openspec/scan/workspace.js +71 -0
  690. package/dist/core/openspec/scan/workspace.js.map +1 -0
  691. package/dist/core/owners/codeowners.js +141 -0
  692. package/dist/core/owners/codeowners.js.map +1 -0
  693. package/dist/core/pack/features.js +120 -0
  694. package/dist/core/pack/features.js.map +1 -0
  695. package/dist/core/pack/joins.js +112 -0
  696. package/dist/core/pack/joins.js.map +1 -0
  697. package/dist/core/pack/living.js +137 -0
  698. package/dist/core/pack/living.js.map +1 -0
  699. package/dist/core/pack/pack.js +76 -0
  700. package/dist/core/pack/pack.js.map +1 -0
  701. package/dist/core/permissions/permissions.js +87 -0
  702. package/dist/core/permissions/permissions.js.map +1 -0
  703. package/dist/core/projection/api.js +84 -0
  704. package/dist/core/projection/api.js.map +1 -0
  705. package/dist/core/projection/arch-slice.js +63 -0
  706. package/dist/core/projection/arch-slice.js.map +1 -0
  707. package/dist/core/projection/events.js +34 -0
  708. package/dist/core/projection/events.js.map +1 -0
  709. package/dist/core/provenance/findings.js +208 -0
  710. package/dist/core/provenance/findings.js.map +1 -0
  711. package/dist/core/provenance/git.js +225 -0
  712. package/dist/core/provenance/git.js.map +1 -0
  713. package/dist/core/provenance/gitq/moves.js +182 -0
  714. package/dist/core/provenance/gitq/moves.js.map +1 -0
  715. package/dist/core/provenance/gitq/vouched-ancestor.js +179 -0
  716. package/dist/core/provenance/gitq/vouched-ancestor.js.map +1 -0
  717. package/dist/core/provenance/sample/scope.js +238 -0
  718. package/dist/core/provenance/sample/scope.js.map +1 -0
  719. package/dist/core/provenance/sample/sections.js +61 -0
  720. package/dist/core/provenance/sample/sections.js.map +1 -0
  721. package/dist/core/provenance/sources.js +263 -0
  722. package/dist/core/provenance/sources.js.map +1 -0
  723. package/dist/core/provenance/stamp.js +232 -0
  724. package/dist/core/provenance/stamp.js.map +1 -0
  725. package/dist/core/provenance/walk.js +157 -0
  726. package/dist/core/provenance/walk.js.map +1 -0
  727. package/dist/core/repo/authored/paths.js +210 -0
  728. package/dist/core/repo/authored/paths.js.map +1 -0
  729. package/dist/core/repo/entries.js +126 -0
  730. package/dist/core/repo/entries.js.map +1 -0
  731. package/dist/core/repo/paths.js +277 -0
  732. package/dist/core/repo/paths.js.map +1 -0
  733. package/dist/core/repo/repo.js +248 -0
  734. package/dist/core/repo/repo.js.map +1 -0
  735. package/dist/core/repo/service-target.js +153 -0
  736. package/dist/core/repo/service-target.js.map +1 -0
  737. package/dist/core/repo/state.js +58 -0
  738. package/dist/core/repo/state.js.map +1 -0
  739. package/dist/core/repo/tree/find.js +52 -0
  740. package/dist/core/repo/tree/find.js.map +1 -0
  741. package/dist/core/repo/tree/fs.js +64 -0
  742. package/dist/core/repo/tree/fs.js.map +1 -0
  743. package/dist/core/repo/tree/marker.js +61 -0
  744. package/dist/core/repo/tree/marker.js.map +1 -0
  745. package/dist/core/repo/tree/views.js +172 -0
  746. package/dist/core/repo/tree/views.js.map +1 -0
  747. package/dist/core/repo/tree/walk.js +234 -0
  748. package/dist/core/repo/tree/walk.js.map +1 -0
  749. package/dist/core/results.js +99 -2
  750. package/dist/core/results.js.map +1 -1
  751. package/dist/core/scaffold/landscape.js +131 -0
  752. package/dist/core/scaffold/landscape.js.map +1 -0
  753. package/dist/core/scaffold/readme.js +84 -0
  754. package/dist/core/scaffold/readme.js.map +1 -0
  755. package/dist/core/staging/commit.js +241 -0
  756. package/dist/core/staging/commit.js.map +1 -0
  757. package/dist/core/staging/interrupted.js +96 -0
  758. package/dist/core/staging/interrupted.js.map +1 -0
  759. package/dist/core/staging/lock.js +206 -0
  760. package/dist/core/staging/lock.js.map +1 -0
  761. package/dist/core/staging/recovery/finding.js +35 -0
  762. package/dist/core/staging/recovery/finding.js.map +1 -0
  763. package/dist/core/staging/recovery/intent.js +98 -0
  764. package/dist/core/staging/recovery/intent.js.map +1 -0
  765. package/dist/core/staging/recovery/recover.js +126 -0
  766. package/dist/core/staging/recovery/recover.js.map +1 -0
  767. package/dist/core/staging/recovery/residue.js +62 -0
  768. package/dist/core/staging/recovery/residue.js.map +1 -0
  769. package/dist/core/staging/snapshot.js +202 -0
  770. package/dist/core/staging/snapshot.js.map +1 -0
  771. package/dist/core/staging/txn/forward.js +171 -0
  772. package/dist/core/staging/txn/forward.js.map +1 -0
  773. package/dist/core/staging/txn/journal.js +139 -0
  774. package/dist/core/staging/txn/journal.js.map +1 -0
  775. package/dist/core/staging/txn/transaction.js +75 -0
  776. package/dist/core/staging/txn/transaction.js.map +1 -0
  777. package/dist/core/staging/writes.js +113 -0
  778. package/dist/core/staging/writes.js.map +1 -0
  779. package/dist/core/status/actions/execution.js +49 -0
  780. package/dist/core/status/actions/execution.js.map +1 -0
  781. package/dist/core/status/contracts.js +102 -0
  782. package/dist/core/status/contracts.js.map +1 -0
  783. package/dist/core/status/feature/artifacts.js +196 -0
  784. package/dist/core/status/feature/artifacts.js.map +1 -0
  785. package/dist/core/status/feature/feature.js +207 -0
  786. package/dist/core/status/feature/feature.js.map +1 -0
  787. package/dist/core/status/feature/next.js +150 -0
  788. package/dist/core/status/feature/next.js.map +1 -0
  789. package/dist/core/status/feature/state.js +21 -0
  790. package/dist/core/status/feature/state.js.map +1 -0
  791. package/dist/core/status/fleet/fleet.js +197 -0
  792. package/dist/core/status/fleet/fleet.js.map +1 -0
  793. package/dist/core/status/fleet/next.js +207 -0
  794. package/dist/core/status/fleet/next.js.map +1 -0
  795. package/dist/core/status/interrupted.js +97 -0
  796. package/dist/core/status/interrupted.js.map +1 -0
  797. package/dist/core/status/report.js +31 -0
  798. package/dist/core/status/report.js.map +1 -0
  799. package/dist/core/status/scan.js +41 -0
  800. package/dist/core/status/scan.js.map +1 -0
  801. package/dist/core/status/verification.js +201 -0
  802. package/dist/core/status/verification.js.map +1 -0
  803. package/dist/core/usecases/capability.js +169 -0
  804. package/dist/core/usecases/capability.js.map +1 -0
  805. package/dist/core/usecases/delta/claims.js +116 -0
  806. package/dist/core/usecases/delta/claims.js.map +1 -0
  807. package/dist/core/usecases/delta/flows.js +103 -0
  808. package/dist/core/usecases/delta/flows.js.map +1 -0
  809. package/dist/core/usecases/delta/overlay.js +72 -0
  810. package/dist/core/usecases/delta/overlay.js.map +1 -0
  811. package/dist/core/usecases/fleet.js +137 -0
  812. package/dist/core/usecases/fleet.js.map +1 -0
  813. package/dist/core/usecases/operations.js +111 -0
  814. package/dist/core/usecases/operations.js.map +1 -0
  815. package/dist/core/usecases/place.js +44 -0
  816. package/dist/core/usecases/place.js.map +1 -0
  817. package/dist/core/usecases/touch.js +101 -0
  818. package/dist/core/usecases/touch.js.map +1 -0
  819. package/dist/core/verify/answers.js +173 -0
  820. package/dist/core/verify/answers.js.map +1 -0
  821. package/dist/core/verify/build.js +150 -0
  822. package/dist/core/verify/build.js.map +1 -0
  823. package/dist/core/verify/checklist.js +201 -0
  824. package/dist/core/verify/checklist.js.map +1 -0
  825. package/dist/core/verify/claims/identity.js +61 -0
  826. package/dist/core/verify/claims/identity.js.map +1 -0
  827. package/dist/core/verify/cross/diff.js +97 -0
  828. package/dist/core/verify/cross/diff.js.map +1 -0
  829. package/dist/core/verify/evidence/contract.js +169 -0
  830. package/dist/core/verify/evidence/contract.js.map +1 -0
  831. package/dist/core/verify/file.js +257 -0
  832. package/dist/core/verify/file.js.map +1 -0
  833. package/dist/core/verify/pins/lint.js +157 -0
  834. package/dist/core/verify/pins/lint.js.map +1 -0
  835. package/dist/core/verify/pins/pin.js +95 -0
  836. package/dist/core/verify/pins/pin.js.map +1 -0
  837. package/dist/core/verify/record.js +142 -0
  838. package/dist/core/verify/record.js.map +1 -0
  839. package/dist/core/verify/store/commit.js +89 -0
  840. package/dist/core/verify/store/commit.js.map +1 -0
  841. package/dist/core/verify/store/render.js +57 -0
  842. package/dist/core/verify/store/render.js.map +1 -0
  843. package/dist/core/vocabulary/health.js +91 -0
  844. package/dist/core/vocabulary/health.js.map +1 -0
  845. package/dist/core/vocabulary/issue.js +58 -0
  846. package/dist/core/vocabulary/issue.js.map +1 -0
  847. package/dist/core/vocabulary/maturity.js +145 -0
  848. package/dist/core/vocabulary/maturity.js.map +1 -0
  849. package/dist/core/{report.js → vocabulary/report.js} +30 -2
  850. package/dist/core/vocabulary/report.js.map +1 -0
  851. package/dist/core/vocabulary/steps.js +266 -0
  852. package/dist/core/vocabulary/steps.js.map +1 -0
  853. package/dist/core/workspace/discover.js +239 -0
  854. package/dist/core/workspace/discover.js.map +1 -0
  855. package/dist/core/workspace/render.js +52 -0
  856. package/dist/core/workspace/render.js.map +1 -0
  857. package/examples/README.md +189 -0
  858. package/examples/docs/architecture/adrs/0001-transactional-outbox.md +33 -0
  859. package/examples/docs/architecture/capabilities.yaml +31 -0
  860. package/examples/docs/architecture/landscape.likec4 +280 -0
  861. package/examples/docs/architecture/obligations.yaml +23 -0
  862. package/examples/docs/architecture/permissions.yaml +50 -0
  863. package/examples/docs/architecture/subsystems.likec4 +11 -0
  864. package/examples/docs/architecture/usecases/order-notification.likec4 +65 -0
  865. package/examples/docs/capabilities/checkout/spec.md +55 -0
  866. package/examples/docs/capabilities/identity/tokens/spec.md +42 -0
  867. package/examples/docs/capabilities/order-notifications/spec.md +43 -0
  868. package/examples/docs/features/FEAT-101-payment-splitting/adrs/0001-dedicated-split-service.md +18 -0
  869. package/examples/docs/features/FEAT-101-payment-splitting/delta.likec4 +94 -0
  870. package/examples/docs/features/FEAT-101-payment-splitting/intent.md +44 -0
  871. package/examples/docs/features/FEAT-101-payment-splitting/specs/checkout-web/spec.md +21 -0
  872. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/asyncapi.yaml +129 -0
  873. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-service/spec.md +36 -0
  874. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/arch.spec.md +40 -0
  875. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/openapi.yaml +116 -0
  876. package/examples/docs/features/FEAT-101-payment-splitting/specs/payment-split-service/spec.md +55 -0
  877. package/examples/docs/features/FEAT-112-retire-order-v1/intent.md +35 -0
  878. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/openapi.yaml +28 -0
  879. package/examples/docs/features/FEAT-112-retire-order-v1/specs/order-service/spec.md +17 -0
  880. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/architecture/landscape.likec4 +253 -0
  881. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/order-service/spec.md +121 -0
  882. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/openapi.yaml +111 -0
  883. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/files/services/payment-service/spec.md +58 -0
  884. package/examples/docs/features/archive/FEAT-088-refunds/.loam-before/manifest.json +32 -0
  885. package/examples/docs/features/archive/FEAT-088-refunds/adrs/0001-refunds-stay-in-payment-service.md +26 -0
  886. package/examples/docs/features/archive/FEAT-088-refunds/delta.likec4 +28 -0
  887. package/examples/docs/features/archive/FEAT-088-refunds/intent.md +26 -0
  888. package/examples/docs/features/archive/FEAT-088-refunds/specs/order-service/spec.md +37 -0
  889. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/openapi.yaml +70 -0
  890. package/examples/docs/features/archive/FEAT-088-refunds/specs/payment-service/spec.md +23 -0
  891. package/examples/docs/features/archive/FEAT-088-refunds/verification.yaml +76 -0
  892. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/architecture/landscape.likec4 +275 -0
  893. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/asyncapi.yaml +96 -0
  894. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/payment-service/spec.md +82 -0
  895. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/asyncapi.yaml +164 -0
  896. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/files/services/platform/notification-service/spec.md +91 -0
  897. package/examples/docs/features/archive/FEAT-120-refund-notification/.loam-before/manifest.json +46 -0
  898. package/examples/docs/features/archive/FEAT-120-refund-notification/delta.likec4 +36 -0
  899. package/examples/docs/features/archive/FEAT-120-refund-notification/intent.md +22 -0
  900. package/examples/docs/features/archive/FEAT-120-refund-notification/scenario-report.json +10 -0
  901. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/asyncapi.yaml +208 -0
  902. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/notification-service/spec.md +24 -0
  903. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/asyncapi.yaml +137 -0
  904. package/examples/docs/features/archive/FEAT-120-refund-notification/specs/payment-service/spec.md +31 -0
  905. package/examples/docs/features/archive/FEAT-120-refund-notification/verification.yaml +84 -0
  906. package/examples/docs/glossary/order.md +15 -0
  907. package/examples/docs/glossary/payments/authorization.md +14 -0
  908. package/examples/docs/likec4.config.json +9 -0
  909. package/examples/docs/loam.json +3 -0
  910. package/examples/docs/services/checkout-web/model.likec4 +109 -0
  911. package/examples/docs/services/checkout-web/spec.md +91 -0
  912. package/examples/docs/services/checkout-web/ui/pages/checkout.page.yaml +40 -0
  913. package/examples/docs/services/checkout-web/ui/pages/order-status.page.yaml +24 -0
  914. package/examples/docs/services/checkout-web/ui/pages/split-payment.page.yaml +26 -0
  915. package/examples/docs/services/order-service/adrs/0001-orchestrated-order-lifecycle.md +52 -0
  916. package/examples/docs/services/order-service/arch.spec.md +127 -0
  917. package/examples/docs/services/order-service/asyncapi.yaml +108 -0
  918. package/examples/docs/services/order-service/health.yaml +57 -0
  919. package/examples/docs/services/order-service/model.likec4 +138 -0
  920. package/examples/docs/services/order-service/openapi.yaml +257 -0
  921. package/examples/docs/services/order-service/runbook.md +62 -0
  922. package/examples/docs/services/order-service/spec.md +134 -0
  923. package/examples/docs/services/payment-service/adrs/0001-payments-outbox.md +18 -0
  924. package/examples/docs/services/payment-service/adrs/0002-idempotency-keys-on-authorization.md +27 -0
  925. package/examples/docs/services/payment-service/arch.spec.md +73 -0
  926. package/examples/docs/services/payment-service/asyncapi.yaml +130 -0
  927. package/examples/docs/services/payment-service/health.yaml +39 -0
  928. package/examples/docs/services/payment-service/model.likec4 +67 -0
  929. package/examples/docs/services/payment-service/openapi.yaml +151 -0
  930. package/examples/docs/services/payment-service/runbook.md +37 -0
  931. package/examples/docs/services/payment-service/spec.md +88 -0
  932. package/examples/docs/services/platform/identity-service/adrs/0001-token-introspection-over-local-validation.md +60 -0
  933. package/examples/docs/services/platform/identity-service/arch.spec.md +117 -0
  934. package/examples/docs/services/platform/identity-service/health.yaml +70 -0
  935. package/examples/docs/services/platform/identity-service/model.likec4 +83 -0
  936. package/examples/docs/services/platform/identity-service/openapi.yaml +197 -0
  937. package/examples/docs/services/platform/identity-service/runbook.md +95 -0
  938. package/examples/docs/services/platform/identity-service/spec.md +119 -0
  939. package/examples/docs/services/platform/notification-service/asyncapi.yaml +199 -0
  940. package/examples/docs/services/platform/notification-service/health.yaml +35 -0
  941. package/examples/docs/services/platform/notification-service/model.likec4 +118 -0
  942. package/examples/docs/services/platform/notification-service/runbook.md +48 -0
  943. package/examples/docs/services/platform/notification-service/spec.md +112 -0
  944. package/examples/docs/services/platform/subsystem.yaml +2 -0
  945. package/examples/fleet.yaml +57 -0
  946. package/package.json +19 -6
  947. package/dist/commands/adopt.js +0 -240
  948. package/dist/commands/adopt.js.map +0 -1
  949. package/dist/commands/archive.js +0 -1313
  950. package/dist/commands/archive.js.map +0 -1
  951. package/dist/commands/delta.js +0 -388
  952. package/dist/commands/delta.js.map +0 -1
  953. package/dist/commands/docs-repo-gate.js.map +0 -1
  954. package/dist/commands/format.js +0 -17
  955. package/dist/commands/format.js.map +0 -1
  956. package/dist/commands/gherkin.js +0 -309
  957. package/dist/commands/gherkin.js.map +0 -1
  958. package/dist/commands/init.js.map +0 -1
  959. package/dist/commands/list.js +0 -295
  960. package/dist/commands/list.js.map +0 -1
  961. package/dist/commands/migrate-openspec.js +0 -950
  962. package/dist/commands/migrate-openspec.js.map +0 -1
  963. package/dist/commands/new.js +0 -413
  964. package/dist/commands/new.js.map +0 -1
  965. package/dist/commands/rebase.js +0 -356
  966. package/dist/commands/rebase.js.map +0 -1
  967. package/dist/commands/show.js.map +0 -1
  968. package/dist/commands/status.js +0 -262
  969. package/dist/commands/status.js.map +0 -1
  970. package/dist/commands/unarchive.js.map +0 -1
  971. package/dist/commands/validate.js +0 -1773
  972. package/dist/commands/validate.js.map +0 -1
  973. package/dist/commands/verify.js +0 -775
  974. package/dist/commands/verify.js.map +0 -1
  975. package/dist/commands/vouch.js +0 -421
  976. package/dist/commands/vouch.js.map +0 -1
  977. package/dist/core/agent.js +0 -2173
  978. package/dist/core/agent.js.map +0 -1
  979. package/dist/core/agents-stamp.js.map +0 -1
  980. package/dist/core/arch.js +0 -130
  981. package/dist/core/arch.js.map +0 -1
  982. package/dist/core/asyncapi.js.map +0 -1
  983. package/dist/core/brief.js +0 -755
  984. package/dist/core/brief.js.map +0 -1
  985. package/dist/core/coherence.js +0 -577
  986. package/dist/core/coherence.js.map +0 -1
  987. package/dist/core/concurrency.js.map +0 -1
  988. package/dist/core/config.js.map +0 -1
  989. package/dist/core/delta.js +0 -476
  990. package/dist/core/delta.js.map +0 -1
  991. package/dist/core/dependencies.js +0 -356
  992. package/dist/core/dependencies.js.map +0 -1
  993. package/dist/core/doctor.js +0 -596
  994. package/dist/core/doctor.js.map +0 -1
  995. package/dist/core/document-bytes.js.map +0 -1
  996. package/dist/core/explore.js.map +0 -1
  997. package/dist/core/frontmatter.js.map +0 -1
  998. package/dist/core/gherkin.js +0 -463
  999. package/dist/core/gherkin.js.map +0 -1
  1000. package/dist/core/health.js +0 -67
  1001. package/dist/core/health.js.map +0 -1
  1002. package/dist/core/ids.js +0 -122
  1003. package/dist/core/ids.js.map +0 -1
  1004. package/dist/core/issue.js +0 -9
  1005. package/dist/core/issue.js.map +0 -1
  1006. package/dist/core/json.js +0 -74
  1007. package/dist/core/json.js.map +0 -1
  1008. package/dist/core/likec4.js +0 -489
  1009. package/dist/core/likec4.js.map +0 -1
  1010. package/dist/core/maturity.js +0 -66
  1011. package/dist/core/maturity.js.map +0 -1
  1012. package/dist/core/openapi-merge.js +0 -552
  1013. package/dist/core/openapi-merge.js.map +0 -1
  1014. package/dist/core/openapi.js.map +0 -1
  1015. package/dist/core/openspec-inventory.js +0 -1440
  1016. package/dist/core/openspec-inventory.js.map +0 -1
  1017. package/dist/core/path-safety.js.map +0 -1
  1018. package/dist/core/provenance.js +0 -787
  1019. package/dist/core/provenance.js.map +0 -1
  1020. package/dist/core/records.js.map +0 -1
  1021. package/dist/core/repo.js +0 -438
  1022. package/dist/core/repo.js.map +0 -1
  1023. package/dist/core/report.js.map +0 -1
  1024. package/dist/core/spec.js +0 -505
  1025. package/dist/core/spec.js.map +0 -1
  1026. package/dist/core/staging.js +0 -890
  1027. package/dist/core/staging.js.map +0 -1
  1028. package/dist/core/status.js +0 -1132
  1029. package/dist/core/status.js.map +0 -1
  1030. package/dist/core/steps.js +0 -72
  1031. package/dist/core/steps.js.map +0 -1
  1032. package/dist/core/verify.js +0 -807
  1033. package/dist/core/verify.js.map +0 -1
  1034. package/dist/core/version.js.map +0 -1
  1035. /package/dist/core/{concurrency.js → kernel/concurrency.js} +0 -0
  1036. /package/dist/core/{records.js → kernel/records.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-md.js","sourceRoot":"","sources":["../../../src/core/agent/agents-md.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6JnB,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,eAAe,CAAC,YAAY,CAAC,KAAK,WAAW,EAAE,CAAC","sourcesContent":["/**\n * The small, always-loaded orientation contract for a loam docs repository.\n *\n * Detailed grammars and workflows live behind `loam instructions`: those pages\n * describe the binary that is about to run, while this file is written once and\n * may be loaded into every agent turn for years. Keep only enough here to form\n * the next question, find the relevant page, and avoid an unsafe write.\n */\nimport { agentsStampLine } from \"./agents-stamp.js\";\nimport { LOAM_VERSION } from \"../envelope/version.js\";\n\nconst ORIENTATION = `# Working in this docs repo\n\nThis is a **loam** docs repo: plain files are the shared source of truth for a governed software\nfleet's architecture, requirements, contracts and verification evidence. A service may be a modular monolith, a network service, a CLI or a worker.\nloam has no server or database. Delete it and the documents still make sense.\n\n## What is where\n\n\\`architecture/landscape.likec4\\` is the fleet map, and\n\\`architecture/adrs/\\` optional system-level decisions — only their links are graded.\n\\`services/<id>/\\` holds a boundary's living \\`model.likec4\\`, \\`spec.md\\`,\n\\`arch.spec.md\\`, OpenAPI, AsyncAPI, runbook and health facts.\n\\`features/<FEAT>/\\` holds a change in flight: \\`intent.md\\`, \\`delta.likec4\\`,\nper-service requirement and contract deltas, and \\`verification.yaml\\`.\n\\`features/archive/\\` is shipped history.\n\nLiving documents are the complete current state. A feature document is a diff\nagainst them, reviewed as a diff; \\`loam archive\\` folds it into living state.\nDo not hand-edit the living landscape to add a feature change.\n\n## Linking between documents\n\nDocuments join with **standard markdown links** whose targets are real relative\npaths, for example \\`[decision](../adrs/ADR-001.md)\\`. They render in pull-request\nreview instead of showing literal brackets,\nand make “does this link resolve” a filesystem question; \\`[[Wikilinks]]\\` would\nrequire shortest-unique-path guessing.\nObsidian supports markdown links, autocomplete and rename-tracking when its\nwikilink setting is off. \\`link.unresolved\\` grades missing targets and CASE\n**is** graded; links outside this repository, \\`#section\\` targets, a fenced code\nblock or an inline code span are deliberately not graded.\n\n## \\`loam.json\\` — the wiring\n\nEvery repository commits its own \\`loam.json\\`:\n\n\\`{ \"docsDir\": \"../docs\", \"service\": \"payment-service\", \"gherkinDir\": \"features\" }\\`\n\n\\`docsDir\\` is stored exactly as it was passed and resolved against the directory\nholding the \\`loam.json\\`, so a relative path survives a clone; an absolute one\nraises \\`doctor.docs-absolute\\`. \\`service\\` binds a service checkout to the one boundary\nit may write evidence for. \\`gherkinDir\\` is optional. \\`agentTools\\` and\n\\`agentProfile\\` record which agent surfaces and workflow subset init manages;\n\\`agentFiles\\` records digests so unchanged generated pointers can refresh while\ncustomized ones remain untouched. With no config, loam refuses with \\`no-config\\`\nrather than guessing.\n\n\\`loam init --docs <dir>\\` **joins** an existing docs repo. Add \\`--create\\` only\nwhen creating a new one; a typo must not scaffold a second source of truth.\n\n## Starting from chat\n\nThere are two equivalent entry points into the same version-matched protocol.\nPrefer the explicit one when a user wants a predictable lifecycle: invoke\n\\`/loam-feature <FEAT> \"<title>\"\\` to propose, \\`/loam-implement <FEAT> [service]\\`\nto build, \\`/loam-check\\` and \\`/loam-verify <FEAT>\\` to grade it, and\n\\`/loam-ship <FEAT>\\` to finish. Most hosts use that flat slash\nspelling; Gemini uses \\`/loam:feature\\`, Amazon Q uses \\`@loam-feature\\`, and a\nskills-only host can invoke \\`$loam-feature\\`. Natural-language requests may load\nthe matching Agent Skill instead. Once either entry point is selected, the agent\ndrives the internal status/edit/validate loop and asks the user only for a real\ndecision or human-only act; the user does not have to type every loam command.\n\nIf loam or an agent integration behaves unexpectedly, invoke \\`/loam-report\\` (or\nload \\`$loam-report\\` on a skills-only host). It collects a sanitized, reproducible\nMarkdown report under \\`loam-reports/\\` without repairing the repository, retrying a\nwriter or uploading anything. This is support, not a seventh lifecycle step.\n\n## The cycle\n\n0. **Wire the repo** — in each service checkout run\n \\`loam init --docs <path-to-docs-repo> --service <id>\\`, then \\`loam doctor\\`.\n1. **Adopt** — for an undocumented boundary load \\`loam instructions loam-adopt\n <id>\\`, then use \\`loam adopt --service <id> --json\\`. Write drafts; a person,\n never an agent, later vouches for them.\n2. **Understand** — start or resume with \\`loam status --json\\`; its ordered\n \\`next[]\\` is the work queue. Read \\`next[0].execution\\`: run it only when\n \\`runnable\\` is true; otherwise use \\`kind\\`, \\`cwd\\`, \\`needs\\` and \\`after\\`\n to complete the edit or external-repo step. Use \\`loam list --json\\`, \\`loam show <id> --json\\`\n and \\`loam explore <id> --json\\` before proposing a change. Never propose a\n change to a service you have not read.\n3. **Scaffold** — load \\`loam instructions loam-feature <FEAT>\\`, then run\n \\`loam new <FEAT> --title \"...\" --touches <service>\\`.\n4. **Author** — fill the scaffolded TODOs and run \\`loam rebase <FEAT>\\` after\n reading the living baselines. The exact joins and authoring grammars are in\n the reference pages below.\n5. **Check** — load \\`loam instructions loam-check --no-fix-tables\\`, run\n \\`loam validate <FEAT> --json\\`, and use \\`loam explain <code>\\` for reported\n codes. \\`loam dependencies --json\\` names features that must archive first.\n6. **Build** — load \\`loam instructions loam-implement <FEAT>\\`.\n \\`loam delta <FEAT> --service <id> --json\\` is one service's task; in that\n service checkout, \\`loam gherkin <FEAT>\\` emits its executable scenarios.\n7. **Verify** — \\`loam verify <FEAT> --json\\` is the checklist. Record evidence\n from each affected service's own checkout. Read\n \\`loam instructions loam-done-check\\` before recording anything.\n8. **Ship** — load \\`loam instructions loam-ship <FEAT>\\`; begin with\n \\`loam archive <FEAT> --dry-run --json\\`, then archive only after the code is\n merged and the plan is the one reviewed.\n\n## Reading loam's output\n\nEvery command takes \\`--json\\`. The envelope has \\`contractVersion\\`, \\`ok\\` and,\non refusal, \\`error.code\\`. Unknown flags are \\`invalid-option\\`; \\`--help\\` and\n\\`--version\\` pass through. Branch on stable codes, never message prose.\n\nValidation \\`findings[]\\` carry \\`severity\\`; archive-related findings also carry\n\\`gates\\`. Severity and gating are two different questions: errors invalidate,\nwhile \\`gates: true\\` makes archive refuse — archive is gated on coherence, so a\ngating finding stops it whatever its severity. Advisory warnings never block.\n\\`--approve\\` overrides the gating issues — only those that are judgement calls —\nand never a mechanical loss. For example \\`delta.requirement-not-merged\\` warns but gates;\n\\`living.requirement-outside-requirements\\` cannot be approved, while\n\\`openapi.op-modified\\` is reviewable.\n\n\\`loam status --json\\` orders executable next actions. Findings include structured\n\\`locations[]\\`; use their paths instead of extracting filenames from prose.\n\\`loam show <FEAT> --json\\` includes a \\`review\\` pack with intent, architecture,\ncontracts, dependencies, verification, blockers and the same next actions.\n\\`loam explain <code> --json\\`\nreturns one code's meaning and fix; \\`loam explain --codes --json\\` lists them.\nWhich codes an INVOCATION can raise is in \\`loam instructions loam-codes\\`.\n\n## The identity rule\n\nA service is the element whose \\`metadata { service '<id>' }\\` matches its\n\\`services/<id>/\\` directory. An exact element id is the legacy fallback. Never\ninfer identity from display names or containment. Relationships join to contracts\nthrough exact ids: OpenAPI \\`operationId\\`, requirement \\`Operations:\\`, and C4\n\\`metadata { op '...' }\\`. Consult \\`loam instructions loam-spine\\` before editing\na join.\n\n## Reference pages — fetch when needed\n\n- \\`loam instructions loam-codes\\` — finding/refusal inventory and fixes.\n- \\`loam instructions loam-spine\\` — operation, message, coverage, permission,\n capability and baseline joins.\n- \\`loam instructions loam-authoring\\` — arch requirements, generated Gherkin\n and frontmatter/vouch grammar.\n- \\`loam instructions loam-done-check\\` — verification evidence and verdicts.\n\nBare \\`loam instructions\\` lists the six workflows, the separate \\`loam-report\\`\nsupport protocol and these references. Generated agent command/skill files are\nsmall pointers to them, so the runtime page wins if an old pointer disagrees with\nthe installed binary. MCP clients can read the same pages as\n\\`loam://orientation\\` and \\`loam://instructions/<name>\\` resources.\n\n## Safety and hand-back\n\nloam's writers are journaled, but the lifecycle still matters. Do not run\n\\`loam vouch\\` for a human, do not invent evidence, do not archive before code is\nmerged, and do not edit generated files under \\`<gherkinDir>/loam/\\` by hand.\n\\`loam unarchive <FEAT>\\` is the supported undo. To abandon a feature that was\nnever archived, review it and use \\`git rm -r features/<FEAT>\\`; loam deliberately\nhas no destructive drop command.\n\nFinish by reporting remaining warnings, unverifiable claims, files or directories\nyou did not inspect, and the exact human action still owed.\n`;\n\nexport const AGENTS_MD = `${agentsStampLine(LOAM_VERSION)}\\n${ORIENTATION}`;\n"]}
@@ -72,6 +72,56 @@ export function versionTrails(stamp, binary) {
72
72
  }
73
73
  return comparePre(s.pre, b.pre) < 0;
74
74
  }
75
+ /**
76
+ * Does `stamp` name a version NEWER than the binary reading it? The mirror of
77
+ * {@link versionTrails}, and a different subject rather than its negation:
78
+ * equal versions are neither.
79
+ */
80
+ export function versionAhead(stamp, binary) {
81
+ return versionTrails(binary, stamp);
82
+ }
83
+ /**
84
+ * `docs.binary-behind` — this loam is OLDER than the loam that wrote the docs
85
+ * repo it is reading.
86
+ *
87
+ * The false-green this closes is the sharpest one in the product, because it
88
+ * inverts the meaning of a passing run rather than merely missing a defect.
89
+ * loam's whole promise is that a token spelled here must be spelled there — so
90
+ * every check is an existence constraint over a value the parser recognised.
91
+ * A binary that predates a grammar addition does not FAIL on the newer
92
+ * directive; it does not see it, produces no value, has nothing to join, and
93
+ * reports green. The corpus is checked less than it looks, and nothing anywhere
94
+ * says so. `agents.stale` is the opposite direction and explicitly declines
95
+ * this case ("that is an old binary, not a stale file") — correctly, because
96
+ * the fix is different: upgrade loam, do not edit the file.
97
+ *
98
+ * A WARNING, not an error, and the reasoning is the `sources.stale` doctrine.
99
+ * A mixed-version fleet is ordinary — one engineer's global install trails a
100
+ * release by a week — and failing every command in that repo would be a
101
+ * refusal aimed at the wrong person on the wrong day. What the message must do
102
+ * instead is say plainly that a green run from this binary is worth less than
103
+ * it appears, which no other finding says. A fleet that wants it to gate has
104
+ * `--strict`, which is exactly the lever that doctrine reserves for this.
105
+ *
106
+ * Silent when there is no file, no stamp, or the stamp is equal or older —
107
+ * every one of those is somebody else's finding.
108
+ */
109
+ export function binaryBehindFinding(text, binary) {
110
+ if (text === null)
111
+ return null;
112
+ const stamp = agentsStampVersion(text);
113
+ if (stamp === null || !versionAhead(stamp, binary))
114
+ return null;
115
+ return {
116
+ severity: "warn",
117
+ code: "docs.binary-behind",
118
+ message: `This docs repo was written by loam v${stamp}; this binary is v${binary}. A newer loam may check ` +
119
+ "joins this one cannot parse — an unrecognised directive is read as prose, so it produces no " +
120
+ "join to fail and this run reports green without having graded it. Treat a pass from this " +
121
+ `binary as incomplete rather than clean, and upgrade to v${stamp} or later (\`npm i -g @ybotok/loam\`). ` +
122
+ "Nothing here is wrong with the documents; the reader is behind them.",
123
+ };
124
+ }
75
125
  /**
76
126
  * The one finding `loam validate --all` owes the agent contract. `text` is the
77
127
  * docs repo's AGENTS.md, or null when there is none — no file means no contract
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-stamp.js","sourceRoot":"","sources":["../../../src/core/agent/agents-stamp.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The AGENTS.md version stamp: detection, never refresh.\n *\n * AGENTS.md is written once by `loam init` and never touched again — that is\n * the ownership contract (agent.ts): it is a starting point, and a team's edits\n * to it outrank ours. But the file tells agents to branch on flag and code\n * tables, and those tables describe the binary that wrote them. OpenSpec hit\n * the same wall and answered with auto-refresh, which teaches everyone the file\n * belongs to the tool after all; loam answers with the smallest honest thing —\n * a version stamp in the generated file, and one warning when the stamp is\n * missing or trails the running binary. Reviewing the file and bumping the\n * stamp is a human act, and a hand-curated file silences the warning the same\n * way: by saying, in the stamp, that someone has looked.\n */\nimport type { Finding } from \"../vocabulary/report.js\";\n\n/** The stamp `loam init` writes at the top of AGENTS.md. */\nexport function agentsStampLine(version: string): string {\n return `<!-- generated by loam v${version} -->`;\n}\n\n/** Matches a stamp line anywhere in the file; the capture is the version text. */\nconst STAMP_RE = /<!--\\s*generated by loam v(\\S+?)\\s*-->/;\n\n/**\n * The version the stamp names, or null when there is no stamp (or one whose\n * version does not read as numbers — unparseable is indistinguishable from\n * absent, and both get the same advice).\n */\nexport function agentsStampVersion(text: string): string | null {\n const m = STAMP_RE.exec(text);\n return m !== null && parseVersion(m[1]!) !== null ? m[1]! : null;\n}\n\n/** A version split the way precedence is decided: the triple, then the prerelease identifiers. */\ninterface ParsedVersion {\n release: [number, number, number];\n /**\n * The dot-separated identifiers of a `-beta.2` suffix, empty for a final\n * release. Build metadata (`+sha`) is dropped — semver excludes it from\n * precedence, and two builds of one version are the same instructions.\n */\n pre: string[];\n}\n\n/** `X.Y.Z[-pre][+build]`, or null when the leading triple does not read as numbers. */\nfunction parseVersion(v: string): ParsedVersion | null {\n const m = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/.exec(v);\n if (m === null) return null;\n return {\n release: [Number(m[1]), Number(m[2]), Number(m[3])],\n pre: m[4] === undefined ? [] : m[4].split(\".\"),\n };\n}\n\n/**\n * Semver identifier precedence: numeric identifiers compare numerically and\n * rank below alphanumeric ones, and a longer identifier list outranks a prefix\n * of itself. -1 / 0 / 1, so the caller reads like the triple comparison above.\n */\nfunction comparePre(a: string[], b: string[]): number {\n // No prerelease outranks any prerelease — `1.2.0` is newer than `1.2.0-beta.9`\n // — which is why this cannot be the plain lexicographic walk the identifiers get.\n if (a.length === 0 || b.length === 0) return a.length === b.length ? 0 : a.length === 0 ? 1 : -1;\n for (let i = 0; i < Math.min(a.length, b.length); i += 1) {\n const [x, y] = [a[i]!, b[i]!];\n if (x === y) continue;\n const [nx, ny] = [/^\\d+$/.test(x), /^\\d+$/.test(y)];\n if (nx && ny) return Number(x) < Number(y) ? -1 : 1;\n if (nx !== ny) return nx ? -1 : 1;\n return x < y ? -1 : 1;\n }\n return a.length === b.length ? 0 : a.length < b.length ? -1 : 1;\n}\n\n/**\n * Does `stamp` name an older version than `binary`? A stamp NEWER than the\n * binary does not trail: that is an old binary, not a stale file, and the fix\n * (upgrade loam) is not an AGENTS.md edit.\n *\n * Prerelease identifiers are compared, not ignored, and the difference is the\n * whole reason this check exists. Comparing the numeric triple alone made\n * `0.1.0-beta.1` and `0.1.0-beta.2` indistinguishable — and beta.2 is precisely\n * the release that changed the FORM of every generated file (embedded protocol\n * text became a pointer at `loam instructions`), with a CHANGELOG telling\n * readers to delete the files and re-run `loam init`. The one upgrade that most\n * needed the warning was the one bump shape that could not raise it. A\n * prerelease line is where a generated file's form actually moves, because that\n * is what a prerelease is for.\n */\nexport function versionTrails(stamp: string, binary: string): boolean {\n const s = parseVersion(stamp);\n const b = parseVersion(binary);\n if (s === null || b === null) return false;\n for (let i = 0; i < 3; i += 1) {\n if (s.release[i]! !== b.release[i]!) return s.release[i]! < b.release[i]!;\n }\n return comparePre(s.pre, b.pre) < 0;\n}\n\n/**\n * Does `stamp` name a version NEWER than the binary reading it? The mirror of\n * {@link versionTrails}, and a different subject rather than its negation:\n * equal versions are neither.\n */\nexport function versionAhead(stamp: string, binary: string): boolean {\n return versionTrails(binary, stamp);\n}\n\n/**\n * `docs.binary-behind` — this loam is OLDER than the loam that wrote the docs\n * repo it is reading.\n *\n * The false-green this closes is the sharpest one in the product, because it\n * inverts the meaning of a passing run rather than merely missing a defect.\n * loam's whole promise is that a token spelled here must be spelled there — so\n * every check is an existence constraint over a value the parser recognised.\n * A binary that predates a grammar addition does not FAIL on the newer\n * directive; it does not see it, produces no value, has nothing to join, and\n * reports green. The corpus is checked less than it looks, and nothing anywhere\n * says so. `agents.stale` is the opposite direction and explicitly declines\n * this case (\"that is an old binary, not a stale file\") — correctly, because\n * the fix is different: upgrade loam, do not edit the file.\n *\n * A WARNING, not an error, and the reasoning is the `sources.stale` doctrine.\n * A mixed-version fleet is ordinary — one engineer's global install trails a\n * release by a week — and failing every command in that repo would be a\n * refusal aimed at the wrong person on the wrong day. What the message must do\n * instead is say plainly that a green run from this binary is worth less than\n * it appears, which no other finding says. A fleet that wants it to gate has\n * `--strict`, which is exactly the lever that doctrine reserves for this.\n *\n * Silent when there is no file, no stamp, or the stamp is equal or older —\n * every one of those is somebody else's finding.\n */\nexport function binaryBehindFinding(text: string | null, binary: string): Finding | null {\n if (text === null) return null;\n const stamp = agentsStampVersion(text);\n if (stamp === null || !versionAhead(stamp, binary)) return null;\n return {\n severity: \"warn\",\n code: \"docs.binary-behind\",\n message:\n `This docs repo was written by loam v${stamp}; this binary is v${binary}. A newer loam may check ` +\n \"joins this one cannot parse — an unrecognised directive is read as prose, so it produces no \" +\n \"join to fail and this run reports green without having graded it. Treat a pass from this \" +\n `binary as incomplete rather than clean, and upgrade to v${stamp} or later (\\`npm i -g @ybotok/loam\\`). ` +\n \"Nothing here is wrong with the documents; the reader is behind them.\",\n };\n}\n\n/**\n * The one finding `loam validate --all` owes the agent contract. `text` is the\n * docs repo's AGENTS.md, or null when there is none — no file means no contract\n * to have drifted, and this check stays silent rather than inventing a second\n * meaning for its code. Returns null when the stamp is current (or newer).\n */\nexport function agentsStaleFinding(text: string | null, binary: string): Finding | null {\n if (text === null) return null;\n const stamp = agentsStampVersion(text);\n if (stamp === null) {\n return {\n severity: \"warn\",\n code: \"agents.stale\",\n message:\n \"AGENTS.md has no version stamp — it predates stamping or was hand-created, so nothing says \" +\n \"which loam its flag and code tables describe. Review it against the current `loam --help`, \" +\n `then add \\`${agentsStampLine(binary)}\\` near the top; a hand-curated file keeps the warning ` +\n \"off the same way, by keeping the stamp current.\",\n };\n }\n if (!versionTrails(stamp, binary)) return null;\n return {\n severity: \"warn\",\n code: \"agents.stale\",\n message:\n `AGENTS.md was written by loam v${stamp}; this binary is v${binary} — the flag and code tables ` +\n \"agents branch on may have moved. Review the file against the current `loam --help`, then \" +\n `update the stamp line to v${binary} (a hand-curated file silences this by bumping the stamp itself).`,\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../src/core/agent/contract.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * The shapes of the agent contract: what a workflow protocol is made of and\n * what a per-tool delivery adds around it. Types only, deliberately — a leaf\n * module the rest of the package `import type`s from. scripts/package-graph.mjs\n * counts only value imports, so keeping this file value-free is what lets\n * workflows/ and tools/ depend on the shapes without a package edge back into\n * the agent root, and what keeps that graph acyclic.\n */\n/**\n * One slash command, format-free. `body` is the whole protocol — the per-tool\n * emitters in AGENT_TOOLS add only a path and a wrapper (frontmatter fields, a\n * TOML shell), never their own prose: one source of truth, thin spellings.\n * Bodies keep Claude's positional `$1`/`$2` placeholder convention across\n * every tool — dialects differ (Gemini's {{args}}, Copilot's ${input}) and rewriting the\n * text per tool would be a second copy of the protocol in all but name; an\n * agent reading the file still sees which argument goes where.\n */\n/**\n * What a protocol's positional placeholder denotes. `free` is the one that\n * cannot be checked — `loam-feature`'s `$2` is a human title, and any string is\n * a legal one — and it is spelled rather than left implicit so a new\n * placeholder has to state which of the three it is.\n */\nexport type PlaceholderKind = \"service\" | \"feature\" | \"free\";\n\nexport interface CommandContent {\n /** Stable command name (`loam-check`) — also the flat file name everywhere. */\n name: string;\n description: string;\n /** What the user passes, in Claude's `argument-hint` spelling. */\n argumentHint: string;\n /** One or two sentences: what this workflow is for, and who does which half. */\n purpose: string;\n /**\n * The literal `loam instructions …` line the generated file tells an agent to\n * run, placeholders and all. Spelled per command rather than derived from\n * `argumentHint`, because the mapping from a hint to positional arguments is\n * exactly the kind of clever derivation that is right five times and wrong\n * once — and the once is a command an agent pastes.\n */\n invocation: string;\n /**\n * What `$1`, `$2`, … stand for in `body`, in order — so the substitution can\n * be checked instead of merely performed.\n *\n * `loam instructions loam-adopt \"$PWD\"` used to render a protocol reading\n * `services//Users/someone/work/svc/` and `--service /Users/someone/…`: the\n * placeholder is a service id, the value was an absolute path, and nothing\n * between the shell and the printed page knew the difference. The commands\n * downstream all refuse it — `assertServiceId` is one rule in one place, and\n * it says so well — so a bad brief could never become bad documentation. But\n * the refusal arrives one step late, after an agent has read a page of\n * confident instructions built around a value that cannot work, and the\n * cheapest place to say \"that is not a service id\" is the command that was\n * told the argument IS one.\n */\n placeholders: readonly PlaceholderKind[];\n /**\n * The verbs, in order, and nothing else. This is the half of the protocol\n * that does not move between releases: a reader with a stale file can still\n * tell whether a run went sideways, without the file claiming to know this\n * binary's flags or finding codes.\n */\n spine: string[];\n /** The protocol itself: markdown, ends with a newline. */\n body: string;\n}\n\n/**\n * One delivery of one command: where the file goes, and what goes in it. Both\n * halves are thin by construction — the protocol is `CommandContent.body` and\n * nothing here may restate it.\n */\nexport interface AgentFileEmitter {\n /** Repo-relative path segments of the file. */\n path(name: string): string[];\n /** The full file: this tool's wrapper around the shared body. */\n format(cmd: CommandContent): string;\n}\n\n/**\n * A tool the commands can be emitted for — the registry key is the `--tools`\n * id (OpenSpec's ids where the tool has one there). A path and a wrapper are\n * the WHOLE adapter: OpenSpec's per-tool command layer, minus everything loam\n * refuses on principle — no version stamps in command files, no\n * overwrite-on-update, no managed marker blocks in anyone else's file. Paths\n * and wrappers follow each tool's own documented convention, pinned in\n * test/agents.test.ts.\n */\nexport interface AgentTool {\n /**\n * Repo-relative path segments of one command's file. Absent — together with\n * `format` — for a tool that registers no command files at all: Codex reads\n * skills and nothing else, and inventing a command directory for it would\n * scatter files no agent ever loads.\n */\n path?(name: string): string[];\n /** The full command file: this tool's wrapper around the shared body. */\n format?(cmd: CommandContent): string;\n /** The skill delivery. Absent for a tool with no skills convention. */\n skill?: AgentFileEmitter;\n /**\n * Repo-relative paths whose presence means this tool is in use here — what\n * `loam init` scans when no `--tools` says otherwise. Usually just the tool's\n * own dot-directory; spelled per tool because the exceptions matter more than\n * the rule (see `github-copilot`, whose `.github/` says nothing at all).\n */\n detect: string[];\n}\n"]}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * The protocol surface: six lifecycle workflows, the support protocol and the
3
+ * reference pages — what `loam instructions` prints (commands/instructions.ts)
4
+ * and the corpus every check over loam's agent-facing prose reads
5
+ * (test/codes-drift.test.ts, test/agent-contract.test.ts,
6
+ * test/agent-commands-runnable.test.ts).
7
+ */
8
+ import { featureIdProblem } from "../kernel/ids/feature.js";
9
+ import { serviceIdProblem } from "../kernel/ids/service.js";
10
+ import { LOAM_ADOPT } from "./workflows/adopt.js";
11
+ import { LOAM_CHECK } from "./workflows/check.js";
12
+ import { LOAM_VERIFY, LOAM_SHIP } from "./workflows/closing.js";
13
+ import { LOAM_FEATURE } from "./workflows/feature.js";
14
+ import { LOAM_IMPLEMENT } from "./workflows/implement.js";
15
+ import { REFERENCES } from "./workflows/reference/reference.js";
16
+ import { LOAM_REPORT } from "./support/report.js";
17
+ /**
18
+ * The six protocols, in cycle order. One assembly, exported: scaffold.ts
19
+ * derives the generated files through this same list, so what
20
+ * `loam instructions` prints and what a fresh scaffold writes cannot drift
21
+ * apart.
22
+ */
23
+ export const COMMANDS = [
24
+ LOAM_ADOPT,
25
+ LOAM_FEATURE,
26
+ LOAM_IMPLEMENT,
27
+ LOAM_CHECK,
28
+ LOAM_VERIFY,
29
+ LOAM_SHIP,
30
+ ];
31
+ /**
32
+ * Support entry points generated beside the lifecycle, but not counted as
33
+ * lifecycle steps. Reporting a bad run must be discoverable in every profile;
34
+ * placing it in COMMANDS would make a consumer iterating that list try to run
35
+ * incident collection after every feature.
36
+ */
37
+ export const SUPPORT = [LOAM_REPORT];
38
+ /** Every command/skill file init generates, regardless of category. */
39
+ export const AGENT_COMMANDS = [...COMMANDS, ...SUPPORT];
40
+ /**
41
+ * Everything `loam instructions <name>` can print: the six workflows, support
42
+ * protocol and four reference pages, in that order.
43
+ *
44
+ * The pages join the generated protocols HERE and nowhere else — not in
45
+ * {@link AGENT_COMMANDS}, which is what scaffold.ts derives `SLASH_COMMANDS`
46
+ * and `plannedCommandFiles` from. That is the whole mechanism, and the
47
+ * asymmetry is the point: a page is printable by name but `loam init` writes no
48
+ * file for it, so moving 44 KB out of AGENTS.md did not put 44 KB back as four
49
+ * new artifacts in every repository loam touches. The support protocol does
50
+ * belong in AGENT_COMMANDS because discovery is its purpose, while its separate
51
+ * menu category keeps it out of the lifecycle. test/agents.test.ts asserts the
52
+ * reference-page halves separately, because a future edit can break either
53
+ * alone.
54
+ */
55
+ const PRINTABLE = [...AGENT_COMMANDS, ...REFERENCES];
56
+ /**
57
+ * The printable bodies, keyed by name — what `loam instructions <name>` prints,
58
+ * and the corpus every check over loam's agent-facing prose reads.
59
+ *
60
+ * Separate from SLASH_COMMANDS since the file became a pointer: the protocol is
61
+ * still the thing that must document every stable code (`codes-drift`) and
62
+ * every `loam …` line it teaches must still parse against the real CLI
63
+ * (`agent-commands-runnable`). Those two properties are about the INSTRUCTIONS,
64
+ * and they did not move just because the delivery did.
65
+ *
66
+ * The reference pages belong in this record for exactly that reason. Every code
67
+ * they carry LEFT AGENTS.md to get here, and `codes-drift` reads
68
+ * `AGENTS_MD + PROTOCOLS` — so the guard stays green by construction, because
69
+ * the codes moved from one half of that corpus into the other. If it goes red
70
+ * after a change here, something was deleted rather than moved.
71
+ */
72
+ export const PROTOCOLS = Object.fromEntries(PRINTABLE.map((c) => [c.name, c.body]));
73
+ /**
74
+ * What each page's `$1`, `$2`, … denote — see {@link CommandContent.placeholders}.
75
+ * A reference page declares `[]`, which is not a formality: `placeholderProblems`
76
+ * keys off this record, and a name absent from it is treated as unknown rather
77
+ * than as taking no arguments.
78
+ */
79
+ export const PLACEHOLDERS = Object.fromEntries(PRINTABLE.map((c) => [c.name, c.placeholders]));
80
+ /**
81
+ * Whether nothing was supplied for this position — the two shapes an absent
82
+ * argument actually arrives in, in one place because both call sites below owe
83
+ * the same answer.
84
+ *
85
+ * The first is empty; {@link protocolFor} says which dialects send that. The
86
+ * second is the placeholder ITSELF, arriving as data. One body serves twenty
87
+ * tool dialects (tools/registry.ts) and keeps Claude's positional `$1`/`$2`
88
+ * convention in all of them (see {@link CommandContent}), so every generated
89
+ * stub carries the spelling verbatim: `.gemini/commands/loam/adopt.toml`
90
+ * contains the literal line `loam instructions loam-adopt $1`. Gemini's own
91
+ * convention is `{{args}}` and Copilot's is `${input:…}`, and Cline, Kilo Code
92
+ * and Roo Code substitute nothing whatever — so on those three the `$1` reaches
93
+ * this command exactly as written, and loam refused the literal first
94
+ * instruction of its own workflow with `invalid-option`. (Unquoted in a POSIX
95
+ * shell the same line degrades the other way: `$1` expands to empty, and the
96
+ * agent receives a protocol addressed to nobody.) The same class already cost
97
+ * `loam-check` its placeholder — see the comment in workflows/check.ts; this is
98
+ * the general fix, made once in the RECEIVING command rather than per dialect.
99
+ *
100
+ * Scoped to `^\$[1-9]$` and no wider. `{{args}}` and `${input:…}` are
101
+ * deliberately NOT matched: the tools that spell placeholders that way
102
+ * substitute them before an agent ever reads the file, so they cannot arrive
103
+ * here, and loam emits neither. A value that merely CONTAINS a placeholder
104
+ * (`FEAT-$1`) is a real argument and is still checked as one.
105
+ */
106
+ const unsupplied = (arg) => arg === undefined || arg === "" || /^\$[1-9]$/.test(arg);
107
+ /**
108
+ * Why the arguments given to `name` cannot be substituted into its protocol, or
109
+ * null when they can. One sentence per bad argument, already naming the
110
+ * placeholder it was meant to fill.
111
+ *
112
+ * The grammars are `core/kernel/ids/`'s, never a second copy: a value this accepts
113
+ * and `loam adopt` refuses would be worse than no check, because the protocol
114
+ * would still be wrong and now something had approved it. An argument nobody
115
+ * supplied is not an error — `protocolFor` leaves that placeholder standing on
116
+ * purpose, so the page reads as "the service id goes here" — and by
117
+ * {@link unsupplied} that covers the placeholder text arriving as the argument,
118
+ * which is what an untouched generated stub sends.
119
+ */
120
+ export function placeholderProblems(name, args) {
121
+ const kinds = PLACEHOLDERS[name];
122
+ if (kinds === undefined)
123
+ return null;
124
+ const problems = kinds.flatMap((kind, i) => {
125
+ const arg = args[i];
126
+ // The `undefined` arm is `unsupplied`'s own; it is repeated here because
127
+ // that is what narrows `arg` to a string for the id grammars below.
128
+ if (arg === undefined || unsupplied(arg) || kind === "free")
129
+ return [];
130
+ const problem = kind === "service"
131
+ ? serviceIdProblem(arg, `$${i + 1}`)
132
+ : featureIdProblem(arg, `feature id ($${i + 1})`);
133
+ return problem === null ? [] : [problem];
134
+ });
135
+ return problems.length === 0 ? null : problems;
136
+ }
137
+ const row = ({ name, description, argumentHint }) => ({ name, description, argumentHint });
138
+ /** The workflow names, in cycle order — `loam instructions` with no argument lists these. */
139
+ export const WORKFLOWS = COMMANDS.map(row);
140
+ /** Support protocols, listed separately so no caller mistakes one for a lifecycle step. */
141
+ export const SUPPORT_PAGES = SUPPORT.map(row);
142
+ /**
143
+ * The reference-page names, listed by the same bare `loam instructions` and
144
+ * kept a SEPARATE list rather than appended to {@link WORKFLOWS}.
145
+ *
146
+ * A page is not a workflow: it has no steps, it is not part of the cycle, and
147
+ * running one is not doing anything. A menu that ran the ten together would
148
+ * read as a ten-step process, which is the one thing the six-step cycle must
149
+ * not be confused with — so the command prints them under their own heading
150
+ * (commands/instructions.ts) and test/instructions.test.ts pins that they stay
151
+ * apart.
152
+ */
153
+ export const REFERENCE_PAGES = REFERENCES.map(row);
154
+ /**
155
+ * One workflow's protocol with `$1`, `$2`, … replaced by the arguments given.
156
+ *
157
+ * An unsupplied placeholder is LEFT STANDING rather than blanked: the bodies
158
+ * are written so `$1` reads as "the feature id goes here", and a protocol that
159
+ * silently dropped it would hand an agent `loam validate --feature --json` — a
160
+ * command that parses, runs, and answers a different question. Extra arguments
161
+ * are ignored for the same reason: this substitutes, it does not validate.
162
+ *
163
+ * "Unsupplied" is {@link unsupplied}'s two shapes, not merely a missing
164
+ * element, and neither is pedantry — they are the two things a tool actually
165
+ * sends. An EMPTY argument is the first: several dialects expand an absent
166
+ * positional to the empty string, and `loam-feature`'s own invocation quotes
167
+ * its second one (`--title "$2"`), so `/loam-feature FEAT-101` with no title
168
+ * arrives here as `["FEAT-101", ""]`. Blanking it produced
169
+ * `loam new FEAT-101 --title ""` — which is exactly the failure the paragraph
170
+ * above describes, reached by the one path that paragraph did not cover: the
171
+ * command succeeds, and writes a feature whose title is the empty string and
172
+ * whose intent.md opens with a bare `#`.
173
+ *
174
+ * The LITERAL PLACEHOLDER is the second: the dialects that substitute nothing
175
+ * hand this command the `$1` their generated stub was written with, so
176
+ * `loam instructions loam-adopt $1` renders the same page as
177
+ * `loam instructions loam-adopt` — the placeholder standing, the protocol
178
+ * printed. Here the shape mostly falls out anyway (planting `$1` where `$1`
179
+ * stood is a no-op); it is spelled all the same, because a MISNUMBERED one
180
+ * would not be — `$3` given for `$1` would renumber the placeholder in the
181
+ * printed page — and because the check above and this render have to agree on
182
+ * one definition or a value can pass one and be rewritten by the other.
183
+ */
184
+ export function protocolFor(name, args = []) {
185
+ const body = PROTOCOLS[name];
186
+ if (body === undefined)
187
+ return null;
188
+ return body.replace(/\$([1-9])/g, (whole, digit) => {
189
+ const arg = args[Number(digit) - 1];
190
+ return arg === undefined || unsupplied(arg) ? whole : arg;
191
+ });
192
+ }
193
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/core/agent/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The protocol surface: six lifecycle workflows, the support protocol and the\n * reference pages — what `loam instructions` prints (commands/instructions.ts)\n * and the corpus every check over loam's agent-facing prose reads\n * (test/codes-drift.test.ts, test/agent-contract.test.ts,\n * test/agent-commands-runnable.test.ts).\n */\nimport { featureIdProblem } from \"../kernel/ids/feature.js\";\nimport { serviceIdProblem } from \"../kernel/ids/service.js\";\nimport type { CommandContent, PlaceholderKind } from \"./contract.js\";\nimport { LOAM_ADOPT } from \"./workflows/adopt.js\";\nimport { LOAM_CHECK } from \"./workflows/check.js\";\nimport { LOAM_VERIFY, LOAM_SHIP } from \"./workflows/closing.js\";\nimport { LOAM_FEATURE } from \"./workflows/feature.js\";\nimport { LOAM_IMPLEMENT } from \"./workflows/implement.js\";\nimport { REFERENCES } from \"./workflows/reference/reference.js\";\nimport { LOAM_REPORT } from \"./support/report.js\";\n\n/**\n * The six protocols, in cycle order. One assembly, exported: scaffold.ts\n * derives the generated files through this same list, so what\n * `loam instructions` prints and what a fresh scaffold writes cannot drift\n * apart.\n */\nexport const COMMANDS: CommandContent[] = [\n LOAM_ADOPT,\n LOAM_FEATURE,\n LOAM_IMPLEMENT,\n LOAM_CHECK,\n LOAM_VERIFY,\n LOAM_SHIP,\n];\n\n/**\n * Support entry points generated beside the lifecycle, but not counted as\n * lifecycle steps. Reporting a bad run must be discoverable in every profile;\n * placing it in COMMANDS would make a consumer iterating that list try to run\n * incident collection after every feature.\n */\nexport const SUPPORT: CommandContent[] = [LOAM_REPORT];\n\n/** Every command/skill file init generates, regardless of category. */\nexport const AGENT_COMMANDS: CommandContent[] = [...COMMANDS, ...SUPPORT];\n\n/**\n * Everything `loam instructions <name>` can print: the six workflows, support\n * protocol and four reference pages, in that order.\n *\n * The pages join the generated protocols HERE and nowhere else — not in\n * {@link AGENT_COMMANDS}, which is what scaffold.ts derives `SLASH_COMMANDS`\n * and `plannedCommandFiles` from. That is the whole mechanism, and the\n * asymmetry is the point: a page is printable by name but `loam init` writes no\n * file for it, so moving 44 KB out of AGENTS.md did not put 44 KB back as four\n * new artifacts in every repository loam touches. The support protocol does\n * belong in AGENT_COMMANDS because discovery is its purpose, while its separate\n * menu category keeps it out of the lifecycle. test/agents.test.ts asserts the\n * reference-page halves separately, because a future edit can break either\n * alone.\n */\nconst PRINTABLE: CommandContent[] = [...AGENT_COMMANDS, ...REFERENCES];\n\n/**\n * The printable bodies, keyed by name — what `loam instructions <name>` prints,\n * and the corpus every check over loam's agent-facing prose reads.\n *\n * Separate from SLASH_COMMANDS since the file became a pointer: the protocol is\n * still the thing that must document every stable code (`codes-drift`) and\n * every `loam …` line it teaches must still parse against the real CLI\n * (`agent-commands-runnable`). Those two properties are about the INSTRUCTIONS,\n * and they did not move just because the delivery did.\n *\n * The reference pages belong in this record for exactly that reason. Every code\n * they carry LEFT AGENTS.md to get here, and `codes-drift` reads\n * `AGENTS_MD + PROTOCOLS` — so the guard stays green by construction, because\n * the codes moved from one half of that corpus into the other. If it goes red\n * after a change here, something was deleted rather than moved.\n */\nexport const PROTOCOLS: Record<string, string> = Object.fromEntries(\n PRINTABLE.map((c) => [c.name, c.body]),\n);\n\n/**\n * What each page's `$1`, `$2`, … denote — see {@link CommandContent.placeholders}.\n * A reference page declares `[]`, which is not a formality: `placeholderProblems`\n * keys off this record, and a name absent from it is treated as unknown rather\n * than as taking no arguments.\n */\nexport const PLACEHOLDERS: Record<string, readonly PlaceholderKind[]> = Object.fromEntries(\n PRINTABLE.map((c) => [c.name, c.placeholders]),\n);\n\n/**\n * Whether nothing was supplied for this position — the two shapes an absent\n * argument actually arrives in, in one place because both call sites below owe\n * the same answer.\n *\n * The first is empty; {@link protocolFor} says which dialects send that. The\n * second is the placeholder ITSELF, arriving as data. One body serves twenty\n * tool dialects (tools/registry.ts) and keeps Claude's positional `$1`/`$2`\n * convention in all of them (see {@link CommandContent}), so every generated\n * stub carries the spelling verbatim: `.gemini/commands/loam/adopt.toml`\n * contains the literal line `loam instructions loam-adopt $1`. Gemini's own\n * convention is `{{args}}` and Copilot's is `${input:…}`, and Cline, Kilo Code\n * and Roo Code substitute nothing whatever — so on those three the `$1` reaches\n * this command exactly as written, and loam refused the literal first\n * instruction of its own workflow with `invalid-option`. (Unquoted in a POSIX\n * shell the same line degrades the other way: `$1` expands to empty, and the\n * agent receives a protocol addressed to nobody.) The same class already cost\n * `loam-check` its placeholder — see the comment in workflows/check.ts; this is\n * the general fix, made once in the RECEIVING command rather than per dialect.\n *\n * Scoped to `^\\$[1-9]$` and no wider. `{{args}}` and `${input:…}` are\n * deliberately NOT matched: the tools that spell placeholders that way\n * substitute them before an agent ever reads the file, so they cannot arrive\n * here, and loam emits neither. A value that merely CONTAINS a placeholder\n * (`FEAT-$1`) is a real argument and is still checked as one.\n */\nconst unsupplied = (arg: string | undefined): boolean =>\n arg === undefined || arg === \"\" || /^\\$[1-9]$/.test(arg);\n\n/**\n * Why the arguments given to `name` cannot be substituted into its protocol, or\n * null when they can. One sentence per bad argument, already naming the\n * placeholder it was meant to fill.\n *\n * The grammars are `core/kernel/ids/`'s, never a second copy: a value this accepts\n * and `loam adopt` refuses would be worse than no check, because the protocol\n * would still be wrong and now something had approved it. An argument nobody\n * supplied is not an error — `protocolFor` leaves that placeholder standing on\n * purpose, so the page reads as \"the service id goes here\" — and by\n * {@link unsupplied} that covers the placeholder text arriving as the argument,\n * which is what an untouched generated stub sends.\n */\nexport function placeholderProblems(name: string, args: readonly string[]): string[] | null {\n const kinds = PLACEHOLDERS[name];\n if (kinds === undefined) return null;\n const problems = kinds.flatMap((kind, i) => {\n const arg = args[i];\n // The `undefined` arm is `unsupplied`'s own; it is repeated here because\n // that is what narrows `arg` to a string for the id grammars below.\n if (arg === undefined || unsupplied(arg) || kind === \"free\") return [];\n const problem = kind === \"service\"\n ? serviceIdProblem(arg, `$${i + 1}`)\n : featureIdProblem(arg, `feature id ($${i + 1})`);\n return problem === null ? [] : [problem];\n });\n return problems.length === 0 ? null : problems;\n}\n\n/** One row of the `loam instructions` menu: enough to choose, and nothing more. */\ntype MenuRow = Pick<CommandContent, \"name\" | \"description\" | \"argumentHint\">;\n\nconst row = ({ name, description, argumentHint }: CommandContent): MenuRow =>\n ({ name, description, argumentHint });\n\n/** The workflow names, in cycle order — `loam instructions` with no argument lists these. */\nexport const WORKFLOWS: readonly MenuRow[] = COMMANDS.map(row);\n\n/** Support protocols, listed separately so no caller mistakes one for a lifecycle step. */\nexport const SUPPORT_PAGES: readonly MenuRow[] = SUPPORT.map(row);\n\n/**\n * The reference-page names, listed by the same bare `loam instructions` and\n * kept a SEPARATE list rather than appended to {@link WORKFLOWS}.\n *\n * A page is not a workflow: it has no steps, it is not part of the cycle, and\n * running one is not doing anything. A menu that ran the ten together would\n * read as a ten-step process, which is the one thing the six-step cycle must\n * not be confused with — so the command prints them under their own heading\n * (commands/instructions.ts) and test/instructions.test.ts pins that they stay\n * apart.\n */\nexport const REFERENCE_PAGES: readonly MenuRow[] = REFERENCES.map(row);\n\n/**\n * One workflow's protocol with `$1`, `$2`, … replaced by the arguments given.\n *\n * An unsupplied placeholder is LEFT STANDING rather than blanked: the bodies\n * are written so `$1` reads as \"the feature id goes here\", and a protocol that\n * silently dropped it would hand an agent `loam validate --feature --json` — a\n * command that parses, runs, and answers a different question. Extra arguments\n * are ignored for the same reason: this substitutes, it does not validate.\n *\n * \"Unsupplied\" is {@link unsupplied}'s two shapes, not merely a missing\n * element, and neither is pedantry — they are the two things a tool actually\n * sends. An EMPTY argument is the first: several dialects expand an absent\n * positional to the empty string, and `loam-feature`'s own invocation quotes\n * its second one (`--title \"$2\"`), so `/loam-feature FEAT-101` with no title\n * arrives here as `[\"FEAT-101\", \"\"]`. Blanking it produced\n * `loam new FEAT-101 --title \"\"` — which is exactly the failure the paragraph\n * above describes, reached by the one path that paragraph did not cover: the\n * command succeeds, and writes a feature whose title is the empty string and\n * whose intent.md opens with a bare `#`.\n *\n * The LITERAL PLACEHOLDER is the second: the dialects that substitute nothing\n * hand this command the `$1` their generated stub was written with, so\n * `loam instructions loam-adopt $1` renders the same page as\n * `loam instructions loam-adopt` — the placeholder standing, the protocol\n * printed. Here the shape mostly falls out anyway (planting `$1` where `$1`\n * stood is a no-op); it is spelled all the same, because a MISNUMBERED one\n * would not be — `$3` given for `$1` would renumber the placeholder in the\n * printed page — and because the check above and this render have to agree on\n * one definition or a value can pass one and be rewritten by the other.\n */\nexport function protocolFor(name: string, args: readonly string[] = []): string | null {\n const body = PROTOCOLS[name];\n if (body === undefined) return null;\n return body.replace(/\\$([1-9])/g, (whole, digit: string) => {\n const arg = args[Number(digit) - 1];\n return arg === undefined || unsupplied(arg) ? whole : arg;\n });\n}\n"]}
@@ -0,0 +1,259 @@
1
+ /**
2
+ * The generated FILES: what a pointer file contains (the stub), what this
3
+ * binary would write (SLASH_COMMANDS, plannedCommandFiles), and how the files
4
+ * land and are detected on disk.
5
+ *
6
+ * The command and skill files go into the repo `init` runs in, because that is
7
+ * where the agent is invoked — for whichever tools the repo shows signs of, via
8
+ * the AGENT_TOOLS registry (tools/registry.ts): one shared body, a per-tool
9
+ * path and wrapper. A delivery is refreshed only while its bytes still match
10
+ * the digest loam recorded when it wrote them; a team's edits revoke that
11
+ * authority and outrank ours.
12
+ *
13
+ * Two deliveries, one body. A slash command has to be TYPED, so it only ever
14
+ * reaches an agent whose operator already knows loam exists. A skill is loaded
15
+ * by the model itself when the task matches its `description`, which is how the
16
+ * protocol reaches an agent that was never told about it. That difference is
17
+ * the whole reason both are written by default.
18
+ *
19
+ * The per-tool command and skill files carry the same version stamp AGENTS.md
20
+ * does (agents-md.ts), for the same reason and with the same answer:
21
+ * `loam doctor` reports `doctor.agent-files-stale` without writing. A later
22
+ * `loam init` can refresh only a digest-matched pointer. Without the stamp,
23
+ * absence was the only drift doctor could see — a command file mangled to one
24
+ * line left it saying `healthy: true`, which across a hundred repositories is
25
+ * invisible rot with no repair path.
26
+ */
27
+ import { createHash } from "node:crypto";
28
+ import { existsSync } from "node:fs";
29
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
30
+ import { dirname, join, relative } from "node:path";
31
+ import { agentsStampLine } from "./agents-stamp.js";
32
+ import { LOAM_VERSION } from "../envelope/version.js";
33
+ import { AGENT_COMMANDS } from "./protocol.js";
34
+ import { AGENT_TOOLS, CLAUDE } from "./tools/registry.js";
35
+ /**
36
+ * What a generated file actually contains: the purpose, the spine, and the
37
+ * command that prints the rest.
38
+ *
39
+ * The protocol itself stays in `body` and ships inside the binary, reachable as
40
+ * `loam instructions <name>`. The file on disk gets a pointer to it, because
41
+ * these two things go stale in opposite directions and only one of them can be
42
+ * fixed. A generated file is refreshed only while its bytes still match the
43
+ * digest loam recorded; any edit revokes that authority because your edits
44
+ * outrank the template. Without that distinction a repo scaffolded a year ago
45
+ * holds a year-old protocol: exact
46
+ * flags, exact finding codes, exact step order, all of it asserted with total
47
+ * confidence by a file whose reader has no way to know it is describing a
48
+ * different release. That is not a hypothetical failure mode. It is the one
49
+ * every project shipping generated agent instructions has had, and the fix
50
+ * everybody reaches for — regenerate on upgrade — trades it for silently
51
+ * overwriting what a human wrote.
52
+ *
53
+ * Thinning the file is the third option. What remains is what does not move
54
+ * between releases: what this workflow is for, and the verbs in order. What
55
+ * leaves is everything version-shaped. `doctor.agent-files-stale` still reports
56
+ * a file whose stamp has fallen behind, and now has almost nothing to be right
57
+ * about — which is the point.
58
+ *
59
+ * The trade is real and worth stating: an agent that cannot execute `loam` now
60
+ * has a spine instead of a protocol. That is the correct failure. The exact
61
+ * diagnostic and lifecycle invocations belong to the binary-owned page; an
62
+ * agent that cannot run loam cannot finish either kind from an embedded copy —
63
+ * it can only try using a year-old flag.
64
+ *
65
+ * The last clause of the pointer is the one sentence here that changes what an
66
+ * agent DOES rather than what it knows. `loam instructions loam-check` prints
67
+ * 84 KB — about a fifth of a 100k-token window, 223 fix-table rows of which a
68
+ * run needs two or three — and every file written from this stub opens by
69
+ * telling the agent to run it. `--no-fix-tables` (commands/instructions.ts)
70
+ * drops the rows, and `loam explain <code>` answers the one row the run turned
71
+ * out to need in under 500 bytes. The flag is what makes the lazy path payable;
72
+ * this sentence is what makes an agent take it.
73
+ */
74
+ function stubBody(c) {
75
+ const steps = c.spine.map((s, i) => ` ${i + 1}. ${s}`).join("\n");
76
+ const entry = c.name === "loam-report"
77
+ ? `This support protocol has two equivalent chat entry points: the explicit command a
78
+ user chooses, and the Agent Skill an unexpected-run request may load. Both reach
79
+ the same local, sanitized report; the agent owns the diagnostic steps.`
80
+ : `This workflow has two equivalent chat entry points: the explicit command a user
81
+ chooses, and the Agent Skill a natural-language request may load. Both reach this
82
+ same body and must produce the same status/edit/validate loop; do not make the
83
+ user type the internal loam commands one by one.`;
84
+ const output = c.name === "loam-report"
85
+ ? `The runtime protocol decides which diagnostics are safe to run and what may enter the
86
+ report. Do not infer permission to retry a writer, repair files or send the result
87
+ from the broader lifecycle commands another generated skill may allow.`
88
+ : `Every step above is a \`loam\` invocation, and each command's own \`--json\` output
89
+ carries what to do next: findings have stable codes, and \`loam status --json\` puts
90
+ the ordered \`next[]\` — each entry a code and the literal command — in one place.
91
+ Branch on the codes, never on the prose. The check workflow starts with
92
+ \`--no-fix-tables\`; use \`loam explain <code>\` for each code the run actually
93
+ reports, and remove that flag only when you deliberately need the complete table.`;
94
+ return `${c.purpose}
95
+
96
+ ${entry}
97
+
98
+ **Run this first.** It is the protocol, and it ships with the binary you are about
99
+ to call — so it names this loam's flags, its finding codes and its fix tables,
100
+ not the ones that were current when this repository was scaffolded:
101
+
102
+ ${c.invocation}
103
+
104
+ The spine it fills in, so you can tell a run that went sideways from one that did not:
105
+
106
+ ${steps}
107
+
108
+ ${output}
109
+
110
+ This file is a pointer, not the protocol. loam may refresh it while its bytes still
111
+ match the digest recorded in loam.json. Editing it revokes that authority: your
112
+ changes outrank the template and stay untouched. Where this file and
113
+ \`loam instructions\` disagree, the command is right.
114
+ `;
115
+ }
116
+ /**
117
+ * The command body a file actually gets: the pointer, under the same version
118
+ * stamp AGENTS.md carries.
119
+ *
120
+ * The stamp is applied once, here, rather than in twenty wrappers — it is a
121
+ * fact about loam, not about a tool's dialect, and a per-wrapper copy is twenty
122
+ * chances to forget it. It rides at the top of the BODY (not the file) because
123
+ * every dialect puts something of its own first: YAML frontmatter, a TOML key,
124
+ * a title line. An HTML comment is invisible in all of them, and
125
+ * `agentsStampVersion` matches it wherever in the file it lands.
126
+ *
127
+ * A repo initialized before stamping existed has unstamped files, which is
128
+ * exactly what `doctor.agent-files-stale` is for: nobody has confirmed that
129
+ * those instructions still describe this binary.
130
+ */
131
+ const stubbed = (c) => ({
132
+ ...c,
133
+ body: `${agentsStampLine(LOAM_VERSION)}\n\n${stubBody(c)}`,
134
+ });
135
+ /**
136
+ * The Claude-format files, keyed by command name: exactly what **this** binary
137
+ * would write, derived through the same adapter that writes them, so the export
138
+ * and a freshly scaffolded repo can never disagree.
139
+ *
140
+ * Read that scope literally. It used to be described as the on-disk contract of
141
+ * every repo initialized before `--tools` existed, and that is no longer true
142
+ * of anything but a fresh scaffold: a file holds the STUB now, every repo
143
+ * scaffolded before that holds the full protocol. A recorded, byte-identical
144
+ * pointer can refresh; an older unrecorded file or any customized file cannot,
145
+ * so an export cannot describe files this binary did not write.
146
+ *
147
+ * The protocol those older files carry is `PROTOCOLS`. Anything asserting on
148
+ * protocol content wants that one — this answers "what would loam write here",
149
+ * not "what does loam instruct".
150
+ */
151
+ export const SLASH_COMMANDS = Object.fromEntries(AGENT_COMMANDS.map((c) => [c.name, CLAUDE.format(stubbed(c))]));
152
+ /** The two ways a command body reaches an agent. Both are on by default. */
153
+ export const DELIVERIES = ["commands", "skills"];
154
+ export const AGENT_PROFILES = ["full", "service", "docs"];
155
+ const PROFILE_COMMANDS = {
156
+ full: new Set(AGENT_COMMANDS.map((command) => command.name)),
157
+ service: new Set(["loam-adopt", "loam-implement", "loam-check", "loam-verify", "loam-report"]),
158
+ docs: new Set(["loam-feature", "loam-check", "loam-ship", "loam-report"]),
159
+ };
160
+ /**
161
+ * Every file the selected tools would lay down, in creation order — the same
162
+ * list `init` probes for `skipped` BEFORE the scaffold runs, so created +
163
+ * skipped is the same list on every repo.
164
+ *
165
+ * Called with two arguments it returns EVERYTHING the binary would write under
166
+ * default delivery: commands and skills both. That is the contract callers
167
+ * outside this module depend on — `loam doctor` asks "what should be here?"
168
+ * and a half-answer would report a fully-scaffolded repo as fully scaffolded
169
+ * while ignoring every skill file. The name predates the second delivery and is
170
+ * kept because it is imported elsewhere; `delivery` narrows it.
171
+ */
172
+ export function plannedCommandFiles(cwd, toolIds, delivery = DELIVERIES, profile = "full") {
173
+ return toolIds.flatMap((id) => {
174
+ const tool = AGENT_TOOLS[id];
175
+ if (tool === undefined)
176
+ throw new Error(`unknown agent tool: ${id}`);
177
+ const emitters = [];
178
+ // A tool declares only the deliveries it actually reads, so an absent
179
+ // emitter is a fact about the tool, never a reason to fall back to some
180
+ // other tool's convention.
181
+ const { path, format, skill } = tool;
182
+ if (delivery.includes("commands") && path !== undefined && format !== undefined) {
183
+ emitters.push({ path, format });
184
+ }
185
+ if (delivery.includes("skills") && skill !== undefined)
186
+ emitters.push(skill);
187
+ return emitters.flatMap((e) => AGENT_COMMANDS.filter((command) => PROFILE_COMMANDS[profile].has(command.name)).map((c) => ({
188
+ path: join(cwd, ...e.path(c.name)),
189
+ content: e.format(stubbed(c)),
190
+ })));
191
+ });
192
+ }
193
+ function contentDigest(content) {
194
+ return createHash("sha256").update(content).digest("hex");
195
+ }
196
+ function manifestPath(cwd, path) {
197
+ return relative(cwd, path).replaceAll("\\", "/");
198
+ }
199
+ export function updatedAgentFileManifest(cwd, planned, existing, managed) {
200
+ const out = { ...existing };
201
+ for (const file of planned)
202
+ delete out[manifestPath(cwd, file.path)];
203
+ return Object.assign(out, managed);
204
+ }
205
+ /**
206
+ * Create missing files and refresh only files still byte-identical to the
207
+ * digest recorded when loam last wrote them. A human edit breaks that equality
208
+ * and therefore revokes loam's authority over the file without a marker block
209
+ * or a prompt.
210
+ */
211
+ export async function syncAgentCommands(req) {
212
+ const { cwd, toolIds = ["claude"], delivery = DELIVERIES, profile = "full", known = {} } = req;
213
+ const out = { created: [], refreshed: [], managed: {} };
214
+ for (const { path, content } of plannedCommandFiles(cwd, toolIds, delivery, profile)) {
215
+ const key = manifestPath(cwd, path);
216
+ const desired = contentDigest(content);
217
+ if (!existsSync(path)) {
218
+ await mkdir(dirname(path), { recursive: true });
219
+ await writeFile(path, content, "utf8");
220
+ out.created.push(path);
221
+ out.managed[key] = desired;
222
+ continue;
223
+ }
224
+ const current = contentDigest(await readFile(path));
225
+ if (current === desired) {
226
+ out.managed[key] = desired;
227
+ continue;
228
+ }
229
+ if (known[key] !== current)
230
+ continue;
231
+ await writeFile(path, content, "utf8");
232
+ out.refreshed.push(path);
233
+ out.managed[key] = desired;
234
+ }
235
+ return out;
236
+ }
237
+ /**
238
+ * Backward-compatible create-only wrapper. Callers that own no digest manifest
239
+ * leave every existing file alone and receive only the paths created.
240
+ */
241
+ export async function scaffoldAgentCommands(cwd, toolIds = ["claude"], delivery = DELIVERIES) {
242
+ return (await syncAgentCommands({ cwd, toolIds, delivery })).created;
243
+ }
244
+ /**
245
+ * The registry ids whose marker paths are present in `cwd` — what `loam init`
246
+ * writes for when nobody passed `--tools`.
247
+ *
248
+ * A repo with `.cursor/` and no Claude Code used to get `.claude/commands/`
249
+ * and nothing it could actually run. Presence is the whole test, and existence
250
+ * (not directory-ness) is what is asked, because a marker is as often a file as
251
+ * a directory — `.github/copilot-instructions.md` is the honest signal for
252
+ * Copilot where `.github/` itself is noise.
253
+ */
254
+ export function detectAgentTools(cwd) {
255
+ return Object.entries(AGENT_TOOLS)
256
+ .filter(([, tool]) => tool.detect.some((marker) => existsSync(join(cwd, marker))))
257
+ .map(([id]) => id);
258
+ }
259
+ //# sourceMappingURL=scaffold.js.map