@dsdenes/devboard 0.1.560 → 0.1.563

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 (323) hide show
  1. package/AGENTS.md +59 -0
  2. package/README.md +2497 -26
  3. package/bin/devboard.mjs +352 -118
  4. package/client/App.svelte +523 -0
  5. package/client/FeedbackOverlay.svelte +1125 -0
  6. package/client/FlowMode.svelte +1015 -0
  7. package/client/app.css +3922 -0
  8. package/client/env.d.ts +23 -0
  9. package/client/lib/commands.ts +836 -0
  10. package/client/lib/components/ActivityBar.svelte +295 -0
  11. package/client/lib/components/AdrTable.svelte +241 -0
  12. package/client/lib/components/CommandPalette.svelte +198 -0
  13. package/client/lib/components/ConceptKind.svelte +66 -0
  14. package/client/lib/components/ConfirmDialog.svelte +62 -0
  15. package/client/lib/components/DataTable.svelte +243 -0
  16. package/client/lib/components/DetailSplit.svelte +68 -0
  17. package/client/lib/components/DiscoverOverview.svelte +898 -0
  18. package/client/lib/components/DiscoverWorkspace.svelte +437 -0
  19. package/client/lib/components/DraftsPage.svelte +186 -0
  20. package/client/lib/components/GoalWorkspace.svelte +1042 -0
  21. package/client/lib/components/IssuesAgentFocus.svelte +117 -0
  22. package/client/lib/components/IssuesAgentLog.svelte +50 -0
  23. package/client/lib/components/IssuesQuestion.svelte +95 -0
  24. package/client/lib/components/IssuesWorkspace.svelte +577 -0
  25. package/client/lib/components/MermaidDiagram.svelte +89 -0
  26. package/client/lib/components/MonacoEditor.svelte +190 -0
  27. package/client/lib/components/NotificationRegion.svelte +195 -0
  28. package/client/lib/components/PaneHandle.svelte +25 -0
  29. package/client/lib/components/ScoutIssues.svelte +215 -0
  30. package/client/lib/components/ScoutWorkspace.svelte +180 -0
  31. package/client/lib/components/Sidebar.svelte +622 -0
  32. package/client/lib/components/StatusBar.svelte +118 -0
  33. package/client/lib/components/Terminal.svelte +193 -0
  34. package/client/lib/components/WatchdogWorkspace.svelte +537 -0
  35. package/client/lib/components/ui/button.svelte +56 -0
  36. package/client/lib/components/ui/icon-button.svelte +56 -0
  37. package/client/lib/components/ui/input.svelte +19 -0
  38. package/client/lib/components/ui/page-header.svelte +120 -0
  39. package/client/lib/components/ui/stage-track.svelte +141 -0
  40. package/client/lib/components/watchdog-indicator.svelte +189 -0
  41. package/client/lib/connection.svelte.ts +210 -0
  42. package/client/lib/dependency-diagram.test.ts +90 -0
  43. package/client/lib/dependency-diagram.ts +75 -0
  44. package/client/lib/discover-format.test.ts +265 -0
  45. package/client/lib/discover-format.ts +394 -0
  46. package/client/lib/discover.svelte.ts +412 -0
  47. package/client/lib/draft-format.test.ts +48 -0
  48. package/client/lib/draft-format.ts +13 -0
  49. package/client/lib/flow-save.test.ts +148 -0
  50. package/client/lib/flow.svelte.ts +445 -0
  51. package/client/lib/goal-reconnect.test.ts +282 -0
  52. package/client/lib/goal.svelte.ts +652 -0
  53. package/client/lib/issues.svelte.ts +439 -0
  54. package/client/lib/layout.svelte.ts +234 -0
  55. package/client/lib/notification-issue.test.ts +53 -0
  56. package/client/lib/notification-issue.ts +27 -0
  57. package/client/lib/notifications.svelte.ts +62 -0
  58. package/client/lib/poll-status.test.ts +141 -0
  59. package/client/lib/poll-status.ts +88 -0
  60. package/client/lib/record-status.test.ts +19 -0
  61. package/client/lib/record-status.ts +25 -0
  62. package/client/lib/scout.svelte.ts +164 -0
  63. package/client/lib/skill-document.test.ts +77 -0
  64. package/client/lib/skill-document.ts +57 -0
  65. package/client/lib/status-tone.test.ts +40 -0
  66. package/client/lib/status-tone.ts +33 -0
  67. package/client/lib/types.ts +578 -0
  68. package/client/lib/utils.ts +6 -0
  69. package/client/lib/viewport.svelte.ts +20 -0
  70. package/client/lib/watchdog.svelte.ts +69 -0
  71. package/client/main.ts +7 -0
  72. package/dist/apple-touch-icon.png +0 -0
  73. package/dist/assets/abnfDiagram-VCTEODGH-CmBSMArZ.js +1 -0
  74. package/dist/assets/arc-BZgCSX2H.js +1 -0
  75. package/dist/assets/architecture-7GRP2DOG-CF9MHlfo.js +1 -0
  76. package/dist/assets/architectureDiagram-5GKGNRK7-DzWB6xiQ.js +36 -0
  77. package/dist/assets/array-BifhSqXX.js +1 -0
  78. package/dist/assets/blockDiagram-I7D4REHJ-BtmGJ0hn.js +129 -0
  79. package/dist/assets/c4Diagram-7LVT6UL2-D5CHrrRX.js +38 -0
  80. package/dist/assets/channel-CgM4lcUW.js +1 -0
  81. package/dist/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
  82. package/dist/assets/chunk-4HAMMTFA-DeIufjFl.js +62 -0
  83. package/dist/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
  84. package/dist/assets/chunk-75Z2AOVW-DbtzyKUg.js +2 -0
  85. package/dist/assets/chunk-DU6HZSFF-C0fdbx3K.js +127 -0
  86. package/dist/assets/chunk-F27PBJKO-HObL2IvF.js +1 -0
  87. package/dist/assets/chunk-FOHPRMQF-DD4dKubD.js +161 -0
  88. package/dist/assets/chunk-GMAD6QVW-fg8wvtPY.js +72 -0
  89. package/dist/assets/chunk-GVQU2GXP-C0TaHOrD.js +1 -0
  90. package/dist/assets/chunk-IMKFNOWR-BVoIdx20.js +231 -0
  91. package/dist/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
  92. package/dist/assets/chunk-L3NEJ4N5-B_kmqfk5.js +1 -0
  93. package/dist/assets/chunk-OSK3NFVY-DO0vhxHH.js +10 -0
  94. package/dist/assets/chunk-P2QGCYS3-CjljLvFj.js +1 -0
  95. package/dist/assets/chunk-POPQ4Y6H-BU0C7tw6.js +1 -0
  96. package/dist/assets/chunk-PWAF6VOD-Dn0OjBt0.js +1 -0
  97. package/dist/assets/chunk-SHT3W25Y-CMCZE2xx.js +168 -0
  98. package/dist/assets/chunk-SVP7TREG-BIRmRy_W.js +88 -0
  99. package/dist/assets/chunk-TICWLB2K-C1bc2CDE.js +206 -0
  100. package/dist/assets/chunk-XXDRQBXY-Cc38QUmR.js +1 -0
  101. package/dist/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
  102. package/dist/assets/classDiagram-ZZMXUADV-BDh5w6Nc.js +1 -0
  103. package/dist/assets/classDiagram-v2-VYDZK3BY-BDh5w6Nc.js +1 -0
  104. package/dist/assets/cose-bilkent-JH36ORCC-B7pU7qhM.js +1 -0
  105. package/dist/assets/cynefin-OW5HDTMX-76dswSqS.js +1 -0
  106. package/dist/assets/cynefinDiagram-5FMLGOSQ-2kS4q01d.js +62 -0
  107. package/dist/assets/cytoscape.esm-BegBNzOV.js +321 -0
  108. package/dist/assets/dagre-D7JM2Yhv.js +1 -0
  109. package/dist/assets/dagre-GXQ25YYZ-B5Y21TQM.js +4 -0
  110. package/dist/assets/defaultLocale-BFoDCU3G.js +1 -0
  111. package/dist/assets/diagram-S7CK7UJ4-CY6td7Et.js +30 -0
  112. package/dist/assets/diagram-UQ7AKVKN-DmDqnGZf.js +41 -0
  113. package/dist/assets/diagram-VSXAHHWV-KGLWOOcE.js +3 -0
  114. package/dist/assets/diagram-VX7I27RA-D5syUraJ.js +24 -0
  115. package/dist/assets/diagram-Z3DM3KII-Dtrbs1Om.js +24 -0
  116. package/dist/assets/dist-Dce-2YbA.js +1 -0
  117. package/dist/assets/ebnfDiagram-PWID7BFC-CQpJLtU3.js +1 -0
  118. package/dist/assets/editor.worker-BmdWdrHZ.js +33 -0
  119. package/dist/assets/erDiagram-RLTQ6QDP-cMTzKLu_.js +99 -0
  120. package/dist/assets/eventmodeling-NTZA5JFV-CMzLdNaL.js +1 -0
  121. package/dist/assets/flowDiagram-HODETNUW-BMUajB-G.js +1 -0
  122. package/dist/assets/ganttDiagram-EL5Y4UJY-DseBS5Fs.js +292 -0
  123. package/dist/assets/gitGraph-4MIJSDKK-CUQZRpxJ.js +1 -0
  124. package/dist/assets/gitGraphDiagram-WWUBYQGX-CfMfsJ3b.js +106 -0
  125. package/dist/assets/graphlib-DS17s2tU.js +1 -0
  126. package/dist/assets/index-ByQ-XX38.css +1 -0
  127. package/dist/assets/index-CIf5TpfY.js +214 -0
  128. package/dist/assets/info-A6RAGUB7-D3nAKZ8M.js +1 -0
  129. package/dist/assets/infoDiagram-27XIBGKW-zu1O0WOy.js +2 -0
  130. package/dist/assets/init-C-OQMol4.js +1 -0
  131. package/dist/assets/ishikawaDiagram-5VMMS53U-DKC7BO9p.js +70 -0
  132. package/dist/assets/journeyDiagram-3NMN7TZE-Ld5mXse7.js +139 -0
  133. package/dist/assets/kanban-definition-UXKFOSKX-CH7_QlHL.js +89 -0
  134. package/dist/assets/katex-DJhrJSbw.js +257 -0
  135. package/dist/assets/line-N9XiCREw.js +1 -0
  136. package/dist/assets/linear-C9hnqmJv.js +1 -0
  137. package/dist/assets/mermaid-parser.core-DgPwV5Bh.js +7 -0
  138. package/dist/assets/mermaid.core-BKqynXLR.js +44 -0
  139. package/dist/assets/mindmap-definition-YA3MSWOX-DkiL-wiW.js +96 -0
  140. package/dist/assets/monaco-DjpsE8to.css +1 -0
  141. package/dist/assets/monaco-DqzJaNIe.js +908 -0
  142. package/dist/assets/ordinal-BDEzSJ7C.js +1 -0
  143. package/dist/assets/packet-AYTQ26CC-DuMTvpEJ.js +1 -0
  144. package/dist/assets/path-fybaL0A-.js +1 -0
  145. package/dist/assets/pegDiagram-XKGWAZYB-DvMl_xSe.js +1 -0
  146. package/dist/assets/pie-WAS4IAKB-Da0xPaD8.js +1 -0
  147. package/dist/assets/pieDiagram-E7YTZNPT-amANNRJY.js +39 -0
  148. package/dist/assets/quadrantDiagram-AXDQQJYC-BrgvDMnk.js +7 -0
  149. package/dist/assets/radar-RG4KPBEZ-Dz3Ih5-N.js +1 -0
  150. package/dist/assets/railroad-74A4TZTK-CKMW-IV2.js +1 -0
  151. package/dist/assets/railroad-abnf-HS5TGJTU-ChqmSWSF.js +1 -0
  152. package/dist/assets/railroad-ebnf-LZEXJU2U-V3R4fFdb.js +1 -0
  153. package/dist/assets/railroad-peg-WCYAUIDC-B-RuhUQW.js +1 -0
  154. package/dist/assets/railroadDiagram-O6MQD6OU-FjG-6OLu.js +1 -0
  155. package/dist/assets/requirementDiagram-BXWQKSXE-Cnj8RfE4.js +84 -0
  156. package/dist/assets/rolldown-runtime-XKyaHtl9.js +1 -0
  157. package/dist/assets/rough.esm-Dy-Kn_BL.js +1 -0
  158. package/dist/assets/sankeyDiagram-P5KCCOFB-DMu1fnEh.js +40 -0
  159. package/dist/assets/sequenceDiagram-WJ2MYXX4-CtCtaRpW.js +162 -0
  160. package/dist/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
  161. package/dist/assets/src-CGp3bfio.js +1 -0
  162. package/dist/assets/stateDiagram-D77RDMKH-xcJbLNhz.js +1 -0
  163. package/dist/assets/stateDiagram-v2-MP3YSRHH-DYHrQmJJ.js +1 -0
  164. package/dist/assets/swimlanes-42K2YHIH-BwLln_ga.js +1 -0
  165. package/dist/assets/swimlanesDiagram-VR7AAH4N-BcDfUQ0A.js +8 -0
  166. package/dist/assets/timeline-definition-24CTP7MA-ucNGsUUz.js +120 -0
  167. package/dist/assets/treeView-Q6P3EWNA-3uOomRue.js +1 -0
  168. package/dist/assets/treemap-WGGIJYW6-iGK7vwID.js +1 -0
  169. package/dist/assets/vennDiagram-4TSXK5OY-B9LgGe16.js +34 -0
  170. package/dist/assets/wardley-WFR3VGLG-FupMOf6k.js +1 -0
  171. package/dist/assets/wardleyDiagram-VM6X3IG4-CGZdEXM2.js +78 -0
  172. package/dist/assets/xterm-BrP-ENHg.css +1 -0
  173. package/dist/assets/xterm-C8zLTNGk.js +16 -0
  174. package/dist/assets/xychartDiagram-S5SC5T6Z-DafZrSBJ.js +7 -0
  175. package/dist/favicon.ico +0 -0
  176. package/dist/favicon.svg +6 -0
  177. package/dist/index.html +34 -0
  178. package/extensions/implement-goal-issue.ts +368 -0
  179. package/extensions/implement-next-epic.ts +835 -0
  180. package/index.html +28 -0
  181. package/install.sh +111 -0
  182. package/issues/control.ts +91 -0
  183. package/issues/guards.ts +12 -0
  184. package/issues/ledger.ts +122 -0
  185. package/issues/legacy.ts +68 -0
  186. package/issues/lock.ts +305 -0
  187. package/issues/paths.ts +76 -0
  188. package/issues/preflight.ts +189 -0
  189. package/issues/repository.ts +203 -0
  190. package/issues/scout/actions.ts +255 -0
  191. package/issues/scout/control.ts +80 -0
  192. package/issues/scout/github.ts +358 -0
  193. package/issues/scout/paths.ts +129 -0
  194. package/issues/scout/preflight.ts +277 -0
  195. package/issues/scout/recommendation.ts +400 -0
  196. package/issues/scout/scan.ts +143 -0
  197. package/issues/scout/state.ts +448 -0
  198. package/issues/scout/worker.ts +1282 -0
  199. package/issues/state.ts +584 -0
  200. package/issues/tracker.ts +271 -0
  201. package/issues/worker.ts +1065 -0
  202. package/lib/dependencies.ts +61 -0
  203. package/lib/forge-auth.ts +953 -0
  204. package/lib/forge.ts +141 -0
  205. package/lib/gitea.ts +729 -0
  206. package/lib/github-release.ts +318 -0
  207. package/lib/inventory.test.ts +79 -0
  208. package/lib/inventory.ts +53 -0
  209. package/lib/release.test.ts +269 -0
  210. package/lib/release.ts +801 -0
  211. package/omp/commands/adr-resolve.md +8 -0
  212. package/omp/commands/discover.md +6 -0
  213. package/omp/commands/epic-next.md +8 -0
  214. package/omp/commands/flow-change.md +8 -0
  215. package/omp/commands/flow-goal.md +8 -0
  216. package/omp/commands/flow-implement.md +8 -0
  217. package/omp/commands/flow-widget.md +8 -0
  218. package/omp/commands/goal-draft.md +8 -0
  219. package/omp/commands/goal-outcome.md +8 -0
  220. package/omp/commands/implement-issue.md +8 -0
  221. package/omp/commands/prepare-skills.md +6 -0
  222. package/omp/commands/scout-recommendations.md +8 -0
  223. package/omp/commands/setup-devboard.md +24 -0
  224. package/omp/config.yml +12 -0
  225. package/omp/extensions/implement-goal-issue.ts +2 -0
  226. package/omp/extensions/implement-next-epic.ts +2 -0
  227. package/omp/mcp.json +9 -0
  228. package/package.json +86 -7
  229. package/prompts/adr-resolve.md +130 -0
  230. package/prompts/discover.md +541 -0
  231. package/prompts/epic-next.md +533 -0
  232. package/prompts/flow-change.md +76 -0
  233. package/prompts/flow-goal.md +126 -0
  234. package/prompts/flow-implement.md +103 -0
  235. package/prompts/flow-widget.md +54 -0
  236. package/prompts/goal-draft.md +147 -0
  237. package/prompts/goal-outcome.md +87 -0
  238. package/prompts/implement-issue.md +66 -0
  239. package/prompts/prepare-skills.md +142 -0
  240. package/prompts/scout-recommendations.md +143 -0
  241. package/public/apple-touch-icon.png +0 -0
  242. package/public/favicon.ico +0 -0
  243. package/public/favicon.svg +6 -0
  244. package/server/acp.ts +540 -0
  245. package/server/activity.test.ts +96 -0
  246. package/server/activity.ts +48 -0
  247. package/server/app.test.ts +882 -0
  248. package/server/app.ts +6179 -0
  249. package/server/ask.test.ts +543 -0
  250. package/server/ask.ts +589 -0
  251. package/server/dependencies.test.ts +118 -0
  252. package/server/discover-remote.test.ts +1602 -0
  253. package/server/discover-sheet.test.ts +176 -0
  254. package/server/discover.test.ts +1510 -0
  255. package/server/discover.ts +3198 -0
  256. package/server/feedback.test.ts +458 -0
  257. package/server/feedback.ts +369 -0
  258. package/server/fixtures/adr-source.ts +71 -0
  259. package/server/fixtures/hang-download.ts +14 -0
  260. package/server/fixtures/stub-agent.ts +1870 -0
  261. package/server/fixtures/stub-forge.ts +141 -0
  262. package/server/fixtures/stub-gh.ts +57 -0
  263. package/server/flow-pr.test.ts +976 -0
  264. package/server/flow.test.ts +1632 -0
  265. package/server/flow.ts +2655 -0
  266. package/server/forge-pr.ts +387 -0
  267. package/server/goal-creation.test.ts +957 -0
  268. package/server/goal-draft.test.ts +348 -0
  269. package/server/goal-drafts.ts +449 -0
  270. package/server/goal-proposal.test.ts +479 -0
  271. package/server/goal-proposal.ts +232 -0
  272. package/server/goal-revision.test.ts +613 -0
  273. package/server/goal-slug.test.ts +56 -0
  274. package/server/goal-slug.ts +96 -0
  275. package/server/goal.ts +20 -0
  276. package/server/index.ts +147 -0
  277. package/server/issue-close.test.ts +100 -0
  278. package/server/issue-close.ts +178 -0
  279. package/server/issues.test.ts +167 -0
  280. package/server/issues.ts +479 -0
  281. package/server/journal.test.ts +350 -0
  282. package/server/journal.ts +329 -0
  283. package/server/lifecycle-pause.test.ts +1795 -0
  284. package/server/lifecycle.test.ts +1879 -0
  285. package/server/parallel-lifecycle.test.ts +1029 -0
  286. package/server/persistence-restart.test.ts +723 -0
  287. package/server/persistence.test.ts +1935 -0
  288. package/server/records.test.ts +180 -0
  289. package/server/records.ts +99 -0
  290. package/server/reset-implementation.test.ts +997 -0
  291. package/server/run.test.ts +611 -0
  292. package/server/scout.test.ts +877 -0
  293. package/server/scout.ts +459 -0
  294. package/server/skills-preparation.test.ts +1073 -0
  295. package/server/state.ts +249 -0
  296. package/server/tracker.ts +369 -0
  297. package/server/updates.test.ts +444 -0
  298. package/server/updates.ts +198 -0
  299. package/server/version.test.ts +140 -0
  300. package/server/version.ts +151 -0
  301. package/server/watchdog.ts +389 -0
  302. package/svelte.config.js +5 -0
  303. package/templates/host-AGENTS.md +235 -0
  304. package/tsconfig.json +21 -0
  305. package/vite.config.ts +21 -0
  306. package/watchdog/cleanup-main.ts +98 -0
  307. package/watchdog/cleanup.ts +301 -0
  308. package/watchdog/collect.ts +311 -0
  309. package/watchdog/coordinator.ts +397 -0
  310. package/watchdog/delivery.ts +107 -0
  311. package/watchdog/discovery.ts +209 -0
  312. package/watchdog/findings.ts +211 -0
  313. package/watchdog/github.ts +189 -0
  314. package/watchdog/history.ts +138 -0
  315. package/watchdog/install.ts +103 -0
  316. package/watchdog/ledger.ts +188 -0
  317. package/watchdog/lock.ts +63 -0
  318. package/watchdog/main.ts +106 -0
  319. package/watchdog/status.ts +71 -0
  320. package/watchdog/systemd.ts +96 -0
  321. package/watchdog/uninstall.ts +30 -0
  322. package/watchdog/units/devboard-watchdog.service +9 -0
  323. package/watchdog/units/devboard-watchdog.timer +10 -0
@@ -0,0 +1,541 @@
1
+ ---
2
+ description: Crawl the host read-only and stage an evidence-backed project sheet, one UbiLang glossary per bounded context, and five project-specific Discover Agent Skills.
3
+ ---
4
+
5
+ `/discover <staging-dir>`: crawl the host read-only, then write a staged Discover result that the
6
+ server validates and publishes. This turn produces data, not conversation: no interview, no
7
+ questions, no prose report.
8
+
9
+ ## Contract
10
+
11
+ - `<host>` is the git top level: `git rev-parse --show-toplevel`. If that fails, use the current
12
+ working directory.
13
+ - `<staging-dir>` is the single argument after `/discover` (`$ARGUMENTS` in the wrapper). It is the
14
+ only directory this turn may write. Create the subdirectories named below; create nothing else.
15
+ - The server owns publication. Never write outside `<staging-dir>`, and never touch
16
+ `<host>/.omp/discover/`, `<host>/.omp/skills/`, `<host>/GOAL.md`, anything under
17
+ `<host>/adrs/`, or any host source file.
18
+ - Never write `manifest.json` or `decisions.json`; the server generates both. The staged sheet has
19
+ no `freshness` key; the server injects freshness on publication.
20
+ - This is a read-only crawl. Read files and use only these safe read-only git facts:
21
+ `git rev-parse`, `git log`, `git branch`, `git status`, `git ls-files`. Run no other git
22
+ subcommand and no project command, test, build, package-manager step, install, formatter, code
23
+ generator, web fetch, forge query, or network request. The only network traffic in this turn is
24
+ the model endpoint that serves this session.
25
+ - Record configuration names and environment variable names, never their values. Never copy a
26
+ token, credential, password, private key, secret, private URL, or URL containing user info into
27
+ any staged file.
28
+ - If `<staging-dir>` is missing, empty, unwritable, or outside `<host>/.omp/discover/staging/`,
29
+ reply exactly `halt: staging directory is not usable` and stop. Otherwise write no status line.
30
+
31
+ ## Crawl
32
+
33
+ Read only what you need, and prefer breadth first so the sheet describes the whole host.
34
+
35
+ 1. Inventory the git top level with `git ls-files` and `git status`; note the default branch with
36
+ `git branch` and recent history with `git log` when it supports a claim.
37
+ 2. Read `README`, `AGENTS.md`, `GOAL.md`, and `adrs/` when present. They are evidence and context
38
+ only: never edit them and never copy their prose into a value.
39
+ 3. Read manifests, lockfile metadata without dependency contents, task-runner files, configuration,
40
+ CI configuration, container and deployment descriptors, and documentation that names runtime,
41
+ build, test, release, or environment facts.
42
+ 4. Read source and tests to locate contexts, entry points, dependency direction, conventions, test
43
+ levels, fixtures, and domain terms. Read ignored files never. Read dependency caches, vendored
44
+ third-party trees, build outputs, and generated artifacts never.
45
+ 5. Exclude from the crawl entirely: `<host>/.devboard/`, `<host>/.worktree/`, `<host>/.git/`
46
+ internals, every path under `<host>/.omp/`, package manager and tool caches, virtual
47
+ environments, build and coverage outputs, and every ignored path. Do not cite an excluded path
48
+ as evidence.
49
+ 6. Do not open files that plainly hold secrets, such as environment value files, keystores, or
50
+ credential stores. Environment names and configuration keys may be recorded from manifests,
51
+ templates, descriptors, and documentation; their values never.
52
+
53
+ Never block on an ambiguity and never ask a question. When the evidence is absent, contradictory,
54
+ or insufficient, write `unknown` with a short reason. Never guess, fill a plausible value, or
55
+ invent a path, command, environment, context, or term.
56
+
57
+ ## Staged layout
58
+
59
+ Write exactly this layout under `<staging-dir>`:
60
+
61
+ ```
62
+ sheet.json
63
+ glossary/<boundedContext>.glossary.yaml
64
+ glossary/significance.json
65
+ skills/<skill-name>/SKILL.md
66
+ ```
67
+
68
+ - `sheet.json` is one JSON object with no freshness key.
69
+ - Write at least one glossary file. The file name is the bounded-context id in kebab case; at least
70
+ one bounded context must be detected.
71
+ - Write exactly one `SKILL.md` for each of the five fixed names below and no other skill directory.
72
+ - Write no other files, no notes, no logs, and no temporary files. Order every object key, array,
73
+ and enum exactly as specified so two crawls of unchanged input produce the same structural
74
+ digest apart from deliberately bounded prose.
75
+
76
+ ## `sheet.json`
77
+
78
+ Write these top-level keys in this canonical order:
79
+
80
+ ```
81
+ schemaVersion, definition, stack, deployment, environments, commands, branching,
82
+ testing, architecture, ci, runtime, dependencyMap, delivery
83
+ ```
84
+
85
+ `schemaVersion` is the integer `1`.
86
+
87
+ Every value below is a **leaf**:
88
+
89
+ ```json
90
+ {
91
+ "value": null,
92
+ "evidence": [],
93
+ "confidence": "unknown",
94
+ "reason": "short reason"
95
+ }
96
+ ```
97
+
98
+ - `value` is the fact, or `null` exactly when `confidence` is `unknown`.
99
+ - `evidence` is a sorted, de-duplicated list of repository-relative paths, symbol anchors, or safe
100
+ read-only git facts. No leading `/`, no `..`, no drive letter, no absolute path, no URL. A
101
+ non-`unknown` leaf needs at least one evidence entry and carries at most 32 entries.
102
+ - `confidence` is exactly one of `observed` (read directly), `declared` (stated by the project's
103
+ own documentation or configuration), `inferred` (supported but not stated), or `unknown`.
104
+ - `reason` is required and short (at most 200 characters) when `confidence` is `unknown`; it is
105
+ omitted otherwise.
106
+ - Every string value and every string inside a list value is non-empty and one line of at most 160
107
+ characters. No value is a paragraph, a sentence fragment copied from documentation, or a secret.
108
+ A list carries at most 64 entries.
109
+ - Lists are sorted by their first string. A leaf whose fact does not exist is `unknown` with
110
+ `"value": null` and a reason; it is never an empty guess. `environments` is the exception and
111
+ always carries at least the production entry described below; `architecture.externalBoundaries`
112
+ is the other exception and stages an observed empty list, as the External boundaries section
113
+ states.
114
+
115
+ Sections and required keys:
116
+
117
+ ```jsonc
118
+ {
119
+ "schemaVersion": 1,
120
+ "definition": { "value": "Short one-sentence project definition of at most 240 characters.", "evidence": ["README.md"], "confidence": "declared" },
121
+ "stack": { "value": ["one technology per entry"], "evidence": ["path"], "confidence": "declared" },
122
+ "deployment": {
123
+ "class": { "value": "package|container|static-site|service|cli|library|plugin|none", "evidence": ["path"], "confidence": "observed" },
124
+ "artifact": { "value": "artifact name", "evidence": ["path"], "confidence": "observed" },
125
+ "target": { "value": "target or registry", "evidence": ["path"], "confidence": "declared" },
126
+ "pipelineSources": { "value": ["path"], "evidence": ["path"], "confidence": "observed" }
127
+ },
128
+ "environments": { "value": [{ "name": "environment name", "purpose": "short purpose" }], "evidence": ["path"], "confidence": "declared" },
129
+ "commands": {
130
+ "install": { "value": "exact command", "evidence": ["path"], "confidence": "declared" },
131
+ "build": { "value": "exact command", "evidence": ["path"], "confidence": "declared" },
132
+ "test": { "value": "exact command", "evidence": ["path"], "confidence": "declared" },
133
+ "lint": { "value": "exact command", "evidence": ["path"], "confidence": "declared" },
134
+ "typecheck": { "value": "exact command", "evidence": ["path"], "confidence": "declared" },
135
+ "dev": { "value": "exact command", "evidence": ["path"], "confidence": "declared" },
136
+ "tryOut": { "value": "exact command", "evidence": ["path"], "confidence": "declared" },
137
+ "release": { "value": "exact command", "evidence": ["path"], "confidence": "declared" }
138
+ },
139
+ "branching": {
140
+ "defaultBranch": { "value": "branch name", "evidence": ["git branch"], "confidence": "observed" },
141
+ "mergeMethod": { "value": "merge method", "evidence": ["git log", "path"], "confidence": "inferred" },
142
+ "releaseBranches": { "value": ["branch name"], "evidence": ["git branch"], "confidence": "observed" },
143
+ "model": { "value": "direct|pull-request|git-flow", "evidence": ["git log"], "confidence": "inferred" }
144
+ },
145
+ "testing": {
146
+ "levels": { "value": [{ "level": "unit|integration|end-to-end|contract|other", "tests": "exact test count", "happyPath": "exact happy-path test count", "paths": ["path"], "command": "declared command", "fixtures": ["path"] }], "evidence": ["path"], "confidence": "observed" },
147
+ "pyramid": { "value": "short pyramid description", "evidence": ["path"], "confidence": "inferred" }
148
+ },
149
+ "architecture": {
150
+ "contexts": { "value": [{ "name": "context name", "path": "repo-relative path", "responsibility": "short responsibility", "entryPoints": ["repo-relative path"] }], "evidence": ["path"], "confidence": "observed" },
151
+ "dependencies": { "value": [{ "from": "context name", "to": "context name" }], "evidence": ["path"], "confidence": "observed" },
152
+ "dependencyDirection": { "value": "short direction statement", "evidence": ["path"], "confidence": "inferred" },
153
+ "externalBoundaries": { "value": ["external system"], "evidence": ["path"], "confidence": "observed" },
154
+ "sharedKernels": { "value": ["kernel and path"], "evidence": ["path"], "confidence": "observed" }
155
+ },
156
+ "ci": {
157
+ "provider": { "value": "provider or none detected", "evidence": ["path"], "confidence": "observed" },
158
+ "triggers": { "value": ["trigger"], "evidence": ["path"], "confidence": "observed" },
159
+ "jobs": { "value": ["job name"], "evidence": ["path"], "confidence": "observed" },
160
+ "qualityGates": {
161
+ "value": [{ "name": "required gate", "checks": "what the gate checks, in one short line" }],
162
+ "evidence": ["path"], "confidence": "declared"
163
+ },
164
+ "artifacts": { "value": ["artifact"], "evidence": ["path"], "confidence": "observed" }
165
+ },
166
+ "runtime": {
167
+ "languages": { "value": ["language plus version"], "evidence": ["path"], "confidence": "observed" },
168
+ "runtimes": { "value": ["runtime and version"], "evidence": ["path"], "confidence": "declared" },
169
+ "packageManagers": { "value": ["package manager"], "evidence": ["path"], "confidence": "observed" },
170
+ "versions": { "value": ["pinned version fact"], "evidence": ["path"], "confidence": "observed" },
171
+ "manifests": { "value": ["repo-relative manifest path"], "evidence": ["path"], "confidence": "observed" }
172
+ },
173
+ "dependencyMap": {
174
+ "binaries": { "value": ["binary"], "evidence": ["path"], "confidence": "observed" },
175
+ "packages": { "value": ["package"], "evidence": ["path"], "confidence": "observed" },
176
+ "routes": { "value": ["route"], "evidence": ["path"], "confidence": "observed" },
177
+ "jobs": { "value": ["job"], "evidence": ["path"], "confidence": "observed" },
178
+ "externalServices": { "value": ["service"], "evidence": ["path"], "confidence": "observed" },
179
+ "dataStores": { "value": ["store"], "evidence": ["path"], "confidence": "observed" },
180
+ "keyDependencies": { "value": ["dependency"], "evidence": ["path"], "confidence": "declared" }
181
+ },
182
+ "delivery": {
183
+ "artifactTarget": { "value": "registry or artifact target", "evidence": ["path"], "confidence": "declared" },
184
+ "releaseChannels": { "value": ["channel"], "evidence": ["path"], "confidence": "declared" },
185
+ "versionScheme": { "value": "scheme", "evidence": ["path"], "confidence": "declared" },
186
+ "migrationPolicy": { "value": "policy or none detected", "evidence": ["path"], "confidence": "declared" }
187
+ }
188
+ }
189
+ ```
190
+
191
+ Section rules:
192
+
193
+ - `definition` is exactly one sentence of at most 240 characters, ends with `.`, and describes what
194
+ the project is for its users. It is not a copy of the README's opening paragraph.
195
+ - `stack` is the short platform list: languages, runtimes, package managers, frameworks, and major
196
+ tools actually used to build or run the project. Do not list individual third-party
197
+ dependencies; those belong in `dependencyMap.keyDependencies`.
198
+ - `deployment.class` uses the fixed enum; use `none` when the host publishes nothing, and
199
+ `value: null` with `confidence: unknown` when the class is undetermined. Only the confidence can
200
+ be `unknown`; the literal string `unknown` is not an enum value.
201
+ - `environments` always records at least one entry. Record every environment name found in
202
+ manifests, configuration, container files, CI configuration, and deployment descriptors, with
203
+ its short purpose. When no other environment is evidenced, record exactly one `production`
204
+ entry whose purpose states how changes reach it, such as a direct push or a published package.
205
+ A source path belongs in `evidence`; never invent additional environments.
206
+ - `commands` repeats the exact install, build, test, lint, typecheck, dev/run, try-out, and release
207
+ command found in a manifest, task runner, CI file, or documentation. `test` is the one command
208
+ that runs the whole suite. `tryOut` starts or opens the project for a hands-on try — a dev
209
+ server, a demo entry point, or an example invocation — and is never the test command; when the
210
+ crawl found no such command, write `unknown`. A command the crawl did not observe is `unknown`;
211
+ never execute it and never reconstruct it from another ecosystem's habit.
212
+ An alias is not a separate command. When a candidate resolves to another recorded command —
213
+ `npm test` declared as `node --test test/*.test.js`, or a script that only wraps the test,
214
+ build, lint, typecheck, or release command — it is that command under another name and must not
215
+ be recorded as `tryOut`. Write `tryOut` only for a command that starts, serves, or opens the
216
+ project for hands-on use and that no other recorded command subshells into. When the only
217
+ candidate is an alias, or the crawl cannot tell whether it is one, stage `tryOut` as `unknown`
218
+ with a reason; never guess a try-out command from a test runner, a demo script name, or the
219
+ ecosystem's habit.
220
+ Record the invocation a developer would type, not the program a script expands to. When
221
+ `package.json` declares `scripts.test`, `commands.test` is `npm test` and `evidence` names
222
+ `package.json`; when it declares a script for one level (`test:unit`, `test:contract`), that
223
+ level's `command` is `npm run <script>`. Only without a declared script does the command become
224
+ the program the manifest or CI file invokes.
225
+ - `branching` reports the observed default branch and release branches, the observed or inferred
226
+ merge method, and one of `direct`, `pull-request`, or `git-flow`, supported by git and CI
227
+ evidence. A model the repository does not evidence is `value: null` with `confidence: unknown`
228
+ and a reason.
229
+ - `testing` reports the observed test levels, an exact test count for each level, representative
230
+ paths, commands, fixtures, and the resulting pyramid. Count the test cases you can see statically
231
+ in the test files; never run the suite. A level with evidence but no test case is `0`; a level
232
+ with no evidence is omitted. Never write `unknown` as a count.
233
+ `happyPath` is the part of that level's count that exercises the primary success path — the
234
+ expected input reaching the expected outcome with no error or edge branch — judged from test
235
+ names, fixtures, and assertions. It is an exact count from `0` to `tests`, never a percentage
236
+ and never `unknown`. A level whose tests are all error, negative, or boundary cases records `0`.
237
+ `command` is the narrowest declared invocation that runs only that level, such as
238
+ `npm run test:unit`, `pytest tests/unit`, or `cargo test --test contract`; when the level has no
239
+ separate entry point, it is the whole-suite invocation.
240
+ - `architecture` reports detected bounded contexts or modules with path and responsibility, entry
241
+ points, the directed dependencies between them, allowed dependency direction, shared kernels, and
242
+ `externalBoundaries`, which carries external systems only and never internal architecture.
243
+ `dependencies` records one `{ from, to }` entry per edge where the context named `from` imports,
244
+ calls, or otherwise reaches the context named `to`; both names are contexts in this same sheet,
245
+ `from` is never `to`, and one edge appears once. Record an edge only when a file in the source
246
+ proves it; a project whose contexts never reach each other records `[]` with `confidence:
247
+ observed` and evidence naming the context paths, and a crawl that cannot determine the edges
248
+ records `unknown` with a reason. `ci` reports provider, triggers, jobs,
249
+ required quality gates, and artifacts; with no CI configuration use `none detected`, never
250
+ invented jobs. A quality gate is one required check with its name and a `checks` line that says
251
+ what the gate verifies, such as `pre-commit` checking formatting and lint on staged files. Ground
252
+ that line in the gate's configuration, hook id, or script; keep it to one short sentence and never
253
+ list checks the configuration does not name.
254
+ - `runtime`, `dependencyMap`, and `delivery` are mandatory cards. Report languages, runtimes,
255
+ package managers, versions, and manifests; binaries, packages, routes, jobs, external services,
256
+ data stores, and key dependencies; artifact target, release channels, version scheme, and
257
+ migration policy.
258
+
259
+ ## External boundaries
260
+
261
+ `architecture.externalBoundaries` names external systems only. It is the one architecture leaf with
262
+ a rule of its own, and that rule overrides the general empty-list rule above.
263
+
264
+ - An external boundary is an external system the host integrates with across its own process and
265
+ artifact: a remote API or service, a message broker, a database, an identity provider, or an
266
+ external tool the host does not ship. Name the external system, not the module or primitive that
267
+ reaches it, and stage that system's own name.
268
+ - Language and runtime built-ins are never a boundary. `node:child_process`, `node:worker_threads`,
269
+ and the other concurrency primitives and standard-library modules a runtime ships describe
270
+ internal architecture: they start, schedule, or coordinate the host's own work inside its own
271
+ process and artifact. A language built-in, a standard-library type, an operating-system facility,
272
+ and a concurrency primitive are each never a boundary.
273
+ - A name that is not verbatim in a cited file comes from the host's own configuration,
274
+ documentation, or constant: the host name or endpoint its code calls, the client library it
275
+ imports, or the identifier it declares. Never name a system from the usual stack of the
276
+ ecosystem, from habit, or by rewriting a domain out of a path. Two crawls of unchanged input
277
+ therefore stage the same entry.
278
+ - `architecture.externalBoundaries is the one leaf that stages an empty observed list`: when the
279
+ host integrates with no external system, write `"value": []` with `confidence: observed` and at
280
+ least one evidence entry naming the files that prove the absence, never `unknown` and never an
281
+ invented entry.
282
+
283
+ Examples:
284
+
285
+ - A module that spawns the host's own worker script and subprocesses through `node:child_process`
286
+ and `node:worker_threads`: no boundary, because both are runtime built-ins.
287
+ - A module that calls `fetch("https://api.openweathermap.org/data/2.5/weather")` for weather:
288
+ `api.openweathermap.org`, the external system.
289
+ - A service that reads and writes through a Postgres driver: `PostgreSQL`, the external system.
290
+
291
+ ## Glossary (UbiLang)
292
+
293
+ Write one YAML document per detected bounded context at
294
+ `glossary/<boundedContext>.glossary.yaml`. It must be a complete, parseable UbiLang glossary.
295
+
296
+ Top-level key order: `boundedContext`, `titles`, `concepts`. `titles` is a list of
297
+ `{language, text}` entries.
298
+
299
+ Each concept carries these keys in this order:
300
+
301
+ ```
302
+ id, prefLabels, altLabels, hiddenLabels, definitions, scopeNote, example, historyNote,
303
+ status, origin, standardRef, kind, grounding, broader, related
304
+ ```
305
+
306
+ - `id` is kebab case, unique in the document; `boundedContext` is also kebab case.
307
+ - `prefLabels`, `altLabels`, and `definitions` are lists of `{language, text}` with `language`
308
+ `en` or `de`. `prefLabels` is non-empty, has at most one entry per language, and always includes
309
+ an `en` label. Every concept has at least one `en` definition. `altLabels` may be `[]`.
310
+ - `hiddenLabels` is `[]`; a hidden or rejected label is a human decision the server preserves, so
311
+ this crawl never synthesizes one.
312
+ - `scopeNote`, `example`, `historyNote`, `standardRef`, and `broader` may be `null` when unused.
313
+ `related` is a list, `[]` when none. `broader` and `related` name concept ids that exist in the
314
+ same document.
315
+ - `status` is one of `confirmed`, `unconfirmed`, `proposed`, `deprecated`, `invalidated`. This
316
+ crawl writes only `unconfirmed` for a term found in existing code or documentation and
317
+ `proposed` for a term the agent names for an existing but unnamed concept. Never write
318
+ `confirmed`, `deprecated`, or `invalidated`; those are human decisions the server preserves.
319
+ - `origin` is one of `owner`, `standard`, `llm`. Grounded existing terms use `owner` or `standard`;
320
+ an agent proposal uses `llm`. `origin: standard` requires a `standardRef`.
321
+ - `kind` is one of `entity`, `event`, `field`, `role`, `actor`, `value`, `rule`.
322
+ - `grounding` is a non-empty list. Each entry is `code:<repository-relative path that exists>` or
323
+ `model:<symbol or model name that appears in the crawled host>`. The `model:` name matches
324
+ `^[A-Za-z_][A-Za-z0-9_.-]*$` and appears as a whole word in one crawled file. A candidate with
325
+ no grounding is omitted, never invented.
326
+ - Fields use camelCase; enum values use the exact snake_case spelling above. Write no undeclared
327
+ field. Keep every label, definition, and note on one line of at most 160 characters; a definition
328
+ is one sentence.
329
+ - Detect at least one bounded context, and give every glossary document at least one grounded
330
+ concept. When the source contains a named concept, define it; when it contains an important
331
+ unnamed concept, propose one explicitly with `status: proposed` and `origin: llm`.
332
+ - Prefer significant, project-specific concepts over generic vocabulary. The preferred label is
333
+ the domain's own compound name, such as a multi-word term or a compound identifier that appears
334
+ in the host's code and documentation. Omit generic framework words and single generic tokens
335
+ (`option`, `command`, `value`, `config`, `error`, `page`, `action`, `data`, `file`, `name`,
336
+ `state`, `request`, `response`, `type`) unless the host defines that exact term as a
337
+ project-specific concept with a one-sentence definition and grounds it in at least two files.
338
+ The glossary maps the host's language; it is not an inventory of its framework.
339
+ - Prefer concepts whose grounding spans more than one file, and record every code path and model
340
+ symbol that demonstrates the concept. A concept the operator would not recognize as part of this
341
+ project's domain does not belong in the glossary.
342
+
343
+ Before writing glossaries, read the currently published
344
+ `<host>/.omp/discover/glossary/` and `<host>/.omp/discover/decisions.json` when present, read-only.
345
+ Never give an invalidated or human-rejected term a new proposed or unconfirmed entry, never
346
+ resurrect an invalidated id, and never restate a human rejection. The server merges human decisions
347
+ during publication; do not copy `confirmed` or `invalidated` statuses into the staged files.
348
+
349
+ ## Glossary significance
350
+
351
+ A concept belongs in the glossary only when the host itself names it as part of the project's
352
+ domain. Omit generic framework, library, language, and UI vocabulary: never include `option`,
353
+ `hook`, `command`, or any comparable generic token unless the host defines that exact term as a
354
+ project concept and grounds it in at least two distinct host files. A label that would read the same
355
+ in an unrelated project is evidence of generic vocabulary, not of a project concept.
356
+
357
+ Score every included concept on a scale from 0 to 100. 50 is the significance floor: a score at or
358
+ above it means the concept is central enough to name in the project's own language, and a score
359
+ below it means the term is incidental. Score from the crawling evidence, not from how often a word
360
+ occurs: a term mentioned a thousand times is insignificant when the host merely passes it through,
361
+ and a domain term named once is significant when the host's model depends on it. Every score carries
362
+ a one-line reason of at most 160 characters that states the evidence, without a path, a secret, or a
363
+ second sentence.
364
+
365
+ Stage the scores at `glossary/significance.json`, beside the glossaries, with exactly this shape:
366
+
367
+ ```json
368
+ {
369
+ "schemaVersion": 1,
370
+ "contexts": {
371
+ "<boundedContext>": {
372
+ "<concept-id>": { "score": 0, "reason": "One line of evidence." }
373
+ }
374
+ }
375
+ }
376
+ ```
377
+
378
+ - `schemaVersion: 1` is the only schema version; write no other top-level key.
379
+ - `contexts` names exactly the staged bounded contexts and nothing else. Each context names exactly
380
+ that glossary's concept ids and nothing else.
381
+ - Each entry carries exactly `score` and `reason`. `score` is an integer from `0` to `100`; `reason`
382
+ is one line of at most 160 characters, is not empty, and contains no absolute path and no secret.
383
+ - Every glossary concept has a significance score. A missing entry, an extra entry, a score outside
384
+ the range, or a rejected reason fails the run, so never stage a partial sidecar.
385
+ - Exclude significance from the glossary YAML: no concept carries a score or a reason field.
386
+
387
+ The five generated skills name no concept absent from the glossary and no generic label the
388
+ glossary omits. When a skill describes a rule about a term, that term appears in the glossary with
389
+ its score.
390
+
391
+ ## Discover skills
392
+
393
+ Write exactly these five directories, each with one `SKILL.md`:
394
+
395
+ ```
396
+ discover-testing-strategy
397
+ discover-naming-conventions
398
+ discover-coding-conventions
399
+ discover-architecture-boundaries
400
+ discover-glossary
401
+ ```
402
+
403
+ Frontmatter, in this shape:
404
+
405
+ ```yaml
406
+ ---
407
+ name: discover-<role>
408
+ description: One sentence naming the project-specific policy and when to apply it.
409
+ metadata:
410
+ devboard-managed: "true"
411
+ devboard-family: "discover"
412
+ devboard-skill: <role>
413
+ ---
414
+ ```
415
+
416
+ - `name` equals the directory name, matches `^[a-z0-9]+(?:-[a-z0-9]+)*$`, and is at most 64
417
+ characters. `description` is non-empty and at most 1024 characters. Neither marker may be
418
+ omitted; `devboard-managed` is the quoted string `"true"`.
419
+ - The body is a `#` heading title followed only by imperative bullets, one directive per bullet.
420
+ Every non-empty, non-heading line starts with `- `. No paragraphs, tables, prose introduction, or
421
+ chat report.
422
+ - Do not name a source, test, manifest, or CI file or directory in a bullet. State the rule and
423
+ the convention it applies to directly; the sheet and its evidence already carry the provenance.
424
+ An exact command is allowed even when it contains a path. Never append a path in parentheses to
425
+ show where a claim was derived.
426
+ - Never say where a rule was observed. A bullet carries no evidence clause (`Evidence:`, `See`,
427
+ `found in`, `declared in`), no file or directory name in any form — bare, backticked, quoted, or
428
+ in parentheses — and no path outside an exact command. A manifest such as `package.json`, a CI
429
+ descriptor, a test path, or a configuration file is provenance and never policy. The only two
430
+ paths a bullet may carry are those inside an exact command and the published glossary paths the
431
+ `discover-glossary` skill must name. When a directive would need a location to make sense,
432
+ rewrite it as the rule itself.
433
+ - When a previously published generated baseline exists under
434
+ `<host>/.omp/discover/skills/<name>/SKILL.md`, read it for continuity of scope and structure.
435
+ Always regenerate from the current crawl. Never copy a developer's live edits into the baseline;
436
+ the server preserves edited live skills byte for byte, replaces an unedited live skill with the
437
+ new baseline, and never recreates a deleted one. Write the generated baseline as if every live
438
+ skill were unedited.
439
+
440
+ Content each skill must carry:
441
+
442
+ - **discover-testing-strategy**: the levels actually present, the test pyramid, exact commands,
443
+ fixture roles, coverage expectations, and how to add a test for a change.
444
+ - **discover-naming-conventions**: canonical domain terms, casing for files, modules, types,
445
+ functions, errors, and flags, and rejected aliases.
446
+ - **discover-coding-conventions**: observed patterns, error handling, typing, async style, logging,
447
+ dependency use, formatting and linting, and prohibited constructs.
448
+ - **discover-architecture-boundaries**: bounded contexts, entry points, dependency direction,
449
+ persistence, integrations, and prohibited cross-boundary imports.
450
+ - **discover-glossary**: the canonical glossary directory, the confirmed and rejected term
451
+ rules, and the proposal process. Name every glossary file at its published path
452
+ `.omp/discover/glossary/<bounded-context>.glossary.yaml`, one bullet per bounded context; the
453
+ published glossary is a harness artifact, not a host source, so naming it is allowed.
454
+
455
+ All five baselines must be internally consistent and consistent with the glossary. Never recommend
456
+ an invalidated concept's preferred label. If two generated bullets would contradict, rewrite them
457
+ so both give compatible instructions.
458
+
459
+ ## Determinism
460
+
461
+ Two crawls of the same unchanged host MUST produce the same structural digest. A digest that moves
462
+ is a defect in the crawl, so follow these rules mechanically and do not re-derive a leaf from
463
+ different evidence between crawls.
464
+
465
+ - Use the fixed key orders above; sort every list of facts by its stable identity key; sort and
466
+ de-duplicate evidence; write enum values in their fixed spelling.
467
+ - Cite exactly one evidence entry per non-unknown leaf, never several. When more than one file
468
+ supports the fact, take the first that exists in this fixed order: the manifest or task-runner
469
+ file, then the CI or deployment descriptor, then configuration, then `README`/`AGENTS.md`/
470
+ `GOAL.md`/`adrs/`, then source, then tests. A list value's single evidence is the file that
471
+ declares every entry in it.
472
+ - Copy each free-text value verbatim from its cited file and keep the shortest exact fragment that
473
+ states the fact. Do not paraphrase, expand a version, or merge two files into one cell.
474
+ - Derive confidence by this table and nothing else:
475
+ - `observed` when the value appears verbatim in the cited file under a matching key or line;
476
+ - `declared` when the cited file states the fact in prose or a task name;
477
+ - `inferred` only when the cited git facts support it without stating it;
478
+ - `unknown` when no cited file states or supports it.
479
+ - Apply these fixed rules, so the same files always yield the same value:
480
+ - `deployment.class`: `container` only for a container file; `static-site` only for a static
481
+ build output; `service` only for a server entry point; `cli` only for a `bin` field;
482
+ `library` only for a `main`/`types` field with no `bin`; `package` only for a manifest that
483
+ publishes a package; `plugin` only for a plugin manifest; otherwise `none`, `observed`.
484
+ - `deployment.pipelineSources`: the CI/deployment file paths only when one of them carries a
485
+ publish, package, or deploy step; otherwise `unknown`.
486
+ - `branching.model`: `pull-request` only when CI triggers on `pull_request` or
487
+ `merge_request`; `git-flow` only when both a `develop` branch and a `release/*` branch exist;
488
+ `direct` only when CI has no review trigger and `git log` shows a linear default branch;
489
+ otherwise `unknown` with a reason.
490
+ - `testing.levels`: include a level only when a file path or command proves it; a level with no
491
+ evidence is omitted, never written with `tests: "0"`.
492
+ - When reading `git status`, ignore every path under `.omp/`: those are this feature's published
493
+ artifacts, not host facts.
494
+ - Write no timestamp, run id, publication time, fingerprint, or machine-specific value. The server
495
+ injects freshness and computes the structural digest.
496
+ - Keep bounded prose (the definition, titles, definitions, scope notes, history notes, and unknown
497
+ reasons) natural, but keep every fact, list, path, enum, and id identical for unchanged input.
498
+
499
+ ## Before you stop
500
+
501
+ Confirm all of the following:
502
+
503
+ - [ ] `<staging-dir>/sheet.json` exists, parses, has no `freshness` key, has every top-level key
504
+ in canonical order, and has every section and leaf required above.
505
+ - [ ] The definition is one sentence of at most 240 characters and ends with `.`.
506
+ - [ ] Every string value and list entry is a non-empty single line of at most 160 characters;
507
+ every `unknown` leaf other than `environments` has a null value, empty evidence, and a
508
+ reason; every known leaf has at least one repo-relative evidence entry; `environments`
509
+ carries at least the production entry.
510
+ - [ ] `architecture.externalBoundaries` names external systems only: each entry is an external
511
+ system, no runtime built-in, `node:` module, or concurrency primitive appears, and a host with
512
+ none stages `[]` with `confidence: observed` and evidence.
513
+ - [ ] Every `architecture.dependencies` entry names one context in `from` and one in `to`, never the
514
+ same context twice in an edge, never repeats an edge, and is grounded in a source file.
515
+ - [ ] No staged file contains an absolute path, a secret value, a URL with user info, a paragraph,
516
+ a timestamp, or a run id.
517
+ - [ ] At least one `glossary/<boundedContext>.glossary.yaml` exists, parses as YAML, has the
518
+ required top-level and concept keys in order, unique kebab-case ids, at least one concept,
519
+ an English preferred label and definition per concept, and at least one valid grounding per
520
+ concept.
521
+ - [ ] Every concept is `unconfirmed` or `proposed`; every `origin: standard` has a `standardRef`;
522
+ no confirmed, deprecated, or invalidated status appears.
523
+ - [ ] `glossary/significance.json` exists beside the glossaries and every staged glossary concept
524
+ carries a significance score in it: one integer from `0` to `100` and a one-line reason,
525
+ with no missing, extra, or unscored entry.
526
+ - [ ] `commands.tryOut` is either a hands-on entry point that no recorded command aliases, or
527
+ `unknown`: it never repeats, wraps, or aliases install, build, test, lint, typecheck,
528
+ dev/run, or release.
529
+ - [ ] No generic label the glossaries omit is named by a generated skill, and every concept a
530
+ generated skill names appears in the glossary.
531
+ - [ ] All five `skills/<name>/SKILL.md` files exist with matching names, non-empty descriptions of
532
+ at most 1024 characters, and both markers; each body is a heading plus imperative bullets,
533
+ and no bullet names a source, test, manifest, or CI path or cites where a rule was observed.
534
+ - [ ] The five baselines do not contradict each other or the glossary, and no skill recommends an
535
+ invalidated label.
536
+ - [ ] Nothing was written outside `<staging-dir>`; `GOAL.md`, `adrs/`, host source, `.omp/discover`,
537
+ and `.omp/skills` are untouched.
538
+ - [ ] No question was asked and no project command, test, build, install, fetch, or forge query was
539
+ run.
540
+
541
+ Reply with nothing. The staged files are the result.