@jinn-network/client 0.1.7 → 0.1.8-canary.09a3b2f6

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 (438) hide show
  1. package/README.md +67 -1
  2. package/dist/adapters/mech/adapter.d.ts +39 -2
  3. package/dist/adapters/mech/adapter.js +178 -20
  4. package/dist/adapters/mech/adapter.js.map +1 -1
  5. package/dist/adapters/mech/contracts.d.ts +22 -1
  6. package/dist/adapters/mech/contracts.js +96 -52
  7. package/dist/adapters/mech/contracts.js.map +1 -1
  8. package/dist/adapters/mech/safe-revert.d.ts +4 -0
  9. package/dist/adapters/mech/safe-revert.js +5 -1
  10. package/dist/adapters/mech/safe-revert.js.map +1 -1
  11. package/dist/adapters/mech/safe.d.ts +1 -1
  12. package/dist/adapters/mech/safe.js +10 -4
  13. package/dist/adapters/mech/safe.js.map +1 -1
  14. package/dist/adapters/mech/types.d.ts +6 -1
  15. package/dist/adapters/mech/types.js.map +1 -1
  16. package/dist/agent/operator-claude.js +8 -0
  17. package/dist/agent/operator-claude.js.map +1 -1
  18. package/dist/api/activity-events-endpoint.d.ts +14 -0
  19. package/dist/api/activity-events-endpoint.js +59 -0
  20. package/dist/api/activity-events-endpoint.js.map +1 -0
  21. package/dist/api/bootstrap-endpoint.d.ts +1 -2
  22. package/dist/api/bootstrap-endpoint.js +42 -24
  23. package/dist/api/bootstrap-endpoint.js.map +1 -1
  24. package/dist/api/codex-doctor-endpoint.d.ts +22 -5
  25. package/dist/api/codex-doctor-endpoint.js +136 -17
  26. package/dist/api/codex-doctor-endpoint.js.map +1 -1
  27. package/dist/api/debug-report-endpoint.d.ts +27 -0
  28. package/dist/api/debug-report-endpoint.js +157 -0
  29. package/dist/api/debug-report-endpoint.js.map +1 -0
  30. package/dist/api/discovery-endpoint.d.ts +1 -0
  31. package/dist/api/discovery-endpoint.js +24 -0
  32. package/dist/api/discovery-endpoint.js.map +1 -1
  33. package/dist/api/fleet-build.d.ts +1 -7
  34. package/dist/api/fleet-build.js +0 -7
  35. package/dist/api/fleet-build.js.map +1 -1
  36. package/dist/api/gather-status.d.ts +39 -0
  37. package/dist/api/gather-status.js +181 -84
  38. package/dist/api/gather-status.js.map +1 -1
  39. package/dist/api/hermes-doctor-endpoint.d.ts +15 -7
  40. package/dist/api/hermes-doctor-endpoint.js +56 -19
  41. package/dist/api/hermes-doctor-endpoint.js.map +1 -1
  42. package/dist/api/launcher-status.d.ts +4 -2
  43. package/dist/api/launcher-status.js +11 -10
  44. package/dist/api/launcher-status.js.map +1 -1
  45. package/dist/api/launcher-tasks.d.ts +1 -1
  46. package/dist/api/launcher-tasks.js +12 -8
  47. package/dist/api/launcher-tasks.js.map +1 -1
  48. package/dist/api/loop-completion-build.d.ts +79 -0
  49. package/dist/api/loop-completion-build.js +155 -0
  50. package/dist/api/loop-completion-build.js.map +1 -0
  51. package/dist/api/operator-artifacts-endpoint.js +73 -6
  52. package/dist/api/operator-artifacts-endpoint.js.map +1 -1
  53. package/dist/api/portfolio-v0-build.d.ts +7 -1
  54. package/dist/api/portfolio-v0-build.js +6 -2
  55. package/dist/api/portfolio-v0-build.js.map +1 -1
  56. package/dist/api/prediction-v1-build.d.ts +6 -0
  57. package/dist/api/prediction-v1-build.js +3 -1
  58. package/dist/api/prediction-v1-build.js.map +1 -1
  59. package/dist/api/server.d.ts +17 -0
  60. package/dist/api/server.js +40 -1
  61. package/dist/api/server.js.map +1 -1
  62. package/dist/api/setup-endpoints.d.ts +13 -9
  63. package/dist/api/setup-endpoints.js +50 -173
  64. package/dist/api/setup-endpoints.js.map +1 -1
  65. package/dist/api/solvernets-endpoints.js +33 -63
  66. package/dist/api/solvernets-endpoints.js.map +1 -1
  67. package/dist/api/status-build.d.ts +140 -17
  68. package/dist/api/status-build.js +47 -34
  69. package/dist/api/status-build.js.map +1 -1
  70. package/dist/api/status-harness-rollup.d.ts +35 -0
  71. package/dist/api/status-harness-rollup.js +45 -0
  72. package/dist/api/status-harness-rollup.js.map +1 -0
  73. package/dist/api/status-rollup-build.d.ts +0 -4
  74. package/dist/api/status-rollup-build.js +0 -4
  75. package/dist/api/status-rollup-build.js.map +1 -1
  76. package/dist/api/task-runs-build.d.ts +8 -0
  77. package/dist/api/task-runs-build.js +5 -1
  78. package/dist/api/task-runs-build.js.map +1 -1
  79. package/dist/build-info.json +4 -4
  80. package/dist/build-meta.json +1 -1
  81. package/dist/captures/live-publisher.js +24 -4
  82. package/dist/captures/live-publisher.js.map +1 -1
  83. package/dist/captures/publish.d.ts +1 -1
  84. package/dist/chain-read-errors.d.ts +12 -0
  85. package/dist/chain-read-errors.js +26 -1
  86. package/dist/chain-read-errors.js.map +1 -1
  87. package/dist/cli/commands/codedigest-revert-check.d.ts +33 -0
  88. package/dist/cli/commands/codedigest-revert-check.js +253 -0
  89. package/dist/cli/commands/codedigest-revert-check.js.map +1 -0
  90. package/dist/cli/commands/doctor.d.ts +3 -0
  91. package/dist/cli/commands/doctor.js +35 -0
  92. package/dist/cli/commands/doctor.js.map +1 -1
  93. package/dist/cli/commands/eval.d.ts +76 -0
  94. package/dist/cli/commands/eval.js +401 -0
  95. package/dist/cli/commands/eval.js.map +1 -0
  96. package/dist/cli/commands/rewards.d.ts +2 -0
  97. package/dist/cli/commands/rewards.js +27 -0
  98. package/dist/cli/commands/rewards.js.map +1 -1
  99. package/dist/cli/commands/solver-nets.d.ts +1 -0
  100. package/dist/cli/commands/solver-nets.js +245 -22
  101. package/dist/cli/commands/solver-nets.js.map +1 -1
  102. package/dist/cli/commands/solver-plugins-block.d.ts +33 -0
  103. package/dist/cli/commands/solver-plugins-block.js +118 -0
  104. package/dist/cli/commands/solver-plugins-block.js.map +1 -0
  105. package/dist/cli/commands/solver-plugins-feedback.d.ts +72 -0
  106. package/dist/cli/commands/solver-plugins-feedback.js +262 -0
  107. package/dist/cli/commands/solver-plugins-feedback.js.map +1 -0
  108. package/dist/cli/commands/solver-plugins-read.d.ts +54 -0
  109. package/dist/cli/commands/solver-plugins-read.js +259 -0
  110. package/dist/cli/commands/solver-plugins-read.js.map +1 -0
  111. package/dist/cli/commands/solver-plugins.d.ts +35 -0
  112. package/dist/cli/commands/solver-plugins.js +399 -2
  113. package/dist/cli/commands/solver-plugins.js.map +1 -1
  114. package/dist/cli/commands/status.js +0 -1
  115. package/dist/cli/commands/status.js.map +1 -1
  116. package/dist/cli/commands/tasks.js +15 -2
  117. package/dist/cli/commands/tasks.js.map +1 -1
  118. package/dist/cli/index.js +4 -0
  119. package/dist/cli/index.js.map +1 -1
  120. package/dist/cli/task-native-readiness.d.ts +7 -0
  121. package/dist/cli/task-native-readiness.js +7 -5
  122. package/dist/cli/task-native-readiness.js.map +1 -1
  123. package/dist/config.d.ts +206 -232
  124. package/dist/config.js +289 -107
  125. package/dist/config.js.map +1 -1
  126. package/dist/daemon/ai-units-gate.d.ts +54 -0
  127. package/dist/daemon/ai-units-gate.js +83 -0
  128. package/dist/daemon/ai-units-gate.js.map +1 -0
  129. package/dist/daemon/creator.js +13 -0
  130. package/dist/daemon/creator.js.map +1 -1
  131. package/dist/daemon/daemon.d.ts +10 -0
  132. package/dist/daemon/daemon.js +205 -30
  133. package/dist/daemon/daemon.js.map +1 -1
  134. package/dist/daemon/eviction-loop.d.ts +7 -0
  135. package/dist/daemon/eviction-loop.js +16 -0
  136. package/dist/daemon/eviction-loop.js.map +1 -1
  137. package/dist/daemon/gate-logger.d.ts +9 -0
  138. package/dist/daemon/gate-logger.js +2 -0
  139. package/dist/daemon/gate-logger.js.map +1 -0
  140. package/dist/daemon/jinn-claim-loop.js +22 -4
  141. package/dist/daemon/jinn-claim-loop.js.map +1 -1
  142. package/dist/daemon/readiness-gate.d.ts +1 -4
  143. package/dist/daemon/readiness-gate.js.map +1 -1
  144. package/dist/daemon/spend-cap-gate.d.ts +40 -0
  145. package/dist/daemon/spend-cap-gate.js +46 -0
  146. package/dist/daemon/spend-cap-gate.js.map +1 -0
  147. package/dist/dashboard/assets/index-3quVQqik.js +167 -0
  148. package/dist/dashboard/assets/index-BVAWkLwY.css +1 -0
  149. package/dist/dashboard/index.html +2 -2
  150. package/dist/discovery/http.d.ts +7 -0
  151. package/dist/discovery/http.js +567 -24
  152. package/dist/discovery/http.js.map +1 -1
  153. package/dist/discovery/onchain.js +197 -5
  154. package/dist/discovery/onchain.js.map +1 -1
  155. package/dist/discovery/types.d.ts +235 -0
  156. package/dist/discovery/types.js +40 -0
  157. package/dist/discovery/types.js.map +1 -1
  158. package/dist/discovery/with-fallback.js +41 -0
  159. package/dist/discovery/with-fallback.js.map +1 -1
  160. package/dist/earning/bootstrap.d.ts +31 -3
  161. package/dist/earning/bootstrap.js +94 -22
  162. package/dist/earning/bootstrap.js.map +1 -1
  163. package/dist/earning/faucet.d.ts +1 -1
  164. package/dist/earning/faucet.js +2 -2
  165. package/dist/earning/faucet.js.map +1 -1
  166. package/dist/earning/safe-adapter.js +34 -11
  167. package/dist/earning/safe-adapter.js.map +1 -1
  168. package/dist/earning/types.d.ts +6 -6
  169. package/dist/earning/viem-clients.d.ts +11 -4
  170. package/dist/earning/viem-clients.js +14 -5
  171. package/dist/earning/viem-clients.js.map +1 -1
  172. package/dist/erc8004/identity.d.ts +19 -3
  173. package/dist/erc8004/identity.js +38 -11
  174. package/dist/erc8004/identity.js.map +1 -1
  175. package/dist/erc8004/index.d.ts +1 -1
  176. package/dist/erc8004/index.js.map +1 -1
  177. package/dist/eval/eval-harness-run.d.ts +63 -0
  178. package/dist/eval/eval-harness-run.js +123 -0
  179. package/dist/eval/eval-harness-run.js.map +1 -0
  180. package/dist/eval/orchestrator.d.ts +163 -0
  181. package/dist/eval/orchestrator.js +232 -0
  182. package/dist/eval/orchestrator.js.map +1 -0
  183. package/dist/eval/paired.d.ts +68 -0
  184. package/dist/eval/paired.js +93 -0
  185. package/dist/eval/paired.js.map +1 -0
  186. package/dist/eval/resolve-slate-tasks.d.ts +35 -0
  187. package/dist/eval/resolve-slate-tasks.js +56 -0
  188. package/dist/eval/resolve-slate-tasks.js.map +1 -0
  189. package/dist/eval/screen-discovery.d.ts +22 -0
  190. package/dist/eval/screen-discovery.js +71 -0
  191. package/dist/eval/screen-discovery.js.map +1 -0
  192. package/dist/eval/screen-progress.d.ts +41 -0
  193. package/dist/eval/screen-progress.js +60 -0
  194. package/dist/eval/screen-progress.js.map +1 -0
  195. package/dist/eval/screen-runner.d.ts +30 -0
  196. package/dist/eval/screen-runner.js +289 -0
  197. package/dist/eval/screen-runner.js.map +1 -0
  198. package/dist/eval/screen.d.ts +107 -0
  199. package/dist/eval/screen.js +159 -0
  200. package/dist/eval/screen.js.map +1 -0
  201. package/dist/eval/slope.d.ts +29 -0
  202. package/dist/eval/slope.js +46 -0
  203. package/dist/eval/slope.js.map +1 -0
  204. package/dist/eval/train-sequence.d.ts +35 -0
  205. package/dist/eval/train-sequence.js +59 -0
  206. package/dist/eval/train-sequence.js.map +1 -0
  207. package/dist/eval/wilson.d.ts +45 -0
  208. package/dist/eval/wilson.js +48 -0
  209. package/dist/eval/wilson.js.map +1 -0
  210. package/dist/events/types.d.ts +2 -2
  211. package/dist/harnesses/cost-estimates.d.ts +10 -31
  212. package/dist/harnesses/cost-estimates.js +11 -43
  213. package/dist/harnesses/cost-estimates.js.map +1 -1
  214. package/dist/harnesses/engine/canonical-json.js +5 -3
  215. package/dist/harnesses/engine/canonical-json.js.map +1 -1
  216. package/dist/harnesses/engine/engine.d.ts +37 -4
  217. package/dist/harnesses/engine/engine.js +151 -20
  218. package/dist/harnesses/engine/engine.js.map +1 -1
  219. package/dist/harnesses/engine/persistence.d.ts +38 -4
  220. package/dist/harnesses/engine/persistence.js +71 -6
  221. package/dist/harnesses/engine/persistence.js.map +1 -1
  222. package/dist/harnesses/engine/state.d.ts +9 -0
  223. package/dist/harnesses/engine/state.js +23 -10
  224. package/dist/harnesses/engine/state.js.map +1 -1
  225. package/dist/harnesses/impls/hermes-agent/adapter.d.ts +2 -0
  226. package/dist/harnesses/impls/hermes-agent/adapter.js +8 -5
  227. package/dist/harnesses/impls/hermes-agent/adapter.js.map +1 -1
  228. package/dist/harnesses/impls/hermes-agent/bootstrap.d.ts +1 -0
  229. package/dist/harnesses/impls/hermes-agent/bootstrap.js +10 -3
  230. package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -1
  231. package/dist/harnesses/impls/hermes-agent/config-builder.d.ts +1 -1
  232. package/dist/harnesses/impls/hermes-agent/config-builder.js +4 -2
  233. package/dist/harnesses/impls/hermes-agent/config-builder.js.map +1 -1
  234. package/dist/harnesses/impls/hermes-agent/harness.d.ts +31 -3
  235. package/dist/harnesses/impls/hermes-agent/harness.js +84 -7
  236. package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -1
  237. package/dist/harnesses/impls/hermes-agent/prompt.d.ts +6 -6
  238. package/dist/harnesses/impls/hermes-agent/prompt.js +6 -6
  239. package/dist/harnesses/impls/index.d.ts +2 -0
  240. package/dist/harnesses/impls/index.js +2 -0
  241. package/dist/harnesses/impls/index.js.map +1 -1
  242. package/dist/harnesses/impls/learner/adapters/claude-code.d.ts +17 -0
  243. package/dist/harnesses/impls/learner/adapters/claude-code.js +118 -14
  244. package/dist/harnesses/impls/learner/adapters/claude-code.js.map +1 -1
  245. package/dist/harnesses/impls/learner/adapters/codex-code.d.ts +9 -0
  246. package/dist/harnesses/impls/learner/adapters/codex-code.js +30 -8
  247. package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -1
  248. package/dist/harnesses/impls/learner/harness.d.ts +41 -1
  249. package/dist/harnesses/impls/learner/harness.js +78 -4
  250. package/dist/harnesses/impls/learner/harness.js.map +1 -1
  251. package/dist/harnesses/impls/learner/harvest.d.ts +3 -1
  252. package/dist/harnesses/impls/learner/harvest.js +30 -6
  253. package/dist/harnesses/impls/learner/harvest.js.map +1 -1
  254. package/dist/harnesses/impls/learner/plugin-path.js +1 -0
  255. package/dist/harnesses/impls/learner/plugin-path.js.map +1 -1
  256. package/dist/harnesses/impls/learner/restoration-patch.d.ts +2 -2
  257. package/dist/harnesses/impls/learner/restoration-patch.js +25 -6
  258. package/dist/harnesses/impls/learner/restoration-patch.js.map +1 -1
  259. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +21 -1
  260. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
  261. package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js +3 -1
  262. package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js.map +1 -1
  263. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +74 -5
  264. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +103 -32
  265. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
  266. package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.d.ts +2 -2
  267. package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.js +3 -1
  268. package/dist/harnesses/impls/swe-rebench-v2-evaluator/index.js.map +1 -1
  269. package/dist/harnesses/readiness-registry.d.ts +7 -0
  270. package/dist/harnesses/readiness-registry.js +9 -0
  271. package/dist/harnesses/readiness-registry.js.map +1 -1
  272. package/dist/harnesses/types.d.ts +14 -0
  273. package/dist/learner/revert-decision.d.ts +74 -0
  274. package/dist/learner/revert-decision.js +73 -0
  275. package/dist/learner/revert-decision.js.map +1 -0
  276. package/dist/learner/revert-stats.d.ts +38 -0
  277. package/dist/learner/revert-stats.js +86 -0
  278. package/dist/learner/revert-stats.js.map +1 -0
  279. package/dist/local-provider-url.d.ts +3 -0
  280. package/dist/local-provider-url.js +28 -0
  281. package/dist/local-provider-url.js.map +1 -0
  282. package/dist/main.js +199 -104
  283. package/dist/main.js.map +1 -1
  284. package/dist/mcp/get-codedigest-reward.d.ts +13 -0
  285. package/dist/mcp/get-codedigest-reward.js +23 -0
  286. package/dist/mcp/get-codedigest-reward.js.map +1 -0
  287. package/dist/mcp/server.js +23 -0
  288. package/dist/mcp/server.js.map +1 -1
  289. package/dist/observability/debug-report-assemble.d.ts +43 -0
  290. package/dist/observability/debug-report-assemble.js +80 -0
  291. package/dist/observability/debug-report-assemble.js.map +1 -0
  292. package/dist/observability/emit-event.d.ts +9 -2
  293. package/dist/observability/emit-event.js +36 -2
  294. package/dist/observability/emit-event.js.map +1 -1
  295. package/dist/observability/file-logger.d.ts +69 -0
  296. package/dist/observability/file-logger.js +177 -0
  297. package/dist/observability/file-logger.js.map +1 -0
  298. package/dist/observability/redact-secrets.d.ts +65 -0
  299. package/dist/observability/redact-secrets.js +300 -0
  300. package/dist/observability/redact-secrets.js.map +1 -0
  301. package/dist/observability/tar.d.ts +30 -0
  302. package/dist/observability/tar.js +102 -0
  303. package/dist/observability/tar.js.map +1 -0
  304. package/dist/plugins/learner/.claude-plugin/plugin.json +1 -1
  305. package/dist/plugins/learner/.codex-plugin/plugin.json +1 -1
  306. package/dist/plugins/learner/hooks/session-start +30 -1
  307. package/dist/plugins/learner/skills/learn/consolidator-prompt.md +22 -1
  308. package/dist/plugins/learner/skills/learn/promoter-prompt.md +72 -1
  309. package/dist/preflight/deployment-readiness.d.ts +147 -0
  310. package/dist/preflight/deployment-readiness.js +366 -0
  311. package/dist/preflight/deployment-readiness.js.map +1 -0
  312. package/dist/preflight/pidfile-liveness.d.ts +50 -0
  313. package/dist/preflight/pidfile-liveness.js +117 -0
  314. package/dist/preflight/pidfile-liveness.js.map +1 -0
  315. package/dist/preflight/rpc-network.d.ts +40 -0
  316. package/dist/preflight/rpc-network.js +67 -1
  317. package/dist/preflight/rpc-network.js.map +1 -1
  318. package/dist/rpc/transport.d.ts +145 -0
  319. package/dist/rpc/transport.js +319 -0
  320. package/dist/rpc/transport.js.map +1 -0
  321. package/dist/scripts/donation-consumption-acceptance.js +7 -28
  322. package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
  323. package/dist/scripts/swe-rebench-v2-pytest-missing.json +16 -0
  324. package/dist/solver-nets/prediction-operator-ux.d.ts +1 -2
  325. package/dist/solver-nets/prediction-operator-ux.js +56 -53
  326. package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
  327. package/dist/solver-nets/registry.d.ts +19 -1
  328. package/dist/solver-nets/registry.js +37 -24
  329. package/dist/solver-nets/registry.js.map +1 -1
  330. package/dist/solver-types/_swe-rebench-v2-held-out-slate.d.ts +76 -0
  331. package/dist/solver-types/_swe-rebench-v2-held-out-slate.js +156 -0
  332. package/dist/solver-types/_swe-rebench-v2-held-out-slate.js.map +1 -0
  333. package/dist/solver-types/_swe-rebench-v2-pool-recovery.d.ts +81 -0
  334. package/dist/solver-types/_swe-rebench-v2-pool-recovery.js +116 -0
  335. package/dist/solver-types/_swe-rebench-v2-pool-recovery.js.map +1 -0
  336. package/dist/solver-types/_swe-rebench-v2-pool.d.ts +9 -2
  337. package/dist/solver-types/_swe-rebench-v2-pool.js +15 -20
  338. package/dist/solver-types/_swe-rebench-v2-pool.js.map +1 -1
  339. package/dist/solver-types/_swe-rebench-v2-state.d.ts +24 -0
  340. package/dist/solver-types/_swe-rebench-v2-state.js +33 -0
  341. package/dist/solver-types/_swe-rebench-v2-state.js.map +1 -1
  342. package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +116 -2
  343. package/dist/solver-types/_swe-rebench-v2-validated-pool.js +296 -21
  344. package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
  345. package/dist/solver-types/slates/held-out-slate.swe-rebench-v2.v1.json +20 -0
  346. package/dist/solver-types/slates/held-out-slate.swe-rebench-v2.v2.json +19 -0
  347. package/dist/solver-types/slates/held-out-slate.swe-rebench-v2.v2.screening-report.json +628 -0
  348. package/dist/solver-types/solver-type.d.ts +8 -0
  349. package/dist/solver-types/swe-rebench-v2-auto.d.ts +20 -11
  350. package/dist/solver-types/swe-rebench-v2-auto.js +64 -19
  351. package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
  352. package/dist/solver-types/swe-rebench-v2.d.ts +10 -2
  353. package/dist/solver-types/swe-rebench-v2.js +233 -13
  354. package/dist/solver-types/swe-rebench-v2.js.map +1 -1
  355. package/dist/solvernets/daemon-init.d.ts +1 -1
  356. package/dist/solvernets/daemon-init.js +19 -4
  357. package/dist/solvernets/daemon-init.js.map +1 -1
  358. package/dist/solvernets/launched-record-dispatcher.d.ts +7 -0
  359. package/dist/solvernets/launched-record-dispatcher.js +10 -4
  360. package/dist/solvernets/launched-record-dispatcher.js.map +1 -1
  361. package/dist/solvernets/registry-client-erc8004.js +40 -37
  362. package/dist/solvernets/registry-client-erc8004.js.map +1 -1
  363. package/dist/solvernets/registry-client.d.ts +6 -0
  364. package/dist/solvernets/store.d.ts +2 -2
  365. package/dist/solvernets/store.js +7 -2
  366. package/dist/solvernets/store.js.map +1 -1
  367. package/dist/spend/ai-units-config.d.ts +49 -0
  368. package/dist/spend/ai-units-config.js +34 -0
  369. package/dist/spend/ai-units-config.js.map +1 -0
  370. package/dist/spend/ai-units.d.ts +140 -0
  371. package/dist/spend/ai-units.js +229 -0
  372. package/dist/spend/ai-units.js.map +1 -0
  373. package/dist/spend/cost-surface-status.d.ts +12 -0
  374. package/dist/spend/cost-surface-status.js +24 -0
  375. package/dist/spend/cost-surface-status.js.map +1 -0
  376. package/dist/spend/credential.d.ts +39 -0
  377. package/dist/spend/credential.js +71 -0
  378. package/dist/spend/credential.js.map +1 -0
  379. package/dist/spend/daemon-config.d.ts +13 -0
  380. package/dist/spend/daemon-config.js +24 -0
  381. package/dist/spend/daemon-config.js.map +1 -0
  382. package/dist/spend/pricing.d.ts +16 -0
  383. package/dist/spend/pricing.js +26 -0
  384. package/dist/spend/pricing.js.map +1 -0
  385. package/dist/spend/record.d.ts +13 -0
  386. package/dist/spend/record.js +43 -0
  387. package/dist/spend/record.js.map +1 -0
  388. package/dist/spend/usage.d.ts +27 -0
  389. package/dist/spend/usage.js +113 -0
  390. package/dist/spend/usage.js.map +1 -0
  391. package/dist/store/store.d.ts +187 -0
  392. package/dist/store/store.js +467 -4
  393. package/dist/store/store.js.map +1 -1
  394. package/dist/trajectory/transcript-parsers/codex-session.d.ts +12 -6
  395. package/dist/trajectory/transcript-parsers/codex-session.js +114 -13
  396. package/dist/trajectory/transcript-parsers/codex-session.js.map +1 -1
  397. package/dist/trajectory/transcript-parsers/types.d.ts +8 -8
  398. package/dist/trajectory/transcript-session-dirs.d.ts +18 -0
  399. package/dist/trajectory/transcript-session-dirs.js +85 -0
  400. package/dist/trajectory/transcript-session-dirs.js.map +1 -0
  401. package/dist/trajectory/transcript-watcher.d.ts +20 -1
  402. package/dist/trajectory/transcript-watcher.js +108 -32
  403. package/dist/trajectory/transcript-watcher.js.map +1 -1
  404. package/dist/tx-retry.d.ts +25 -0
  405. package/dist/tx-retry.js +95 -7
  406. package/dist/tx-retry.js.map +1 -1
  407. package/dist/types/payloads/portfolio-v0.d.ts +3 -3
  408. package/dist/types/payloads/prediction-apy-v0.d.ts +3 -3
  409. package/dist/types/payloads/prediction-v0.d.ts +12 -12
  410. package/dist/vendor/@jinn-network/sdk/dist/payloads/swe-rebench-v2.d.ts +108 -1
  411. package/dist/vendor/@jinn-network/sdk/dist/payloads/swe-rebench-v2.js +25 -1
  412. package/dist/vendor/@jinn-network/sdk/dist/solvernets/swe-rebench-v2-held-out-slate.d.ts +65 -0
  413. package/dist/vendor/@jinn-network/sdk/dist/solvernets/swe-rebench-v2-held-out-slate.js +123 -0
  414. package/dist/vendor/@jinn-network/sdk/dist/solvernets/swe-rebench-v2.d.ts +2 -2
  415. package/dist/vendor/@jinn-network/sdk/dist/solvernets/swe-rebench-v2.js +1 -1
  416. package/dist/vendor/@jinn-network/sdk/package.json +4 -0
  417. package/docker-compose.yml +3 -2
  418. package/package.json +30 -18
  419. package/plugins/learner/.claude-plugin/plugin.json +1 -1
  420. package/plugins/learner/.codex-plugin/plugin.json +1 -1
  421. package/plugins/learner/hooks/session-start +30 -1
  422. package/plugins/learner/skills/learn/consolidator-prompt.md +22 -1
  423. package/plugins/learner/skills/learn/promoter-prompt.md +72 -1
  424. package/plugins/swe-rebench-v2-diffmin/README.md +10 -9
  425. package/plugins/swe-rebench-v2-diffmin/jinn.plugin.json +1 -1
  426. package/plugins/swe-rebench-v2-diffmin/skills/diffmin/SKILL.md +15 -10
  427. package/plugins/swe-rebench-v2-diffmin/skills/test-map/SKILL.md +10 -12
  428. package/plugins/swe-rebench-v2-runtime/.claude-plugin/plugin.json +1 -1
  429. package/plugins/swe-rebench-v2-runtime/.codex-plugin/plugin.json +3 -3
  430. package/plugins/swe-rebench-v2-runtime/README.md +6 -6
  431. package/plugins/swe-rebench-v2-runtime/hooks/hooks.json +16 -0
  432. package/plugins/swe-rebench-v2-runtime/hooks/session-start +74 -0
  433. package/plugins/swe-rebench-v2-runtime/jinn.plugin.json +2 -3
  434. package/plugins/swe-rebench-v2-runtime/skills/task/SKILL.md +81 -0
  435. package/dist/dashboard/assets/index-BUlE8F3Y.js +0 -330
  436. package/dist/dashboard/assets/index-blqc7eqq.css +0 -32
  437. package/plugins/swe-rebench-v2-runtime/skills/orient/SKILL.md +0 -29
  438. package/plugins/swe-rebench-v2-runtime/skills/plan/SKILL.md +0 -53
package/README.md CHANGED
@@ -312,7 +312,7 @@ JINN_PASSWORD=secret jinn run --config ./my-config.json
312
312
  | Config key | Env override | Default |
313
313
  |---|---|---|
314
314
  | network | JINN_NETWORK | `testnet` (Phase 1b default; flips to `mainnet` at Phase 2 launch) |
315
- | rpcUrl | BASE_RPC_URL / JINN_RPC_URL | network-appropriate public RPC |
315
+ | rpcUrl | BASE_RPC_URL / JINN_RPC_URL | testnet: two-provider fallback chain `[publicnode, sepolia.base.org]`; mainnet: single `mainnet.base.org`. Accepts string OR array; env values split on commas. See "RPC fallback chain" below. |
316
316
  | claudeModel | JINN_CLAUDE_MODEL | claude-haiku-4-5-20251001 |
317
317
  | claudePath | JINN_CLAUDE_PATH | claude |
318
318
  | pollIntervalMs | JINN_POLL_INTERVAL_MS | 5000 |
@@ -325,6 +325,72 @@ JINN_PASSWORD=secret jinn run --config ./my-config.json
325
325
 
326
326
  `JINN_PASSWORD` is env-only (keystore encryption, never in config files). Alternatively, use `--password-fd <N>` to read from a file descriptor.
327
327
 
328
+ ### RPC fallback chain
329
+
330
+ Out of the box on testnet, `jinn run` uses a two-provider fallback chain —
331
+ no key required, zero config:
332
+
333
+ ```text
334
+ slot 0 https://base-sepolia.publicnode.com (no-auth, 50k-block getLogs cap)
335
+ slot 1 https://sepolia.base.org (free public Coinbase, 2k cap)
336
+ ```
337
+
338
+ If the primary returns a network error or HTTP 429 / 5xx, viem
339
+ transparently falls through to the next slot. When every slot fails the
340
+ daemon throws `AllRpcsFailedError` (visible in the dashboard's NetworkSection
341
+ and in stderr).
342
+
343
+ #### Bring your own paid primary
344
+
345
+ Operators with a paid Alchemy / Tenderly / QuickNode endpoint should
346
+ **prepend** their URL — the public free chain stays as automatic backup:
347
+
348
+ ```json
349
+ {
350
+ "rpcUrl": [
351
+ "https://my-alchemy-key.example",
352
+ "https://base-sepolia.publicnode.com",
353
+ "https://sepolia.base.org"
354
+ ]
355
+ }
356
+ ```
357
+
358
+ Or via env (comma-separated, same chain capped at 4 providers):
359
+
360
+ ```bash
361
+ JINN_RPC_URL='https://my-alchemy-key.example,https://base-sepolia.publicnode.com,https://sepolia.base.org' jinn run
362
+ ```
363
+
364
+ The chain is built with viem's `fallback({ rank: false })` so operator slot
365
+ order is preserved (no latency-based reshuffling).
366
+
367
+ #### Automatic failure modes
368
+
369
+ | Failure | What used to happen | What now happens |
370
+ |---------------------------------------------|--------------------------------|-------------------------------------------------|
371
+ | Primary RPC returns HTTP 429 (rate limit) | Daemon hot-loops on every call | viem falls through to slot 1; daemon continues |
372
+ | Primary RPC unreachable | Daemon errors silently | viem falls through to slot 1; daemon continues |
373
+ | Primary's API key quota exhausted | Daemon silently degraded | viem falls through to slot 1; daemon continues |
374
+ | Every slot fails (rare) | Daemon errors silently | `AllRpcsFailedError` thrown with masked host list — surfaces as a state message in the operator app |
375
+
376
+ On boot the daemon emits one log line per slot followed by the canonical
377
+ summary line:
378
+
379
+ ```text
380
+ [rpc] L2 base-sepolia.publicnode.com ok latency=87ms
381
+ [rpc] L2 sepolia.base.org ok latency=141ms
382
+ [rpc] L2 transport: fallback chain (2 providers) — primary=base-sepolia.publicnode.com
383
+ ```
384
+
385
+ The probe is **log-only** — secondary-slot 429s warn but never gate
386
+ startup. Only chain-id mismatch against the head URL is fail-loud
387
+ (`checkRpcNetwork`).
388
+
389
+ Note this is the JSON-RPC transport layer. It is distinct from
390
+ `discovery.fallbackToOnchain`, which is a separate flag at the read-API
391
+ layer (Ponder indexer → direct `eth_getLogs` floor). The RPC fallback chain
392
+ operates beneath both.
393
+
328
394
  ## Tokens
329
395
 
330
396
  | Role | Phase 1b (testnet, Base Sepolia) | Phase 2 (mainnet, Base) |
@@ -45,7 +45,6 @@ export declare class MechAdapter implements ExecutionAdapter {
45
45
  */
46
46
  private restorationBodyCache;
47
47
  private requestKinds;
48
- private claimedRestorationTaskIds;
49
48
  private evaluationOpportunities;
50
49
  private pendingEvaluationSolutions;
51
50
  private originalStates;
@@ -53,7 +52,26 @@ export declare class MechAdapter implements ExecutionAdapter {
53
52
  constructor(config: MechAdapterConfig, store?: Store);
54
53
  initialize(): Promise<void>;
55
54
  private recoverPendingState;
56
- private onchainTaskDiscoveryFromBlock;
55
+ /**
56
+ * The gh #300 scorability admission floor: tasks created before this block are
57
+ * "ghosts" from a prior eval-semantics regime and are rejected — including on
58
+ * the `DiscoveryAPI` (indexer) path. Fixed per chain; an explicit operator
59
+ * `onchainFromBlock` raises it. Returns `undefined` when no SolverNet is joined
60
+ * (the daemon claims nothing, so there is no floor to apply).
61
+ *
62
+ * This is deliberately NOT the on-chain scan start — see `onchainScanFromBlock`.
63
+ * Bounding the scan for RPC cost must never narrow which tasks are admitted.
64
+ */
65
+ private taskAdmissionFloorBlock;
66
+ /**
67
+ * Start block for the on-chain TaskCreated backlog scan (the secondary backstop
68
+ * behind `DiscoveryAPI.findClaimableTasks`). Defaults to a bounded rolling
69
+ * window `head − DEFAULT_ONCHAIN_SCAN_WINDOW_BLOCKS`, never below the admission
70
+ * floor (scanning pre-floor blocks only surfaces rejected ghosts). An explicit
71
+ * `onchainFromBlock` override pins an absolute start, honored as the operator's
72
+ * choice. Returns `undefined` when no SolverNet is joined.
73
+ */
74
+ private onchainScanFromBlock;
57
75
  private joinedManifestDigestSet;
58
76
  private allowedDiscoveryTaskIds;
59
77
  private isDiscoveryTaskAllowed;
@@ -62,6 +80,25 @@ export declare class MechAdapter implements ExecutionAdapter {
62
80
  private persistPendingEvaluationSolutions;
63
81
  private rememberPendingEvaluationSolution;
64
82
  private forgetPendingEvaluationSolution;
83
+ /**
84
+ * Increment the per-solution failure counter and prune when it exceeds the
85
+ * MAX_EVALUATION_RETRY_ATTEMPTS budget. Persistence runs on every increment
86
+ * so a crash mid-cycle does not lose the count (and let a wedge resume
87
+ * log-spamming after a restart).
88
+ *
89
+ * Call sites: ONLY the two paths that fail to make progress on this specific
90
+ * solution — the transient `canClaimEvaluation` branch in
91
+ * evaluationAnnouncementForSolution, and the `catch (err)` arm of
92
+ * retryPendingEvaluationSolutions. Do NOT call from the signal-driven prune
93
+ * paths (terminal claimability, null delivery-envelope CID,
94
+ * !isDiscoveryTaskAllowed) — those already prune cleanly.
95
+ *
96
+ * Returns true when the solution was pruned (caller should stop work on it).
97
+ */
98
+ private recordEvaluationFailureAndMaybePrune;
99
+ /** Prune terminal evaluation state so the poll loop stops retrying (#512). */
100
+ private pruneTerminalEvaluationOpportunity;
101
+ private claimEvaluationWithTerminalPrune;
65
102
  private clearPendingDeliveryRecoveryState;
66
103
  private recoveryDeliveryExpirySeconds;
67
104
  private shouldSkipExpiredRecoveryDelivery;
@@ -4,13 +4,23 @@ import { privateKeyToAccount } from 'viem/accounts';
4
4
  import { base, baseSepolia } from 'viem/chains';
5
5
  import { PermanentError, parseTask } from '../../types/index.js';
6
6
  import { createClients } from './safe.js';
7
+ /**
8
+ * Coalesce a string-or-array RPC input down to the head URL for display in
9
+ * error contexts (`formatRpcError` expects a single host). The adapter
10
+ * accepts the full fallback chain at the type level; this helper exists so
11
+ * the error-formatting call sites can keep their old signature.
12
+ */
13
+ function rpcUrlForDisplay(rpcUrl) {
14
+ return Array.isArray(rpcUrl) ? rpcUrl[0] : rpcUrl;
15
+ }
7
16
  import { buildResultPayload, uploadToIpfs, cidToDigestHex, fetchFromIpfs, fetchSignedTaskFromIpfs, fetchSignedEnvelopeFromIpfs, } from './ipfs.js';
8
17
  import { canonicalJson } from '../../harnesses/engine/canonical-json.js';
9
18
  import { normalizeEnvelopeRole, SignedEnvelopeSchema } from '../../types/envelope.js';
10
19
  import { submitTask, claimTask as claimTaskOnchain, claimEvaluation as claimEvaluationOnchain, claimDelivery, getMechDeliveryRate, getTimeoutBounds, decodeTaskCreatedLogs, decodeSolutionDeliveryClaimedLogs, decodeDeliverLogs, findLatestDeliveryDataHexForRequest, getMarketplaceRequestDeliveryMech, getTaskCidDigest, callDeliverToMarketplace, canClaimTask, canClaimEvaluation, } from './contracts.js';
11
- import { isNonRecoverableInnerRevert } from './safe-revert.js';
20
+ import { SafeInnerRevertError, formatDecodedRevert, isNonRecoverableInnerRevert, } from './safe-revert.js';
12
21
  import { verdictCodeFromValue } from './verdict-code.js';
13
22
  import { manifestDigestForCid } from './digest.js';
23
+ import { emitStructured } from '../../events/emitter.js';
14
24
  import { withRecoverableRetry } from '../../tx-retry.js';
15
25
  import { formatRpcError } from '../../rpc-error-context.js';
16
26
  import { SOLUTION_ENVELOPE_CID_CONTEXT_KEY, SOLUTION_TASK_CID_CONTEXT_KEY, RESTORATION_TASK_CID_CONTEXT_KEY, } from '../../harnesses/impls/evaluation-context.js';
@@ -21,6 +31,19 @@ const DEFAULT_MECH_DELIVER_BACKFILL_LOOKBACK_BLOCKS = 100000n;
21
31
  /** Yield to the event loop every N evaluation opportunities so a large retry
22
32
  * backlog can't starve the HTTP API mid-cycle. */
23
33
  const EVALUATION_RETRY_YIELD_EVERY = 10;
34
+ /**
35
+ * Bound the number of consecutive transient/uncaught failures for a single
36
+ * pending evaluation solution. Once exceeded, the solution is pruned from
37
+ * `pendingEvaluationSolutions` to stop unbounded log spam (#645). At default
38
+ * pollIntervalMs=5000, twenty cycles ≈ 100 s — comfortably above a normal
39
+ * transient RPC outage window, well below "spamming the log forever".
40
+ *
41
+ * The signal-driven prunes (terminal claimability, `null` delivery-envelope
42
+ * CID per #553, !isDiscoveryTaskAllowed) still fire on their own conditions;
43
+ * this counter is the backstop for failure modes that don't surface a clean
44
+ * terminal signal.
45
+ */
46
+ const MAX_EVALUATION_RETRY_ATTEMPTS = 20;
24
47
  /**
25
48
  * Decide whether a `canClaimEvaluation` failure means the opportunity can NEVER
26
49
  * become claimable (terminal, prune it) versus one that could still clear later
@@ -41,6 +64,20 @@ function isTerminalEvaluationReason(revertName) {
41
64
  return isNonRecoverableInnerRevert(revertName);
42
65
  }
43
66
  const DEFAULT_ROUTER_LOG_CHUNK_BLOCKS = 9999n;
67
+ /**
68
+ * Default rolling-window size for the on-chain TaskCreated backlog scan (#801).
69
+ *
70
+ * The scan is a *backstop* behind `DiscoveryAPI.findClaimableTasks` (the indexer
71
+ * on testnet, the newest-first RPC floor on mainnet), which is the primary
72
+ * discovery path on every chain. Without a bound the scan replays from the fixed
73
+ * admission floor to head on *every* restart, a range that grows monotonically
74
+ * with the chain — the startup-stall regression #801 documents. Bounding it to
75
+ * `head − N` makes restart cost fixed regardless of chain age while still
76
+ * re-observing a generous recent window (~28h on Base at ~2s/block) for tasks
77
+ * and SolutionDeliveryClaimed events the indexer might have lagged on. Operators
78
+ * who want a wider net pin an absolute start via `taskDiscoveryOnchainFromBlock`.
79
+ */
80
+ const DEFAULT_ONCHAIN_SCAN_WINDOW_BLOCKS = 50000n;
44
81
  /**
45
82
  * Floor block for the on-chain TaskCreated backlog scan, per chain.
46
83
  *
@@ -117,7 +154,6 @@ export class MechAdapter {
117
154
  */
118
155
  restorationBodyCache = new Map();
119
156
  requestKinds = new Map();
120
- claimedRestorationTaskIds = new Set();
121
157
  evaluationOpportunities = new Map();
122
158
  pendingEvaluationSolutions = new Map();
123
159
  // Original Tasks keyed by request ID (restoration and evaluation)
@@ -139,7 +175,7 @@ export class MechAdapter {
139
175
  formatRpcError(message, {
140
176
  operation: 'getBlockNumber',
141
177
  chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
142
- rpcUrl: this.config.rpcUrl,
178
+ rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
143
179
  }));
144
180
  },
145
181
  });
@@ -151,7 +187,7 @@ export class MechAdapter {
151
187
  await this.recoverPendingState(blockNumber);
152
188
  }
153
189
  else {
154
- const fromBlock = this.onchainTaskDiscoveryFromBlock();
190
+ const fromBlock = this.onchainScanFromBlock(blockNumber);
155
191
  if (fromBlock && fromBlock <= blockNumber) {
156
192
  this.requestBlockCursor = fromBlock - 1n;
157
193
  }
@@ -171,17 +207,27 @@ export class MechAdapter {
171
207
  if (routerFromBlock < currentBlock) {
172
208
  this.requestBlockCursor = routerFromBlock;
173
209
  }
174
- const scanFromBlock = this.onchainTaskDiscoveryFromBlock();
210
+ const scanFromBlock = this.onchainScanFromBlock(currentBlock);
175
211
  if (scanFromBlock && scanFromBlock <= currentBlock) {
176
212
  const canonicalCursor = scanFromBlock - 1n;
177
213
  if (canonicalCursor < this.requestBlockCursor) {
178
214
  this.requestBlockCursor = canonicalCursor;
179
215
  }
180
- console.error(`[mech] TaskCreated canonical backlog scan enabled from block ${scanFromBlock}; ` +
181
- 'subgraph discovery is optional acceleration only');
216
+ console.error(`[mech] TaskCreated backlog scan (bounded backstop) enabled from block ${scanFromBlock}; ` +
217
+ 'DiscoveryAPI.findClaimableTasks is the primary discovery path');
182
218
  }
183
219
  }
184
- onchainTaskDiscoveryFromBlock() {
220
+ /**
221
+ * The gh #300 scorability admission floor: tasks created before this block are
222
+ * "ghosts" from a prior eval-semantics regime and are rejected — including on
223
+ * the `DiscoveryAPI` (indexer) path. Fixed per chain; an explicit operator
224
+ * `onchainFromBlock` raises it. Returns `undefined` when no SolverNet is joined
225
+ * (the daemon claims nothing, so there is no floor to apply).
226
+ *
227
+ * This is deliberately NOT the on-chain scan start — see `onchainScanFromBlock`.
228
+ * Bounding the scan for RPC cost must never narrow which tasks are admitted.
229
+ */
230
+ taskAdmissionFloorBlock() {
185
231
  const discovery = this.config.taskDiscovery;
186
232
  const hasJoinedSolverNet = (discovery?.solverNetManifestCids?.length ?? 0) > 0;
187
233
  if (!hasJoinedSolverNet)
@@ -193,6 +239,24 @@ export class MechAdapter {
193
239
  }
194
240
  return DEFAULT_TASK_DISCOVERY_FROM_BLOCK[this.config.chainId];
195
241
  }
242
+ /**
243
+ * Start block for the on-chain TaskCreated backlog scan (the secondary backstop
244
+ * behind `DiscoveryAPI.findClaimableTasks`). Defaults to a bounded rolling
245
+ * window `head − DEFAULT_ONCHAIN_SCAN_WINDOW_BLOCKS`, never below the admission
246
+ * floor (scanning pre-floor blocks only surfaces rejected ghosts). An explicit
247
+ * `onchainFromBlock` override pins an absolute start, honored as the operator's
248
+ * choice. Returns `undefined` when no SolverNet is joined.
249
+ */
250
+ onchainScanFromBlock(head) {
251
+ const floor = this.taskAdmissionFloorBlock();
252
+ if (floor === undefined)
253
+ return undefined;
254
+ // An explicit override is reflected verbatim in `floor`; honor it as the pin.
255
+ if (this.config.taskDiscovery?.onchainFromBlock !== undefined)
256
+ return floor;
257
+ const window = head - DEFAULT_ONCHAIN_SCAN_WINDOW_BLOCKS;
258
+ return window > floor ? window : floor;
259
+ }
196
260
  joinedManifestDigestSet() {
197
261
  const cids = this.config.taskDiscovery?.solverNetManifestCids ?? [];
198
262
  return new Set(cids
@@ -249,6 +313,13 @@ export class MechAdapter {
249
313
  ? item.transactionHash
250
314
  : undefined,
251
315
  blockNumber: typeof item.blockNumber === 'number' ? item.blockNumber : undefined,
316
+ // #645: clamp to a non-negative integer. A tampered or corrupted
317
+ // store row carrying a negative or fractional failedAttempts could
318
+ // otherwise underflow the prune budget (e.g. -1_000_000_000 would
319
+ // defeat the bound for ~10^9 cycles).
320
+ failedAttempts: typeof item.failedAttempts === 'number' && Number.isFinite(item.failedAttempts)
321
+ ? Math.max(0, Math.floor(item.failedAttempts))
322
+ : 0,
252
323
  };
253
324
  this.pendingEvaluationSolutions.set(solution.requestId, solution);
254
325
  }
@@ -271,6 +342,61 @@ export class MechAdapter {
271
342
  return;
272
343
  this.persistPendingEvaluationSolutions();
273
344
  }
345
+ /**
346
+ * Increment the per-solution failure counter and prune when it exceeds the
347
+ * MAX_EVALUATION_RETRY_ATTEMPTS budget. Persistence runs on every increment
348
+ * so a crash mid-cycle does not lose the count (and let a wedge resume
349
+ * log-spamming after a restart).
350
+ *
351
+ * Call sites: ONLY the two paths that fail to make progress on this specific
352
+ * solution — the transient `canClaimEvaluation` branch in
353
+ * evaluationAnnouncementForSolution, and the `catch (err)` arm of
354
+ * retryPendingEvaluationSolutions. Do NOT call from the signal-driven prune
355
+ * paths (terminal claimability, null delivery-envelope CID,
356
+ * !isDiscoveryTaskAllowed) — those already prune cleanly.
357
+ *
358
+ * Returns true when the solution was pruned (caller should stop work on it).
359
+ */
360
+ recordEvaluationFailureAndMaybePrune(solution) {
361
+ const next = (solution.failedAttempts ?? 0) + 1;
362
+ solution.failedAttempts = next;
363
+ if (next > MAX_EVALUATION_RETRY_ATTEMPTS) {
364
+ console.log(`[mech] pruning evaluation opportunity ${solution.requestId} for task ${solution.taskId}/${solution.attemptIndex}: ` +
365
+ `exceeded retry budget (${MAX_EVALUATION_RETRY_ATTEMPTS}) — pruned`);
366
+ this.forgetPendingEvaluationSolution(solution.requestId);
367
+ return true;
368
+ }
369
+ this.persistPendingEvaluationSolutions();
370
+ return false;
371
+ }
372
+ /** Prune terminal evaluation state so the poll loop stops retrying (#512). */
373
+ pruneTerminalEvaluationOpportunity(params) {
374
+ const { opportunityId, solutionRequestId, reason } = params;
375
+ const target = opportunityId ?? solutionRequestId ?? 'unknown';
376
+ console.log(`[mech] pruning evaluation opportunity ${target}: ${reason} (terminal — pruned)`);
377
+ if (opportunityId) {
378
+ this.evaluationOpportunities.delete(opportunityId);
379
+ this.observedTasks.delete(opportunityId);
380
+ }
381
+ if (solutionRequestId) {
382
+ this.forgetPendingEvaluationSolution(solutionRequestId);
383
+ }
384
+ }
385
+ async claimEvaluationWithTerminalPrune(opportunityId, evaluationOpportunity, evaluationTaskCidDigest) {
386
+ try {
387
+ return await this.claimEvaluation(evaluationOpportunity.taskId, evaluationOpportunity.attemptIndex, evaluationTaskCidDigest);
388
+ }
389
+ catch (err) {
390
+ if (err instanceof SafeInnerRevertError && isNonRecoverableInnerRevert(err.decodedName)) {
391
+ this.pruneTerminalEvaluationOpportunity({
392
+ opportunityId,
393
+ solutionRequestId: evaluationOpportunity.task.restorationRequestId,
394
+ reason: formatDecodedRevert(err.decodedName, err.decodedArgs),
395
+ });
396
+ }
397
+ throw err;
398
+ }
399
+ }
274
400
  clearPendingDeliveryRecoveryState(requestId) {
275
401
  this.originalStates.delete(requestId);
276
402
  this.pendingEvaluations.delete(requestId);
@@ -514,12 +640,10 @@ export class MechAdapter {
514
640
  console.error('[mech] task discovery (DiscoveryAPI) failed:', err instanceof Error ? err.message : err);
515
641
  return;
516
642
  }
517
- const discoveryFloorBlock = this.onchainTaskDiscoveryFromBlock();
643
+ const discoveryFloorBlock = this.taskAdmissionFloorBlock();
518
644
  for (const candidate of candidates) {
519
645
  if (!this.isDiscoveryTaskAllowed(candidate.taskId))
520
646
  continue;
521
- if (this.claimedRestorationTaskIds.has(candidate.taskId))
522
- continue;
523
647
  // gh #300 ghost-task floor — same floor as the on-chain TaskCreated
524
648
  // backlog scan, applied to the DiscoveryAPI path too. Without this,
525
649
  // the Ponder indexer (or onchain floor's listClaimableTasks) returns
@@ -610,7 +734,15 @@ export class MechAdapter {
610
734
  console.log(`[mech] skipping evaluation opportunity ${solution.requestId} for task ${solution.taskId}/${solution.attemptIndex}: ${claimable.reason}` +
611
735
  (terminal ? ' (terminal — pruned)' : ' (transient — will retry)'));
612
736
  if (terminal) {
613
- this.forgetPendingEvaluationSolution(solution.requestId);
737
+ this.pruneTerminalEvaluationOpportunity({
738
+ solutionRequestId: solution.requestId,
739
+ reason: claimable.reason,
740
+ });
741
+ }
742
+ else {
743
+ // #645 backstop: bound retries on transient/unclassified claimability
744
+ // failures so a wedged opportunity can't log-spam forever.
745
+ this.recordEvaluationFailureAndMaybePrune(solution);
614
746
  }
615
747
  return undefined;
616
748
  }
@@ -621,9 +753,10 @@ export class MechAdapter {
621
753
  // retry with the same toBlock cannot reach an older event, so this is
622
754
  // terminal — prune so the loop never re-pays the canClaimEvaluation +
623
755
  // restoration lookup cost on a deterministically-failing opportunity.
624
- console.log(`[mech] pruning evaluation opportunity ${solution.requestId} for task ${solution.taskId}/${solution.attemptIndex}: ` +
625
- `no Deliver event found within configured lookback (terminal — pruned)`);
626
- this.forgetPendingEvaluationSolution(solution.requestId);
756
+ this.pruneTerminalEvaluationOpportunity({
757
+ solutionRequestId: solution.requestId,
758
+ reason: `no Deliver event found within configured lookback for task ${solution.taskId}/${solution.attemptIndex}`,
759
+ });
627
760
  return undefined;
628
761
  }
629
762
  const resultPayload = await fetchFromIpfs(this.config.ipfsGatewayUrl, solutionEnvelopeCid);
@@ -650,6 +783,14 @@ export class MechAdapter {
650
783
  task: evaluationTask,
651
784
  });
652
785
  this.observedTasks.set(opportunityId, announcement);
786
+ // #645: a successful announcement means the candidate has made progress;
787
+ // reset the transient-failure counter so that subsequent transient errors
788
+ // (e.g. IPFS hiccups in the announce → claim window) don't accumulate
789
+ // across the candidate's lifetime and silently false-prune legitimate work.
790
+ if (solution.failedAttempts) {
791
+ solution.failedAttempts = 0;
792
+ this.persistPendingEvaluationSolutions();
793
+ }
653
794
  return announcement;
654
795
  }
655
796
  async *retryPendingEvaluationSolutions() {
@@ -671,6 +812,10 @@ export class MechAdapter {
671
812
  }
672
813
  catch (err) {
673
814
  console.error(`[mech] evaluation opportunity retry failed for ${requestId}:`, err);
815
+ // #645 backstop: bound retries on any uncaught failure so a wedged
816
+ // requestId (e.g. an RPC failure path that re-throws every cycle)
817
+ // can't log-spam forever.
818
+ this.recordEvaluationFailureAndMaybePrune(solution);
674
819
  }
675
820
  }
676
821
  }
@@ -700,7 +845,7 @@ export class MechAdapter {
700
845
  for (const { taskId, taskCidDigest, manifestDigest, transactionHash, blockNumber } of createdTasks) {
701
846
  if (!this.isDiscoveryTaskAllowed(taskId))
702
847
  continue;
703
- if (this.claimedRestorationTaskIds.has(taskId) || this.observedTasks.has(taskId))
848
+ if (this.observedTasks.has(taskId))
704
849
  continue;
705
850
  if (joinedManifestDigests.size > 0 && !joinedManifestDigests.has(manifestDigest.toLowerCase()))
706
851
  continue;
@@ -729,7 +874,7 @@ export class MechAdapter {
729
874
  console.error('[mech] Error polling for tasks:', formatRpcError(err, {
730
875
  operation: 'pollTaskCreated',
731
876
  chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
732
- rpcUrl: this.config.rpcUrl,
877
+ rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
733
878
  contract: this.config.routerAddress,
734
879
  fromBlock: this.requestBlockCursor + 1n,
735
880
  }));
@@ -743,7 +888,7 @@ export class MechAdapter {
743
888
  const signedEvaluationTask = await this.signTaskDocument(evaluationOpportunity.task);
744
889
  const evaluationCid = await uploadToIpfs(this.config.ipfsRegistryUrl, signedEvaluationTask);
745
890
  const evaluationTaskCidDigest = cidToDigestHex(evaluationCid);
746
- const claimed = await this.claimEvaluation(evaluationOpportunity.taskId, evaluationOpportunity.attemptIndex, evaluationTaskCidDigest);
891
+ const claimed = await this.claimEvaluationWithTerminalPrune(taskId, evaluationOpportunity, evaluationTaskCidDigest);
747
892
  this.pendingEvaluations.set(claimed.requestId, evaluationOpportunity.task);
748
893
  this.originalStates.set(claimed.requestId, evaluationOpportunity.task);
749
894
  this.requestKinds.set(claimed.requestId, 'verdict');
@@ -768,7 +913,6 @@ export class MechAdapter {
768
913
  }
769
914
  const claimed = await claimTaskOnchain(this.publicClient, this.walletClient, this.config.safeAddress, this.config.routerAddress, taskId, this.config.mechContractAddress, this.config.evictionRecovery);
770
915
  const task = announcement.task;
771
- this.claimedRestorationTaskIds.add(claimed.taskId);
772
916
  this.pendingEvaluations.set(claimed.requestId, task);
773
917
  this.originalStates.set(claimed.requestId, { ...task, role: task.role ?? 'restoration' });
774
918
  this.requestKinds.set(claimed.requestId, 'solution');
@@ -865,6 +1009,20 @@ export class MechAdapter {
865
1009
  return 'already-claimed';
866
1010
  }
867
1011
  console.error(`[mech] claimDelivery failed for ${requestId}:`, err);
1012
+ // Paired SSE signal for the operator-app `claim_failed` notification
1013
+ // (OPERATOR-APP-SPEC §2.10). The early-return branches above
1014
+ // (`skipped` / `already-claimed`) are not failures and intentionally do not emit.
1015
+ emitStructured({
1016
+ kind: 'intent',
1017
+ message: 'Delivery claim failed',
1018
+ requestId,
1019
+ errorCode: 'claim_failed',
1020
+ details: {
1021
+ kind: claimOptions.kind,
1022
+ source: 'mech.claimDelivery',
1023
+ error: message,
1024
+ },
1025
+ });
868
1026
  return 'retry';
869
1027
  }
870
1028
  }
@@ -991,7 +1149,7 @@ export class MechAdapter {
991
1149
  console.error('[mech] Error polling for deliveries:', formatRpcError(err, {
992
1150
  operation: 'pollDeliveries',
993
1151
  chain: this.config.chainId === 84532 ? 'base-sepolia' : 'base',
994
- rpcUrl: this.config.rpcUrl,
1152
+ rpcUrl: rpcUrlForDisplay(this.config.rpcUrl),
995
1153
  contract: this.config.mechContractAddress,
996
1154
  fromBlock: this.deliveryBlockCursor + 1n,
997
1155
  }));