@jinn-network/client 0.1.6 → 0.1.7-canary.205587f0

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 (291) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/deployments/deployment-jinn-mvi-l1-sepolia-fast.json +23 -4
  3. package/deployments/deployment-jinn-mvi-l1-sepolia.json +23 -4
  4. package/deployments/deployment-jinn-mvi-l2-baseSepolia.json +5 -4
  5. package/dist/adapters/mech/adapter.d.ts +38 -1
  6. package/dist/adapters/mech/adapter.js +241 -54
  7. package/dist/adapters/mech/adapter.js.map +1 -1
  8. package/dist/adapters/mech/contracts.d.ts +17 -4
  9. package/dist/adapters/mech/contracts.js +8 -2
  10. package/dist/adapters/mech/contracts.js.map +1 -1
  11. package/dist/adapters/mech/safe-revert.d.ts +20 -0
  12. package/dist/adapters/mech/safe-revert.js +12 -4
  13. package/dist/adapters/mech/safe-revert.js.map +1 -1
  14. package/dist/adapters/mech/safe.d.ts +5 -1
  15. package/dist/adapters/mech/safe.js +27 -8
  16. package/dist/adapters/mech/safe.js.map +1 -1
  17. package/dist/adapters/mech/verdict-code.d.ts +1 -0
  18. package/dist/adapters/mech/verdict-code.js +18 -0
  19. package/dist/adapters/mech/verdict-code.js.map +1 -1
  20. package/dist/api/admin-endpoint.d.ts +15 -3
  21. package/dist/api/admin-endpoint.js +24 -2
  22. package/dist/api/admin-endpoint.js.map +1 -1
  23. package/dist/api/bootstrap-endpoint.js +49 -0
  24. package/dist/api/bootstrap-endpoint.js.map +1 -1
  25. package/dist/api/codex-doctor-endpoint.d.ts +73 -0
  26. package/dist/api/codex-doctor-endpoint.js +177 -0
  27. package/dist/api/codex-doctor-endpoint.js.map +1 -0
  28. package/dist/api/discovery-endpoint.d.ts +1 -0
  29. package/dist/api/discovery-endpoint.js +26 -0
  30. package/dist/api/discovery-endpoint.js.map +1 -1
  31. package/dist/api/fleet-build.d.ts +1 -0
  32. package/dist/api/fleet-build.js +2 -1
  33. package/dist/api/fleet-build.js.map +1 -1
  34. package/dist/api/gather-status.d.ts +11 -0
  35. package/dist/api/gather-status.js +467 -4
  36. package/dist/api/gather-status.js.map +1 -1
  37. package/dist/api/hermes-doctor-endpoint.d.ts +117 -0
  38. package/dist/api/hermes-doctor-endpoint.js +229 -23
  39. package/dist/api/hermes-doctor-endpoint.js.map +1 -1
  40. package/dist/api/launcher-status.d.ts +21 -16
  41. package/dist/api/launcher-status.js +2 -1
  42. package/dist/api/launcher-status.js.map +1 -1
  43. package/dist/api/portfolio-v0-build.d.ts +10 -0
  44. package/dist/api/portfolio-v0-build.js +24 -5
  45. package/dist/api/portfolio-v0-build.js.map +1 -1
  46. package/dist/api/prediction-v1-build.d.ts +10 -0
  47. package/dist/api/prediction-v1-build.js +7 -1
  48. package/dist/api/prediction-v1-build.js.map +1 -1
  49. package/dist/api/server.d.ts +31 -1
  50. package/dist/api/server.js +68 -1
  51. package/dist/api/server.js.map +1 -1
  52. package/dist/api/setup-endpoints.d.ts +16 -0
  53. package/dist/api/setup-endpoints.js +78 -4
  54. package/dist/api/setup-endpoints.js.map +1 -1
  55. package/dist/api/setup-retry-endpoint.d.ts +19 -0
  56. package/dist/api/setup-retry-endpoint.js +32 -0
  57. package/dist/api/setup-retry-endpoint.js.map +1 -0
  58. package/dist/api/solvernets-endpoints.d.ts +8 -0
  59. package/dist/api/solvernets-endpoints.js +71 -43
  60. package/dist/api/solvernets-endpoints.js.map +1 -1
  61. package/dist/api/status-build.d.ts +78 -0
  62. package/dist/api/status-build.js +74 -18
  63. package/dist/api/status-build.js.map +1 -1
  64. package/dist/api/task-run-routing.d.ts +7 -0
  65. package/dist/api/task-run-routing.js +12 -0
  66. package/dist/api/task-run-routing.js.map +1 -0
  67. package/dist/api/task-runs-build.d.ts +21 -0
  68. package/dist/api/task-runs-build.js +14 -1
  69. package/dist/api/task-runs-build.js.map +1 -1
  70. package/dist/build-info.json +4 -4
  71. package/dist/build-meta.json +1 -1
  72. package/dist/chain-read-errors.d.ts +10 -0
  73. package/dist/chain-read-errors.js +15 -0
  74. package/dist/chain-read-errors.js.map +1 -1
  75. package/dist/cli/commands/auth.js +1 -1
  76. package/dist/cli/commands/auth.js.map +1 -1
  77. package/dist/cli/commands/create.js +3 -2
  78. package/dist/cli/commands/create.js.map +1 -1
  79. package/dist/cli/commands/doctor.d.ts +2 -0
  80. package/dist/cli/commands/doctor.js +2 -0
  81. package/dist/cli/commands/doctor.js.map +1 -1
  82. package/dist/cli/commands/rewards.js +11 -7
  83. package/dist/cli/commands/rewards.js.map +1 -1
  84. package/dist/cli/commands/solver-nets.js +24 -9
  85. package/dist/cli/commands/solver-nets.js.map +1 -1
  86. package/dist/cli/commands/status.js +1 -1
  87. package/dist/cli/commands/status.js.map +1 -1
  88. package/dist/cli/commands/tasks.js +86 -9
  89. package/dist/cli/commands/tasks.js.map +1 -1
  90. package/dist/cli/commands/update.d.ts +10 -0
  91. package/dist/cli/commands/update.js +36 -0
  92. package/dist/cli/commands/update.js.map +1 -1
  93. package/dist/cli/introspection-context.js +5 -0
  94. package/dist/cli/introspection-context.js.map +1 -1
  95. package/dist/cli/task-native-readiness.d.ts +3 -1
  96. package/dist/cli/task-native-readiness.js +28 -6
  97. package/dist/cli/task-native-readiness.js.map +1 -1
  98. package/dist/config.d.ts +118 -5
  99. package/dist/config.js +132 -18
  100. package/dist/config.js.map +1 -1
  101. package/dist/daemon/checkpoint-loop.d.ts +48 -0
  102. package/dist/daemon/checkpoint-loop.js +76 -0
  103. package/dist/daemon/checkpoint-loop.js.map +1 -0
  104. package/dist/daemon/creator.d.ts +1 -1
  105. package/dist/daemon/creator.js +7 -3
  106. package/dist/daemon/creator.js.map +1 -1
  107. package/dist/daemon/daemon.d.ts +19 -0
  108. package/dist/daemon/daemon.js +68 -1
  109. package/dist/daemon/daemon.js.map +1 -1
  110. package/dist/daemon/eviction-loop.d.ts +40 -0
  111. package/dist/daemon/eviction-loop.js +67 -0
  112. package/dist/daemon/eviction-loop.js.map +1 -0
  113. package/dist/daemon/jinn-claim-loop-wiring.d.ts +33 -0
  114. package/dist/daemon/jinn-claim-loop-wiring.js +40 -0
  115. package/dist/daemon/jinn-claim-loop-wiring.js.map +1 -0
  116. package/dist/daemon/jinn-claim-loop.d.ts +24 -17
  117. package/dist/daemon/jinn-claim-loop.js +77 -23
  118. package/dist/daemon/jinn-claim-loop.js.map +1 -1
  119. package/dist/daemon/skip-log-dedup.d.ts +69 -0
  120. package/dist/daemon/skip-log-dedup.js +106 -0
  121. package/dist/daemon/skip-log-dedup.js.map +1 -0
  122. package/dist/dashboard/assets/index-DMm7Y4f7.css +32 -0
  123. package/dist/dashboard/assets/index-Dt1RV0Ee.js +330 -0
  124. package/dist/dashboard/index.html +2 -2
  125. package/dist/discovery/factory.d.ts +17 -5
  126. package/dist/discovery/factory.js +46 -18
  127. package/dist/discovery/factory.js.map +1 -1
  128. package/dist/discovery/http.js +142 -3
  129. package/dist/discovery/http.js.map +1 -1
  130. package/dist/discovery/onchain.d.ts +5 -0
  131. package/dist/discovery/onchain.js +407 -15
  132. package/dist/discovery/onchain.js.map +1 -1
  133. package/dist/discovery/types.d.ts +45 -1
  134. package/dist/discovery/types.js +8 -10
  135. package/dist/discovery/types.js.map +1 -1
  136. package/dist/discovery/with-fallback.d.ts +7 -0
  137. package/dist/discovery/with-fallback.js +10 -0
  138. package/dist/discovery/with-fallback.js.map +1 -1
  139. package/dist/earning/bootstrap.d.ts +92 -1
  140. package/dist/earning/bootstrap.js +203 -63
  141. package/dist/earning/bootstrap.js.map +1 -1
  142. package/dist/earning/contracts.d.ts +14 -0
  143. package/dist/earning/contracts.js +17 -5
  144. package/dist/earning/contracts.js.map +1 -1
  145. package/dist/earning/funding-plan.js +27 -18
  146. package/dist/earning/funding-plan.js.map +1 -1
  147. package/dist/earning/jinn-rewards.d.ts +46 -0
  148. package/dist/earning/jinn-rewards.js +32 -0
  149. package/dist/earning/jinn-rewards.js.map +1 -1
  150. package/dist/earning/safe-adapter.d.ts +2 -0
  151. package/dist/earning/safe-adapter.js +26 -12
  152. package/dist/earning/safe-adapter.js.map +1 -1
  153. package/dist/earning/store.d.ts +8 -0
  154. package/dist/earning/store.js.map +1 -1
  155. package/dist/earning/testnet-setup-migration.d.ts +12 -0
  156. package/dist/earning/testnet-setup-migration.js +27 -1
  157. package/dist/earning/testnet-setup-migration.js.map +1 -1
  158. package/dist/earning/types.d.ts +15 -0
  159. package/dist/erc8004/reputation.d.ts +8 -0
  160. package/dist/erc8004/reputation.js +22 -3
  161. package/dist/erc8004/reputation.js.map +1 -1
  162. package/dist/harnesses/cost-estimates.d.ts +145 -0
  163. package/dist/harnesses/cost-estimates.js +297 -0
  164. package/dist/harnesses/cost-estimates.js.map +1 -0
  165. package/dist/harnesses/engine/engine.d.ts +72 -0
  166. package/dist/harnesses/engine/engine.js +105 -8
  167. package/dist/harnesses/engine/engine.js.map +1 -1
  168. package/dist/harnesses/engine/persistence.d.ts +51 -1
  169. package/dist/harnesses/engine/persistence.js +118 -5
  170. package/dist/harnesses/engine/persistence.js.map +1 -1
  171. package/dist/harnesses/engine/work-dir-reaper.d.ts +65 -0
  172. package/dist/harnesses/engine/work-dir-reaper.js +100 -0
  173. package/dist/harnesses/engine/work-dir-reaper.js.map +1 -0
  174. package/dist/harnesses/impls/hermes-agent/adapter.js +40 -0
  175. package/dist/harnesses/impls/hermes-agent/adapter.js.map +1 -1
  176. package/dist/harnesses/impls/hermes-agent/bootstrap.d.ts +20 -0
  177. package/dist/harnesses/impls/hermes-agent/bootstrap.js +40 -6
  178. package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -1
  179. package/dist/harnesses/impls/hermes-agent/harness.d.ts +59 -1
  180. package/dist/harnesses/impls/hermes-agent/harness.js +104 -0
  181. package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
  182. package/dist/harnesses/impls/index.d.ts +9 -0
  183. package/dist/harnesses/impls/index.js +19 -1
  184. package/dist/harnesses/impls/index.js.map +1 -1
  185. package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +3 -0
  186. package/dist/harnesses/impls/learner/adapters/codex-code.js +49 -0
  187. package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
  188. package/dist/harnesses/impls/learner/harness.d.ts +41 -4
  189. package/dist/harnesses/impls/learner/harness.js +114 -2
  190. package/dist/harnesses/impls/learner/harness.js.map +1 -1
  191. package/dist/harnesses/impls/learner/plugin-path.d.ts +0 -13
  192. package/dist/harnesses/impls/learner/plugin-path.js +35 -15
  193. package/dist/harnesses/impls/learner/plugin-path.js.map +1 -1
  194. package/dist/harnesses/impls/learner/types.d.ts +15 -0
  195. package/dist/harnesses/impls/stub.d.ts +58 -0
  196. package/dist/harnesses/impls/stub.js +89 -0
  197. package/dist/harnesses/impls/stub.js.map +1 -0
  198. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.d.ts +69 -50
  199. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +178 -93
  200. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
  201. package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.d.ts +12 -1
  202. package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js +121 -7
  203. package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js.map +1 -1
  204. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +15 -0
  205. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +54 -4
  206. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
  207. package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.d.ts +6 -0
  208. package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.js +1 -1
  209. package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.js.map +1 -1
  210. package/dist/harnesses/readiness-registry.js +9 -1
  211. package/dist/harnesses/readiness-registry.js.map +1 -1
  212. package/dist/main.js +373 -82
  213. package/dist/main.js.map +1 -1
  214. package/dist/observability/emit-event.d.ts +1 -1
  215. package/dist/observability/emit-event.js.map +1 -1
  216. package/dist/operator-errors.d.ts +7 -0
  217. package/dist/operator-errors.js +13 -1
  218. package/dist/operator-errors.js.map +1 -1
  219. package/dist/plugins/learner/.claude-plugin/plugin.json +9 -0
  220. package/dist/plugins/learner/.codex-plugin/plugin.json +39 -0
  221. package/dist/plugins/learner/AGENTS.md +40 -0
  222. package/dist/plugins/learner/CLAUDE.md +33 -0
  223. package/dist/plugins/learner/README.md +59 -0
  224. package/dist/plugins/learner/hooks/hooks.json +16 -0
  225. package/dist/plugins/learner/hooks/session-start +38 -0
  226. package/dist/plugins/learner/skills/learn/SKILL.md +412 -0
  227. package/dist/plugins/learner/skills/learn/analyst-prompt.md +68 -0
  228. package/dist/plugins/learner/skills/learn/consolidator-prompt.md +94 -0
  229. package/dist/plugins/learner/skills/learn/explorer-prompt.md +53 -0
  230. package/dist/plugins/learner/skills/learn/planner-prompt.md +87 -0
  231. package/dist/plugins/learner/skills/learn/promoter-prompt.md +113 -0
  232. package/dist/plugins/learner/skills/learn/step-worker-prompt.md +47 -0
  233. package/dist/plugins/learner/skills/learn/strategist-prompt.md +85 -0
  234. package/dist/restart-daemon.d.ts +90 -0
  235. package/dist/restart-daemon.js +95 -0
  236. package/dist/restart-daemon.js.map +1 -0
  237. package/dist/setup/halt-mode.d.ts +14 -0
  238. package/dist/setup/halt-mode.js +17 -0
  239. package/dist/setup/halt-mode.js.map +1 -0
  240. package/dist/solver-nets/prediction-operator-ux.js +43 -3
  241. package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
  242. package/dist/solver-nets/registry.d.ts +1 -0
  243. package/dist/solver-nets/registry.js +1 -1
  244. package/dist/solver-nets/registry.js.map +1 -1
  245. package/dist/solver-types/_swe-rebench-v2-pool-cache.d.ts +58 -0
  246. package/dist/solver-types/_swe-rebench-v2-pool-cache.js +87 -0
  247. package/dist/solver-types/_swe-rebench-v2-pool-cache.js.map +1 -0
  248. package/dist/solver-types/_swe-rebench-v2-substrate.d.ts +1 -0
  249. package/dist/solver-types/_swe-rebench-v2-substrate.js +10 -0
  250. package/dist/solver-types/_swe-rebench-v2-substrate.js.map +1 -1
  251. package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +65 -0
  252. package/dist/solver-types/_swe-rebench-v2-validated-pool.js +243 -26
  253. package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
  254. package/dist/solver-types/swe-rebench-v2-auto.d.ts +22 -7
  255. package/dist/solver-types/swe-rebench-v2-auto.js +45 -20
  256. package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
  257. package/dist/solver-types/swe-rebench-v2.d.ts +13 -2
  258. package/dist/solver-types/swe-rebench-v2.js +233 -94
  259. package/dist/solver-types/swe-rebench-v2.js.map +1 -1
  260. package/dist/solvernets/daemon-init.d.ts +10 -2
  261. package/dist/solvernets/daemon-init.js +22 -2
  262. package/dist/solvernets/daemon-init.js.map +1 -1
  263. package/dist/solvernets/launched-record-dispatcher.js +35 -7
  264. package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
  265. package/dist/solvernets/store.d.ts +5 -0
  266. package/dist/solvernets/store.js +1 -0
  267. package/dist/solvernets/store.js.map +1 -1
  268. package/dist/store/store.d.ts +15 -0
  269. package/dist/store/store.js +118 -3
  270. package/dist/store/store.js.map +1 -1
  271. package/dist/tasks/sources.d.ts +18 -1
  272. package/dist/tasks/sources.js +33 -5
  273. package/dist/tasks/sources.js.map +1 -1
  274. package/dist/tx-retry.d.ts +151 -19
  275. package/dist/tx-retry.js +286 -32
  276. package/dist/tx-retry.js.map +1 -1
  277. package/dist/types/payloads/prediction-apy-v0.d.ts +5 -5
  278. package/dist/types/payloads/prediction-v0.d.ts +5 -5
  279. package/dist/types/task-document.d.ts +392 -0
  280. package/dist/types/task-document.js +10 -0
  281. package/dist/types/task-document.js.map +1 -1
  282. package/dist/types/task.d.ts +28 -0
  283. package/dist/util/extract-tx-hash.d.ts +14 -0
  284. package/dist/util/extract-tx-hash.js +19 -0
  285. package/dist/util/extract-tx-hash.js.map +1 -0
  286. package/dist/vendor/@jinn-network/sdk/dist/contracts.js +1 -1
  287. package/dist/vendor/@jinn-network/sdk/dist/solvernets/manifest-schema.d.ts +3 -0
  288. package/dist/vendor/@jinn-network/sdk/dist/solvernets/manifest-schema.js +1 -0
  289. package/package.json +29 -12
  290. package/dist/dashboard/assets/index-DOlzFN8a.css +0 -32
  291. package/dist/dashboard/assets/index-NkZ7CTAT.js +0 -140
@@ -1,7 +1,9 @@
1
- import { CLAUDE_CODE_HARNESS } from '../../names.js';
1
+ import { CLAUDE_CODE_HARNESS, CODEX_HARNESS, canonicalHarnessName } from '../../names.js';
2
2
  import { resolvePluginRoot } from './plugin-path.js';
3
3
  import { harvestOutput } from './harvest.js';
4
4
  import { buildClaudeIsReady } from '../../../preflight/claude-auth.js';
5
+ import { probeCodexDoctor } from '../../../api/codex-doctor-endpoint.js';
6
+ import { isLocalCodexBaseUrl } from './adapters/codex-code.js';
5
7
  /**
6
8
  * `Harness` shell. Bridges the engine's dispatch contract
7
9
  * (`await impl.run(ctx)`) into the harness adapter + markdown plugin.
@@ -16,6 +18,9 @@ export class LearnerHarness {
16
18
  adapter;
17
19
  pluginRoot;
18
20
  claudePath;
21
+ codexPath;
22
+ codexBaseUrl;
23
+ codexDoctorTimeoutMs;
19
24
  runtimeMode;
20
25
  constructor(config) {
21
26
  this.adapter = config.adapter;
@@ -23,12 +28,119 @@ export class LearnerHarness {
23
28
  this.version = config.version ?? '0.1.0-shim';
24
29
  this.pluginRoot = config.pluginRoot ?? resolvePluginRoot();
25
30
  this.claudePath = config.claudePath ?? 'claude';
31
+ this.codexPath = config.codexPath;
32
+ this.codexBaseUrl = config.codexBaseUrl;
33
+ this.codexDoctorTimeoutMs = config.codexDoctorTimeoutMs;
26
34
  this.runtimeMode = config.runtimeMode ?? 'bare';
27
35
  }
28
- isReady = buildClaudeIsReady({
36
+ claudeIsReady = buildClaudeIsReady({
29
37
  getClaudePath: () => this.claudePath,
30
38
  getContext: () => this.runtimeMode,
31
39
  });
40
+ /**
41
+ * Readiness probe.
42
+ *
43
+ * The `LearnerHarness` shell backs two distinct CLIs: claude-code (the
44
+ * default) and Codex (`name === CODEX_HARNESS`). The probe MUST match the
45
+ * CLI actually invoked — delegating the Codex variant to the claude auth
46
+ * probe makes a missing/unconfigured `codex` install look always-ready and
47
+ * burns N/N failed claims (#348, the same-shape bug as #330).
48
+ *
49
+ * - claude-code → `buildClaudeIsReady` (shells `claude auth status`).
50
+ * - Codex → `probeCodexDoctor` (shells `codex --version`, then
51
+ * checks for `OPENAI_API_KEY` / a `codex login` auth file).
52
+ */
53
+ async isReady(ctx) {
54
+ if (canonicalHarnessName(this.name) === CODEX_HARNESS) {
55
+ return this.codexIsReady();
56
+ }
57
+ return this.claudeIsReady(ctx);
58
+ }
59
+ /**
60
+ * Codex-specific readiness probe. Shells `codex --version` via the shared
61
+ * `probeCodexDoctor` helper (same logic the SPA precheck endpoint uses).
62
+ * Reports:
63
+ * - `installed: false` → binary not on PATH → ready=false with an install
64
+ * nextStep so the operator sees an actionable message instead of N/N
65
+ * failed claims (#348).
66
+ * - `exitCode !== 0` → binary exists but `codex --version` failed →
67
+ * ready=false pointing at the Codex precheck panel.
68
+ * - local `codexBaseUrl` → binary runs and the local sidecar owns auth, so
69
+ * Codex auth is not required.
70
+ * - `authStatus: 'not_configured'` → binary runs but no `OPENAI_API_KEY`
71
+ * and no `codex login` session → ready=false with a sign-in nextStep.
72
+ * - `authStatus: 'expired'` → an `auth.json` is present but its OAuth
73
+ * session has expired (or the file is malformed) → ready=false with a
74
+ * re-login nextStep. Distinct from `not_configured` so a logged-out
75
+ * operator with a leftover file is not treated as ready (#366).
76
+ * - otherwise → ready=true.
77
+ */
78
+ codexIsReady() {
79
+ const config = {};
80
+ if (this.codexPath !== undefined)
81
+ config.codexPath = this.codexPath;
82
+ if (this.codexDoctorTimeoutMs !== undefined) {
83
+ config.codexDoctorTimeoutMs = this.codexDoctorTimeoutMs;
84
+ }
85
+ const result = probeCodexDoctor(config);
86
+ if (!result.installed) {
87
+ return {
88
+ ready: false,
89
+ reason: 'codex binary not installed',
90
+ nextStep: {
91
+ description: 'Install the Codex CLI — see the Codex precheck panel in the operator dashboard for the install command.',
92
+ url: '/api/codex/doctor',
93
+ },
94
+ };
95
+ }
96
+ if (result.exitCode !== 0) {
97
+ const stderr = result.stderr.trim();
98
+ const stdout = result.stdout.trim();
99
+ const detail = stderr.length > 0 ? stderr : stdout;
100
+ return {
101
+ ready: false,
102
+ reason: `codex --version exit ${result.exitCode}${detail ? `: ${detail}` : ''}`,
103
+ nextStep: {
104
+ description: 'Run `codex --version` locally to surface the problem, or open the Codex precheck panel in the operator dashboard.',
105
+ url: '/api/codex/doctor',
106
+ },
107
+ };
108
+ }
109
+ if (this.codexBaseUrl) {
110
+ if (isLocalCodexBaseUrl(this.codexBaseUrl)) {
111
+ return { ready: true };
112
+ }
113
+ return {
114
+ ready: false,
115
+ reason: 'codex base URL must be local',
116
+ nextStep: {
117
+ description: 'Use a local Codex provider URL such as http://127.0.0.1:11434/v1 or unset JINN_CODEX_BASE_URL.',
118
+ url: '/api/codex/doctor',
119
+ },
120
+ };
121
+ }
122
+ if (result.authStatus === 'expired') {
123
+ return {
124
+ ready: false,
125
+ reason: 'codex auth expired',
126
+ nextStep: {
127
+ description: 'Codex sign-in has expired — run `codex login` to refresh the session (or set OPENAI_API_KEY), then re-check the Codex precheck panel in the operator dashboard.',
128
+ url: '/api/codex/doctor',
129
+ },
130
+ };
131
+ }
132
+ if (result.authStatus !== 'ok') {
133
+ return {
134
+ ready: false,
135
+ reason: 'codex auth not configured',
136
+ nextStep: {
137
+ description: 'Sign in to Codex — set OPENAI_API_KEY or run `codex login`, then re-check the Codex precheck panel in the operator dashboard.',
138
+ url: '/api/codex/doctor',
139
+ },
140
+ };
141
+ }
142
+ return { ready: true };
143
+ }
32
144
  supports(spec) {
33
145
  if (spec.role === 'evaluation')
34
146
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../../src/harnesses/impls/learner/harness.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../../src/harnesses/impls/learner/harness.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1 @@
1
- /**
2
- * Resolve the learner plugin root from the impl directory's
3
- * runtime location.
4
- *
5
- * Layout assumption: this file lives at
6
- * <package>/<src-or-dist>/harnesses/impls/learner/plugin-path.{ts,js}
7
- * and the plugin lives at
8
- * <package>/plugins/learner/
9
- *
10
- * Walks up four directories from this file (impls → harness → src/dist →
11
- * package root) then descends into plugins/learner/. Verifies the
12
- * expected layout exists and throws with a clear message if not.
13
- */
14
1
  export declare function resolvePluginRoot(): string;
@@ -2,29 +2,49 @@ import { existsSync } from 'node:fs';
2
2
  import { dirname, join, resolve } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  /**
5
- * Resolve the learner plugin root from the impl directory's
6
- * runtime location.
5
+ * Resolve the learner plugin root from the impl directory's runtime location.
7
6
  *
8
- * Layout assumption: this file lives at
9
- * <package>/<src-or-dist>/harnesses/impls/learner/plugin-path.{ts,js}
10
- * and the plugin lives at
11
- * <package>/plugins/learner/
7
+ * Canonical layout (compiled): this file lives at
8
+ * <package>/dist/harnesses/impls/learner/plugin-path.js
9
+ * and the plugin tree is co-located inside dist/:
10
+ * <package>/dist/plugins/learner/
12
11
  *
13
- * Walks up four directories from this file (impls harness src/dist →
14
- * package root) then descends into plugins/learner/. Verifies the
15
- * expected layout exists and throws with a clear message if not.
12
+ * The build step copies plugins/learnerdist/plugins/learner so the
13
+ * compiled code and the plugin runtime assets are always version-locked
14
+ * within the same dist/ tree for published npm installs and source
15
+ * checkouts alike (after `yarn build`).
16
+ *
17
+ * Source-checkout / tsx path (e.g. vitest): this file lives at
18
+ * <package>/src/harnesses/impls/learner/plugin-path.ts
19
+ * Walking up four directories reaches the package root, and the plugin
20
+ * lives at <package>/plugins/learner/.
21
+ *
22
+ * Detection: if the resolved path three levels up ends with `/dist` the
23
+ * runtime is inside a compiled dist tree; otherwise fall back to the
24
+ * package-root layout (four levels up).
16
25
  */
26
+ function requireAsset(pluginRoot, relative, hint) {
27
+ if (!existsSync(join(pluginRoot, relative))) {
28
+ const suffix = hint ? ` — ${hint}` : '';
29
+ throw new Error(`learner plugin at ${pluginRoot} is missing ${relative}${suffix}`);
30
+ }
31
+ }
17
32
  export function resolvePluginRoot() {
18
33
  const here = dirname(fileURLToPath(import.meta.url));
19
- const packageRoot = resolve(here, '..', '..', '..', '..');
20
- const pluginRoot = join(packageRoot, 'plugins', 'learner');
34
+ const threeUp = resolve(here, '..', '..', '..');
35
+ // Compiled dist layout: dist/harnesses/impls/learner → dist/ → dist/plugins/learner
36
+ const isDistTree = threeUp.endsWith('/dist');
37
+ const pluginRoot = isDistTree
38
+ ? join(threeUp, 'plugins', 'learner')
39
+ : join(resolve(here, '..', '..', '..', '..'), 'plugins', 'learner');
21
40
  if (!existsSync(pluginRoot)) {
22
41
  throw new Error(`learner plugin not found at expected path: ${pluginRoot}. ` +
23
- `Resolved from impl dir: ${here}.`);
24
- }
25
- if (!existsSync(join(pluginRoot, 'skills', 'learn', 'SKILL.md'))) {
26
- throw new Error(`learner plugin at ${pluginRoot} is missing skills/learn/SKILL.md`);
42
+ `Resolved from impl dir: ${here}. ` +
43
+ `Run \`yarn build\` to copy plugins/learner into dist/plugins/learner.`);
27
44
  }
45
+ requireAsset(pluginRoot, 'skills/learn/SKILL.md');
46
+ requireAsset(pluginRoot, 'hooks/session-start', 'plugin assets may be stale or incomplete; rebuild the plugin');
47
+ requireAsset(pluginRoot, 'hooks/hooks.json', 'plugin assets may be stale or incomplete; rebuild the plugin');
28
48
  return pluginRoot;
29
49
  }
30
50
  //# sourceMappingURL=plugin-path.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-path.js","sourceRoot":"","sources":["../../../../src/harnesses/impls/learner/plugin-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAE3D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,8CAA8C,UAAU,IAAI;YAC1D,2BAA2B,IAAI,GAAG,CACrC,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACb,qBAAqB,UAAU,mCAAmC,CACnE,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"plugin-path.js","sourceRoot":"","sources":["../../../../src/harnesses/impls/learner/plugin-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAS,YAAY,CAAC,UAAkB,EAAE,QAAgB,EAAE,IAAa;IACvE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,eAAe,QAAQ,GAAG,MAAM,EAAE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAEhD,oFAAoF;IACpF,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,UAAU;QAC3B,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;QACrC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAEtE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,8CAA8C,UAAU,IAAI;YAC1D,2BAA2B,IAAI,IAAI;YACnC,uEAAuE,CAC1E,CAAC;IACJ,CAAC;IACD,YAAY,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IAClD,YAAY,CAAC,UAAU,EAAE,qBAAqB,EAAE,8DAA8D,CAAC,CAAC;IAChH,YAAY,CAAC,UAAU,EAAE,kBAAkB,EAAE,8DAA8D,CAAC,CAAC;IAC7G,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -121,4 +121,19 @@ export interface LearnerHarnessConfig {
121
121
  * Defaults to 'bare'.
122
122
  */
123
123
  runtimeMode?: 'bare' | 'container' | 'docker-compose';
124
+ /**
125
+ * Path to the `codex` executable. Used by `isReady()` when this
126
+ * `LearnerHarness` is the Codex variant (`name === CODEX_HARNESS`) — it is
127
+ * passed to `probeCodexDoctor()`. Defaults to 'codex' (from PATH).
128
+ */
129
+ codexPath?: string;
130
+ /** Default Codex model when a SolverNet does not specify one. */
131
+ codexModel?: string;
132
+ /** Local OpenAI-compatible Codex provider base URL. */
133
+ codexBaseUrl?: string;
134
+ /**
135
+ * Timeout (ms) for the `codex --version` probe in the Codex variant's
136
+ * `isReady()`. Defaults to 30s.
137
+ */
138
+ codexDoctorTimeoutMs?: number;
124
139
  }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Env-gated stub harness for the T2.2 producer/evaluator gate.
3
+ *
4
+ * When JINN_HARNESS_STUB_INSTANCE is set, the canned patch at
5
+ * <fixturesDir>/<instanceMatcher>.patch is returned as a SWE-rebench v2
6
+ * restoration solution. Never calls an LLM; never accepts tasks whose
7
+ * spec.instance_id differs from the configured matcher.
8
+ *
9
+ * PRODUCTION SAFETY — two-env-var requirement.
10
+ * This is a *fake* harness: it produces canned, non-genuine work. If it ever
11
+ * entered a real operator run it would generate fraudulent on-chain activity.
12
+ * To make accidental activation impossible, the factory requires BOTH:
13
+ * JINN_HARNESS_STUB_INSTANCE — instance ID this stub responds to
14
+ * JINN_TEST_MODE === '1' — explicit test-mode sentinel
15
+ * If JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is not '1', the
16
+ * factory THROWS rather than silently registering the stub. A single stray
17
+ * exported env var in an operator's shell can no longer activate it.
18
+ *
19
+ * Activated by environment variables:
20
+ * JINN_HARNESS_STUB_INSTANCE — instance ID this stub responds to (required to activate)
21
+ * JINN_TEST_MODE — must equal '1' (defense-in-depth; required to activate)
22
+ * JINN_HARNESS_STUB_FIXTURES_DIR — dir containing <instanceMatcher>.patch files
23
+ * (default: client/test/release/tier-2/fixtures)
24
+ */
25
+ import type { Harness, HarnessContext, ReadyStatus, Solution } from '../types.js';
26
+ export interface StubHarnessConfig {
27
+ /** Directory containing <instanceMatcher>.patch files. */
28
+ fixturesDir: string;
29
+ /** The instance ID this stub will accept. Tasks with other instance IDs are rejected. */
30
+ instanceMatcher: string;
31
+ }
32
+ /**
33
+ * A zero-LLM Harness that returns a canned patch for a specific SWE-rebench v2
34
+ * instance. Intended exclusively for T2.2 release-gate automation.
35
+ */
36
+ export declare class StubHarness implements Harness {
37
+ readonly name = "harness:stub";
38
+ readonly version = "0.1.0-stub";
39
+ private readonly fixturesDir;
40
+ private readonly instanceMatcher;
41
+ constructor(config: StubHarnessConfig);
42
+ supports(ctx: {
43
+ solverType: string;
44
+ role?: 'restoration' | 'evaluation';
45
+ }): boolean;
46
+ isReady(): Promise<ReadyStatus>;
47
+ run(ctx: HarnessContext): Promise<Solution>;
48
+ }
49
+ /**
50
+ * Factory that reads JINN_HARNESS_STUB_INSTANCE and JINN_HARNESS_STUB_FIXTURES_DIR
51
+ * from the environment and returns a configured StubHarness, or null if the env
52
+ * var is absent (allowing the registry to skip registration silently).
53
+ *
54
+ * Defense-in-depth: if JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is
55
+ * not exactly '1', this THROWS rather than returning a harness — a real
56
+ * operator run must never silently pick up the fake stub harness.
57
+ */
58
+ export declare function maybeCreateStubHarnessFromEnv(): StubHarness | null;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Env-gated stub harness for the T2.2 producer/evaluator gate.
3
+ *
4
+ * When JINN_HARNESS_STUB_INSTANCE is set, the canned patch at
5
+ * <fixturesDir>/<instanceMatcher>.patch is returned as a SWE-rebench v2
6
+ * restoration solution. Never calls an LLM; never accepts tasks whose
7
+ * spec.instance_id differs from the configured matcher.
8
+ *
9
+ * PRODUCTION SAFETY — two-env-var requirement.
10
+ * This is a *fake* harness: it produces canned, non-genuine work. If it ever
11
+ * entered a real operator run it would generate fraudulent on-chain activity.
12
+ * To make accidental activation impossible, the factory requires BOTH:
13
+ * JINN_HARNESS_STUB_INSTANCE — instance ID this stub responds to
14
+ * JINN_TEST_MODE === '1' — explicit test-mode sentinel
15
+ * If JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is not '1', the
16
+ * factory THROWS rather than silently registering the stub. A single stray
17
+ * exported env var in an operator's shell can no longer activate it.
18
+ *
19
+ * Activated by environment variables:
20
+ * JINN_HARNESS_STUB_INSTANCE — instance ID this stub responds to (required to activate)
21
+ * JINN_TEST_MODE — must equal '1' (defense-in-depth; required to activate)
22
+ * JINN_HARNESS_STUB_FIXTURES_DIR — dir containing <instanceMatcher>.patch files
23
+ * (default: client/test/release/tier-2/fixtures)
24
+ */
25
+ import * as fs from 'node:fs/promises';
26
+ import * as path from 'node:path';
27
+ /**
28
+ * A zero-LLM Harness that returns a canned patch for a specific SWE-rebench v2
29
+ * instance. Intended exclusively for T2.2 release-gate automation.
30
+ */
31
+ export class StubHarness {
32
+ name = 'harness:stub';
33
+ version = '0.1.0-stub';
34
+ fixturesDir;
35
+ instanceMatcher;
36
+ constructor(config) {
37
+ this.fixturesDir = config.fixturesDir;
38
+ this.instanceMatcher = config.instanceMatcher;
39
+ }
40
+ supports(ctx) {
41
+ if (ctx.role === 'evaluation')
42
+ return false;
43
+ return ctx.solverType === 'swe-rebench-v2.v1';
44
+ }
45
+ async isReady() {
46
+ return { ready: true };
47
+ }
48
+ async run(ctx) {
49
+ const taskInstanceId = ctx.task.spec?.['instance_id'];
50
+ if (taskInstanceId !== this.instanceMatcher) {
51
+ throw new Error(`stub harness: task.spec.instance_id=${String(taskInstanceId)} does not match configured instanceMatcher=${this.instanceMatcher}`);
52
+ }
53
+ const patchPath = path.join(this.fixturesDir, `${this.instanceMatcher}.patch`);
54
+ const patch = await fs.readFile(patchPath, 'utf-8');
55
+ return {
56
+ venueRef: { name: this.name },
57
+ gating: {},
58
+ solutionPayload: {
59
+ schemaVersion: 'swe-rebench-v2-solution.v1',
60
+ patch,
61
+ },
62
+ };
63
+ }
64
+ }
65
+ /**
66
+ * Factory that reads JINN_HARNESS_STUB_INSTANCE and JINN_HARNESS_STUB_FIXTURES_DIR
67
+ * from the environment and returns a configured StubHarness, or null if the env
68
+ * var is absent (allowing the registry to skip registration silently).
69
+ *
70
+ * Defense-in-depth: if JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is
71
+ * not exactly '1', this THROWS rather than returning a harness — a real
72
+ * operator run must never silently pick up the fake stub harness.
73
+ */
74
+ export function maybeCreateStubHarnessFromEnv() {
75
+ const instanceMatcher = process.env['JINN_HARNESS_STUB_INSTANCE'];
76
+ if (!instanceMatcher)
77
+ return null;
78
+ if (process.env['JINN_TEST_MODE'] !== '1') {
79
+ throw new Error('stub harness must never activate in a real operator run: ' +
80
+ 'JINN_HARNESS_STUB_INSTANCE is set but JINN_TEST_MODE is not "1". ' +
81
+ 'The stub harness produces canned, non-genuine work and would generate ' +
82
+ 'fraudulent on-chain activity. Set JINN_TEST_MODE=1 if this is a Tier 2 ' +
83
+ 'test; otherwise unset JINN_HARNESS_STUB_INSTANCE.');
84
+ }
85
+ const fixturesDir = process.env['JINN_HARNESS_STUB_FIXTURES_DIR'] ??
86
+ path.resolve(process.cwd(), 'test', 'release', 'tier-2', 'fixtures');
87
+ return new StubHarness({ instanceMatcher, fixturesDir });
88
+ }
89
+ //# sourceMappingURL=stub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stub.js","sourceRoot":"","sources":["../../../src/harnesses/impls/stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAUlC;;;GAGG;AACH,MAAM,OAAO,WAAW;IACb,IAAI,GAAG,cAAc,CAAC;IACtB,OAAO,GAAG,YAAY,CAAC;IAEf,WAAW,CAAS;IACpB,eAAe,CAAS;IAEzC,YAAY,MAAyB;QACnC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;IAChD,CAAC;IAED,QAAQ,CAAC,GAAgE;QACvE,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,KAAK,CAAC;QAC5C,OAAO,GAAG,CAAC,UAAU,KAAK,mBAAmB,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,OAAO;QACX,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAmB;QAC3B,MAAM,cAAc,GAAI,GAAG,CAAC,IAAI,CAAC,IAA4C,EAAE,CAAC,aAAa,CAAC,CAAC;QAC/F,IAAI,cAAc,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CACb,uCAAuC,MAAM,CAAC,cAAc,CAAC,8CAA8C,IAAI,CAAC,eAAe,EAAE,CAClI,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,eAAe,QAAQ,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACpD,OAAO;YACL,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YAC7B,MAAM,EAAE,EAAE;YACV,eAAe,EAAE;gBACf,aAAa,EAAE,4BAA4B;gBAC3C,KAAK;aACN;SACF,CAAC;IACJ,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,6BAA6B;IAC3C,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAClE,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,GAAG,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,2DAA2D;YACzD,mEAAmE;YACnE,wEAAwE;YACxE,yEAAyE;YACzE,mDAAmD,CACtD,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GACf,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IACvE,OAAO,IAAI,WAAW,CAAC,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC,CAAC;AAC3D,CAAC"}
@@ -37,6 +37,36 @@ export declare class EvalCouldNotGradeError extends Error {
37
37
  readonly logExcerpt: string;
38
38
  constructor(reason: string, logExcerpt?: string);
39
39
  }
40
+ /**
41
+ * Thrown by `runEval` when the disk cannot be brought above the eval
42
+ * disk-floor even after a broad prune. A clean abort — the caller stops
43
+ * gracefully; no instance is graded, nothing is marked. Distinct from
44
+ * `EvalCouldNotGradeError`: this is operator-environment, retryable, and must
45
+ * never be turned into a `scorable: false` admission (#476).
46
+ */
47
+ export declare class InsufficientDiskError extends Error {
48
+ readonly freeBytes: number;
49
+ readonly floorBytes: number;
50
+ constructor(freeBytes: number, floorBytes: number);
51
+ }
52
+ /**
53
+ * Default free-disk floor required before an eval round: 20 GB. A single
54
+ * SWE-rebench eval image was observed to peak transiently at ~12.6 GB, so the
55
+ * floor clears the worst observed instance with real margin. Override with
56
+ * `JINN_EVAL_DISK_FLOOR_GB` on constrained hosts.
57
+ */
58
+ export declare const DEFAULT_EVAL_DISK_FLOOR_BYTES = 20000000000;
59
+ /** Resolve the disk floor: explicit option > `JINN_EVAL_DISK_FLOOR_GB` env > default. */
60
+ export declare function resolveDiskFloorBytes(opt: number | undefined): number;
61
+ /**
62
+ * Default wall-clock limit for one upstream eval.py invocation: 2 hours. Some
63
+ * linux/amd64 SWE-rebench images can wedge indefinitely under Apple Silicon
64
+ * emulation after a native crash, so the subprocess gets a hard guardrail.
65
+ * Override with `JINN_SWE_REBENCH_EVAL_TIMEOUT_MS`; set `0` to disable.
66
+ */
67
+ export declare const DEFAULT_EVAL_TIMEOUT_MS: number;
68
+ /** Resolve the eval timeout: explicit option > env > default. */
69
+ export declare function resolveEvalTimeoutMs(opt: number | undefined): number;
40
70
  export interface PythonEvalRunnerOptions {
41
71
  /** Path to the cloned SWE-rebench-V2 repo (cached locally). */
42
72
  upstreamRepoDir: string;
@@ -45,66 +75,55 @@ export interface PythonEvalRunnerOptions {
45
75
  /** Workers for parallel eval (defaults to 1; we run one task at a time). */
46
76
  maxWorkers?: number;
47
77
  /**
48
- * Max number of distinct eval images to keep in the local Docker cache.
49
- * The runner tracks an in-process LRU keyed by image tag; once usage exceeds
50
- * this cap, the least-recently-used images are removed via
51
- * {@link PythonEvalRunnerOptions.cleanupImage}.
52
- *
53
- * The leaderboard pool has hundreds of unique instances at ~3 GB/image, so
54
- * an unbounded cache fills operator disks in days (jinn-mono-uy6v.11).
78
+ * Removes a completed round's entire Docker footprint the round's image,
79
+ * stopped containers, and build cache so eval disk usage never
80
+ * accumulates across instances (#476). Called once per `runEval`, in a
81
+ * `finally`, even when the eval threw.
55
82
  *
56
- * Default: `process.env.JINN_EVAL_IMAGE_CACHE_MAX` parsed as an integer, or
57
- * `DEFAULT_EVAL_IMAGE_CACHE_MAX` (20) if unset/invalid.
83
+ * Defaults to {@link defaultPruneRound}. Implementations MUST NOT throw
84
+ * `runEval` guards defensively, but cleanup failures should be swallowed
85
+ * (logged elsewhere if desired) so a flaky `docker` never escapes `runEval`.
58
86
  */
59
- imageCacheMax?: number;
87
+ pruneRound?: (image: string) => Promise<void>;
60
88
  /**
61
- * Removes an image from the local Docker cache (or no-ops if the operator
62
- * has chosen not to GC). Called for each eviction from the LRU.
63
- *
64
- * Defaults to `docker rmi <image>` via the system `docker` binary. Test
65
- * suites inject a stub to capture the eviction order without shelling out.
66
- *
67
- * Implementations MUST NOT throw — failures should be swallowed (logged
68
- * elsewhere if desired) so a missing/failed `docker rmi` never escapes
69
- * `runEval`. The runner enforces this defensively too.
89
+ * Resolves the eval image digest while the image is still local, before
90
+ * per-round pruning removes it. Defaults to `docker image inspect`.
91
+ */
92
+ resolveImageDigest?: (image: string) => Promise<string | null>;
93
+ /**
94
+ * Required free disk (bytes) before an eval round starts. Explicit value >
95
+ * `JINN_EVAL_DISK_FLOOR_GB` env > {@link DEFAULT_EVAL_DISK_FLOOR_BYTES}.
70
96
  */
71
- cleanupImage?: (image: string) => Promise<void>;
97
+ diskFloorBytes?: number;
98
+ /** Probe of free disk (bytes). Defaults to a `statfs` on the temp dir. */
99
+ freeDiskBytes?: () => Promise<number>;
100
+ /**
101
+ * Broad reclaim invoked when free disk is below the floor. Defaults to
102
+ * `docker system prune -f`. MUST NOT throw.
103
+ */
104
+ systemPrune?: () => Promise<void>;
105
+ /**
106
+ * Wall-clock timeout (ms) for one upstream eval.py invocation. Explicit value
107
+ * > `JINN_SWE_REBENCH_EVAL_TIMEOUT_MS` env > {@link DEFAULT_EVAL_TIMEOUT_MS}.
108
+ * Set to 0 to disable.
109
+ */
110
+ evalTimeoutMs?: number;
72
111
  }
73
- /**
74
- * Default cap on the per-instance Docker image cache when no explicit
75
- * `imageCacheMax` and no `JINN_EVAL_IMAGE_CACHE_MAX` env var are configured.
76
- *
77
- * 20 images × ~3 GB/image ≈ 60 GB working set — small enough that even a
78
- * 256 GB disk has headroom, large enough that the steady-state loop on a
79
- * frequently-repeating subset of the pool rarely re-pulls.
80
- */
81
- export declare const DEFAULT_EVAL_IMAGE_CACHE_MAX = 20;
82
- export declare function resolveImageCacheMax(opt: number | undefined): number;
83
112
  export declare function matchInfraSignature(log: string): string | null;
84
113
  export declare class PythonEvalRunner implements EvalRunner {
85
114
  private readonly opts;
86
- /**
87
- * LRU of image tags whose Docker layers may be cached locally. Stored as a
88
- * `Set<string>` because `Set` preserves insertion order; we delete-then-add
89
- * to refresh recency and `next()` on the keys iterator to find the
90
- * least-recently-used entry.
91
- */
92
- private readonly imageLru;
93
- private readonly imageCacheMax;
94
- private readonly cleanupImage;
115
+ private readonly pruneRound;
116
+ private readonly diskFloorBytes;
117
+ private readonly freeDiskBytes;
118
+ private readonly systemPrune;
119
+ private readonly resolveImageDigest;
120
+ private readonly evalTimeoutMs;
95
121
  constructor(opts: PythonEvalRunnerOptions);
96
- runEval(args: Parameters<EvalRunner['runEval']>[0]): ReturnType<EvalRunner['runEval']>;
97
122
  /**
98
- * Move `image` to the most-recently-used slot of the in-process LRU; if the
99
- * set now exceeds {@link imageCacheMax}, evict the oldest entries via
100
- * {@link cleanupImage}. Eviction failures are swallowed so a flaky
101
- * `docker rmi` cannot escape `runEval`.
102
- *
103
- * The cap is enforced after the just-used image is inserted: the
104
- * just-evaluated image is the *most* recent, so repeat-evals of recently
105
- * used instances never re-pull. Only when more than N distinct images have
106
- * been used does the oldest get rmi'd.
123
+ * Ensure enough free disk for an eval round. Below the floor broad prune →
124
+ * re-probe; still below `InsufficientDiskError` (clean abort). (#476)
107
125
  */
108
- private recordImageUsage;
126
+ private ensureDiskHeadroom;
127
+ runEval(args: Parameters<EvalRunner['runEval']>[0]): ReturnType<EvalRunner['runEval']>;
109
128
  private runEvalImpl;
110
129
  }