@galaxyproject/orbit 0.0.0 → 0.9.0

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 (451) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/LICENSE +21 -0
  3. package/README.md +760 -5
  4. package/bin/legacy-mcp-config.js +363 -0
  5. package/bin/orbit.js +810 -0
  6. package/bin/pi-extension-path.d.ts +4 -0
  7. package/bin/pi-extension-path.js +44 -0
  8. package/bin/provider-auth.d.ts +22 -0
  9. package/bin/provider-auth.js +77 -0
  10. package/bin/thinking-pref.js +38 -0
  11. package/bin/update-check.d.ts +15 -0
  12. package/bin/update-check.js +137 -0
  13. package/extensions/cli-update/index.ts +32 -0
  14. package/extensions/orbit/activity-hooks.ts +141 -0
  15. package/extensions/orbit/activity.ts +116 -0
  16. package/extensions/orbit/agent-dir.ts +11 -0
  17. package/extensions/orbit/auto-resume.ts +352 -0
  18. package/extensions/orbit/config.ts +3 -0
  19. package/extensions/orbit/confusables.ts +1 -0
  20. package/extensions/orbit/context.ts +957 -0
  21. package/extensions/orbit/dashboard-commands.ts +191 -0
  22. package/extensions/orbit/dashboard-store.ts +473 -0
  23. package/extensions/orbit/dashboard-tools.ts +1185 -0
  24. package/extensions/orbit/empty-completion.ts +99 -0
  25. package/extensions/orbit/evidence-gate.ts +1276 -0
  26. package/extensions/orbit/evidence-override-command.ts +294 -0
  27. package/extensions/orbit/exec-guard/bash-risk.ts +1408 -0
  28. package/extensions/orbit/exec-guard/gate.ts +181 -0
  29. package/extensions/orbit/exec-guard/guardian-config.ts +54 -0
  30. package/extensions/orbit/exec-guard/index.ts +1 -0
  31. package/extensions/orbit/exec-guard/model-tier.ts +36 -0
  32. package/extensions/orbit/exec-guard/path-jail.ts +54 -0
  33. package/extensions/orbit/exec-guard/policy.ts +342 -0
  34. package/extensions/orbit/exec-guard/runtime-state.ts +15 -0
  35. package/extensions/orbit/exec-guard/sensitive-read.ts +525 -0
  36. package/extensions/orbit/exec-guard/types.ts +42 -0
  37. package/extensions/orbit/execution-commands.ts +134 -0
  38. package/extensions/orbit/feedback-command.ts +81 -0
  39. package/extensions/orbit/feedback.ts +96 -0
  40. package/extensions/orbit/galaxy-api.test.ts +122 -0
  41. package/extensions/orbit/galaxy-api.ts +606 -0
  42. package/extensions/orbit/galaxy-artifact-link-guidance.ts +5 -0
  43. package/extensions/orbit/galaxy-destructive-gate.ts +113 -0
  44. package/extensions/orbit/galaxy-enrich.ts +1108 -0
  45. package/extensions/orbit/galaxy-failure.ts +101 -0
  46. package/extensions/orbit/galaxy-fixture.ts +126 -0
  47. package/extensions/orbit/galaxy-history-guard.ts +233 -0
  48. package/extensions/orbit/galaxy-job-block.ts +347 -0
  49. package/extensions/orbit/galaxy-job-ops.ts +288 -0
  50. package/extensions/orbit/galaxy-live-source.ts +929 -0
  51. package/extensions/orbit/galaxy-markdown-adapter.ts +248 -0
  52. package/extensions/orbit/galaxy-op-policy.ts +332 -0
  53. package/extensions/orbit/galaxy-ops-tools.ts +326 -0
  54. package/extensions/orbit/galaxy-output-store.ts +80 -0
  55. package/extensions/orbit/galaxy-output.ts +346 -0
  56. package/extensions/orbit/galaxy-page-binding.ts +222 -0
  57. package/extensions/orbit/galaxy-page-markdown-guidance.ts +15 -0
  58. package/extensions/orbit/galaxy-page-ops.ts +159 -0
  59. package/extensions/orbit/galaxy-page-sync.test.ts +417 -0
  60. package/extensions/orbit/galaxy-page-sync.ts +318 -0
  61. package/extensions/orbit/galaxy-pages-api.ts +203 -0
  62. package/extensions/orbit/galaxy-pages-sync.ts +409 -0
  63. package/extensions/orbit/galaxy-poll-guard.ts +189 -0
  64. package/extensions/orbit/galaxy-poller.ts +706 -0
  65. package/extensions/orbit/galaxy-provenance.ts +623 -0
  66. package/extensions/orbit/galaxy-reconcile.ts +956 -0
  67. package/extensions/orbit/galaxy-recovery.ts +176 -0
  68. package/extensions/orbit/galaxy-repeat-guard.ts +55 -0
  69. package/extensions/orbit/galaxy-submission-capture.ts +707 -0
  70. package/extensions/orbit/galaxy-submission.ts +502 -0
  71. package/extensions/orbit/galaxy-tool-source.ts +78 -0
  72. package/extensions/orbit/galaxy-tool-wrap.ts +234 -0
  73. package/extensions/orbit/galaxy-udt-block.ts +127 -0
  74. package/extensions/orbit/galaxy-upload-tus.ts +334 -0
  75. package/extensions/orbit/galaxy-upload.ts +300 -0
  76. package/extensions/orbit/galaxy-version-capture.ts +65 -0
  77. package/extensions/orbit/git.ts +173 -0
  78. package/extensions/orbit/harness-block-fields.ts +597 -0
  79. package/extensions/orbit/index.ts +593 -0
  80. package/extensions/orbit/init-gate.ts +284 -0
  81. package/extensions/orbit/instructions-command.ts +136 -0
  82. package/extensions/orbit/invocation-failure-hint.ts +57 -0
  83. package/extensions/orbit/iwc-plan-check.ts +94 -0
  84. package/extensions/orbit/lesson-command.ts +303 -0
  85. package/extensions/orbit/lesson-hint.ts +245 -0
  86. package/extensions/orbit/lesson-nudge.ts +106 -0
  87. package/extensions/orbit/lessons/compose.ts +177 -0
  88. package/extensions/orbit/lessons/counters.ts +120 -0
  89. package/extensions/orbit/lessons/enabled.ts +116 -0
  90. package/extensions/orbit/lessons/matcher.ts +346 -0
  91. package/extensions/orbit/lessons/paths.ts +286 -0
  92. package/extensions/orbit/lessons/pi-event-contract.ts +105 -0
  93. package/extensions/orbit/lessons/propose-replay.ts +103 -0
  94. package/extensions/orbit/lessons/propose-tool.ts +222 -0
  95. package/extensions/orbit/lessons/propose.ts +502 -0
  96. package/extensions/orbit/lessons/replay.ts +89 -0
  97. package/extensions/orbit/lessons/reproduction-index.ts +83 -0
  98. package/extensions/orbit/lessons/search-tool.ts +99 -0
  99. package/extensions/orbit/lessons/search.ts +136 -0
  100. package/extensions/orbit/lessons/store.ts +415 -0
  101. package/extensions/orbit/lessons/text.ts +36 -0
  102. package/extensions/orbit/lessons/types.ts +69 -0
  103. package/extensions/orbit/lessons/user-dir.ts +24 -0
  104. package/extensions/orbit/lessons/user-lesson.ts +88 -0
  105. package/extensions/orbit/lessons/wrapper.ts +61 -0
  106. package/extensions/orbit/lessons-command.ts +147 -0
  107. package/extensions/orbit/local-exec.ts +39 -0
  108. package/extensions/orbit/mcp-output.ts +179 -0
  109. package/extensions/orbit/mcp-servers.test.ts +24 -0
  110. package/extensions/orbit/mcp-servers.ts +25 -0
  111. package/extensions/orbit/model-script.ts +351 -0
  112. package/extensions/orbit/notebook-anchors.ts +342 -0
  113. package/extensions/orbit/notebook-writer.ts +863 -0
  114. package/extensions/orbit/observation-allowlists.ts +1109 -0
  115. package/extensions/orbit/observation-replay.ts +148 -0
  116. package/extensions/orbit/observation-triggers.ts +563 -0
  117. package/extensions/orbit/observation-ui.ts +175 -0
  118. package/extensions/orbit/observations-command.ts +421 -0
  119. package/extensions/orbit/observations-config.ts +200 -0
  120. package/extensions/orbit/observations.ts +1381 -0
  121. package/extensions/orbit/profiles.ts +270 -0
  122. package/extensions/orbit/progress-updates.ts +95 -0
  123. package/extensions/orbit/proposal-commands.ts +882 -0
  124. package/extensions/orbit/provenance-fs-file.ts +59 -0
  125. package/extensions/orbit/provenance-fs.ts +32 -0
  126. package/extensions/orbit/provenance-memory-fs.ts +59 -0
  127. package/extensions/orbit/record-store-file.ts +177 -0
  128. package/extensions/orbit/record-store-page.ts +77 -0
  129. package/extensions/orbit/record-store-seam.ts +47 -0
  130. package/extensions/orbit/record-store.ts +149 -0
  131. package/extensions/orbit/registry-carrier.ts +107 -0
  132. package/extensions/orbit/registry-eligibility.ts +95 -0
  133. package/extensions/orbit/registry-evaluation.ts +403 -0
  134. package/extensions/orbit/registry-evaluator.ts +519 -0
  135. package/extensions/orbit/registry-import.ts +91 -0
  136. package/extensions/orbit/registry-lock.ts +221 -0
  137. package/extensions/orbit/registry-memory-fs.ts +42 -0
  138. package/extensions/orbit/registry-page-carrier.ts +103 -0
  139. package/extensions/orbit/registry-proposal.ts +1348 -0
  140. package/extensions/orbit/registry-runtime.ts +234 -0
  141. package/extensions/orbit/registry-schema.ts +735 -0
  142. package/extensions/orbit/registry-submitter.ts +59 -0
  143. package/extensions/orbit/registry-templates.ts +346 -0
  144. package/extensions/orbit/registry.ts +476 -0
  145. package/extensions/orbit/sandbox/index.ts +120 -0
  146. package/extensions/orbit/sandbox/sandbox-bash.ts +93 -0
  147. package/extensions/orbit/sandbox/sandbox-config.ts +87 -0
  148. package/extensions/orbit/sandbox/sandbox-init-message.ts +28 -0
  149. package/extensions/orbit/secret-redaction.ts +247 -0
  150. package/extensions/orbit/session-index/cwd.ts +18 -0
  151. package/extensions/orbit/session-index/db.ts +56 -0
  152. package/extensions/orbit/session-index/indexer.ts +154 -0
  153. package/extensions/orbit/session-index/is-enabled.ts +17 -0
  154. package/extensions/orbit/session-index/parse.ts +254 -0
  155. package/extensions/orbit/session-index/query.ts +209 -0
  156. package/extensions/orbit/session-index/schema.ts +72 -0
  157. package/extensions/orbit/session-index/tools.ts +152 -0
  158. package/extensions/orbit/session-lifecycle.ts +321 -0
  159. package/extensions/orbit/skill-triggers.ts +159 -0
  160. package/extensions/orbit/skills-command.ts +48 -0
  161. package/extensions/orbit/skills-discovery.ts +435 -0
  162. package/extensions/orbit/skills.ts +84 -0
  163. package/extensions/orbit/sra-import-gate.ts +77 -0
  164. package/extensions/orbit/state.ts +265 -0
  165. package/extensions/orbit/submission-replay.ts +147 -0
  166. package/extensions/orbit/sync-command.ts +157 -0
  167. package/extensions/orbit/teams/critic-parser.ts +93 -0
  168. package/extensions/orbit/teams/dispatcher.ts +210 -0
  169. package/extensions/orbit/teams/is-enabled.ts +22 -0
  170. package/extensions/orbit/teams/tool.ts +187 -0
  171. package/extensions/orbit/teams/types.ts +57 -0
  172. package/extensions/orbit/teams/validate.ts +42 -0
  173. package/extensions/orbit/tester-id-command.ts +133 -0
  174. package/extensions/orbit/tools-sync.ts +279 -0
  175. package/extensions/orbit/tools.ts +1300 -0
  176. package/extensions/orbit/types.ts +41 -0
  177. package/extensions/orbit/ui-bridge.ts +55 -0
  178. package/extensions/orbit/ulid.ts +60 -0
  179. package/extensions/orbit/user-instructions.ts +388 -0
  180. package/extensions/orbit/vendor/skills/_catalog.json +68 -0
  181. package/extensions/orbit/vendor/skills/_manifest.json +1106 -0
  182. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/SKILL.md +112 -0
  183. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_provenance.json +218 -0
  184. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_required_tools.json +33 -0
  185. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_verify.json +4 -0
  186. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/add.json +50 -0
  187. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-extract.json +51 -0
  188. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-next-step.json +42 -0
  189. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-validate.json +140 -0
  190. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/list.json +32 -0
  191. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/galaxy-tool-job-failure-reference.md +137 -0
  192. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/open-requirements-ledger.md +173 -0
  193. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-tool-summary.schema.json +175 -0
  194. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
  195. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/SKILL.md +82 -0
  196. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_provenance.json +133 -0
  197. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_required_tools.json +16 -0
  198. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_verify.json +4 -0
  199. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/cli/draft-validate.json +140 -0
  200. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/galaxy-workflow-draft-format.md +135 -0
  201. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
  202. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
  203. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/SKILL.md +84 -0
  204. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_provenance.json +166 -0
  205. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_verify.json +29 -0
  206. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/galaxy-workflow-testability-design.md +136 -0
  207. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  208. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-test-data-conventions.md +308 -0
  209. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-asserts-idioms.md +246 -0
  210. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-workflow-test-architecture.md +151 -0
  211. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
  212. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  213. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/tests-format.schema.json +7328 -0
  214. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/SKILL.md +127 -0
  215. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_provenance.json +198 -0
  216. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_required_tools.json +16 -0
  217. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_verify.json +4 -0
  218. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/cli/convert.json +123 -0
  219. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/galaxy-data-flow-draft-contract.md +129 -0
  220. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  221. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-test-data-conventions.md +308 -0
  222. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/open-requirements-ledger.md +173 -0
  223. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/SKILL.md +73 -0
  224. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_provenance.json +160 -0
  225. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_verify.json +4 -0
  226. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.md +43 -0
  227. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.yml +1250 -0
  228. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-tool-job-failure-reference.md +137 -0
  229. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  230. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  231. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/nextflow-operators-to-galaxy-collection-recipes.md +98 -0
  232. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-asserts-idioms.md +246 -0
  233. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-workflow-test-architecture.md +151 -0
  234. package/extensions/orbit/vendor/skills/discover-shed-tool/SKILL.md +174 -0
  235. package/extensions/orbit/vendor/skills/discover-shed-tool/_provenance.json +130 -0
  236. package/extensions/orbit/vendor/skills/discover-shed-tool/_required_tools.json +18 -0
  237. package/extensions/orbit/vendor/skills/discover-shed-tool/_verify.json +17 -0
  238. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-revisions.json +48 -0
  239. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-search.json +95 -0
  240. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-versions.json +39 -0
  241. package/extensions/orbit/vendor/skills/discover-shed-tool/references/notes/component-tool-shed-search.md +230 -0
  242. package/extensions/orbit/vendor/skills/discover-shed-tool/references/schemas/galaxy-tool-discovery.schema.json +231 -0
  243. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/SKILL.md +93 -0
  244. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_provenance.json +201 -0
  245. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_required_tools.json +28 -0
  246. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_verify.json +17 -0
  247. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/planemo.md +44 -0
  248. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/validate-tests.json +40 -0
  249. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/galaxy-workflow-testability-design.md +136 -0
  250. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  251. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-test-data-conventions.md +308 -0
  252. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
  253. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
  254. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
  255. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/tests-format.schema.json +7328 -0
  256. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/SKILL.md +81 -0
  257. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_provenance.json +93 -0
  258. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_verify.json +17 -0
  259. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
  260. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  261. package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/SKILL.md +81 -0
  262. package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/_assembly.json +23 -0
  263. package/extensions/orbit/vendor/skills/run-workflow-test/SKILL.md +79 -0
  264. package/extensions/orbit/vendor/skills/run-workflow-test/_provenance.json +125 -0
  265. package/extensions/orbit/vendor/skills/run-workflow-test/_required_tools.json +28 -0
  266. package/extensions/orbit/vendor/skills/run-workflow-test/_verify.json +4 -0
  267. package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/planemo.md +44 -0
  268. package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/validate-tests.json +40 -0
  269. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  270. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
  271. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
  272. package/extensions/orbit/vendor/skills/run-workflow-test/references/schemas/tests-format.schema.json +7328 -0
  273. package/extensions/orbit/vendor/skills/skills/LICENSE +21 -0
  274. package/extensions/orbit/vendor/skills/skills/collection-manipulation/README.md +39 -0
  275. package/extensions/orbit/vendor/skills/skills/collection-manipulation/SKILL.md +892 -0
  276. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/api-patterns.md +927 -0
  277. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/apply-rules.md +1482 -0
  278. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/test-patterns.md +996 -0
  279. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/tools.md +609 -0
  280. package/extensions/orbit/vendor/skills/skills/galaxy-data-libraries/SKILL.md +170 -0
  281. package/extensions/orbit/vendor/skills/skills/galaxy-integration/README.md +162 -0
  282. package/extensions/orbit/vendor/skills/skills/galaxy-integration/SKILL.md +99 -0
  283. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/README.md +119 -0
  284. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/tool-checking.md +419 -0
  285. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/workflow-testing.md +617 -0
  286. package/extensions/orbit/vendor/skills/skills/galaxy-integration/galaxy-integration.md +614 -0
  287. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/SKILL.md +144 -0
  288. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/average_col3.ipynb +68 -0
  289. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/extract_sample_metadata.ipynb +190 -0
  290. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/variant_annotation.ipynb +816 -0
  291. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/vcp_variant_map.ipynb +443 -0
  292. package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/README.md +165 -0
  293. package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/galaxy_tool_checker.py +521 -0
  294. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/SKILL.md +128 -0
  295. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/gotchas.md +135 -0
  296. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/history-access.md +132 -0
  297. package/extensions/orbit/vendor/skills/skills/reproduciblify/SKILL.md +146 -0
  298. package/extensions/orbit/vendor/skills/skills/reproduciblify/references/directives.yml +496 -0
  299. package/extensions/orbit/vendor/skills/skills/udt-authoring/SKILL.md +245 -0
  300. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/01-minimal-echo.yml +27 -0
  301. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/02-single-data-in-out.yml +27 -0
  302. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/03-multiple-data-js.yml +28 -0
  303. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/04-select-integer-boolean.yml +41 -0
  304. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/05-resource-requirements.yml +25 -0
  305. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/06-biocontainer-tool.yml +38 -0
  306. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/07-inline-python-script.yml +56 -0
  307. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/08-configfile-script.yml +74 -0
  308. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/common-mistakes.md +76 -0
  309. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/schema-reference.md +155 -0
  310. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/templating.md +196 -0
  311. package/extensions/orbit/vendor/skills/skills/udt-authoring/scripts/validate.py +109 -0
  312. package/extensions/orbit/vendor/skills/skills/workflow-reports/README.md +71 -0
  313. package/extensions/orbit/vendor/skills/skills/workflow-reports/SKILL.md +190 -0
  314. package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/histology-staining.md +145 -0
  315. package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/tissue-microarray-analysis.md +176 -0
  316. package/extensions/orbit/vendor/skills/skills/workflow-reports/references/directives.md +415 -0
  317. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/SKILL.md +98 -0
  318. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_provenance.json +93 -0
  319. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_required_tools.json +28 -0
  320. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_verify.json +17 -0
  321. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/convert.json +123 -0
  322. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/foundry.md +25 -0
  323. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/validate.json +142 -0
  324. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  325. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/SKILL.md +74 -0
  326. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_provenance.json +71 -0
  327. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_required_tools.json +16 -0
  328. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_verify.json +4 -0
  329. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/cli/validate.json +142 -0
  330. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  331. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-testability-design.md +136 -0
  332. package/extensions/orbit/vendor-skills.ts +283 -0
  333. package/extensions/orbit/workspace-state-dir.ts +46 -0
  334. package/extensions/orbit-handoff/index.ts +73 -0
  335. package/extensions/orbit-handoff/orbit-launcher.ts +142 -0
  336. package/extensions/whats-new/index.ts +98 -0
  337. package/lessons/LICENSE +17 -0
  338. package/lessons/README.md +117 -0
  339. package/lessons/SCHEMA.md +187 -0
  340. package/lessons/build-snapshot.mjs +311 -0
  341. package/lessons/data/downloaded-file-is-not-what-its-extension-says.md +61 -0
  342. package/lessons/galaxy-api/403-history-is-a-hard-stop.md +57 -0
  343. package/lessons/galaxy-api/collection-into-single-dataset-input.md +61 -0
  344. package/lessons/galaxy-api/connectedvalue-in-command-line.md +62 -0
  345. package/lessons/galaxy-api/hid-is-not-an-id.md +59 -0
  346. package/lessons/galaxy-api/invoke-workflow-inputs-not-params.md +60 -0
  347. package/lessons/galaxy-api/repeat-param-pipe-keys.md +63 -0
  348. package/lessons/galaxy-api/run-tool-returns-on-submit.md +61 -0
  349. package/lessons/galaxy-tools/reference-index-not-on-server.md +62 -0
  350. package/lessons/log.md +42 -0
  351. package/lessons/reproduction/input-population-mismatch.md +59 -0
  352. package/lessons/reproduction/methods-text-vs-executed-parameters.md +62 -0
  353. package/lessons/snapshot.json +1004 -0
  354. package/lessons/stats/de-contrast-direction-and-sample-labels.md +63 -0
  355. package/lessons/stats/na-coerced-to-zero-in-filters.md +59 -0
  356. package/lessons/validate.mjs +1219 -0
  357. package/package.json +103 -5
  358. package/shared/agent-prompt.d.ts +8 -0
  359. package/shared/agent-prompt.js +15 -0
  360. package/shared/approval-prompt.d.ts +4 -0
  361. package/shared/approval-prompt.js +61 -0
  362. package/shared/brain-env.d.ts +14 -0
  363. package/shared/brain-env.js +108 -0
  364. package/shared/brain-exit.d.ts +20 -0
  365. package/shared/brain-exit.js +149 -0
  366. package/shared/capability-profile.d.ts +16 -0
  367. package/shared/capability-profile.js +75 -0
  368. package/shared/config-source.d.ts +13 -0
  369. package/shared/config-source.js +17 -0
  370. package/shared/confusables.d.ts +3 -0
  371. package/shared/confusables.js +93 -0
  372. package/shared/custom-provider.d.ts +45 -0
  373. package/shared/custom-provider.js +169 -0
  374. package/shared/dashboard-contract.d.ts +123 -0
  375. package/shared/dashboard-contract.js +560 -0
  376. package/shared/dashboard-layout-store.d.ts +44 -0
  377. package/shared/dashboard-layout-store.js +281 -0
  378. package/shared/feedback-contract.d.ts +61 -0
  379. package/shared/feedback-contract.js +146 -0
  380. package/shared/galaxy-artifact-links.d.ts +30 -0
  381. package/shared/galaxy-artifact-links.js +166 -0
  382. package/shared/galaxy-credentials.d.ts +26 -0
  383. package/shared/galaxy-credentials.js +71 -0
  384. package/shared/galaxy-destructive.d.ts +21 -0
  385. package/shared/galaxy-destructive.js +269 -0
  386. package/shared/galaxy-guidance.d.ts +2 -0
  387. package/shared/galaxy-guidance.js +53 -0
  388. package/shared/galaxy-live-contract.d.ts +92 -0
  389. package/shared/galaxy-live-contract.js +180 -0
  390. package/shared/galaxy-page-cells.d.ts +2 -0
  391. package/shared/galaxy-page-cells.js +22 -0
  392. package/shared/galaxy-tool-family.d.ts +5 -0
  393. package/shared/galaxy-tool-family.js +27 -0
  394. package/shared/galaxy-url.d.ts +1 -0
  395. package/shared/galaxy-url.js +48 -0
  396. package/shared/gtn.d.ts +31 -0
  397. package/shared/gtn.js +253 -0
  398. package/shared/handled-prompt.d.ts +3 -0
  399. package/shared/handled-prompt.js +26 -0
  400. package/shared/known-provider.d.ts +11 -0
  401. package/shared/known-provider.js +89 -0
  402. package/shared/lesson-hint-marker.d.ts +7 -0
  403. package/shared/lesson-hint-marker.js +32 -0
  404. package/shared/lesson-rules.d.ts +150 -0
  405. package/shared/lesson-rules.js +203 -0
  406. package/shared/malformed-object-ids.d.ts +1 -0
  407. package/shared/malformed-object-ids.js +37 -0
  408. package/shared/markdown-sections.d.ts +10 -0
  409. package/shared/markdown-sections.js +118 -0
  410. package/shared/notebook-fences.d.ts +12 -0
  411. package/shared/notebook-fences.js +53 -0
  412. package/shared/observation-contract.d.ts +91 -0
  413. package/shared/observation-contract.js +544 -0
  414. package/shared/orbit-config.d.ts +226 -0
  415. package/shared/orbit-config.js +189 -0
  416. package/shared/orbit-env.d.ts +13 -0
  417. package/shared/orbit-env.js +124 -0
  418. package/shared/orbit-shell-contract.d.ts +74 -0
  419. package/shared/orbit-shell-contract.js +30 -0
  420. package/shared/page-content-hash.d.ts +1 -0
  421. package/shared/page-content-hash.js +13 -0
  422. package/shared/pi-default-model.d.ts +7 -0
  423. package/shared/pi-default-model.js +41 -0
  424. package/shared/prompt-blocks.d.ts +87 -0
  425. package/shared/prompt-blocks.js +898 -0
  426. package/shared/provider-auth-caps.d.ts +22 -0
  427. package/shared/provider-auth-caps.js +57 -0
  428. package/shared/random.d.ts +2 -0
  429. package/shared/random.js +15 -0
  430. package/shared/record-excerpt.d.ts +4 -0
  431. package/shared/record-excerpt.js +16 -0
  432. package/shared/redirect-guard.d.ts +36 -0
  433. package/shared/redirect-guard.js +235 -0
  434. package/shared/skills-pin.d.ts +8 -0
  435. package/shared/skills-pin.js +9 -0
  436. package/shared/skills-router.d.ts +17 -0
  437. package/shared/skills-router.js +63 -0
  438. package/shared/sra-import.d.ts +34 -0
  439. package/shared/sra-import.js +206 -0
  440. package/shared/state-dir.d.ts +21 -0
  441. package/shared/state-dir.js +240 -0
  442. package/shared/team-dispatch-contract.d.ts +28 -0
  443. package/shared/team-dispatch-contract.js +1 -0
  444. package/shared/truncate-middle.d.ts +11 -0
  445. package/shared/truncate-middle.js +68 -0
  446. package/shared/version-compare.d.ts +10 -0
  447. package/shared/version-compare.js +74 -0
  448. package/shared/whats-new.d.ts +31 -0
  449. package/shared/whats-new.js +83 -0
  450. package/shared/wsl.d.ts +10 -0
  451. package/shared/wsl.js +24 -0
@@ -0,0 +1,117 @@
1
+ # Lessons
2
+
3
+ A lesson records one observed, scoped thing: _in this situation this goes wrong,
4
+ here is how to tell it is this one, here is what to do, and here is how to know
5
+ it worked._ It is not a skill. A skill is authored, prescriptive and broad; a
6
+ lesson is a note from a specific failure that nobody wrote down the first time.
7
+
8
+ The corpus is deliberately small. Most knowledge belongs somewhere else, and the
9
+ sorting rule below is about sending it there.
10
+
11
+ ## The sorting rule
12
+
13
+ Before writing a lesson, ask what the knowledge is. Exactly one destination:
14
+
15
+ | What it is | Where it goes |
16
+ | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
17
+ | Already in a GTN FAQ, tutorial or forum thread | Cite that. No lesson. |
18
+ | Already a lesson here | Add evidence to the existing one -- counts, versions, another `sources` entry. No new lesson. |
19
+ | Something a validator, a schema or a better error message would catch | An issue on galaxy-mcp, the Foundry, or Galaxy. Never the corpus. |
20
+ | A general how-to | A GTN FAQ pull request. Regular docs are the default landing. |
21
+ | Agent misbehaviour | The Orbit prompt plus an eval. Not knowledge. |
22
+ | A silent scientific pitfall, an expectation, a choice, a source quirk, or a reproduction note, with no hit above | A lesson here. |
23
+
24
+ The last row is the whole corpus. If a lesson would be better as an error
25
+ message, write the error message.
26
+
27
+ ## Namespaces
28
+
29
+ The namespace is the first path segment and part of the lesson's id, so
30
+ `stats/na-coerced-to-zero-in-filters.md` has the id
31
+ `stats/na-coerced-to-zero-in-filters`.
32
+
33
+ - `stats` -- statistical reasoning and interpretation.
34
+ - `reproduction` -- reproducing a published analysis.
35
+ - `data` -- acquiring data and what the source actually hands back.
36
+ - `galaxy-tools` -- a tool or a server's configuration of it.
37
+ - `galaxy-api` -- lessons whose durable fix now lives somewhere else. Kept for
38
+ the record, never surfaced: a non-empty `graduated_to` is what makes that
39
+ true, and the validator requires one in this namespace.
40
+
41
+ ## Layout
42
+
43
+ ```
44
+ lessons/
45
+ README.md SCHEMA.md LICENSE log.md
46
+ validate.mjs build-snapshot.mjs snapshot.json
47
+ <namespace>/<slug>.md
48
+ ```
49
+
50
+ `snapshot.json` is generated and committed. Never hand-edit it: run
51
+ `npm run build:lessons` and commit the result. `npm run check:lessons` validates
52
+ every lesson and fails if the snapshot is out of date, and runs in CI.
53
+
54
+ ## Writing one
55
+
56
+ `SCHEMA.md` is the field list. The things that actually decide whether a lesson
57
+ earns its place:
58
+
59
+ - **The title is the situation, not the fix.** "Numeric filters treat NA as 0"
60
+ rather than "Always exclude NA".
61
+ - **`Check first` and `Validate` are required, and are the point.** The first
62
+ keeps the lesson from being applied to a situation that merely looks similar.
63
+ The second keeps "the error went away" from passing as success.
64
+ - **Cause is optional and labelled.** Recovering from something is not proof you
65
+ diagnosed it. Say `hypothesized` when it is a hypothesis.
66
+ - **Evidence, editorial status and applicability are three separate axes.**
67
+ `evidence.{symptom,cause,outcome}` each carry their own label and a `method`;
68
+ `status` is editorial; `applies_to.versions` is scope. There is no single
69
+ confidence score and nothing is promoted automatically.
70
+ - **Triggers are machine-matchable or they are decoration.** Literal normalized
71
+ signatures, tool ids, `galaxy_*` MCP tool names, datatypes, bare hostnames,
72
+ dotted extensions, lowercase plan-step keywords. The prose `cues` field is for
73
+ humans and is never matched. A lesson with every trigger list empty is
74
+ rejected.
75
+ - **An upstream fix narrows `applies_to.versions`.** It does not retire the
76
+ lesson -- older installs still hit it.
77
+ - **`stale_after` is required.** A lesson that nobody will re-verify should drop
78
+ out on its own.
79
+
80
+ The body carries nothing to follow and nothing to run: no URLs, no markdown
81
+ links, images or HTML, no code blocks, printable ASCII only, each section at
82
+ most 600 characters. Those are enforced, not advisory. Provenance goes in
83
+ `sources`, and a link there must point at one of the hosts listed in
84
+ `LINK_HOSTS` in `validate.mjs`.
85
+
86
+ ## Contributing
87
+
88
+ 1. Fork, branch, add one `.md` file under the right namespace.
89
+ 2. `npm run check:lessons` -- it prints `path:line: message` for every problem.
90
+ 3. `npm run build:lessons` and commit `lessons/snapshot.json` alongside.
91
+ 4. Add a line to `log.md`.
92
+ 5. Open a pull request against `main`.
93
+
94
+ Your pull request needs both of these, checked by you:
95
+
96
+ ```
97
+ - [ ] This lesson contains no personal data and no research data. No filesystem
98
+ paths, dataset or history ids, URLs, private server hostnames, dataset,
99
+ history, sample or account names, and no values copied out of anyone's
100
+ data -- mine or anybody else's.
101
+ - [ ] Signed-off-by line present (Developer Certificate of Origin 1.1), and I
102
+ am licensing this lesson under CC BY 4.0 as described in LICENSE.
103
+ ```
104
+
105
+ Sign off with `git commit -s`, which appends
106
+ `Signed-off-by: Your Name <you@example.com>`. That line is the Developer
107
+ Certificate of Origin 1.1 assertion: you wrote the contribution, or have the
108
+ right to submit it under the licence above.
109
+
110
+ The validator is the second line of defence on the first checkbox, not the
111
+ first. It refuses the shapes of URLs, links, HTML, paths, ids, addresses and
112
+ keys and caps every field, but it cannot tell that a plausible-looking tool id
113
+ was a private server's, that a sentence describes one specific person's data,
114
+ or that a sentence is an instruction aimed at the model rather than advice. That judgement is yours, and a
115
+ published lesson cannot be unpublished from git history -- the privacy decision
116
+ happens before the pull request, which is why the checkbox is phrased the way
117
+ it is.
@@ -0,0 +1,187 @@
1
+ # Lesson schema v1
2
+
3
+ The file format. `validate.mjs` is the authoritative version of all of this:
4
+ where this document and that script disagree, the script wins and this document
5
+ is wrong. Run `npm run check:lessons`.
6
+
7
+ One markdown file per lesson at `lessons/<namespace>/<slug>.md`. The id is the
8
+ path minus `.md`, e.g. `stats/na-coerced-to-zero-in-filters`. The slug is
9
+ lowercase words joined by hyphens, at most 80 characters.
10
+
11
+ The format is Google Cloud's Open Knowledge Format: a directory of markdown with
12
+ YAML frontmatter, distributed as a git repository. OKF fields come first; Orbit's
13
+ extension fields come after.
14
+
15
+ ## Frontmatter
16
+
17
+ ```yaml
18
+ type: Lesson # OKF required
19
+ title: string # <= 120 chars; the situation, not the fix
20
+ description: string # <= 200 chars, one line
21
+ tags: [string] # free; stage and formats are mirrored here by the build
22
+ status: draft | stable | deprecated # OKF
23
+ generated: { by: string, at: string } # e.g. "agent:loom/0.6.0" or "human:loom-maintainers"
24
+ verified: [{ by: string, at: string }] # optional; by = "human:<pseudonym>", never a contributor id
25
+ stale_after: string # ISO date; required
26
+ sources: [{ id: string, resource?: string, title?: string }] # provenance; required when derived from GTN/forum
27
+
28
+ kind: pitfall | expectation | choice | source-quirk | reproduction
29
+ stage:
30
+ [
31
+ data-acquisition | metadata-reconciliation | tool-parameterization | job-execution | result-interpretation,
32
+ ]
33
+ trigger:
34
+ signatures: [string] # literal, normalized, each <= 200
35
+ tools: [string] # Galaxy tool ids or families
36
+ mcp_tools: [string] # galaxy_* names
37
+ formats: [string] # datatypes / extensions
38
+ hosts: [string] # hostnames seen in URLs/commands, e.g. "ncbi.nlm.nih.gov"
39
+ extensions: [string] # file extensions seen in args, e.g. ".gtf"
40
+ step_keywords: [string] # lowercase words matched against plan-step text
41
+ cues: string # human-readable description of when this applies (not matched)
42
+ applies_to: { versions: string, tested: string }
43
+ evidence:
44
+ symptom: verified | reported
45
+ cause: verified | hypothesized | unknown
46
+ outcome: validated | unvalidated
47
+ method: string
48
+ graduated_to: [string] # free text or links; non-empty => not surfaced by the matcher
49
+ upstream: [string]
50
+ supersedes: [string] # lesson ids
51
+ ```
52
+
53
+ ## Body
54
+
55
+ Exactly these `##` sections, in this order. `Cause` is optional; the rest are
56
+ required.
57
+
58
+ `Symptom`, `Cause`, `Check first`, `Intervention`, `Validate`,
59
+ `Does NOT apply when`.
60
+
61
+ Each section is at most 600 characters and must not be empty. Nothing before
62
+ the first heading. No fenced code blocks anywhere on a line, and no indented
63
+ code blocks, at any depth (a short inline backtick span is fine). No URLs of
64
+ any scheme, protocol-relative, scheme-less or `www.`, anywhere in the body. No
65
+ heading other than those six, whether `#`-style at any indent or a setext
66
+ underline, and no horizontal rules. The whole file is at most 16384 bytes.
67
+
68
+ The body and every frontmatter string are also run through `marked`'s GFM lexer,
69
+ so "is this a link" is answered the way a renderer answers it rather than by a
70
+ line regex. Refused at any depth (inside blockquotes, list items and tables
71
+ too): links of every kind (inline, reference, autolinks), link reference
72
+ definitions, images, HTML, backslash escapes and character references
73
+ (`&#64;`, `&#x40;`, `&amp;`). A code span may show a placeholder such as
74
+ `<collection id>`, but not a tag with attributes, a closing tag, a link, a nested
75
+ code span hiding either, or an element like `<script>` or `<iframe>` that is
76
+ live even bare. The placeholders `normalizeSignature` writes (`<path>`, `<id>`,
77
+ `<url>`, `<n>`, `<email>`) are text anywhere. A string longer than the file cap
78
+ is refused unchecked.
79
+
80
+ ## What the validator adds on top of the field list
81
+
82
+ The contract names the fields; these are the rules the validator applies to
83
+ them, and they are part of the schema.
84
+
85
+ - **Unknown keys are rejected**, at the top level and inside `generated`,
86
+ `verified[]`, `sources[]`, `trigger`, `applies_to` and `evidence`. Every
87
+ required key must be present; `verified` is the only optional one.
88
+ - **Printable ASCII only, in the whole file and in every parsed value.** A
89
+ Unicode em-dash, a smart quote or a non-breaking space is an error, reported
90
+ by codepoint. Write `--`. Parsed values are checked too, so a YAML escape like
91
+ `"\u202e"` cannot carry a control character past the file check.
92
+ - **Plain YAML only.** No comments (they ship in the raw file and would
93
+ otherwise go unchecked), no anchors or aliases, no explicit tags.
94
+ - **Nothing identifying, anywhere.** No absolute or home-directory paths,
95
+ Windows or UNC paths, hex ids of 16 or more characters, uuids, IPv4 or IPv6
96
+ addresses (the `::` forms too), email addresses, hostnames on network
97
+ top-level domains, or credential-shaped strings (provider API keys, AWS key
98
+ ids, GitHub and Slack tokens, private key headers, JWTs) in the body, in any
99
+ frontmatter value or on any raw frontmatter line. `trigger.hosts` is the one
100
+ field that holds a hostname, and it must be a public one (no `.internal`,
101
+ `.local`, `.lan`, `.corp` and the like). No URL in the body or in a
102
+ frontmatter field: nothing with `://`, no `www.`, no known scheme such as
103
+ `mailto:`, `tel:` or `data:` followed by anything, and no other `word:`
104
+ followed by a host or an address. A plain `word:word` (`batch:condition`,
105
+ `list:paired`) is prose. Paths include `$HOME/...`, `%USERPROFILE%\...` and
106
+ drive-less backslash paths. An IPv4 address starting with `0.` is not
107
+ refused, so a four-part tool version like `0.7.17.4` is not either; one
108
+ starting with any other number is.
109
+ - **Links** go only in `graduated_to`, `upstream` and `sources[].resource`, and
110
+ each must be a canonical `https` URL to one of the hosts in `LINK_HOSTS` at the
111
+ top of `validate.mjs`: no port, credentials, query, fragment, percent-escape
112
+ or `..`; a path of letters, digits and `._~/+-` only; and the path still gets
113
+ the identifying-data checks, hostnames and URLs included (so no commit SHAs,
114
+ uuids, home paths or a second host in the path). Those fields may hold free text
115
+ instead, like `galaxy-mcp#55`. To link somewhere new, add the host to
116
+ `LINK_HOSTS` in the same pull request and say why.
117
+ - **These are shape checks, not meaning checks.** A private hostname written as
118
+ prose, a person's name, a copied data value or an instruction aimed at the
119
+ model ("ignore prior instructions and...") all pass. They need the
120
+ contributor's own judgement and a reviewer's.
121
+ - **Dates** are `YYYY-MM-DD` strings that are also real calendar dates.
122
+ - **`generated.by`** matches `agent:<something>` or `human:<something>`;
123
+ **`verified[].by`** must be `human:<pseudonym>`. It is the one identity field
124
+ in the schema, and the shared tier uses maintainer pseudonyms rather than
125
+ contributor ids.
126
+ - **Signatures must be specific.** At least 8 characters, and never the
127
+ normalizer's `unknown` fallback, which would match every empty error.
128
+ - **Signatures must already be normalized.** The validator runs the same
129
+ normalization the matcher will run over a tool result and rejects any
130
+ signature it would change, naming the normalized form to store instead. A
131
+ signature stored raw can never match anything. Normalization takes the first
132
+ line, collapses whitespace, then replaces URLs with `<url>`, emails with
133
+ `<email>`, paths with two or more separators with `<path>`, runs of 16+ hex
134
+ characters with `<id>` and integers of 5+ digits with `<n>`, in that order,
135
+ and truncates to 200.
136
+ - **At least one trigger list must be non-empty.** A lesson nothing can match is
137
+ documentation, and documentation belongs in the GTN.
138
+ - **Per-entry shapes.** `mcp_tools` are `galaxy_*`; `hosts` are bare hostnames
139
+ with no scheme and no path; `extensions` start with a dot; `step_keywords` are
140
+ lowercase; `formats` are lowercase; `supersedes` entries are namespaced lesson
141
+ ids. Lists cap at 20 entries.
142
+ - **Caps.** title 120, description 200, each tag 40, cues 300, each signature
143
+ 200, each tool id 200, each MCP tool name 80, each format 40, each host 100,
144
+ each extension 20, each step keyword 40, each `applies_to` field 200,
145
+ `evidence.method` 300, each source id 100, each free-text list entry 200, each
146
+ body section 600.
147
+ - **A `galaxy-api` lesson must have a non-empty `graduated_to`.** That namespace
148
+ exists for lessons whose durable fix lives elsewhere, and `graduated_to` is
149
+ what keeps them unsurfaced.
150
+ - **Directory shape.** A namespace directory holds `.md` lesson files only, one
151
+ level deep. Top-level files (this one, README, LICENSE, log, the scripts) are
152
+ not lessons and are not validated.
153
+
154
+ ## The snapshot
155
+
156
+ `npm run build:lessons` writes `lessons/snapshot.json`:
157
+
158
+ ```ts
159
+ interface LessonSnapshot {
160
+ schema: 1;
161
+ built_at: string; // ISO
162
+ source: { repo: "galaxyproject/orbit"; commit: string };
163
+ licence: "CC-BY-4.0";
164
+ lessons: Lesson[];
165
+ }
166
+ interface Lesson {
167
+ id: string; // "stats/na-coerced-to-zero-in-filters"
168
+ // every frontmatter field above, same names, same shapes
169
+ sections: {
170
+ symptom: string;
171
+ cause?: string;
172
+ check_first: string;
173
+ intervention: string;
174
+ validate: string;
175
+ not_when: string;
176
+ };
177
+ }
178
+ ```
179
+
180
+ A lesson is left out when `status` is `deprecated` or when `stale_after` has
181
+ passed as of the snapshot's own `built_at`. `tags` in the snapshot is the
182
+ authored tags plus the lesson's `stage` values and `trigger.formats`, deduped.
183
+
184
+ Published file:
185
+ `https://raw.githubusercontent.com/galaxyproject/orbit/main/lessons/snapshot.json`.
186
+ A lesson's canonical page:
187
+ `https://github.com/galaxyproject/orbit/blob/main/lessons/<id>.md`.
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Build `lessons/snapshot.json`: the validated, committed JSON every consumer
4
+ * reads -- the package (the matcher), galaxy-mcp, and the hosted docs-search
5
+ * `lessons` collection.
6
+ *
7
+ * npm run build:lessons # validate, build, write snapshot.json
8
+ * npm run check:lessons # validate + fail if snapshot.json is out of date
9
+ *
10
+ * Same shape of gate as `sync:skills` / `check:skills`: the generated artifact
11
+ * is committed so consumers get it with no build step, and CI refuses a diff
12
+ * that changed `lessons/` without rebuilding.
13
+ *
14
+ * `built_at` and `source.commit` are provenance, not content, so `--check`
15
+ * reuses the committed values and the only thing it can fail on is a lesson
16
+ * that changed without a rebuild. Staleness is evaluated as of `built_at` for
17
+ * the same reason -- otherwise this gate would start failing on a date, on
18
+ * somebody else's unrelated pull request. Real-time staleness is a warning.
19
+ */
20
+
21
+ import fs from "node:fs";
22
+ import path from "node:path";
23
+ import { spawnSync } from "node:child_process";
24
+ import { realpathSync } from "node:fs";
25
+ import { fileURLToPath } from "node:url";
26
+ import { SECTIONS, collectLessonFiles, parseLesson, validateLessonsDir } from "./validate.mjs";
27
+
28
+ export const LESSONS_DIR = path.dirname(fileURLToPath(import.meta.url));
29
+ export const REPO_ROOT = path.resolve(LESSONS_DIR, "..");
30
+ export const SNAPSHOT_PATH = path.join(LESSONS_DIR, "snapshot.json");
31
+
32
+ export const SNAPSHOT_SCHEMA = 1;
33
+ export const SNAPSHOT_REPO = "galaxyproject/orbit";
34
+ export const SNAPSHOT_LICENCE = "CC-BY-4.0";
35
+
36
+ /** Past the end of its `stale_after` day, in UTC. */
37
+ export function isStale(staleAfter, nowMs) {
38
+ const end = Date.parse(`${staleAfter}T23:59:59Z`);
39
+ return Number.isFinite(end) && end < nowMs;
40
+ }
41
+
42
+ /**
43
+ * The exact shape `Date.prototype.toISOString` writes. Anything looser and a
44
+ * hand-edited `built_at` parses to NaN, which silently turns the staleness
45
+ * comparison off.
46
+ */
47
+ export function isIsoTimestamp(value) {
48
+ if (typeof value !== "string") return false;
49
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value)) return false;
50
+ const ms = Date.parse(value);
51
+ return Number.isFinite(ms) && new Date(ms).toISOString() === value;
52
+ }
53
+
54
+ function dedupe(values) {
55
+ return [...new Set(values)];
56
+ }
57
+
58
+ /**
59
+ * One snapshot entry. Every field is copied by name rather than spread, so the
60
+ * key order is deterministic (the drift gate compares bytes) and a frontmatter
61
+ * key the validator would have rejected cannot ride along into the published
62
+ * artifact.
63
+ */
64
+ export function toSnapshotLesson(rel, frontmatter, sections) {
65
+ const fm = frontmatter;
66
+ const lesson = {
67
+ id: rel.replace(/\.md$/, ""),
68
+ type: fm.type,
69
+ title: fm.title,
70
+ description: fm.description,
71
+ // The build mirrors stage and formats into tags, so a consumer that only
72
+ // indexes tags (the docs-search collection does) still sees both axes.
73
+ tags: dedupe([...fm.tags, ...fm.stage, ...fm.trigger.formats]),
74
+ status: fm.status,
75
+ generated: { by: fm.generated.by, at: fm.generated.at },
76
+ };
77
+ if (fm.verified !== undefined) {
78
+ lesson.verified = fm.verified.map((v) => ({ by: v.by, at: v.at }));
79
+ }
80
+ lesson.stale_after = fm.stale_after;
81
+ lesson.sources = fm.sources.map((s) => {
82
+ const out = { id: s.id };
83
+ if (s.resource !== undefined) out.resource = s.resource;
84
+ if (s.title !== undefined) out.title = s.title;
85
+ return out;
86
+ });
87
+ lesson.kind = fm.kind;
88
+ lesson.stage = [...fm.stage];
89
+ lesson.trigger = {
90
+ signatures: [...fm.trigger.signatures],
91
+ tools: [...fm.trigger.tools],
92
+ mcp_tools: [...fm.trigger.mcp_tools],
93
+ formats: [...fm.trigger.formats],
94
+ hosts: [...fm.trigger.hosts],
95
+ extensions: [...fm.trigger.extensions],
96
+ step_keywords: [...fm.trigger.step_keywords],
97
+ };
98
+ lesson.cues = fm.cues;
99
+ lesson.applies_to = { versions: fm.applies_to.versions, tested: fm.applies_to.tested };
100
+ lesson.evidence = {
101
+ symptom: fm.evidence.symptom,
102
+ cause: fm.evidence.cause,
103
+ outcome: fm.evidence.outcome,
104
+ method: fm.evidence.method,
105
+ };
106
+ lesson.graduated_to = [...fm.graduated_to];
107
+ lesson.upstream = [...fm.upstream];
108
+ lesson.supersedes = [...fm.supersedes];
109
+ lesson.sections = {};
110
+ for (const spec of SECTIONS) {
111
+ if (sections[spec.key] !== undefined) lesson.sections[spec.key] = sections[spec.key];
112
+ }
113
+ return lesson;
114
+ }
115
+
116
+ /**
117
+ * Build the snapshot object. `nowMs` defaults to `builtAt` so a build and a
118
+ * later `--check` of the same bytes agree.
119
+ */
120
+ export function buildSnapshot({ dir = LESSONS_DIR, builtAt, commit, nowMs } = {}) {
121
+ if (!isIsoTimestamp(builtAt)) {
122
+ throw new Error(`built_at must be an ISO timestamp (got ${JSON.stringify(builtAt)})`);
123
+ }
124
+ const asOf = nowMs ?? Date.parse(builtAt);
125
+ const lessons = [];
126
+ const skipped = [];
127
+ for (const rel of collectLessonFiles(dir)) {
128
+ const { frontmatter, sections } = parseLesson(fs.readFileSync(path.join(dir, rel), "utf8"));
129
+ const id = rel.replace(/\.md$/, "");
130
+ if (frontmatter.status === "deprecated") {
131
+ skipped.push({ id, why: "status: deprecated" });
132
+ continue;
133
+ }
134
+ if (isStale(frontmatter.stale_after, asOf)) {
135
+ skipped.push({ id, why: `past stale_after ${frontmatter.stale_after}` });
136
+ continue;
137
+ }
138
+ lessons.push(toSnapshotLesson(rel, frontmatter, sections));
139
+ }
140
+ const snapshot = {
141
+ schema: SNAPSHOT_SCHEMA,
142
+ built_at: builtAt,
143
+ source: { repo: SNAPSHOT_REPO, commit },
144
+ licence: SNAPSHOT_LICENCE,
145
+ lessons,
146
+ };
147
+ return { snapshot, skipped };
148
+ }
149
+
150
+ export function serializeSnapshot(snapshot) {
151
+ return `${JSON.stringify(snapshot, null, 2)}\n`;
152
+ }
153
+
154
+ /** First differing line of two serialized snapshots, as printable lines. */
155
+ export function firstDiff(committed, rebuilt) {
156
+ const a = committed.split("\n");
157
+ const b = rebuilt.split("\n");
158
+ const trunc = (s) =>
159
+ s === undefined ? "<end of file>" : s.length > 120 ? `${s.slice(0, 117)}...` : s;
160
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
161
+ if (a[i] === b[i]) continue;
162
+ return [
163
+ `first difference at line ${i + 1}:`,
164
+ `committed: ${trunc(a[i])}`,
165
+ `rebuilt: ${trunc(b[i])}`,
166
+ ];
167
+ }
168
+ return ["the two serializations differ in length only"];
169
+ }
170
+
171
+ /**
172
+ * The commit the corpus was read at. This is HEAD at build time, so it names
173
+ * the commit before the one that lands the snapshot -- which is the honest
174
+ * answer to "what was on disk when this was built".
175
+ */
176
+ function headCommit(repoRoot) {
177
+ const run = spawnSync("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf8" });
178
+ const sha = run.status === 0 ? run.stdout.trim() : "";
179
+ return /^[0-9a-f]{40}$/.test(sha) ? sha : "unknown";
180
+ }
181
+
182
+ function reportViolations(label, violations) {
183
+ console.error(`${label} FAILED -- ${violations.length} schema violation(s)`);
184
+ for (const v of violations) console.error(` ${v}`);
185
+ process.exit(1);
186
+ }
187
+
188
+ function build() {
189
+ const violations = validateLessonsDir(LESSONS_DIR);
190
+ if (violations.length > 0) reportViolations("build:lessons", violations);
191
+
192
+ const builtAt = process.env.LESSONS_BUILT_AT ?? new Date().toISOString();
193
+ const commit = process.env.LESSONS_COMMIT ?? headCommit(REPO_ROOT);
194
+ const { snapshot, skipped } = buildSnapshot({ builtAt, commit });
195
+ if (snapshot.lessons.length === 0) {
196
+ console.error("build:lessons FAILED -- every lesson was skipped, the snapshot would be empty");
197
+ for (const s of skipped) console.error(` ${s.id}: ${s.why}`);
198
+ process.exit(1);
199
+ }
200
+ fs.writeFileSync(SNAPSHOT_PATH, serializeSnapshot(snapshot));
201
+ console.log(`build:lessons OK -- ${snapshot.lessons.length} lesson(s) in lessons/snapshot.json`);
202
+ for (const s of skipped) console.log(` left out ${s.id} (${s.why})`);
203
+ }
204
+
205
+ /**
206
+ * The drift gate as a function, so it can be exercised against any corpus.
207
+ * `failure` is the lines to print when it fails; `warnings` never fail it.
208
+ */
209
+ export function checkSnapshot({
210
+ dir = LESSONS_DIR,
211
+ snapshotPath = SNAPSHOT_PATH,
212
+ nowMs = Date.now(),
213
+ } = {}) {
214
+ const violations = validateLessonsDir(dir);
215
+ if (violations.length > 0) {
216
+ return {
217
+ ok: false,
218
+ failure: [
219
+ `check:lessons FAILED -- ${violations.length} schema violation(s)`,
220
+ ...violations.map((v) => ` ${v}`),
221
+ ],
222
+ };
223
+ }
224
+ if (!fs.existsSync(snapshotPath)) {
225
+ return {
226
+ ok: false,
227
+ failure: [
228
+ "check:lessons FAILED -- lessons/snapshot.json is missing",
229
+ "\nRun `npm run build:lessons` and commit the result.",
230
+ ],
231
+ };
232
+ }
233
+ const committedText = fs.readFileSync(snapshotPath, "utf8").replace(/\r\n/g, "\n");
234
+ let committed;
235
+ try {
236
+ committed = JSON.parse(committedText);
237
+ } catch (err) {
238
+ const message = err instanceof Error ? err.message : String(err);
239
+ return {
240
+ ok: false,
241
+ failure: [`check:lessons FAILED -- lessons/snapshot.json is not valid JSON: ${message}`],
242
+ };
243
+ }
244
+ const builtAt = committed?.built_at;
245
+ if (!isIsoTimestamp(builtAt)) {
246
+ return {
247
+ ok: false,
248
+ failure: [
249
+ `check:lessons FAILED -- lessons/snapshot.json built_at is not an ISO timestamp (got ${JSON.stringify(builtAt)})`,
250
+ "\nRun `npm run build:lessons` and commit lessons/snapshot.json.",
251
+ ],
252
+ };
253
+ }
254
+ const commit = typeof committed?.source?.commit === "string" ? committed.source.commit : "";
255
+ const { snapshot } = buildSnapshot({ dir, builtAt, commit });
256
+ const rebuilt = serializeSnapshot(snapshot);
257
+ if (rebuilt !== committedText) {
258
+ return {
259
+ ok: false,
260
+ failure: [
261
+ "check:lessons FAILED -- lessons/snapshot.json does not match lessons/",
262
+ ...firstDiff(committedText, rebuilt).map((line) => ` ${line}`),
263
+ "\nRun `npm run build:lessons` and commit lessons/snapshot.json.",
264
+ ],
265
+ };
266
+ }
267
+
268
+ // Not fatal: a lesson that has aged out should be re-verified or dropped
269
+ // deliberately, and a date is a bad reason to turn somebody else's CI red.
270
+ const warnings = snapshot.lessons
271
+ .filter((l) => isStale(l.stale_after, nowMs))
272
+ .map(
273
+ (l) =>
274
+ ` warning: ${l.id} is past stale_after ${l.stale_after} -- re-verify it, or rebuild to drop it`,
275
+ );
276
+ return { ok: true, count: snapshot.lessons.length, warnings };
277
+ }
278
+
279
+ function check() {
280
+ const result = checkSnapshot();
281
+ if (!result.ok) {
282
+ for (const line of result.failure) console.error(line);
283
+ process.exit(1);
284
+ }
285
+ for (const w of result.warnings) console.warn(w);
286
+ console.log(`check:lessons OK -- ${result.count} lesson(s) match lessons/snapshot.json`);
287
+ }
288
+
289
+ function isDirectInvocation() {
290
+ if (!process.argv[1]) return false;
291
+ try {
292
+ return fileURLToPath(import.meta.url) === realpathSync(process.argv[1]);
293
+ } catch {
294
+ return false;
295
+ }
296
+ }
297
+
298
+ if (isDirectInvocation()) {
299
+ const args = process.argv.slice(2);
300
+ if (args.length > 1 || (args.length === 1 && args[0] !== "--check")) {
301
+ console.error(`usage: build-snapshot.mjs [--check] (got ${args.join(" ")})`);
302
+ process.exit(2);
303
+ }
304
+ try {
305
+ if (args[0] === "--check") check();
306
+ else build();
307
+ } catch (err) {
308
+ console.error(`lessons/build-snapshot: ${err instanceof Error ? err.message : err}`);
309
+ process.exit(1);
310
+ }
311
+ }
@@ -0,0 +1,61 @@
1
+ ---
2
+ type: Lesson
3
+ title: A supplementary-file download can return an HTML page saved under the expected filename
4
+ description: A landing page, consent interstitial or bot-block answers with 200 and the client saves it as the requested name, so the parse failure surfaces several steps later.
5
+ tags: [download, supplementary-data, file-type, landing-page]
6
+ status: draft
7
+ generated: { by: "human:loom-maintainers", at: "2026-09-30" }
8
+ stale_after: "2027-03-31"
9
+ sources:
10
+ - { id: "loom#356" }
11
+ - { id: "loom#282" }
12
+
13
+ kind: source-quirk
14
+ stage: [data-acquisition]
15
+ trigger:
16
+ signatures: []
17
+ tools: []
18
+ mcp_tools: []
19
+ formats: [xlsx, gz, tsv, csv]
20
+ hosts: ["doi.org", "zenodo.org", "figshare.com", "static-content.springer.com", "journals.plos.org", "www.ncbi.nlm.nih.gov"]
21
+ extensions: [".xlsx", ".tsv.gz", ".tsv", ".csv", ".gz"]
22
+ step_keywords: ["download", "supplementary", "fetch", "wget", "curl", "doi", "landing page"]
23
+ cues: "Fetching a supplementary or data file from a journal, a repository landing page, or a DOI link."
24
+ applies_to: { versions: "n/a", tested: "local download of journal supplementary files" }
25
+ evidence:
26
+ symptom: verified
27
+ cause: hypothesized
28
+ outcome: unvalidated
29
+ method: "the file was later found to be HTML or XML"
30
+ graduated_to: []
31
+ upstream: []
32
+ supersedes: []
33
+ ---
34
+
35
+ ## Symptom
36
+
37
+ An `.xlsx` or `.tsv.gz` will not parse, or parses into nonsense, several steps after it was
38
+ fetched.
39
+
40
+ ## Cause
41
+
42
+ Likely: the URL was a landing page, a login or consent interstitial, or a bot-block response, and
43
+ the client saved the body under the requested name with a 200.
44
+
45
+ ## Check first
46
+
47
+ Right after any download: file size, leading bytes (zip or gzip magic versus `<`), and
48
+ content-type if available.
49
+
50
+ ## Intervention
51
+
52
+ Find the direct file URL, or have Galaxy fetch it server-side; if access is gated, tell the user
53
+ rather than working around it.
54
+
55
+ ## Validate
56
+
57
+ The file opens as its claimed type and has the expected shape: sheets, columns, row count.
58
+
59
+ ## Does NOT apply when
60
+
61
+ The file is genuinely the right type and the parse error is about its contents.