@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,519 @@
1
+ /**
2
+ * The evaluation writer: asks Galaxy about every registry attempt that has a
3
+ * submission, evaluates it (`registry-evaluation.ts`), and writes the result
4
+ * through the store, with one `registry.evaluated` row per evaluation that
5
+ * changed something.
6
+ *
7
+ * It runs from the capture queue (`galaxy-reconcile.ts` `followThrough`), so on
8
+ * session start, on every poller tick (which is where
9
+ * terminal transitions and enrichment completions land), every Nth tick's
10
+ * reconcile, `/reconcile`, and after a Page pull or resume. A tick only
11
+ * re-asks about attempts whose evaluation isn't settled yet; everything else
12
+ * re-asks about all of them, which is how an imported attempt comes back
13
+ * through re-verification rather than inheriting what it claimed.
14
+ *
15
+ * Facts come from Galaxy only. The one thing Galaxy won't say -- a job's tool
16
+ * version, which its job details drop -- is taken from the capture record's
17
+ * submission-time seed when one exists, since that was Galaxy's own answer at
18
+ * submission and lives under the `.loom/` floor; failing that, from a toolshed
19
+ * id's version segment; failing that, it is unknown and conformity can't be
20
+ * shown.
21
+ */
22
+
23
+ import * as path from "path";
24
+ import { appendActivityEvent } from "./activity";
25
+ import {
26
+ GalaxyApiError,
27
+ INVOCATION_SCHEDULED_OK,
28
+ INVOCATION_SCHEDULING_DONE,
29
+ galaxyGetDataset,
30
+ galaxyGetInvocation,
31
+ galaxyGetJobDetails,
32
+ getGalaxyConfig,
33
+ isGalaxyFetchOverridden,
34
+ type GalaxyJobDetailsResponse,
35
+ type InvocationDetail,
36
+ } from "./galaxy-api";
37
+ import { parseDatasetRefs, versionFromToolId, walkInvocationJobs } from "./galaxy-enrich";
38
+ import {
39
+ isTerminalJobState,
40
+ locateJobBlock,
41
+ upsertJobBlock,
42
+ type JobYaml,
43
+ } from "./galaxy-job-block";
44
+ import type { HarnessBlockFields } from "./harness-block-fields";
45
+ import {
46
+ NotebookChangedError,
47
+ locateInvocationBlock,
48
+ readNotebook,
49
+ statNotebook,
50
+ upsertInvocationBlock,
51
+ withNotebookLock,
52
+ writeNotebook,
53
+ type InvocationYaml,
54
+ } from "./notebook-writer";
55
+ import { getNotebookPath } from "./state";
56
+ import { attemptOwns, listAttemptRecords, type AttemptRecord } from "./galaxy-provenance";
57
+ import {
58
+ canonicalJson,
59
+ computeHandoffEligible,
60
+ sha256Hex,
61
+ type Attempt,
62
+ type AttemptId,
63
+ type Registry,
64
+ } from "./registry";
65
+ import {
66
+ evaluateAttempt,
67
+ type RunDataset,
68
+ type RunFacts,
69
+ type RunJob,
70
+ } from "./registry-evaluation";
71
+ import { getSessionRegistry, sessionView, type SessionRegistry } from "./registry-runtime";
72
+
73
+ export type EvaluationTrigger =
74
+ "session_start" | "tick" | "enrich" | "command" | "page_pull" | "page_resume";
75
+
76
+ export interface EvaluatorDeps {
77
+ getJob: (jobId: string) => Promise<GalaxyJobDetailsResponse>;
78
+ getInvocation: (invocationId: string) => Promise<InvocationDetail>;
79
+ getDataset: (datasetId: string) => Promise<Record<string, unknown>>;
80
+ /** Capture's records, for submission-time version seeds. */
81
+ records: (analysisDir: string) => Promise<AttemptRecord[]>;
82
+ now: () => number;
83
+ registry: () => SessionRegistry | null;
84
+ /** Whether there is a Galaxy to ask: credentials, or the Tier-1 fixture. */
85
+ connected: () => boolean;
86
+ }
87
+
88
+ const defaultDeps: EvaluatorDeps = {
89
+ getJob: (jobId) => galaxyGetJobDetails(jobId, undefined, { full: true }),
90
+ getInvocation: (id) => galaxyGetInvocation(id),
91
+ getDataset: (id) => galaxyGetDataset(id),
92
+ records: (dir) => listAttemptRecords(dir),
93
+ now: () => Date.now(),
94
+ registry: getSessionRegistry,
95
+ connected: () => !!getGalaxyConfig() || isGalaxyFetchOverridden(),
96
+ };
97
+
98
+ /** Galaxy calls per pass are bounded by this many attempts. */
99
+ const MAX_ATTEMPTS_PER_PASS = 25;
100
+ const FAILED_JOB_STATES = new Set(["error", "failed", "deleted"]);
101
+
102
+ function isNotFound(err: unknown): boolean {
103
+ return err instanceof GalaxyApiError && (err.status === 404 || err.status === 400);
104
+ }
105
+
106
+ function str(v: unknown): string | undefined {
107
+ return typeof v === "string" && v.length > 0 ? v : undefined;
108
+ }
109
+
110
+ /** The submission-time version capture recorded for a job, when it was Galaxy's word. */
111
+ function seededVersion(records: readonly AttemptRecord[], jobId: string): string | undefined {
112
+ for (const r of records) {
113
+ if (r.origin === "notebook" || r.fixture) continue;
114
+ if (!attemptOwns(r, "job", jobId) && !(r.ids.invocation_id && r.jobs[jobId])) continue;
115
+ const v = r.seeds?.[jobId]?.tool_version;
116
+ if (v) return v;
117
+ }
118
+ return undefined;
119
+ }
120
+
121
+ async function datasetsFor(
122
+ deps: EvaluatorDeps,
123
+ ids: readonly string[],
124
+ ): Promise<Map<string, Record<string, unknown> | null>> {
125
+ const out = new Map<string, Record<string, unknown> | null>();
126
+ for (const id of ids) {
127
+ if (out.has(id)) continue;
128
+ try {
129
+ out.set(id, await deps.getDataset(id));
130
+ } catch (err) {
131
+ if (!isNotFound(err)) throw err;
132
+ out.set(id, null);
133
+ }
134
+ }
135
+ return out;
136
+ }
137
+
138
+ async function jobFacts(
139
+ deps: EvaluatorDeps,
140
+ jobId: string,
141
+ records: readonly AttemptRecord[],
142
+ stepVersion?: string,
143
+ ): Promise<RunJob & { history_id?: string }> {
144
+ let details: GalaxyJobDetailsResponse;
145
+ try {
146
+ details = await deps.getJob(jobId);
147
+ } catch (err) {
148
+ if (isNotFound(err)) return { job_id: jobId, unavailable: (err as Error).message };
149
+ throw err;
150
+ }
151
+ if (!details || details.id !== jobId) {
152
+ return { job_id: jobId, unavailable: `Galaxy answered for a different job than ${jobId}` };
153
+ }
154
+ const inputs = parseDatasetRefs(details.inputs);
155
+ const outputs = parseDatasetRefs(details.outputs);
156
+ const hdas = (outputs ?? []).filter((r) => (r.src ?? "hda") === "hda").map((r) => r.id);
157
+ const datasets = await datasetsFor(deps, hdas);
158
+ const toolId = str(details.tool_id);
159
+ const toolVersion =
160
+ seededVersion(records, jobId) ??
161
+ stepVersion ??
162
+ (toolId ? versionFromToolId(toolId) : undefined);
163
+ const params =
164
+ details.params && typeof details.params === "object" && !Array.isArray(details.params)
165
+ ? (details.params as Record<string, unknown>)
166
+ : undefined;
167
+ return {
168
+ job_id: jobId,
169
+ ...(str(details.history_id) ? { history_id: str(details.history_id) } : {}),
170
+ ...(toolId ? { tool_id: toolId } : {}),
171
+ ...(toolVersion ? { tool_version: toolVersion } : {}),
172
+ ...(str(details.state) ? { state: str(details.state) } : {}),
173
+ ...(params ? { params } : {}),
174
+ ...(inputs ? { inputs: inputs.map((r) => ({ name: r.name, id: r.id, src: r.src })) } : {}),
175
+ ...(outputs
176
+ ? {
177
+ outputs: outputs.map((r): RunDataset => {
178
+ const d = datasets.get(r.id);
179
+ return {
180
+ name: r.name,
181
+ id: r.id,
182
+ ...(r.src ? { src: r.src } : {}),
183
+ ...(d ? { ext: str(d.extension) ?? str(d.file_ext) } : {}),
184
+ ...(d ? { state: str(d.state) } : {}),
185
+ };
186
+ }),
187
+ }
188
+ : {}),
189
+ };
190
+ }
191
+
192
+ function jobRunState(job: RunJob): RunFacts["state"] {
193
+ if (job.unavailable) return "unknown";
194
+ if (job.state === "ok") return "success";
195
+ if (FAILED_JOB_STATES.has(job.state ?? "")) return "failed";
196
+ return isTerminalJobState(job.state) ? "unknown" : "running";
197
+ }
198
+
199
+ /**
200
+ * Ask Galaxy about one submission. Null when Galaxy couldn't be asked (no
201
+ * credentials, a 500, a dead network): nothing is written, and the next pass
202
+ * asks again.
203
+ */
204
+ export async function gatherRunFacts(
205
+ deps: EvaluatorDeps,
206
+ submission: NonNullable<Attempt["submission"]>,
207
+ analysisDir: string,
208
+ ): Promise<RunFacts | null> {
209
+ const source = isGalaxyFetchOverridden() ? "fixture" : "galaxy";
210
+ const records = await deps.records(analysisDir).catch(() => [] as AttemptRecord[]);
211
+ try {
212
+ if (submission.invocation_id) {
213
+ const id = submission.invocation_id;
214
+ let inv: InvocationDetail;
215
+ try {
216
+ inv = await deps.getInvocation(id);
217
+ } catch (err) {
218
+ if (!isNotFound(err)) throw err;
219
+ return {
220
+ kind: "invocation",
221
+ run_id: id,
222
+ verified: false,
223
+ state: "unknown",
224
+ jobs: [],
225
+ source,
226
+ };
227
+ }
228
+ if (!inv || inv.id !== id) {
229
+ return {
230
+ kind: "invocation",
231
+ run_id: id,
232
+ verified: false,
233
+ state: "unknown",
234
+ jobs: [],
235
+ source,
236
+ };
237
+ }
238
+ const steps = await walkInvocationJobs(inv, deps.getInvocation);
239
+ const jobs: RunJob[] = [];
240
+ for (const s of steps) {
241
+ const { history_id: _h, ...job } = await jobFacts(deps, s.jobId, records, s.toolVersion);
242
+ jobs.push(job);
243
+ }
244
+ const done = INVOCATION_SCHEDULING_DONE.has(inv.state);
245
+ const states = jobs.map(jobRunState);
246
+ let state: RunFacts["state"];
247
+ if (!done || states.includes("running")) state = "running";
248
+ else if (inv.state === "failed" || inv.state === "cancelled" || states.includes("failed"))
249
+ state = "failed";
250
+ else if (
251
+ INVOCATION_SCHEDULED_OK.has(inv.state) &&
252
+ jobs.length > 0 &&
253
+ states.every((s) => s === "success")
254
+ )
255
+ state = "success";
256
+ else state = "unknown";
257
+ const inputs: Record<string, { id: string; src?: string }> = {};
258
+ for (const [k, v] of Object.entries((inv.inputs ?? {}) as Record<string, unknown>)) {
259
+ const r = v as Record<string, unknown> | null;
260
+ if (r && typeof r.id === "string")
261
+ inputs[k] = { id: r.id, ...(str(r.src) ? { src: str(r.src) } : {}) };
262
+ }
263
+ return {
264
+ kind: "invocation",
265
+ run_id: id,
266
+ verified: true,
267
+ state,
268
+ ...(str(inv.history_id) ? { history_id: str(inv.history_id) } : {}),
269
+ jobs,
270
+ workflow_inputs: inputs,
271
+ source,
272
+ };
273
+ }
274
+ const id = submission.job_id;
275
+ if (!id) return null;
276
+ const { history_id: history, ...job } = await jobFacts(deps, id, records);
277
+ if (job.unavailable) {
278
+ return { kind: "job", run_id: id, verified: false, state: "unknown", jobs: [], source };
279
+ }
280
+ return {
281
+ kind: "job",
282
+ run_id: id,
283
+ verified: true,
284
+ state: jobRunState(job),
285
+ ...(history ? { history_id: history } : {}),
286
+ jobs: [job],
287
+ source,
288
+ };
289
+ } catch {
290
+ return null;
291
+ }
292
+ }
293
+
294
+ /** Whether a tick should ask about this attempt again. */
295
+ function unsettled(a: Attempt): boolean {
296
+ const ev = a.evaluation;
297
+ return !ev || ev.authority !== "established" || ev.execution === "unknown";
298
+ }
299
+
300
+ function sameOutcome(a: Attempt, next: ReturnType<typeof evaluateAttempt>): boolean {
301
+ if (!a.evaluation || !a.provenance || !a.submission) return false;
302
+ const { evaluated_at: _a, ...was } = a.evaluation;
303
+ const { evaluated_at: _b, ...now } = next.evaluation;
304
+ return (
305
+ canonicalJson(was) === canonicalJson(now) &&
306
+ canonicalJson(a.provenance) === canonicalJson(next.provenance) &&
307
+ canonicalJson(a.submission.check) === canonicalJson(next.check) &&
308
+ a.submission.server_verified === next.server_verified
309
+ );
310
+ }
311
+
312
+ export interface EvaluationPass {
313
+ evaluated: AttemptId[];
314
+ unchanged: AttemptId[];
315
+ unreachable: AttemptId[];
316
+ skipped?: string;
317
+ }
318
+
319
+ let running: Promise<EvaluationPass> | null = null;
320
+
321
+ /**
322
+ * Evaluate this session's registry attempts that have a submission. One pass
323
+ * at a time; a second caller gets the pass already running.
324
+ */
325
+ export function evaluateRegistryAttempts(
326
+ trigger: EvaluationTrigger,
327
+ deps: Partial<EvaluatorDeps> = {},
328
+ ): Promise<EvaluationPass> {
329
+ if (running) return running;
330
+ running = runPass(trigger, { ...defaultDeps, ...deps }).finally(() => {
331
+ running = null;
332
+ });
333
+ return running;
334
+ }
335
+
336
+ async function runPass(trigger: EvaluationTrigger, deps: EvaluatorDeps): Promise<EvaluationPass> {
337
+ const out: EvaluationPass = { evaluated: [], unchanged: [], unreachable: [] };
338
+ const session = deps.registry();
339
+ if (!session) return { ...out, skipped: "no registry in this session" };
340
+ if (session.store.mode !== "writer") return { ...out, skipped: "registry is read-only" };
341
+ if (!deps.connected()) return { ...out, skipped: "no Galaxy credentials" };
342
+ const view: Registry = sessionView(session);
343
+ const everything = trigger !== "tick" && trigger !== "enrich";
344
+ const due = Object.values(view.attempts)
345
+ .filter((a) => a.submission && (a.submission.invocation_id || a.submission.job_id))
346
+ .filter((a) => everything || unsettled(a))
347
+ .slice(0, MAX_ATTEMPTS_PER_PASS);
348
+
349
+ for (const attempt of due) {
350
+ const facts = await gatherRunFacts(deps, attempt.submission!, session.analysisDir);
351
+ if (!facts) {
352
+ out.unreachable.push(attempt.attempt_id);
353
+ continue;
354
+ }
355
+ // Content-addressed, so the same answer from Galaxy is the same file.
356
+ const factsRef = path.posix.join(
357
+ ".loom",
358
+ "state",
359
+ "templates",
360
+ `${sha256Hex(canonicalJson(facts))}.json`,
361
+ );
362
+ const now = new Date(deps.now()).toISOString();
363
+ const spec = attempt.approval?.spec_snapshot;
364
+ const templateFrozen =
365
+ !!spec && session.store.getTemplate(spec.template_ref.digest) !== undefined;
366
+ const result = evaluateAttempt(attempt, facts, view.exceptions, {
367
+ now,
368
+ factsRef,
369
+ templateFrozen,
370
+ });
371
+ if (sameOutcome(attempt, result)) {
372
+ out.unchanged.push(attempt.attempt_id);
373
+ continue;
374
+ }
375
+ try {
376
+ session.store.putTemplate(facts);
377
+ } catch (err) {
378
+ out.unreachable.push(attempt.attempt_id);
379
+ console.error("[registry] facts not stored:", err);
380
+ continue;
381
+ }
382
+ let written: Registry;
383
+ try {
384
+ written = session.store.update((draft) => {
385
+ const a = draft.attempts[attempt.attempt_id];
386
+ if (!a?.submission) return;
387
+ a.evaluation = result.evaluation;
388
+ a.provenance = result.provenance;
389
+ a.submission.check = result.check;
390
+ a.submission.server_verified = result.server_verified;
391
+ });
392
+ } catch (err) {
393
+ out.unreachable.push(attempt.attempt_id);
394
+ console.error("[registry] evaluation not written:", err);
395
+ continue;
396
+ }
397
+ const after = written.attempts[attempt.attempt_id];
398
+ // The flag as this session reads it: a revocation held in memory counts.
399
+ const held = sessionView(session).attempts[attempt.attempt_id] ?? after;
400
+ out.evaluated.push(attempt.attempt_id);
401
+ appendActivityEvent(session.analysisDir, {
402
+ timestamp: now,
403
+ kind: "registry.evaluated",
404
+ source: "harness",
405
+ payload: {
406
+ attempt_id: attempt.attempt_id,
407
+ step_anchor: attempt.binding.step_anchor,
408
+ trigger,
409
+ run: { kind: facts.kind, id: facts.run_id },
410
+ execution: result.evaluation.execution,
411
+ conformity: result.evaluation.conformity,
412
+ check: result.check.outcome,
413
+ predicate_result: result.evaluation.predicate_result,
414
+ integrity: result.evaluation.integrity,
415
+ authority: result.evaluation.authority,
416
+ handoff_eligible: held
417
+ ? computeHandoffEligible(held, sessionView(session).exceptions)
418
+ : false,
419
+ ...(result.check.diff ? { diff: result.check.diff } : {}),
420
+ ...(facts.source === "fixture" ? { fixture: true } : {}),
421
+ },
422
+ });
423
+ }
424
+ try {
425
+ await renderRegistryProjection(session);
426
+ } catch (err) {
427
+ console.error("[registry] projection not rendered:", err);
428
+ }
429
+ return out;
430
+ }
431
+
432
+ /** The block fields an attempt's evaluation renders as. */
433
+ export function projectionFields(a: Attempt, registry: Registry): HarnessBlockFields | null {
434
+ if (!a.evaluation || !a.submission) return null;
435
+ return {
436
+ evaluation: {
437
+ execution: a.evaluation.execution,
438
+ conformity: a.evaluation.conformity,
439
+ check: a.submission.check.outcome,
440
+ predicate: a.evaluation.predicate_result,
441
+ integrity: a.evaluation.integrity,
442
+ authority: a.evaluation.authority,
443
+ },
444
+ handoffEligible: computeHandoffEligible(a, registry.exceptions),
445
+ registryRevision: registry.revision,
446
+ };
447
+ }
448
+
449
+ /**
450
+ * Registry first, then render: write each evaluated attempt's verdict onto the
451
+ * block for its run. Representation only -- nothing reads these fields back
452
+ * for a decision -- so a block someone edited is simply rendered again, with a
453
+ * `state.repaired` row.
454
+ */
455
+ export async function renderRegistryProjection(
456
+ session: SessionRegistry,
457
+ nbPath: string | null = getNotebookPath(),
458
+ ): Promise<number> {
459
+ if (!nbPath) return 0;
460
+ const view = sessionView(session);
461
+ const targets = Object.values(view.attempts).filter(
462
+ (a) => a.evaluation && (a.submission?.invocation_id || a.submission?.job_id),
463
+ );
464
+ if (targets.length === 0) return 0;
465
+ return withNotebookLock(nbPath, async () => {
466
+ for (let round = 0; ; round++) {
467
+ const stamp = await statNotebook(nbPath);
468
+ let content: string;
469
+ try {
470
+ content = await readNotebook(nbPath);
471
+ } catch {
472
+ return 0;
473
+ }
474
+ let next = content;
475
+ const repaired: string[] = [];
476
+ for (const a of targets) {
477
+ const fields = projectionFields(a, view);
478
+ if (!fields) continue;
479
+ const sub = a.submission!;
480
+ const located = sub.invocation_id
481
+ ? locateInvocationBlock(next, sub.invocation_id)
482
+ : locateJobBlock(next, sub.job_id!);
483
+ const current = located.record;
484
+ if (!current) continue;
485
+ const rendered = sub.invocation_id
486
+ ? upsertInvocationBlock(next, current as InvocationYaml, fields)
487
+ : upsertJobBlock(next, current as JobYaml, fields);
488
+ if (rendered === next) continue;
489
+ // A block that already carried a verdict and now gets a different one
490
+ // was either edited or rendered from an older revision.
491
+ if (current.evaluation && current.registryRevision === view.revision) {
492
+ repaired.push(a.attempt_id);
493
+ }
494
+ next = rendered;
495
+ }
496
+ if (next === content) return 0;
497
+ try {
498
+ await writeNotebook(nbPath, next, stamp ?? undefined);
499
+ } catch (err) {
500
+ if (!(err instanceof NotebookChangedError) || round >= 2) throw err;
501
+ continue;
502
+ }
503
+ for (const id of repaired) {
504
+ appendActivityEvent(session.analysisDir, {
505
+ timestamp: new Date().toISOString(),
506
+ kind: "state.repaired",
507
+ source: "harness",
508
+ payload: { attempt_id: id, registry_revision: view.revision },
509
+ });
510
+ }
511
+ return 1;
512
+ }
513
+ });
514
+ }
515
+
516
+ /** Test reset. */
517
+ export function resetRegistryEvaluator(): void {
518
+ running = null;
519
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * The import rule (registry design v3 §10), applied to every registry this
3
+ * session did not sign: a file from an earlier session or a clean clone, a
4
+ * carrier another session wrote, or something hand-made.
5
+ *
6
+ * Consent is session-scoped, so nothing that arrives from outside the session
7
+ * keeps any authority it claims. Approvals and exceptions become `restored`,
8
+ * submission checks become `unchecked`, provenance and evaluations become
9
+ * `historical`, and Galaxy's confirmation of the run is forgotten until
10
+ * reconcile asks again. Attempts recorded against another server are moved to
11
+ * `quarantine`. The result can then be re-established in-session, never
12
+ * inherited.
13
+ *
14
+ * Pure: takes a parsed registry, returns a new one.
15
+ */
16
+
17
+ import {
18
+ normalizeServerUrl,
19
+ type Attempt,
20
+ type AttemptId,
21
+ type Exception,
22
+ type Registry,
23
+ } from "./registry-schema";
24
+
25
+ export interface ImportResult {
26
+ registry: Registry;
27
+ quarantined: AttemptId[];
28
+ }
29
+
30
+ function downgradeAttempt(a: Attempt): Attempt {
31
+ const out: Attempt = structuredClone(a);
32
+ if (out.approval) {
33
+ // `revoked` is already ineligible and says more than `restored` does.
34
+ if (out.approval.status !== "revoked") out.approval.status = "restored";
35
+ out.approval.by = "restored";
36
+ }
37
+ if (out.submission) {
38
+ out.submission.check = { outcome: "unchecked", mode: out.submission.check.mode };
39
+ out.submission.server_verified = false;
40
+ }
41
+ if (out.provenance) out.provenance.authority = "historical";
42
+ if (out.evaluation) out.evaluation.authority = "historical";
43
+ out.handoff_eligible = false;
44
+ return out;
45
+ }
46
+
47
+ function downgradeException(x: Exception): Exception {
48
+ return { ...x, by: "restored" };
49
+ }
50
+
51
+ /**
52
+ * Downgrade `imported` for use by a session talking to `serverUrl`. The caller
53
+ * owns revision, writer token and signature; this only touches content.
54
+ */
55
+ export function applyImportRule(imported: Registry, serverUrl: string): ImportResult {
56
+ const ours = normalizeServerUrl(serverUrl);
57
+ const attempts: Record<AttemptId, Attempt> = {};
58
+ const quarantine: Record<AttemptId, Attempt> = {};
59
+ const quarantined: AttemptId[] = [];
60
+
61
+ const place = (a: Attempt) => {
62
+ const downgraded = downgradeAttempt(a);
63
+ const specServer = a.approval?.spec_snapshot.server_url;
64
+ const sameServer =
65
+ normalizeServerUrl(a.server_url) === ours &&
66
+ (specServer === undefined || normalizeServerUrl(specServer) === ours);
67
+ if (sameServer) {
68
+ attempts[a.attempt_id] = downgraded;
69
+ } else {
70
+ quarantine[a.attempt_id] = downgraded;
71
+ quarantined.push(a.attempt_id);
72
+ }
73
+ };
74
+ for (const a of Object.values(imported.attempts)) place(a);
75
+ // Already-quarantined attempts stay there even if the server now matches: a
76
+ // quarantine is lifted by a deliberate act, not by switching profiles.
77
+ for (const a of Object.values(imported.quarantine ?? {})) {
78
+ quarantine[a.attempt_id] = downgradeAttempt(a);
79
+ }
80
+
81
+ const registry: Registry = {
82
+ ...imported,
83
+ server_url: ours,
84
+ attempts,
85
+ exceptions: imported.exceptions.map(downgradeException),
86
+ supervision: structuredClone(imported.supervision),
87
+ };
88
+ if (Object.keys(quarantine).length > 0) registry.quarantine = quarantine;
89
+ else delete registry.quarantine;
90
+ return { registry, quarantined };
91
+ }