@jinn-network/client 0.1.5 → 0.1.6-canary.092089a9

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 (455) hide show
  1. package/CHANGELOG.md +131 -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 +23 -1
  6. package/dist/adapters/mech/adapter.js +171 -33
  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/ipfs-pinfile.d.ts +22 -0
  12. package/dist/adapters/mech/ipfs-pinfile.js +54 -0
  13. package/dist/adapters/mech/ipfs-pinfile.js.map +1 -0
  14. package/dist/adapters/mech/ipfs.d.ts +1 -0
  15. package/dist/adapters/mech/ipfs.js +24 -1
  16. package/dist/adapters/mech/ipfs.js.map +1 -1
  17. package/dist/adapters/mech/safe-revert.d.ts +20 -0
  18. package/dist/adapters/mech/safe-revert.js +12 -4
  19. package/dist/adapters/mech/safe-revert.js.map +1 -1
  20. package/dist/adapters/mech/verdict-code.d.ts +1 -0
  21. package/dist/adapters/mech/verdict-code.js +18 -0
  22. package/dist/adapters/mech/verdict-code.js.map +1 -1
  23. package/dist/api/admin-endpoint.d.ts +15 -3
  24. package/dist/api/admin-endpoint.js +24 -2
  25. package/dist/api/admin-endpoint.js.map +1 -1
  26. package/dist/api/bootstrap-endpoint.js +63 -1
  27. package/dist/api/bootstrap-endpoint.js.map +1 -1
  28. package/dist/api/codex-doctor-endpoint.d.ts +73 -0
  29. package/dist/api/codex-doctor-endpoint.js +177 -0
  30. package/dist/api/codex-doctor-endpoint.js.map +1 -0
  31. package/dist/api/discovery-endpoint.d.ts +32 -0
  32. package/dist/api/discovery-endpoint.js +104 -0
  33. package/dist/api/discovery-endpoint.js.map +1 -0
  34. package/dist/api/fleet-build.d.ts +8 -0
  35. package/dist/api/fleet-build.js +8 -2
  36. package/dist/api/fleet-build.js.map +1 -1
  37. package/dist/api/gather-status.d.ts +9 -0
  38. package/dist/api/gather-status.js +330 -7
  39. package/dist/api/gather-status.js.map +1 -1
  40. package/dist/api/harness-readiness-endpoint.d.ts +25 -0
  41. package/dist/api/harness-readiness-endpoint.js +24 -0
  42. package/dist/api/harness-readiness-endpoint.js.map +1 -0
  43. package/dist/api/hermes-doctor-endpoint.d.ts +66 -0
  44. package/dist/api/hermes-doctor-endpoint.js +75 -0
  45. package/dist/api/hermes-doctor-endpoint.js.map +1 -0
  46. package/dist/api/portfolio-v0-build.d.ts +10 -0
  47. package/dist/api/portfolio-v0-build.js +24 -5
  48. package/dist/api/portfolio-v0-build.js.map +1 -1
  49. package/dist/api/prediction-v1-build.d.ts +9 -0
  50. package/dist/api/prediction-v1-build.js +6 -1
  51. package/dist/api/prediction-v1-build.js.map +1 -1
  52. package/dist/api/server.d.ts +74 -1
  53. package/dist/api/server.js +107 -1
  54. package/dist/api/server.js.map +1 -1
  55. package/dist/api/setup-endpoints.d.ts +21 -0
  56. package/dist/api/setup-endpoints.js +101 -8
  57. package/dist/api/setup-endpoints.js.map +1 -1
  58. package/dist/api/setup-retry-endpoint.d.ts +19 -0
  59. package/dist/api/setup-retry-endpoint.js +32 -0
  60. package/dist/api/setup-retry-endpoint.js.map +1 -0
  61. package/dist/api/solvernets-endpoints.js +8 -1
  62. package/dist/api/solvernets-endpoints.js.map +1 -1
  63. package/dist/api/status-build.d.ts +64 -0
  64. package/dist/api/status-build.js +72 -18
  65. package/dist/api/status-build.js.map +1 -1
  66. package/dist/api/task-run-routing.d.ts +7 -0
  67. package/dist/api/task-run-routing.js +12 -0
  68. package/dist/api/task-run-routing.js.map +1 -0
  69. package/dist/api/task-runs-build.d.ts +20 -0
  70. package/dist/api/task-runs-build.js +13 -1
  71. package/dist/api/task-runs-build.js.map +1 -1
  72. package/dist/build-info.json +4 -4
  73. package/dist/build-meta.json +1 -1
  74. package/dist/chain-read-errors.d.ts +10 -0
  75. package/dist/chain-read-errors.js +15 -0
  76. package/dist/chain-read-errors.js.map +1 -1
  77. package/dist/cli/commands/auth.js +3 -1
  78. package/dist/cli/commands/auth.js.map +1 -1
  79. package/dist/cli/commands/create.d.ts +5 -3
  80. package/dist/cli/commands/create.js +102 -36
  81. package/dist/cli/commands/create.js.map +1 -1
  82. package/dist/cli/commands/solver-nets.d.ts +19 -0
  83. package/dist/cli/commands/solver-nets.js +164 -11
  84. package/dist/cli/commands/solver-nets.js.map +1 -1
  85. package/dist/cli/commands/solver-plugins-publish.d.ts +31 -0
  86. package/dist/cli/commands/solver-plugins-publish.js +169 -0
  87. package/dist/cli/commands/solver-plugins-publish.js.map +1 -0
  88. package/dist/cli/commands/solver-plugins-revoke.d.ts +15 -0
  89. package/dist/cli/commands/solver-plugins-revoke.js +91 -0
  90. package/dist/cli/commands/solver-plugins-revoke.js.map +1 -0
  91. package/dist/cli/commands/solver-plugins.d.ts +50 -6
  92. package/dist/cli/commands/solver-plugins.js +205 -68
  93. package/dist/cli/commands/solver-plugins.js.map +1 -1
  94. package/dist/cli/commands/update.d.ts +10 -0
  95. package/dist/cli/commands/update.js +36 -0
  96. package/dist/cli/commands/update.js.map +1 -1
  97. package/dist/cli/introspection-context.js +5 -0
  98. package/dist/cli/introspection-context.js.map +1 -1
  99. package/dist/config.d.ts +79 -5
  100. package/dist/config.js +85 -9
  101. package/dist/config.js.map +1 -1
  102. package/dist/conformance/checks/hash-signature.js +6 -2
  103. package/dist/conformance/checks/hash-signature.js.map +1 -1
  104. package/dist/conformance/checks/payload.js +4 -2
  105. package/dist/conformance/checks/payload.js.map +1 -1
  106. package/dist/conformance/checks/verdict.d.ts +10 -10
  107. package/dist/conformance/checks/verdict.js +16 -15
  108. package/dist/conformance/checks/verdict.js.map +1 -1
  109. package/dist/conformance/harness.d.ts +1 -1
  110. package/dist/conformance/harness.js +16 -9
  111. package/dist/conformance/harness.js.map +1 -1
  112. package/dist/conformance/types.d.ts +10 -3
  113. package/dist/conformance/types.js.map +1 -1
  114. package/dist/corpus/acquire.d.ts +1 -3
  115. package/dist/corpus/acquire.js.map +1 -1
  116. package/dist/corpus/envelope-projection.d.ts +1 -1
  117. package/dist/corpus/envelope-projection.js +14 -7
  118. package/dist/corpus/envelope-projection.js.map +1 -1
  119. package/dist/corpus/index.d.ts +2 -1
  120. package/dist/corpus/index.js.map +1 -1
  121. package/dist/corpus/prediction-brier-scoreboard-report.js +1 -1
  122. package/dist/corpus/prediction-brier-scoreboard-report.js.map +1 -1
  123. package/dist/corpus/prediction-brier-scoreboard.js +3 -1
  124. package/dist/corpus/prediction-brier-scoreboard.js.map +1 -1
  125. package/dist/corpus/types.d.ts +2 -2
  126. package/dist/daemon/daemon.d.ts +26 -1
  127. package/dist/daemon/daemon.js +63 -1
  128. package/dist/daemon/daemon.js.map +1 -1
  129. package/dist/daemon/eviction-loop.d.ts +40 -0
  130. package/dist/daemon/eviction-loop.js +67 -0
  131. package/dist/daemon/eviction-loop.js.map +1 -0
  132. package/dist/daemon/freeze-fence.js +6 -3
  133. package/dist/daemon/freeze-fence.js.map +1 -1
  134. package/dist/daemon/jinn-claim-loop-wiring.d.ts +33 -0
  135. package/dist/daemon/jinn-claim-loop-wiring.js +40 -0
  136. package/dist/daemon/jinn-claim-loop-wiring.js.map +1 -0
  137. package/dist/daemon/jinn-claim-loop.d.ts +24 -17
  138. package/dist/daemon/jinn-claim-loop.js +63 -21
  139. package/dist/daemon/jinn-claim-loop.js.map +1 -1
  140. package/dist/daemon/readiness-gate.d.ts +30 -0
  141. package/dist/daemon/readiness-gate.js +31 -0
  142. package/dist/daemon/readiness-gate.js.map +1 -0
  143. package/dist/daemon/skip-log-dedup.d.ts +69 -0
  144. package/dist/daemon/skip-log-dedup.js +106 -0
  145. package/dist/daemon/skip-log-dedup.js.map +1 -0
  146. package/dist/dashboard/assets/index-CODvRk_l.js +294 -0
  147. package/dist/dashboard/assets/index-CV4x-_zC.css +32 -0
  148. package/dist/dashboard/index.html +2 -2
  149. package/dist/discovery/http.js +235 -0
  150. package/dist/discovery/http.js.map +1 -1
  151. package/dist/discovery/onchain.d.ts +5 -0
  152. package/dist/discovery/onchain.js +411 -8
  153. package/dist/discovery/onchain.js.map +1 -1
  154. package/dist/discovery/types.d.ts +157 -1
  155. package/dist/discovery/types.js +8 -10
  156. package/dist/discovery/types.js.map +1 -1
  157. package/dist/discovery/with-fallback.js +12 -0
  158. package/dist/discovery/with-fallback.js.map +1 -1
  159. package/dist/earning/agent-wallet-binding.d.ts +20 -1
  160. package/dist/earning/agent-wallet-binding.js +54 -16
  161. package/dist/earning/agent-wallet-binding.js.map +1 -1
  162. package/dist/earning/bootstrap.d.ts +178 -0
  163. package/dist/earning/bootstrap.js +628 -57
  164. package/dist/earning/bootstrap.js.map +1 -1
  165. package/dist/earning/contracts.d.ts +14 -0
  166. package/dist/earning/contracts.js +18 -1
  167. package/dist/earning/contracts.js.map +1 -1
  168. package/dist/earning/funding-plan.js +15 -2
  169. package/dist/earning/funding-plan.js.map +1 -1
  170. package/dist/earning/jinn-rewards.d.ts +46 -0
  171. package/dist/earning/jinn-rewards.js +32 -0
  172. package/dist/earning/jinn-rewards.js.map +1 -1
  173. package/dist/earning/store.d.ts +8 -0
  174. package/dist/earning/store.js +48 -1
  175. package/dist/earning/store.js.map +1 -1
  176. package/dist/earning/testnet-setup-migration.d.ts +12 -0
  177. package/dist/earning/testnet-setup-migration.js +27 -1
  178. package/dist/earning/testnet-setup-migration.js.map +1 -1
  179. package/dist/earning/types.d.ts +45 -0
  180. package/dist/earning/types.js +37 -0
  181. package/dist/earning/types.js.map +1 -1
  182. package/dist/erc8004/abis.d.ts +64 -0
  183. package/dist/erc8004/abis.js +48 -0
  184. package/dist/erc8004/abis.js.map +1 -1
  185. package/dist/erc8004/plugin-registry.d.ts +102 -0
  186. package/dist/erc8004/plugin-registry.js +165 -0
  187. package/dist/erc8004/plugin-registry.js.map +1 -0
  188. package/dist/erc8004/reputation.d.ts +8 -0
  189. package/dist/erc8004/reputation.js +22 -3
  190. package/dist/erc8004/reputation.js.map +1 -1
  191. package/dist/events/types.d.ts +2 -2
  192. package/dist/harnesses/cost-estimates.d.ts +145 -0
  193. package/dist/harnesses/cost-estimates.js +297 -0
  194. package/dist/harnesses/cost-estimates.js.map +1 -0
  195. package/dist/harnesses/engine/engine.d.ts +72 -0
  196. package/dist/harnesses/engine/engine.js +109 -11
  197. package/dist/harnesses/engine/engine.js.map +1 -1
  198. package/dist/harnesses/engine/envelope-assembly.d.ts +2 -2
  199. package/dist/harnesses/engine/envelope-assembly.js +4 -2
  200. package/dist/harnesses/engine/envelope-assembly.js.map +1 -1
  201. package/dist/harnesses/engine/persistence.d.ts +21 -0
  202. package/dist/harnesses/engine/persistence.js +39 -0
  203. package/dist/harnesses/engine/persistence.js.map +1 -1
  204. package/dist/harnesses/engine/work-dir-reaper.d.ts +65 -0
  205. package/dist/harnesses/engine/work-dir-reaper.js +100 -0
  206. package/dist/harnesses/engine/work-dir-reaper.js.map +1 -0
  207. package/dist/harnesses/freeze.d.ts +4 -1
  208. package/dist/harnesses/freeze.js +12 -2
  209. package/dist/harnesses/freeze.js.map +1 -1
  210. package/dist/harnesses/impls/claude-mcp-prediction/index.d.ts +4 -1
  211. package/dist/harnesses/impls/claude-mcp-prediction/index.js +7 -2
  212. package/dist/harnesses/impls/claude-mcp-prediction/index.js.map +1 -1
  213. package/dist/harnesses/impls/claude-mcp-prediction-apy/index.d.ts +4 -1
  214. package/dist/harnesses/impls/claude-mcp-prediction-apy/index.js +7 -2
  215. package/dist/harnesses/impls/claude-mcp-prediction-apy/index.js.map +1 -1
  216. package/dist/harnesses/impls/evaluation-context.d.ts +15 -4
  217. package/dist/harnesses/impls/evaluation-context.js +24 -8
  218. package/dist/harnesses/impls/evaluation-context.js.map +1 -1
  219. package/dist/harnesses/impls/hermes-agent/adapter.d.ts +34 -0
  220. package/dist/harnesses/impls/hermes-agent/adapter.js +205 -0
  221. package/dist/harnesses/impls/hermes-agent/adapter.js.map +1 -0
  222. package/dist/harnesses/impls/hermes-agent/bootstrap.d.ts +18 -0
  223. package/dist/harnesses/impls/hermes-agent/bootstrap.js +231 -0
  224. package/dist/harnesses/impls/hermes-agent/bootstrap.js.map +1 -0
  225. package/dist/harnesses/impls/hermes-agent/config-builder.d.ts +49 -0
  226. package/dist/harnesses/impls/hermes-agent/config-builder.js +132 -0
  227. package/dist/harnesses/impls/hermes-agent/config-builder.js.map +1 -0
  228. package/dist/harnesses/impls/hermes-agent/harness.d.ts +58 -0
  229. package/dist/harnesses/impls/hermes-agent/harness.js +118 -0
  230. package/dist/harnesses/impls/hermes-agent/harness.js.map +1 -0
  231. package/dist/harnesses/impls/hermes-agent/index.d.ts +5 -0
  232. package/dist/harnesses/impls/hermes-agent/index.js +7 -0
  233. package/dist/harnesses/impls/hermes-agent/index.js.map +1 -0
  234. package/dist/harnesses/impls/hermes-agent/prompt.d.ts +15 -0
  235. package/dist/harnesses/impls/hermes-agent/prompt.js +37 -0
  236. package/dist/harnesses/impls/hermes-agent/prompt.js.map +1 -0
  237. package/dist/harnesses/impls/index.d.ts +13 -0
  238. package/dist/harnesses/impls/index.js +32 -4
  239. package/dist/harnesses/impls/index.js.map +1 -1
  240. package/dist/harnesses/impls/learner/adapters/claude-code.js.map +1 -0
  241. package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/codex-code.js +13 -34
  242. package/dist/harnesses/impls/learner/adapters/codex-code.js.map +1 -0
  243. package/dist/harnesses/impls/learner/adapters/codex-workspace.js.map +1 -0
  244. package/dist/harnesses/impls/learner/harness.d.ts +62 -0
  245. package/dist/harnesses/impls/learner/harness.js +179 -0
  246. package/dist/harnesses/impls/learner/harness.js.map +1 -0
  247. package/dist/harnesses/impls/{claude-code-learner → learner}/harvest.js +15 -3
  248. package/dist/harnesses/impls/learner/harvest.js.map +1 -0
  249. package/dist/harnesses/impls/{claude-code-learner → learner}/index.d.ts +5 -5
  250. package/dist/harnesses/impls/{claude-code-learner → learner}/index.js +4 -4
  251. package/dist/harnesses/impls/learner/index.js.map +1 -0
  252. package/dist/harnesses/impls/{claude-code-learner → learner}/plugin-path.d.ts +4 -4
  253. package/dist/harnesses/impls/{claude-code-learner → learner}/plugin-path.js +7 -7
  254. package/dist/harnesses/impls/learner/plugin-path.js.map +1 -0
  255. package/dist/harnesses/impls/{claude-code-learner → learner}/restoration-patch.js +3 -1
  256. package/dist/harnesses/impls/learner/restoration-patch.js.map +1 -0
  257. package/dist/harnesses/impls/learner/test-utils/fake-plugin-outputs.js.map +1 -0
  258. package/dist/harnesses/impls/learner/test-utils/noop-adapter.js.map +1 -0
  259. package/dist/harnesses/impls/{claude-code-learner → learner}/types.d.ts +23 -2
  260. package/dist/harnesses/impls/learner/types.js.map +1 -0
  261. package/dist/harnesses/impls/portfolio-v0-evaluator/index.js +13 -12
  262. package/dist/harnesses/impls/portfolio-v0-evaluator/index.js.map +1 -1
  263. package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.js +7 -7
  264. package/dist/harnesses/impls/prediction-apy-v0-evaluator/index.js.map +1 -1
  265. package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.d.ts +3 -3
  266. package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.js +7 -6
  267. package/dist/harnesses/impls/prediction-apy-v0-evaluator/parse-submission.js.map +1 -1
  268. package/dist/harnesses/impls/prediction-v0-evaluator/checks/integrity.js +1 -1
  269. package/dist/harnesses/impls/prediction-v0-evaluator/checks/integrity.js.map +1 -1
  270. package/dist/harnesses/impls/prediction-v0-evaluator/index.js +11 -10
  271. package/dist/harnesses/impls/prediction-v0-evaluator/index.js.map +1 -1
  272. package/dist/harnesses/impls/prediction-v1-evaluator/index.js +11 -10
  273. package/dist/harnesses/impls/prediction-v1-evaluator/index.js.map +1 -1
  274. package/dist/harnesses/impls/stub.d.ts +58 -0
  275. package/dist/harnesses/impls/stub.js +89 -0
  276. package/dist/harnesses/impls/stub.js.map +1 -0
  277. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.d.ts +48 -50
  278. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js +92 -84
  279. package/dist/harnesses/impls/swe-rebench-v2-evaluator/eval-runner.js.map +1 -1
  280. package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.d.ts +24 -5
  281. package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js +104 -4
  282. package/dist/harnesses/impls/swe-rebench-v2-evaluator/harness.js.map +1 -1
  283. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.d.ts +9 -0
  284. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js +25 -1
  285. package/dist/harnesses/impls/swe-rebench-v2-evaluator/hf-fetcher.js.map +1 -1
  286. package/dist/harnesses/names.d.ts +1 -0
  287. package/dist/harnesses/names.js +3 -0
  288. package/dist/harnesses/names.js.map +1 -1
  289. package/dist/harnesses/readiness-registry.d.ts +48 -0
  290. package/dist/harnesses/readiness-registry.js +144 -0
  291. package/dist/harnesses/readiness-registry.js.map +1 -0
  292. package/dist/harnesses/types.d.ts +7 -0
  293. package/dist/main.d.ts +14 -0
  294. package/dist/main.js +417 -116
  295. package/dist/main.js.map +1 -1
  296. package/dist/mcp/server.js +14 -13
  297. package/dist/mcp/server.js.map +1 -1
  298. package/dist/observability/emit-event.d.ts +1 -1
  299. package/dist/observability/emit-event.js.map +1 -1
  300. package/dist/operator-errors.d.ts +7 -0
  301. package/dist/operator-errors.js +26 -2
  302. package/dist/operator-errors.js.map +1 -1
  303. package/dist/preflight/claude-auth.d.ts +18 -0
  304. package/dist/preflight/claude-auth.js +38 -0
  305. package/dist/preflight/claude-auth.js.map +1 -1
  306. package/dist/restart-daemon.d.ts +79 -0
  307. package/dist/restart-daemon.js +82 -0
  308. package/dist/restart-daemon.js.map +1 -0
  309. package/dist/scripts/donation-consumption-acceptance.js +1 -1
  310. package/dist/scripts/donation-consumption-acceptance.js.map +1 -1
  311. package/dist/scripts/swe-rebench-v2-known-bad.json +12 -0
  312. package/dist/scripts/swe-rebench-v2-seed-pool.json +26 -0
  313. package/dist/setup/halt-mode.d.ts +14 -0
  314. package/dist/setup/halt-mode.js +17 -0
  315. package/dist/setup/halt-mode.js.map +1 -0
  316. package/dist/solver-nets/prediction-operator-ux.js +43 -3
  317. package/dist/solver-nets/prediction-operator-ux.js.map +1 -1
  318. package/dist/solver-nets/registry.d.ts +1 -0
  319. package/dist/solver-nets/registry.js +1 -1
  320. package/dist/solver-nets/registry.js.map +1 -1
  321. package/dist/solver-types/_swe-rebench-v2-pool-cache.d.ts +58 -0
  322. package/dist/solver-types/_swe-rebench-v2-pool-cache.js +87 -0
  323. package/dist/solver-types/_swe-rebench-v2-pool-cache.js.map +1 -0
  324. package/dist/solver-types/_swe-rebench-v2-substrate.d.ts +52 -0
  325. package/dist/solver-types/_swe-rebench-v2-substrate.js +76 -0
  326. package/dist/solver-types/_swe-rebench-v2-substrate.js.map +1 -0
  327. package/dist/solver-types/_swe-rebench-v2-validated-pool.d.ts +38 -12
  328. package/dist/solver-types/_swe-rebench-v2-validated-pool.js +136 -27
  329. package/dist/solver-types/_swe-rebench-v2-validated-pool.js.map +1 -1
  330. package/dist/solver-types/swe-rebench-v2-auto.d.ts +6 -0
  331. package/dist/solver-types/swe-rebench-v2-auto.js.map +1 -1
  332. package/dist/solver-types/swe-rebench-v2.d.ts +1 -0
  333. package/dist/solver-types/swe-rebench-v2.js +42 -17
  334. package/dist/solver-types/swe-rebench-v2.js.map +1 -1
  335. package/dist/solvernets/daemon-init.d.ts +10 -2
  336. package/dist/solvernets/daemon-init.js +22 -2
  337. package/dist/solvernets/daemon-init.js.map +1 -1
  338. package/dist/store/store.js +12 -4
  339. package/dist/store/store.js.map +1 -1
  340. package/dist/templates/plugins/runtime-plugin/.mcp.json.tmpl +8 -0
  341. package/dist/templates/plugins/runtime-plugin/README.md.tmpl +30 -0
  342. package/dist/templates/plugins/runtime-plugin/gitignore.tmpl +3 -0
  343. package/dist/templates/plugins/runtime-plugin/jinn.plugin.json.tmpl +21 -0
  344. package/dist/templates/plugins/runtime-plugin/mcp/server.mjs.tmpl +33 -0
  345. package/dist/templates/plugins/runtime-plugin/package.json.tmpl +15 -0
  346. package/dist/templates/plugins/runtime-plugin/test/plugin.test.ts.tmpl +35 -0
  347. package/dist/templates/plugins/runtime-plugin/tsconfig.json.tmpl +11 -0
  348. package/dist/templates/plugins/solver-type-plugin/README.md.tmpl +35 -0
  349. package/dist/templates/plugins/solver-type-plugin/gitignore.tmpl +3 -0
  350. package/dist/templates/plugins/solver-type-plugin/jinn.plugin.json.tmpl +11 -0
  351. package/dist/templates/plugins/solver-type-plugin/package.json.tmpl +15 -0
  352. package/dist/templates/plugins/solver-type-plugin/skills/example/SKILL.md.tmpl +10 -0
  353. package/dist/templates/plugins/solver-type-plugin/test/plugin.test.ts.tmpl +25 -0
  354. package/dist/templates/plugins/solver-type-plugin/tsconfig.json.tmpl +11 -0
  355. package/dist/tx-retry.d.ts +13 -0
  356. package/dist/tx-retry.js +22 -0
  357. package/dist/tx-retry.js.map +1 -1
  358. package/dist/types/envelope.d.ts +28 -21
  359. package/dist/types/envelope.js +8 -3
  360. package/dist/types/envelope.js.map +1 -1
  361. package/dist/types/payloads/index.d.ts +2 -2
  362. package/dist/types/payloads/index.js +13 -12
  363. package/dist/types/payloads/index.js.map +1 -1
  364. package/dist/types/payloads/portfolio-v0.d.ts +60 -10
  365. package/dist/types/payloads/portfolio-v0.js +16 -6
  366. package/dist/types/payloads/portfolio-v0.js.map +1 -1
  367. package/dist/types/payloads/prediction-apy-v0.d.ts +56 -14
  368. package/dist/types/payloads/prediction-apy-v0.js +16 -6
  369. package/dist/types/payloads/prediction-apy-v0.js.map +1 -1
  370. package/dist/types/payloads/prediction-v0.d.ts +53 -14
  371. package/dist/types/payloads/prediction-v0.js +16 -6
  372. package/dist/types/payloads/prediction-v0.js.map +1 -1
  373. package/dist/util/extract-tx-hash.d.ts +14 -0
  374. package/dist/util/extract-tx-hash.js +19 -0
  375. package/dist/util/extract-tx-hash.js.map +1 -0
  376. package/dist/vendor/@jinn-network/sdk/dist/payloads/prediction-v1.d.ts +45 -6
  377. package/dist/vendor/@jinn-network/sdk/dist/payloads/prediction-v1.js +16 -6
  378. package/dist/x402/handler.js +51 -20
  379. package/dist/x402/handler.js.map +1 -1
  380. package/package.json +38 -13
  381. package/plugins/swe-rebench-v2-diffmin/.claude-plugin/plugin.json +5 -0
  382. package/plugins/swe-rebench-v2-diffmin/.mcp.json +8 -0
  383. package/plugins/swe-rebench-v2-diffmin/README.md +69 -0
  384. package/plugins/swe-rebench-v2-diffmin/jinn.plugin.json +12 -0
  385. package/plugins/swe-rebench-v2-diffmin/mcp/diff-stats-server.mjs +72 -0
  386. package/plugins/swe-rebench-v2-diffmin/mcp/diff-stats.mjs +48 -0
  387. package/plugins/swe-rebench-v2-diffmin/package.json +19 -0
  388. package/plugins/swe-rebench-v2-diffmin/skills/diffmin/SKILL.md +116 -0
  389. package/plugins/swe-rebench-v2-diffmin/skills/test-map/SKILL.md +126 -0
  390. package/plugins/swe-rebench-v2-diffmin/test/diff-stats.test.ts +62 -0
  391. package/plugins/swe-rebench-v2-diffmin/test/manifest.test.ts +53 -0
  392. package/plugins/swe-rebench-v2-diffmin/tsconfig.json +12 -0
  393. package/plugins/swe-rebench-v2-runtime/README.md +13 -0
  394. package/plugins/swe-rebench-v2-runtime/skills/orient/SKILL.md +7 -3
  395. package/plugins/swe-rebench-v2-runtime/skills/plan/SKILL.md +6 -17
  396. package/templates/plugins/runtime-plugin/.mcp.json.tmpl +8 -0
  397. package/templates/plugins/runtime-plugin/README.md.tmpl +30 -0
  398. package/templates/plugins/runtime-plugin/gitignore.tmpl +3 -0
  399. package/templates/plugins/runtime-plugin/jinn.plugin.json.tmpl +21 -0
  400. package/templates/plugins/runtime-plugin/mcp/server.mjs.tmpl +33 -0
  401. package/templates/plugins/runtime-plugin/package.json.tmpl +15 -0
  402. package/templates/plugins/runtime-plugin/test/plugin.test.ts.tmpl +35 -0
  403. package/templates/plugins/runtime-plugin/tsconfig.json.tmpl +11 -0
  404. package/templates/plugins/solver-type-plugin/README.md.tmpl +35 -0
  405. package/templates/plugins/solver-type-plugin/gitignore.tmpl +3 -0
  406. package/templates/plugins/solver-type-plugin/jinn.plugin.json.tmpl +11 -0
  407. package/templates/plugins/solver-type-plugin/package.json.tmpl +15 -0
  408. package/templates/plugins/solver-type-plugin/skills/example/SKILL.md.tmpl +10 -0
  409. package/templates/plugins/solver-type-plugin/test/plugin.test.ts.tmpl +25 -0
  410. package/templates/plugins/solver-type-plugin/tsconfig.json.tmpl +11 -0
  411. package/dist/dashboard/assets/index-BjtltOGc.js +0 -76
  412. package/dist/dashboard/assets/index-D_NMfDfV.css +0 -32
  413. package/dist/harnesses/impls/claude-code-learner/adapters/claude-code.js.map +0 -1
  414. package/dist/harnesses/impls/claude-code-learner/adapters/codex-code.js.map +0 -1
  415. package/dist/harnesses/impls/claude-code-learner/adapters/codex-workspace.js.map +0 -1
  416. package/dist/harnesses/impls/claude-code-learner/harness.d.ts +0 -22
  417. package/dist/harnesses/impls/claude-code-learner/harness.js +0 -62
  418. package/dist/harnesses/impls/claude-code-learner/harness.js.map +0 -1
  419. package/dist/harnesses/impls/claude-code-learner/harvest.js.map +0 -1
  420. package/dist/harnesses/impls/claude-code-learner/index.js.map +0 -1
  421. package/dist/harnesses/impls/claude-code-learner/plugin-path.js.map +0 -1
  422. package/dist/harnesses/impls/claude-code-learner/restoration-patch.js.map +0 -1
  423. package/dist/harnesses/impls/claude-code-learner/test-utils/fake-plugin-outputs.js.map +0 -1
  424. package/dist/harnesses/impls/claude-code-learner/test-utils/noop-adapter.js.map +0 -1
  425. package/dist/harnesses/impls/claude-code-learner/types.js.map +0 -1
  426. package/dist/preflight/claude-required.d.ts +0 -8
  427. package/dist/preflight/claude-required.js +0 -17
  428. package/dist/preflight/claude-required.js.map +0 -1
  429. /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/claude-code.d.ts +0 -0
  430. /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/claude-code.js +0 -0
  431. /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/codex-code.d.ts +0 -0
  432. /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/codex-workspace.d.ts +0 -0
  433. /package/dist/harnesses/impls/{claude-code-learner → learner}/adapters/codex-workspace.js +0 -0
  434. /package/dist/harnesses/impls/{claude-code-learner → learner}/harvest.d.ts +0 -0
  435. /package/dist/harnesses/impls/{claude-code-learner → learner}/restoration-patch.d.ts +0 -0
  436. /package/dist/harnesses/impls/{claude-code-learner → learner}/test-utils/fake-plugin-outputs.d.ts +0 -0
  437. /package/dist/harnesses/impls/{claude-code-learner → learner}/test-utils/fake-plugin-outputs.js +0 -0
  438. /package/dist/harnesses/impls/{claude-code-learner → learner}/test-utils/noop-adapter.d.ts +0 -0
  439. /package/dist/harnesses/impls/{claude-code-learner → learner}/test-utils/noop-adapter.js +0 -0
  440. /package/dist/harnesses/impls/{claude-code-learner → learner}/types.js +0 -0
  441. /package/plugins/{claude-code-learner → learner}/.claude-plugin/plugin.json +0 -0
  442. /package/plugins/{claude-code-learner → learner}/.codex-plugin/plugin.json +0 -0
  443. /package/plugins/{claude-code-learner → learner}/AGENTS.md +0 -0
  444. /package/plugins/{claude-code-learner → learner}/CLAUDE.md +0 -0
  445. /package/plugins/{claude-code-learner → learner}/README.md +0 -0
  446. /package/plugins/{claude-code-learner → learner}/hooks/hooks.json +0 -0
  447. /package/plugins/{claude-code-learner → learner}/hooks/session-start +0 -0
  448. /package/plugins/{claude-code-learner → learner}/skills/learn/SKILL.md +0 -0
  449. /package/plugins/{claude-code-learner → learner}/skills/learn/analyst-prompt.md +0 -0
  450. /package/plugins/{claude-code-learner → learner}/skills/learn/consolidator-prompt.md +0 -0
  451. /package/plugins/{claude-code-learner → learner}/skills/learn/explorer-prompt.md +0 -0
  452. /package/plugins/{claude-code-learner → learner}/skills/learn/planner-prompt.md +0 -0
  453. /package/plugins/{claude-code-learner → learner}/skills/learn/promoter-prompt.md +0 -0
  454. /package/plugins/{claude-code-learner → learner}/skills/learn/step-worker-prompt.md +0 -0
  455. /package/plugins/{claude-code-learner → learner}/skills/learn/strategist-prompt.md +0 -0
package/dist/main.js CHANGED
@@ -26,7 +26,9 @@ import { dirname, join } from 'node:path';
26
26
  import { fileURLToPath } from 'node:url';
27
27
  import { loadConfig, getConfigPathFromArgs, DEFAULT_CONFIG_PATH } from './config.js';
28
28
  import { Store } from './store/store.js';
29
- import { startApiServer } from './api/server.js';
29
+ import { startApiServer, isEmbeddedAgentEnabled } from './api/server.js';
30
+ // addHarnessReadinessRoutes is wired through startApiServer's holder ref now
31
+ // (jinn-mono-u34i). No direct import needed.
30
32
  import { CapturePublishUnavailableError } from './api/captures.js';
31
33
  import { invalidatePredictionOperatorStatusCache } from './api/gather-status.js';
32
34
  import { ensureUiToken } from './api/ui-token.js';
@@ -34,14 +36,11 @@ import { hashImplStateDir } from './harnesses/freeze.js';
34
36
  import { readModeState } from './harnesses/mode-state.js';
35
37
  import { attachAgentWs, updateAgentClaudePath } from './agent/agent-ws.js';
36
38
  import { createSetupModeController } from './setup-mode.js';
39
+ import { requestDaemonRestart } from './restart-daemon.js';
37
40
  import { buildEnvelope, emitEnvelope } from './errors/envelope.js';
38
41
  import { clearBootstrapError, persistBootstrapError, } from './errors/persisted-bootstrap-error.js';
39
42
  import { emitStructured } from './events/emitter.js';
40
- import { checkClaudeBinary } from './preflight/claude-binary.js';
41
- import { emitClaudeBinaryPreflightFailure } from './preflight/claude-invocation-envelope.js';
42
- import { detectAuthContext, probeClaudeAuth } from './preflight/claude-auth.js';
43
- import { configRequiresClaudeAuth } from './preflight/claude-required.js';
44
- import { FleetBootstrapper } from './earning/bootstrap.js';
43
+ import { FleetBootstrapper, recoverEvictedService as recoverEvictedServiceFn } from './earning/bootstrap.js';
45
44
  import { DEFAULT_TESTNET_ARTIFACTS, applyChainGasOverrides, getChainConfig, loadJinnMviConfig } from './earning/contracts.js';
46
45
  import { runLegacyAgentIdMigration } from './earning/migrate-agent-id.js';
47
46
  import { FleetStateStore } from './earning/store.js';
@@ -50,6 +49,7 @@ import { decryptMnemonic, deriveMasterSigner, walletPrivateKeyAtIndex } from './
50
49
  import { MechAdapter } from './adapters/mech/adapter.js';
51
50
  import { ClaudeRunner } from './runner/claude.js';
52
51
  import { Daemon } from './daemon/daemon.js';
52
+ import { buildJinnClaimLoopConfig, shouldWireJinnClaimL1Signer, } from './daemon/jinn-claim-loop-wiring.js';
53
53
  import { createJinnPublicClient, createJinnWalletClient, createJinnL1PublicClient, createJinnL1WalletClient } from './earning/viem-clients.js';
54
54
  import { privateKeyToAccount } from 'viem/accounts';
55
55
  import { getAddress } from 'viem';
@@ -57,7 +57,8 @@ import { DEFAULT_DISABLED_HARNESSES, DEFAULT_HARNESS, HarnessRegistry, } from '.
57
57
  import { joinedSolverNetsViewFromConfig } from './harnesses/engine/engine.js';
58
58
  import { buildHarnesses } from './harnesses/impls/index.js';
59
59
  import { loadExternalImpl } from './harnesses/external-impls/index.js';
60
- import { CLAUDE_CODE_HARNESS, CODEX_HARNESS, harnessStateDirName } from './harnesses/names.js';
60
+ import { CLAUDE_CODE_HARNESS, CODEX_HARNESS, HERMES_AGENT_HARNESS, harnessStateDirName } from './harnesses/names.js';
61
+ import { HarnessReadinessRegistry } from './harnesses/readiness-registry.js';
61
62
  import { createClients } from './adapters/mech/safe.js';
62
63
  import { loadSolverNets } from './solver-nets/registry.js';
63
64
  import { createCorpus } from './corpus/index.js';
@@ -81,6 +82,7 @@ import { GeneratedTaskSource, StaticConfiguredTaskSource } from './tasks/sources
81
82
  import { checkRpcNetwork, logRpcLocalDevToStderr, rpcNetworkFailureHint } from './preflight/rpc-network.js';
82
83
  import { apiPortFailureMessage, checkApiPortAvailable } from './preflight/api-port.js';
83
84
  import { openBrowser } from './cli/open-browser.js';
85
+ import { keepSetupUiOnBootstrapError } from './setup/halt-mode.js';
84
86
  if (process.env['JINN_LOAD_DEV_ENV'] === '1' || process.env['NODE_ENV'] === 'development') {
85
87
  dotenvConfig({ path: join(dirname(fileURLToPath(import.meta.url)), '..', '.env') });
86
88
  }
@@ -133,8 +135,19 @@ const config = loadConfig(CONFIG_PATH);
133
135
  if (config.network === 'mainnet' && process.env['JINN_ENABLE_MAINNET'] !== '1') {
134
136
  console.warn('[main] Mainnet is disabled before launch; using testnet defaults.');
135
137
  config.network = 'testnet';
136
- config.rpcUrl = 'https://sepolia.base.org';
138
+ config.rpcUrl = 'https://base-sepolia.gateway.tenderly.co/75tyLMQuD8EHpXxMwINIKu';
137
139
  }
140
+ // Issue #326: the embedded Claude agent chat surface (right rail + onboarding
141
+ // "Ask Claude" panel + /api/agent/ws bridge) is hidden by default while its
142
+ // action-authority / plugin-scope shape is still in design. Set
143
+ // `JINN_ENABLE_EMBEDDED_AGENT=1` to re-enable it for development. This does
144
+ // NOT affect Claude-Code-as-a-solver-harness — that path is independent.
145
+ //
146
+ // Issue #367: the SPA reads this flag via the injected `window.__JINN_FEATURES__`
147
+ // (`resolveFeatureFlags` in api/server.ts) like every other operator-app flag.
148
+ // This `embeddedAgentEnabled` const is the daemon-side consumer only — it gates
149
+ // whether the `/api/agent/ws` bridge is mounted below.
150
+ const embeddedAgentEnabled = isEmbeddedAgentEnabled();
138
151
  let activeClaudePath = config.claudePath ?? 'claude';
139
152
  const selectClaudePath = (claudePath) => {
140
153
  activeClaudePath = claudePath;
@@ -442,7 +455,7 @@ async function bootstrap() {
442
455
  };
443
456
  // eslint-disable-next-line no-constant-condition
444
457
  while (true) {
445
- result = await bootstrapper.bootstrap(PASSWORD);
458
+ result = await bootstrapper.ensureStage1And2(PASSWORD);
446
459
  if (!result.funding) {
447
460
  clearFundingGate();
448
461
  break;
@@ -485,11 +498,17 @@ async function bootstrap() {
485
498
  hint: 'Fund the listed address and re-run this command.',
486
499
  exampleCli: 'jinn fund-requirements --json',
487
500
  details: {
488
- role: 'master',
501
+ // jinn-mono-hjex.6: structured envelope so SPA can render the
502
+ // specific address + amount instead of a prose disjunction.
503
+ category: 'insufficient_funds',
504
+ step: 'awaiting_funding',
489
505
  address: result.funding.master_address,
506
+ requiredWei: result.funding.eth_required,
507
+ haveWei: result.funding.eth_balance,
508
+ // Legacy aliases kept for any external consumers that read these.
509
+ role: 'master',
490
510
  asset: 'native',
491
511
  needWei: result.funding.eth_required,
492
- haveWei: result.funding.eth_balance,
493
512
  },
494
513
  });
495
514
  }
@@ -504,11 +523,17 @@ async function bootstrap() {
504
523
  hint: 'Bootstrap failed before the fleet reached a runnable state.',
505
524
  details: {
506
525
  cause: result.message,
526
+ // jinn-mono-hjex.6: propagate structured category from the bootstrapper
527
+ // so the SPA can render category-specific UI (e.g. funding shortfall).
528
+ ...(result.errorCategory !== undefined ? { category: result.errorCategory } : {}),
507
529
  // Preserve the raw underlying error so a misclassified summary can
508
530
  // be diagnosed without re-running with JINN_DEBUG. See jinn-mono-jz9f.
509
531
  ...(result.rawErrorMessage && result.rawErrorMessage !== result.message
510
532
  ? { rawErrorMessage: result.rawErrorMessage }
511
533
  : {}),
534
+ // jinn-mono-hjex reviewer fix: propagate tx hash so the SPA can render
535
+ // a block-explorer link for failed on-chain revert transactions.
536
+ ...(result.txHash != null ? { txHash: result.txHash } : {}),
512
537
  },
513
538
  });
514
539
  }
@@ -593,7 +618,9 @@ class SetupBootstrapHalted extends Error {
593
618
  this.name = 'SetupBootstrapHalted';
594
619
  }
595
620
  }
596
- const keepSetupUiOnBootstrapError = () => process.env['JINN_NO_UI'] !== '1' && process.env['JINN_NO_DAEMON'] !== '1';
621
+ // hjex.6: gate for the halt-and-resume loop. Lives in ./setup/halt-mode.ts
622
+ // so it can be unit-tested without dragging main.ts's top-level side
623
+ // effects (password resolution, config load) into the test.
597
624
  // ── Main ────────────────────────────────────────────────────────────────────
598
625
  /**
599
626
  * --json-progress: emit NDJSON progress envelopes on stdout during long
@@ -744,6 +771,34 @@ export async function main() {
744
771
  // on first request); subsystem init below populates `holder.current` and
745
772
  // the route handlers dereference it per-request.
746
773
  const solverNetEndpointsDepsHolder = { current: undefined };
774
+ // jinn-mono-u34i: same pattern for the harness readiness registry. The
775
+ // registry is built post-bootstrap (depends on the keystore being
776
+ // available), but the routes must be registered at server start to land in
777
+ // Hono's matcher before the panel's first poll. Late-mounting via
778
+ // `addHarnessReadinessRoutes(setupApiServer.app, ...)` after the panel had
779
+ // been polling for minutes threw "Can not add a route since the matcher is
780
+ // already built" and crashed the daemon on the running-mode transition.
781
+ const harnessReadinessRegistryHolder = { current: undefined };
782
+ // jinn-mono-u34i: same eager-register / late-populate pattern for the
783
+ // DiscoveryAPI. Pre-fix, /v1/discovery/* routes only mounted when
784
+ // `config.discovery` was set at startApiServer time — but main.ts builds
785
+ // `sharedDiscoveryApi` post-bootstrap, so the routes were never registered
786
+ // and the panel's /build page got a permanent 404 on plugin-publications +
787
+ // builder-artifacts. Holder ref lets the routes register eagerly and
788
+ // start returning real data the moment main.ts assigns holder.current.
789
+ const discoveryApiHolder = { current: undefined };
790
+ // hjex.3: holder for the restake callback. Populated in running mode after
791
+ // bootstrap completes (when mnemonic + distributorAddress are available).
792
+ const restakeCallbackRef = {
793
+ current: undefined,
794
+ };
795
+ // hjex.6: retry signal for the bootstrap halt-and-resume loop.
796
+ // When a SetupBootstrapHalted is caught (fatal non-funding error or funding
797
+ // timeout), main() waits on this promise instead of returning, so the setup
798
+ // API stays alive and the operator can click Retry in the SPA.
799
+ // The retry endpoint resolves this promise to trigger a re-run.
800
+ let retryBootstrapResolve = null;
801
+ let retryBootstrapReject = null;
747
802
  let setupApiServer;
748
803
  try {
749
804
  setupApiServer = await startApiServer({
@@ -753,11 +808,24 @@ export async function main() {
753
808
  bindHost: apiBindHost,
754
809
  corpus: () => corpusForApi,
755
810
  ui: { token: uiToken, handshakeKey },
811
+ hermesDoctor: {
812
+ hermesPath: config.hermesPath,
813
+ hermesDoctorTimeoutMs: config.hermesDoctorTimeoutMs,
814
+ },
815
+ codexDoctor: {
816
+ codexPath: config.codexPath,
817
+ codexDoctorTimeoutMs: config.codexDoctorTimeoutMs,
818
+ },
756
819
  admin: {
757
- onRestartRequested: () => {
758
- console.log('[main] Restart requested via operator MCP. Exiting...');
759
- process.exit(0);
760
- },
820
+ // jinn-mono #289: in interactive mode (the dashboard SPA case),
821
+ // spawn a detached replacement before exiting so the panel reconnects
822
+ // to a live daemon instead of seeing a 502 + terminal prompt. In
823
+ // headless mode (`JINN_NO_UI=1`), exit without respawning so the
824
+ // supervisor / systemd / docker entrypoint decides what to do.
825
+ // Stop: pure exit, never respawn. The operator clicked Stop; they
826
+ // want the daemon down until they explicitly start it again.
827
+ onStopRequested: () => process.exit(0),
828
+ onRestartRequested: (opts) => requestDaemonRestart({ forceRespawn: opts.forceRespawn }),
761
829
  },
762
830
  harnessStatus: {
763
831
  getStatus: async () => {
@@ -840,7 +908,12 @@ export async function main() {
840
908
  contract: { id: 'swe-rebench-v2', version: 'v1' },
841
909
  state: 'live',
842
910
  supportedRoles: ['solving', 'evaluating'],
911
+ // Order matters: the dashboard pre-selects compatibleHarnesses[0]
912
+ // as the default solver harness. Hermes Agent is the SWE-rebench v2
913
+ // default per the 2026-05-12 decision (jinn-mono-8psp.2 / spec §10);
914
+ // operators may switch to Claude Code or Codex.
843
915
  compatibleHarnesses: [
916
+ { name: HERMES_AGENT_HARNESS, version: '0.1.0', supportsRoles: ['solving'] },
844
917
  { name: CLAUDE_CODE_HARNESS, version: '0.1.0', supportsRoles: ['solving'] },
845
918
  { name: CODEX_HARNESS, version: '0.1.0', supportsRoles: ['solving'] },
846
919
  { name: 'swe-rebench-v2-evaluator', version: '0.1.0', supportsRoles: ['evaluating'] },
@@ -856,6 +929,12 @@ export async function main() {
856
929
  // eagerly here; deps are populated by main.ts post-bootstrap via the
857
930
  // holder, and each route handler reads `holder.current` per-request.
858
931
  solverNetsLauncher: { holder: solverNetEndpointsDepsHolder },
932
+ // jinn-mono-u34i: same eager-register / late-populate pattern for the
933
+ // harness readiness routes. Until main.ts sets the holder, requests
934
+ // return 503 subsystem_not_ready (the panel handles that gracefully).
935
+ harnessReadinessRegistry: { holder: harnessReadinessRegistryHolder },
936
+ // jinn-mono-u34i: see discoveryApiHolder comment above.
937
+ discovery: { holder: discoveryApiHolder },
859
938
  // Agent-binding retry: re-run the ERC-1271 bind step from the SPA
860
939
  // without forcing a daemon restart. Constructs a fresh bootstrapper
861
940
  // per call so we don't tangle lifecycle with the long-running one.
@@ -907,7 +986,17 @@ export async function main() {
907
986
  earningDir: config.earningDir,
908
987
  chain: NETWORK_CHAIN,
909
988
  rpcUrl: config.rpcUrl,
910
- minEoaGasWei: (CHAIN_CONFIG.minEoaGasEth * 2n).toString(),
989
+ // Note: do NOT pass minEoaGasWei here. setup-endpoints.ts derives
990
+ // its faucet target from stage1MinMasterEth(getChainConfig(chain),
991
+ // targetServices) — the same helper the daemon's ensureStage1 gate
992
+ // uses. Passing a computed value from here would re-introduce the
993
+ // drift seam that hit operators in the 2026-05-18 canary
994
+ // (jinn-mono-u34i): faucet dripped to one target while the daemon
995
+ // waited for a different one. The override field remains for tests
996
+ // that want a custom target.
997
+ // targetServices DOES need to flow through so the faucet drips enough
998
+ // ETH to cover ALL services for the operator's chosen targetServices.
999
+ targetServices: config.targetServices,
911
1000
  claudePath: activeClaudePath,
912
1001
  getClaudePath: () => activeClaudePath,
913
1002
  configPath: CONFIG_PATH ?? DEFAULT_CONFIG_PATH,
@@ -922,10 +1011,39 @@ export async function main() {
922
1011
  // toggle immediately. (jinn-mono-l2zl.15.4.12)
923
1012
  invalidatePredictionOperatorStatusCache(config);
924
1013
  },
1014
+ // hjex.3: delegate to the live callback populated once running mode starts.
1015
+ restake: (serviceId) => {
1016
+ if (!restakeCallbackRef.current) {
1017
+ return Promise.resolve({ ok: false, error: 'restake_not_available_in_setup_mode' });
1018
+ }
1019
+ return restakeCallbackRef.current(serviceId);
1020
+ },
1021
+ // hjex.6: re-trigger the bootstrap state machine from the SPA Retry button.
1022
+ // Resolves the halt-and-resume promise; main() will loop back and call
1023
+ // bootstrap() again. Rejects if the daemon is not currently halted.
1024
+ retryBootstrap: () => {
1025
+ return new Promise((resolve, reject) => {
1026
+ if (!retryBootstrapResolve) {
1027
+ reject(new Error('daemon_not_halted'));
1028
+ return;
1029
+ }
1030
+ const prevResolve = retryBootstrapResolve;
1031
+ // The resolve will unblock the main loop's await. When bootstrap
1032
+ // completes (success or new halt), the caller receives the result
1033
+ // via the /v1/bootstrap polling endpoint.
1034
+ prevResolve();
1035
+ resolve();
1036
+ });
1037
+ },
925
1038
  },
926
1039
  status: {
927
1040
  earningDir: config.earningDir,
928
1041
  rpcUrl: config.rpcUrl,
1042
+ // tJINN identity comes from the bundled JINN MVI L1 artifact
1043
+ // (`JINN_MVI_CONFIG`) — one source of truth. The Sepolia RPC endpoint
1044
+ // is read from `config.ethereumRpcUrl` via the threaded `config`.
1045
+ tjinnTokenAddress: JINN_MVI_CONFIG.jinn,
1046
+ tjinnChainId: JINN_MVI_CONFIG.l1ChainId,
929
1047
  network: config.network,
930
1048
  pollIntervalMs: config.pollIntervalMs,
931
1049
  masterEthDailyEstimateWei: config.masterEthDailyEstimateWei,
@@ -1074,30 +1192,41 @@ export async function main() {
1074
1192
  // can attach to a long-lived embedded `claude` subprocess. The embedded
1075
1193
  // session reads MCP config we materialise to disk so it can reach the
1076
1194
  // operator MCP server (`jinn mcp`) for tool calls.
1077
- const operatorMcpConfigPath = join(homedir(), '.jinn-client', 'operator-mcp-config.json');
1078
- try {
1079
- mkdirSync(dirname(operatorMcpConfigPath), { recursive: true });
1080
- writeFileSyncMain(operatorMcpConfigPath, JSON.stringify({
1081
- mcpServers: {
1082
- 'jinn-operator': {
1083
- command: 'jinn',
1084
- args: ['mcp'],
1195
+ //
1196
+ // Issue #326: the embedded agent chat surface is hidden by default. The WS
1197
+ // bridge mounts only when `JINN_ENABLE_EMBEDDED_AGENT=1` so the dev-time
1198
+ // path stays end-to-end; with the flag off there is no /api/agent/ws route
1199
+ // and the SPA never renders the chat panel. Claude-Code-as-solver-harness
1200
+ // is independent of this bridge and unaffected.
1201
+ if (embeddedAgentEnabled) {
1202
+ const operatorMcpConfigPath = join(homedir(), '.jinn-client', 'operator-mcp-config.json');
1203
+ try {
1204
+ mkdirSync(dirname(operatorMcpConfigPath), { recursive: true });
1205
+ writeFileSyncMain(operatorMcpConfigPath, JSON.stringify({
1206
+ mcpServers: {
1207
+ 'jinn-operator': {
1208
+ command: 'jinn',
1209
+ args: ['mcp'],
1210
+ },
1085
1211
  },
1086
- },
1087
- }, null, 2));
1212
+ }, null, 2));
1213
+ }
1214
+ catch (err) {
1215
+ console.warn(`[main] Failed to write operator MCP config at ${operatorMcpConfigPath}: ` +
1216
+ (err instanceof Error ? err.message : String(err)));
1217
+ }
1218
+ attachAgentWs({
1219
+ httpServer: setupApiServer.server,
1220
+ uiToken,
1221
+ claudePath: activeClaudePath,
1222
+ cwd: process.cwd(),
1223
+ mcpConfigPath: operatorMcpConfigPath,
1224
+ });
1225
+ console.log(`[main] Agent WS bridge mounted at ws://127.0.0.1:${setupApiServer.port}/api/agent/ws`);
1088
1226
  }
1089
- catch (err) {
1090
- console.warn(`[main] Failed to write operator MCP config at ${operatorMcpConfigPath}: ` +
1091
- (err instanceof Error ? err.message : String(err)));
1227
+ else {
1228
+ console.log('[main] Embedded agent surface disabled (set JINN_ENABLE_EMBEDDED_AGENT=1 to enable).');
1092
1229
  }
1093
- attachAgentWs({
1094
- httpServer: setupApiServer.server,
1095
- uiToken,
1096
- claudePath: activeClaudePath,
1097
- cwd: process.cwd(),
1098
- mcpConfigPath: operatorMcpConfigPath,
1099
- });
1100
- console.log(`[main] Agent WS bridge mounted at ws://127.0.0.1:${setupApiServer.port}/api/agent/ws`);
1101
1230
  // ── Init-if-missing ──────────────────────────────────────────────────────
1102
1231
  // If the keystore is missing but we have a password, run `jinn init` now so
1103
1232
  // bootstrap has something to decrypt. Idempotent: init is a no-op when the
@@ -1138,30 +1267,96 @@ export async function main() {
1138
1267
  // keystore is on disk and we're transitioning into bootstrap.
1139
1268
  setupController.refresh({ keystoreExists: true, allComplete: false });
1140
1269
  }
1270
+ // hjex.6: halt-and-resume loop for bootstrap retries.
1271
+ // When failBootstrap() throws SetupBootstrapHalted, we wait for the operator
1272
+ // to click Retry in the SPA (which resolves retryBootstrapResolve) rather
1273
+ // than returning and exiting. On each retry, we loop back and call bootstrap()
1274
+ // again. bootstrap() is idempotent — completed steps are no-ops.
1141
1275
  let bootstrapResult;
1142
- try {
1143
- bootstrapResult = await bootstrap();
1144
- }
1145
- catch (err) {
1146
- if (err instanceof SetupBootstrapHalted) {
1147
- return {
1148
- schemaVersion: 1,
1149
- generatedAt: new Date().toISOString(),
1150
- kind: 'setup_halted',
1151
- pid: process.pid,
1152
- network: config.network,
1153
- phase: config.network === 'testnet' ? 'phase-1b' : 'phase-0',
1154
- apiPort: setupApiServer.port,
1155
- dashboardUrl: `http://127.0.0.1:${setupApiServer.port}`,
1156
- error: err.envelope,
1157
- };
1276
+ // eslint-disable-next-line no-constant-condition
1277
+ while (true) {
1278
+ try {
1279
+ bootstrapResult = await bootstrap();
1280
+ break; // success exit the retry loop
1281
+ }
1282
+ catch (err) {
1283
+ if (err instanceof SetupBootstrapHalted) {
1284
+ // Install the retry signal so the endpoint can unblock us.
1285
+ const retrySignal = new Promise((resolve, reject) => {
1286
+ retryBootstrapResolve = resolve;
1287
+ retryBootstrapReject = reject;
1288
+ });
1289
+ console.log('[main] Bootstrap halted. Waiting for retry signal from the dashboard...');
1290
+ // hjex.6: Auto-resume funding poller.
1291
+ // When the halt is a funding shortfall, poll the master EOA balance
1292
+ // every JINN_FUNDING_POLL_INTERVAL_MS (default 15s). When the balance
1293
+ // meets or exceeds the required amount, auto-signal the retry loop.
1294
+ // Only runs while the halt signal is pending; stops on any signal.
1295
+ let fundingPollHandle = null;
1296
+ const isHaltedOnFunding = err.envelope.code === 'funding_required';
1297
+ const haltDetails = err.envelope.details;
1298
+ const haltAddress = typeof haltDetails?.['address'] === 'string'
1299
+ ? haltDetails['address']
1300
+ : null;
1301
+ const haltRequired = typeof haltDetails?.['requiredWei'] === 'string'
1302
+ ? BigInt(haltDetails['requiredWei'])
1303
+ : typeof haltDetails?.['needWei'] === 'string'
1304
+ ? BigInt(haltDetails['needWei'])
1305
+ : null;
1306
+ const fundingPollIntervalMs = (() => {
1307
+ const raw = process.env['JINN_FUNDING_POLL_INTERVAL_MS'];
1308
+ if (!raw)
1309
+ return 15_000;
1310
+ const n = Number.parseInt(raw, 10);
1311
+ return Number.isFinite(n) && n > 0 ? n : 15_000;
1312
+ })();
1313
+ if (isHaltedOnFunding && haltAddress && haltRequired !== null) {
1314
+ const publicClient = createJinnPublicClient(config.rpcUrl, NETWORK_CHAIN);
1315
+ const schedulePoll = () => {
1316
+ fundingPollHandle = setTimeout(async () => {
1317
+ // Guard: if the signal was already fired, stop polling.
1318
+ if (!retryBootstrapResolve)
1319
+ return;
1320
+ try {
1321
+ const balance = await publicClient.getBalance({ address: haltAddress });
1322
+ if (balance >= haltRequired) {
1323
+ console.log(`[main] Funding shortfall cleared (have ${balance}, required ${haltRequired}). ` +
1324
+ `Auto-resuming bootstrap...`);
1325
+ retryBootstrapResolve?.();
1326
+ return; // don't schedule the next poll
1327
+ }
1328
+ }
1329
+ catch (pollErr) {
1330
+ // Balance read failed — not fatal, just skip this tick.
1331
+ const msg = pollErr instanceof Error ? pollErr.message : String(pollErr);
1332
+ console.log(`[main] Funding poller balance read failed (will retry): ${msg}`);
1333
+ }
1334
+ schedulePoll(); // reschedule
1335
+ }, fundingPollIntervalMs);
1336
+ };
1337
+ schedulePoll();
1338
+ }
1339
+ try {
1340
+ await retrySignal;
1341
+ }
1342
+ finally {
1343
+ retryBootstrapResolve = null;
1344
+ retryBootstrapReject = null;
1345
+ if (fundingPollHandle !== null) {
1346
+ clearTimeout(fundingPollHandle);
1347
+ fundingPollHandle = null;
1348
+ }
1349
+ }
1350
+ console.log('[main] Retry triggered — re-running bootstrap...');
1351
+ continue; // loop back to the bootstrap() call
1352
+ }
1353
+ // If bootstrap throws an unexpected error (vs. SetupBootstrapHalted),
1354
+ // tear down the API we just started so we don't leave a dangling listener.
1355
+ await setupApiServer.close().catch(() => undefined);
1356
+ await closeCaptureReceiver();
1357
+ sharedStore.close();
1358
+ throw err;
1158
1359
  }
1159
- // If bootstrap throws (vs. emitEnvelope-exits), tear down the API we
1160
- // just started so we don't leave a dangling listener on the port.
1161
- await setupApiServer.close().catch(() => undefined);
1162
- await closeCaptureReceiver();
1163
- sharedStore.close();
1164
- throw err;
1165
1360
  }
1166
1361
  // Bootstrap completed — flip the controller into 'running' so any waiters
1167
1362
  // (future loops gated on this) unblock.
@@ -1207,35 +1402,6 @@ export async function main() {
1207
1402
  },
1208
1403
  });
1209
1404
  }
1210
- const claudeAuthRequired = configRequiresClaudeAuth(config);
1211
- if (claudeAuthRequired) {
1212
- const preflight = await checkClaudeBinary(activeClaudePath);
1213
- if (!preflight.ok) {
1214
- emitClaudeBinaryPreflightFailure(preflight.detail, activeClaudePath);
1215
- }
1216
- const authContext = detectAuthContext({ cwd: process.cwd(), configuredMode: config.runtimeMode });
1217
- const authProbe = probeClaudeAuth({
1218
- context: authContext,
1219
- cwd: process.cwd(),
1220
- claudePath: activeClaudePath,
1221
- });
1222
- if (!authProbe.authenticated) {
1223
- emitEnvelope({
1224
- code: 'invalid_invocation',
1225
- message: 'Claude is not authenticated. Complete Claude setup in the operator app, then restart the daemon.',
1226
- hint: `Detected context: ${authContext}. Run \`jinn run\` to open the app-guided setup flow.`,
1227
- exampleCli: 'jinn run',
1228
- details: {
1229
- field: 'claude_auth',
1230
- context: authContext,
1231
- authenticated: false,
1232
- },
1233
- });
1234
- }
1235
- }
1236
- else {
1237
- console.log('[main] Claude auth preflight skipped; Claude-backed harnesses are disabled.');
1238
- }
1239
1405
  const runner = new ClaudeRunner({
1240
1406
  claudePath: activeClaudePath,
1241
1407
  model: config.claudeModel,
@@ -1246,6 +1412,33 @@ export async function main() {
1246
1412
  const publicClient = createJinnPublicClient(config.rpcUrl, NETWORK_CHAIN);
1247
1413
  publicClientForLauncher = publicClient;
1248
1414
  const masterWallet = createJinnWalletClient(config.rpcUrl, NETWORK_CHAIN, masterAccount);
1415
+ // hjex.3: populate the restake callback now that mnemonic is available.
1416
+ if (config.stakingMode === 'standard' && CHAIN_CONFIG.distributorAddress) {
1417
+ const fleetStore = earningStore;
1418
+ restakeCallbackRef.current = async (serviceId) => {
1419
+ try {
1420
+ const state = await fleetStore.load(NETWORK_CHAIN);
1421
+ const svc = state.services.find(s => s.service_id === serviceId);
1422
+ if (!svc)
1423
+ return { ok: false, error: `service_not_found:${serviceId}` };
1424
+ if (!svc.staking_address)
1425
+ return { ok: false, error: 'staking_address_missing' };
1426
+ await recoverEvictedServiceFn({
1427
+ serviceDisplayIndex: Math.max(0, svc.index - 1),
1428
+ serviceId,
1429
+ stakingAddress: svc.staking_address,
1430
+ distributorAddress: CHAIN_CONFIG.distributorAddress,
1431
+ rpcUrl: config.rpcUrl,
1432
+ chain: NETWORK_CHAIN,
1433
+ mnemonic: mnemonicForMaster,
1434
+ });
1435
+ return { ok: true };
1436
+ }
1437
+ catch (err) {
1438
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
1439
+ }
1440
+ };
1441
+ }
1249
1442
  const evictionRecovery = config.stakingMode === 'standard' &&
1250
1443
  serviceId !== null &&
1251
1444
  stakingAddress &&
@@ -1298,6 +1491,11 @@ export async function main() {
1298
1491
  sharedDiscoveryApi = await buildOnchainFloor();
1299
1492
  }
1300
1493
  }
1494
+ // jinn-mono-u34i: populate the holder so the /v1/discovery/* routes
1495
+ // registered eagerly at server-start time start returning real data on
1496
+ // the panel's next refetch. Before this, the routes 404'd forever and
1497
+ // the /build page rendered "Discovery unavailable" permanently.
1498
+ discoveryApiHolder.current = sharedDiscoveryApi;
1301
1499
  const adapter = new MechAdapter({
1302
1500
  rpcUrl: config.rpcUrl,
1303
1501
  mechMarketplaceAddress: MARKETPLACE_ADDRESS,
@@ -1315,7 +1513,12 @@ export async function main() {
1315
1513
  ? {
1316
1514
  discoveryApi: sharedDiscoveryApi,
1317
1515
  solverNetManifestCids: taskDiscoveryManifestCids,
1318
- onchainFromBlock: config.network === 'testnet' ? 41_153_291 : 25_000_000,
1516
+ // No explicit `onchainFromBlock` let `MechAdapter`'s
1517
+ // `DEFAULT_TASK_DISCOVERY_FROM_BLOCK` per-chain default flow
1518
+ // through. Hardcoding here shadowed the adapter's default and
1519
+ // re-introduced the ghost-task floor every release; removing the
1520
+ // shadow makes `adapter.ts` the single source of truth. See gh
1521
+ // #300.
1319
1522
  ...(config.taskDiscoveryAllowedTaskIds?.length
1320
1523
  ? { allowedTaskIds: config.taskDiscoveryAllowedTaskIds }
1321
1524
  : {}),
@@ -1339,19 +1542,45 @@ export async function main() {
1339
1542
  // ── L1 (Sepolia / Ethereum mainnet) clients for cross-chain JINN claim loop ──
1340
1543
  // Uses the agent EOA because MockMessenger.owner is the agent on testnet.
1341
1544
  // Same key as L2; only the chain differs.
1342
- const l1ClientsForJinnClaim = JINN_MVI_CONFIG.distributor && config.ethereumRpcUrl
1545
+ const shouldWireJinnClaimL1 = shouldWireJinnClaimL1Signer({
1546
+ enabled: config.jinnClaimLoopEnabled,
1547
+ intervalMs: config.jinnClaimLoopIntervalMs,
1548
+ submissionMode: config.jinnClaimSubmissionMode,
1549
+ distributorAddress: JINN_MVI_CONFIG.distributor,
1550
+ ethereumRpcUrl: config.ethereumRpcUrl,
1551
+ });
1552
+ const l1ClientsForJinnClaim = shouldWireJinnClaimL1 && config.ethereumRpcUrl
1343
1553
  ? {
1344
1554
  public: createJinnL1PublicClient(config.ethereumRpcUrl, config.jinnL1Network),
1345
1555
  wallet: createJinnL1WalletClient(config.ethereumRpcUrl, config.jinnL1Network, privateKeyToAccount(agentPrivateKey)),
1346
1556
  }
1347
1557
  : undefined;
1348
- if (l1ClientsForJinnClaim) {
1349
- console.log(`[main] JinnClaimLoop: enabled (mode=${JINN_CLAIM_MESSENGER_MODE}, ` +
1558
+ const jinnClaimLoopConfig = buildJinnClaimLoopConfig({
1559
+ enabled: config.jinnClaimLoopEnabled,
1560
+ intervalMs: config.jinnClaimLoopIntervalMs,
1561
+ submissionMode: config.jinnClaimSubmissionMode,
1562
+ messengerMode: JINN_CLAIM_MESSENGER_MODE,
1563
+ mvi: JINN_MVI_CONFIG,
1564
+ l2Client: agentClients.publicClient,
1565
+ l2ProofClient,
1566
+ l2Wallet: agentClients.walletClient,
1567
+ l1Clients: l1ClientsForJinnClaim,
1568
+ store: earningStore,
1569
+ chain: NETWORK_CHAIN,
1570
+ optimismPortalAddress,
1571
+ disputeGameFactoryAddress,
1572
+ });
1573
+ if (jinnClaimLoopConfig) {
1574
+ console.log(`[main] JinnClaimLoop: enabled (submission=${config.jinnClaimSubmissionMode}, ` +
1575
+ `mode=${JINN_CLAIM_MESSENGER_MODE}, ` +
1350
1576
  `interval=${config.jinnClaimLoopIntervalMs}ms, distributor=${JINN_MVI_CONFIG.distributor}, ` +
1351
1577
  `emitter=${JINN_MVI_CONFIG.claimEmitter})`);
1352
1578
  }
1579
+ else if (!config.jinnClaimLoopEnabled) {
1580
+ console.log('[main] JinnClaimLoop: disabled (jinnClaimLoopEnabled=false)');
1581
+ }
1353
1582
  else {
1354
- console.log(`[main] JinnClaimLoop: disabled (JinnDistributor artifact/override or JINN_ETHEREUM_RPC_URL not set)`);
1583
+ console.log(`[main] JinnClaimLoop: disabled (missing claim-loop artifacts, interval disabled, or L1 submit wiring)`);
1355
1584
  }
1356
1585
  // ── Harness registry ─────────────────────────────────────────────────────────
1357
1586
  const solverNetRegistry = await loadSolverNets(config);
@@ -1440,10 +1669,42 @@ export async function main() {
1440
1669
  externalImpls,
1441
1670
  disabledNames: config.harnesses?.disabled,
1442
1671
  corpusEnv,
1672
+ hermesPath: config.hermesPath,
1673
+ hermesModel: config.hermesModel,
1674
+ hermesProvider: config.hermesProvider,
1675
+ hermesDoctorTimeoutMs: config.hermesDoctorTimeoutMs,
1676
+ codexPath: config.codexPath,
1677
+ codexDoctorTimeoutMs: config.codexDoctorTimeoutMs,
1443
1678
  })) {
1444
1679
  implRegistry.register(impl);
1445
1680
  }
1446
1681
  console.log(`[main] HarnessRegistry: ${implRegistry.list().map(i => i.name).join(', ')}`);
1682
+ // ── Harness readiness registry ─────────────────────────────────────────────
1683
+ // Composes per-harness isReady() probes into a cached snapshot consumed by
1684
+ // claim loops (A5) and /v1/harnesses/readiness (A3).
1685
+ //
1686
+ // The registry is constructed here, after buildHarnesses() has run, which
1687
+ // is necessarily after bootstrap (bootstrap needs the keystore). The HTTP
1688
+ // server was started before bootstrap so it could show setup progress — we
1689
+ // mount the readiness routes on the already-running app via setupApiServer.app
1690
+ // (same pattern used by registerSolverNetsEndpoints). Routes are registered
1691
+ // before the first operator request that cares about harness readiness.
1692
+ //
1693
+ // A2 carry-over: start() only schedules the 4s tick; refreshNow() is called
1694
+ // immediately so the snapshot is populated before the first claim-loop tick.
1695
+ const harnessReadinessRegistry = buildHarnessReadinessRegistry({
1696
+ harnesses: implRegistry.list(),
1697
+ config,
1698
+ });
1699
+ harnessReadinessRegistry.start();
1700
+ await harnessReadinessRegistry.refreshNow();
1701
+ // Routes were registered eagerly at startApiServer time via the holder
1702
+ // ref pattern (jinn-mono-u34i). Populate the holder now and the already-
1703
+ // mounted /v1/harnesses/readiness routes start returning real data.
1704
+ // Late-mounting via addHarnessReadinessRoutes(setupApiServer.app, ...)
1705
+ // is no longer needed and would throw on Hono's locked matcher.
1706
+ harnessReadinessRegistryHolder.current = harnessReadinessRegistry;
1707
+ console.log('[main] HarnessReadinessRegistry started; /v1/harnesses/readiness routes active.');
1447
1708
  // ── Engine deps ───────────────────────────────────────────────────────────────
1448
1709
  // Packaging deps: artifacts are always written to served_artifacts
1449
1710
  // (operator-local SQLite). In public-testnet donation mode, scrubbed artifact
@@ -1812,9 +2073,15 @@ export async function main() {
1812
2073
  nodeEndpoint: config.nodeEndpoint,
1813
2074
  creatorSafeAddress: safeAddress,
1814
2075
  corpusFactory,
2076
+ harnessReadinessRegistry,
1815
2077
  status: {
1816
2078
  earningDir: config.earningDir,
1817
2079
  rpcUrl: config.rpcUrl,
2080
+ // tJINN identity comes from the bundled JINN MVI L1 artifact
2081
+ // (`JINN_MVI_CONFIG`) — one source of truth. The Sepolia RPC endpoint
2082
+ // is read from `config.ethereumRpcUrl` via the threaded `config`.
2083
+ tjinnTokenAddress: JINN_MVI_CONFIG.jinn,
2084
+ tjinnChainId: JINN_MVI_CONFIG.l1ChainId,
1818
2085
  network: config.network,
1819
2086
  pollIntervalMs: config.pollIntervalMs,
1820
2087
  masterEthDailyEstimateWei: config.masterEthDailyEstimateWei,
@@ -1837,28 +2104,7 @@ export async function main() {
1837
2104
  distributorAddress: CHAIN_CONFIG.distributorAddress,
1838
2105
  }
1839
2106
  : undefined,
1840
- jinnClaim: l1ClientsForJinnClaim &&
1841
- JINN_MVI_CONFIG.claimEmitter &&
1842
- JINN_MVI_CONFIG.messenger &&
1843
- JINN_MVI_CONFIG.distributor &&
1844
- config.jinnClaimLoopIntervalMs > 0
1845
- ? {
1846
- intervalMs: config.jinnClaimLoopIntervalMs,
1847
- l2Client: agentClients.publicClient,
1848
- l2ProofClient,
1849
- l2Wallet: agentClients.walletClient,
1850
- l1Client: l1ClientsForJinnClaim.public,
1851
- l1Wallet: l1ClientsForJinnClaim.wallet,
1852
- store: earningStore,
1853
- chain: NETWORK_CHAIN,
1854
- claimEmitterAddress: JINN_MVI_CONFIG.claimEmitter,
1855
- distributorAddress: JINN_MVI_CONFIG.distributor,
1856
- messengerAddress: JINN_MVI_CONFIG.messenger,
1857
- messengerMode: JINN_CLAIM_MESSENGER_MODE,
1858
- optimismPortalAddress,
1859
- disputeGameFactoryAddress,
1860
- }
1861
- : undefined,
2107
+ jinnClaim: jinnClaimLoopConfig,
1862
2108
  restorationEngine: {
1863
2109
  paths: {
1864
2110
  workingDirRoot: config.engine.workingDirRoot,
@@ -1903,6 +2149,32 @@ export async function main() {
1903
2149
  safeTopupTarget: CHAIN_CONFIG.minSafeEth,
1904
2150
  }
1905
2151
  : undefined,
2152
+ // Eviction-check loop — only in standard staking mode (requires distributorAddress).
2153
+ // Running mode only: setup-halted daemons must not try to restake services that
2154
+ // haven't been staked yet (hjex.3).
2155
+ evictionCheck: config.evictionCheckIntervalMs > 0 &&
2156
+ config.stakingMode === 'standard' &&
2157
+ CHAIN_CONFIG.distributorAddress
2158
+ ? {
2159
+ intervalMs: config.evictionCheckIntervalMs,
2160
+ store: earningStore,
2161
+ chain: NETWORK_CHAIN,
2162
+ readContract: (opts) => publicClient.readContract(opts),
2163
+ recoverEvictedService: async (svc) => {
2164
+ if (!svc.service_id || !svc.staking_address)
2165
+ return;
2166
+ await recoverEvictedServiceFn({
2167
+ serviceDisplayIndex: Math.max(0, svc.index - 1),
2168
+ serviceId: svc.service_id,
2169
+ stakingAddress: svc.staking_address,
2170
+ distributorAddress: CHAIN_CONFIG.distributorAddress,
2171
+ rpcUrl: config.rpcUrl,
2172
+ chain: NETWORK_CHAIN,
2173
+ mnemonic: mnemonicForMaster,
2174
+ });
2175
+ },
2176
+ }
2177
+ : undefined,
1906
2178
  });
1907
2179
  // Write pidfile so `jinn stop` can find us.
1908
2180
  const pidPath = join(config.earningDir, 'daemon.pid');
@@ -1928,6 +2200,7 @@ export async function main() {
1928
2200
  let exitCode = 0;
1929
2201
  console.log(`\n[main] Received ${signal}, shutting down...`);
1930
2202
  try {
2203
+ harnessReadinessRegistry.stop();
1931
2204
  await daemon.stop();
1932
2205
  await setupApiServer.close().catch(() => undefined);
1933
2206
  await closeCaptureReceiver();
@@ -1994,4 +2267,32 @@ export async function main() {
1994
2267
  serviceId,
1995
2268
  };
1996
2269
  }
2270
+ // ── Harness readiness registry factory ───────────────────────────────────────
2271
+ // Exported so tests can construct a registry without booting the full daemon.
2272
+ /**
2273
+ * Builds a HarnessReadinessRegistry from the harness list returned by
2274
+ * buildHarnesses() and the operator's joinedSolverNets config block.
2275
+ *
2276
+ * Per A2 carry-over: start() only schedules the background tick; callers that
2277
+ * need the snapshot populated immediately must call refreshNow() after start().
2278
+ */
2279
+ export function buildHarnessReadinessRegistry(args) {
2280
+ const harnessesByName = {};
2281
+ for (const h of args.harnesses) {
2282
+ harnessesByName[h.name] = h;
2283
+ }
2284
+ const joinedHarnessesByCid = {};
2285
+ for (const [cid, entry] of Object.entries(args.config.joinedSolverNets ?? {})) {
2286
+ if (entry.harness) {
2287
+ joinedHarnessesByCid[cid] = {
2288
+ harnessName: entry.harness,
2289
+ roles: entry.roles,
2290
+ };
2291
+ }
2292
+ }
2293
+ return new HarnessReadinessRegistry({
2294
+ harnessesByName,
2295
+ joinedHarnessesByCid,
2296
+ });
2297
+ }
1997
2298
  //# sourceMappingURL=main.js.map