@tangle-network/agent-bench 0.3.6 → 0.3.8

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 (265) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/HARNESS.md +43 -0
  3. package/dist/adapters.js +24 -24
  4. package/dist/benchmarks/_harness.d.ts +1 -1
  5. package/dist/benchmarks/_harness.js +1 -1
  6. package/dist/benchmarks/aec-bench.js +2 -2
  7. package/dist/benchmarks/agentbench.js +2 -2
  8. package/dist/benchmarks/appworld.js +2 -2
  9. package/dist/benchmarks/bfcl.js +2 -2
  10. package/dist/benchmarks/commit0.js +2 -2
  11. package/dist/benchmarks/crag.js +2 -2
  12. package/dist/benchmarks/dabstep.js +2 -2
  13. package/dist/benchmarks/enterpriseops-gym.js +2 -2
  14. package/dist/benchmarks/finresearchbench.js +2 -2
  15. package/dist/benchmarks/humaneval.d.ts +10 -1
  16. package/dist/benchmarks/humaneval.js +5 -3
  17. package/dist/benchmarks/nomiracl.js +2 -2
  18. package/dist/benchmarks/open-rag-bench.js +2 -2
  19. package/dist/benchmarks/programbench.js +2 -2
  20. package/dist/benchmarks/ragbench.js +2 -2
  21. package/dist/benchmarks/swe-bench.js +2 -2
  22. package/dist/benchmarks/t2-ragbench.js +2 -2
  23. package/dist/benchmarks/tau-bench-shared.js +2 -2
  24. package/dist/benchmarks/tau2-bench.js +3 -3
  25. package/dist/benchmarks/tau3-banking.js +3 -3
  26. package/dist/benchmarks/terminal-bench.js +2 -2
  27. package/dist/benchmarks/toollm.js +2 -2
  28. package/dist/benchmarks/webarena-verified.js +2 -2
  29. package/dist/{chunk-CKUVRZ2T.js → chunk-3U5TXJZS.js} +2 -2
  30. package/dist/{chunk-PPYSEKFM.js → chunk-5H5XV76F.js} +73 -15
  31. package/dist/chunk-5H5XV76F.js.map +1 -0
  32. package/dist/{chunk-YCGY7UIZ.js → chunk-7GRVHU22.js} +2 -2
  33. package/dist/{chunk-Z7ML6L77.js → chunk-HWST3SED.js} +2 -2
  34. package/dist/{chunk-SYDW647C.js → chunk-IA2FBTWC.js} +2 -2
  35. package/dist/{chunk-R67DFVLO.js → chunk-IFVINJ4B.js} +2 -2
  36. package/dist/{chunk-R36V2VP7.js → chunk-IZ5M6OAC.js} +2 -2
  37. package/dist/{chunk-ODT47UAY.js → chunk-K3BQGZCT.js} +2 -2
  38. package/dist/{chunk-IFAV6KEM.js → chunk-KP5KD6EN.js} +2 -2
  39. package/dist/{chunk-ZEWMTR5M.js → chunk-MQMRLGOG.js} +2 -2
  40. package/dist/{chunk-TSWPNOYM.js → chunk-NQG5XDSB.js} +2 -2
  41. package/dist/{chunk-7WSD27QQ.js → chunk-PB64GYIG.js} +2 -2
  42. package/dist/{chunk-HBSWHQNJ.js → chunk-RCYQEFNX.js} +3 -3
  43. package/dist/{chunk-J3KDJNX2.js → chunk-RH5F53JT.js} +2 -2
  44. package/dist/{chunk-UAIOHCUK.js → chunk-SFLA7OH3.js} +3 -3
  45. package/dist/{chunk-Y6O2OCUO.js → chunk-SHM6MRRF.js} +2 -2
  46. package/dist/{chunk-KDIKRJGB.js → chunk-SHYIRB7I.js} +2 -2
  47. package/dist/{chunk-HHXFIHXC.js → chunk-SVR2LKYI.js} +2 -2
  48. package/dist/{chunk-5SBJCB6W.js → chunk-V7AEBY6U.js} +22 -22
  49. package/dist/{chunk-LRRD7NAG.js → chunk-WSKWVEQB.js} +18 -2
  50. package/dist/chunk-WSKWVEQB.js.map +1 -0
  51. package/dist/{chunk-2PVVP7GN.js → chunk-XKEFIFIC.js} +2 -2
  52. package/dist/{chunk-JRWWGMK7.js → chunk-XYA4XSNU.js} +2 -2
  53. package/dist/{chunk-X5YKXC6V.js → chunk-YSMEKBTD.js} +2 -2
  54. package/dist/{chunk-2XU6OGEN.js → chunk-Z4TZ76N7.js} +2 -2
  55. package/dist/index.js +24 -24
  56. package/package.json +6 -5
  57. package/scripts/run-package-tests.mjs +30 -8
  58. package/scripts/verify-packed-consumer.mjs +1 -1
  59. package/scripts/verify-pier-agent.mts +1 -0
  60. package/src/benchmarks/_harness.ts +20 -2
  61. package/src/benchmarks/humaneval.test.mts +122 -0
  62. package/src/benchmarks/humaneval.ts +100 -27
  63. package/src/david-attribution.mts +78 -0
  64. package/src/david-goliath.mts +149 -0
  65. package/src/hev-improve.mts +25 -6
  66. package/src/humaneval-object-ablation.mts +201 -0
  67. package/src/live-improve-campaign-mbpp.mts +641 -0
  68. package/src/live-improve-campaign.mts +500 -0
  69. package/src/mbpp-structural.mts +12 -7
  70. package/src/quant-arena/README.md +144 -0
  71. package/src/quant-arena/backtest.test.mts +135 -0
  72. package/src/quant-arena/backtest.ts +218 -0
  73. package/src/quant-arena/data.test.mts +44 -0
  74. package/src/quant-arena/data.ts +141 -0
  75. package/src/quant-arena/driver.test.mts +253 -0
  76. package/src/quant-arena/driver.ts +219 -0
  77. package/src/quant-arena/fixtures/data/PROVENANCE.md +26 -0
  78. package/src/quant-arena/fixtures/data/holdout/IDX.csv +523 -0
  79. package/src/quant-arena/fixtures/data/holdout/S01.csv +523 -0
  80. package/src/quant-arena/fixtures/data/holdout/S02.csv +523 -0
  81. package/src/quant-arena/fixtures/data/holdout/S03.csv +523 -0
  82. package/src/quant-arena/fixtures/data/holdout/S04.csv +523 -0
  83. package/src/quant-arena/fixtures/data/holdout/S05.csv +523 -0
  84. package/src/quant-arena/fixtures/data/holdout/S06.csv +523 -0
  85. package/src/quant-arena/fixtures/data/holdout/S07.csv +523 -0
  86. package/src/quant-arena/fixtures/data/holdout/S08.csv +523 -0
  87. package/src/quant-arena/fixtures/data/holdout/S09.csv +523 -0
  88. package/src/quant-arena/fixtures/data/holdout/S10.csv +523 -0
  89. package/src/quant-arena/fixtures/data/insample/IDX.csv +2087 -0
  90. package/src/quant-arena/fixtures/data/insample/S01.csv +2087 -0
  91. package/src/quant-arena/fixtures/data/insample/S02.csv +2087 -0
  92. package/src/quant-arena/fixtures/data/insample/S03.csv +2087 -0
  93. package/src/quant-arena/fixtures/data/insample/S04.csv +2087 -0
  94. package/src/quant-arena/fixtures/data/insample/S05.csv +2087 -0
  95. package/src/quant-arena/fixtures/data/insample/S06.csv +2087 -0
  96. package/src/quant-arena/fixtures/data/insample/S07.csv +2087 -0
  97. package/src/quant-arena/fixtures/data/insample/S08.csv +2087 -0
  98. package/src/quant-arena/fixtures/data/insample/S09.csv +2087 -0
  99. package/src/quant-arena/fixtures/data/insample/S10.csv +2087 -0
  100. package/src/quant-arena/fixtures/demo-campaign/cost-ledger.jsonl +16 -0
  101. package/src/quant-arena/fixtures/demo-campaign/notebook.jsonl +5 -0
  102. package/src/quant-arena/fixtures/demo-campaign/rollout-manifest.json +171 -0
  103. package/src/quant-arena/fixtures/demo-campaign/strategies/cand-001-default-author/strategy.ts +119 -0
  104. package/src/quant-arena/fixtures/demo-campaign/strategies/cand-002-default-author/strategy.ts +119 -0
  105. package/src/quant-arena/fixtures/demo-campaign/strategies/cand-003-quant-researcher/strategy.ts +105 -0
  106. package/src/quant-arena/fixtures/demo-campaign/strategies/cand-004-quant-researcher/strategy.ts +102 -0
  107. package/src/quant-arena/fixtures/demo-campaign-v2/cost-ledger.jsonl +4 -0
  108. package/src/quant-arena/fixtures/demo-campaign-v2/notebook.jsonl +2 -0
  109. package/src/quant-arena/fixtures/demo-campaign-v2/rollout-manifest.json +84 -0
  110. package/src/quant-arena/fixtures/demo-campaign-v2/strategies/cand-001-quant-researcher/strategy.ts +117 -0
  111. package/src/quant-arena/holdout-certify.mts +206 -0
  112. package/src/quant-arena/holdout-certify.test.mts +82 -0
  113. package/src/quant-arena/leak-audit.test.mts +79 -0
  114. package/src/quant-arena/leak-audit.ts +95 -0
  115. package/src/quant-arena/make-fixtures.mts +161 -0
  116. package/src/quant-arena/multiplicity.test.mts +68 -0
  117. package/src/quant-arena/multiplicity.ts +87 -0
  118. package/src/quant-arena/nautilus-certify.ts +31 -0
  119. package/src/quant-arena/oms.ts +90 -0
  120. package/src/quant-arena/profiles/quant-researcher.profile.json +7 -0
  121. package/src/quant-arena/python/pyproject.toml +8 -0
  122. package/src/quant-arena/python/uv.lock +1297 -0
  123. package/src/quant-arena/python/vbt-worker.py +192 -0
  124. package/src/quant-arena/quant-loop.mts +813 -0
  125. package/src/quant-arena/quant-loop.test.mts +75 -0
  126. package/src/quant-arena/strategies/buy-hold-index/strategy.ts +11 -0
  127. package/src/quant-arena/strategies/equal-weight/strategy.ts +20 -0
  128. package/src/quant-arena/strategies/sma-crossover/strategy.ts +42 -0
  129. package/src/quant-arena/types.ts +133 -0
  130. package/src/quant-arena/vbt-client.ts +321 -0
  131. package/src/quant-arena/vbt-parity.test.mts +183 -0
  132. package/src/quant-arena/windows.test.mts +45 -0
  133. package/src/quant-arena/windows.ts +54 -0
  134. package/src/rollout-ledger/backfill-swe-arena.mts +606 -0
  135. package/src/rollout-ledger/backfill-swe-arena.test.mts +338 -0
  136. package/src/rollout-ledger/settle-capture.mts +442 -0
  137. package/src/rollout-ledger/settle-capture.test.mts +270 -0
  138. package/src/stream-observe.py +45 -0
  139. package/src/stream-observe.tpl.html +247 -0
  140. package/src/supervisor-arena.mts +816 -0
  141. package/src/swe-arena/activation.mts +228 -0
  142. package/src/swe-arena/activation.test.mts +303 -0
  143. package/src/swe-arena/analyze.ts +211 -0
  144. package/src/swe-arena/arms.ts +804 -0
  145. package/src/swe-arena/bootstrap-meta.mts +188 -0
  146. package/src/swe-arena/bootstrap-meta.test.mts +51 -0
  147. package/src/swe-arena/briefing.mts +217 -0
  148. package/src/swe-arena/briefing.test.mts +178 -0
  149. package/src/swe-arena/calibrate.ts +217 -0
  150. package/src/swe-arena/capabilities.mts +76 -0
  151. package/src/swe-arena/capabilities.test.mts +57 -0
  152. package/src/swe-arena/capacity.ts +194 -0
  153. package/src/swe-arena/cell-evidence.mts +437 -0
  154. package/src/swe-arena/cell-evidence.test.mts +248 -0
  155. package/src/swe-arena/diagnosis-ensemble.test.mts +210 -0
  156. package/src/swe-arena/diagnosis-ensemble.ts +520 -0
  157. package/src/swe-arena/execution.test.mts +1170 -0
  158. package/src/swe-arena/factory-command-container.ts +284 -0
  159. package/src/swe-arena/factory-judge-child.mts +228 -0
  160. package/src/swe-arena/factory.test.mts +643 -0
  161. package/src/swe-arena/fixtures/analyze.py +80 -0
  162. package/src/swe-arena/fixtures/excludes.txt +8 -0
  163. package/src/swe-arena/fixtures/factory/agent-eval-309/calibration.md +51 -0
  164. package/src/swe-arena/fixtures/factory/agent-eval-309/manifest.json +29 -0
  165. package/src/swe-arena/fixtures/factory/agent-eval-309/spec.md +64 -0
  166. package/src/swe-arena/fixtures/factory/agent-runtime-232/calibration.md +48 -0
  167. package/src/swe-arena/fixtures/factory/agent-runtime-232/manifest.json +29 -0
  168. package/src/swe-arena/fixtures/factory/agent-runtime-232/spec.md +48 -0
  169. package/src/swe-arena/fixtures/factory/loops-28/calibration.md +47 -0
  170. package/src/swe-arena/fixtures/factory/loops-28/manifest.json +30 -0
  171. package/src/swe-arena/fixtures/factory/loops-28/spec.md +50 -0
  172. package/src/swe-arena/fixtures/gen1-salvage/README.md +45 -0
  173. package/src/swe-arena/fixtures/gen1-salvage/cand0-e6d7361.diff +116 -0
  174. package/src/swe-arena/fixtures/gen1-salvage/cand1-76a8590.diff +293 -0
  175. package/src/swe-arena/fixtures/holdout-preregister.log +12 -0
  176. package/src/swe-arena/fixtures/holdout.json +44 -0
  177. package/src/swe-arena/fixtures/instances.json +146 -0
  178. package/src/swe-arena/fixtures/ledger.jsonl +12 -0
  179. package/src/swe-arena/fixtures/patches/pallets__flask-5014.solo.patch +36 -0
  180. package/src/swe-arena/fixtures/patches/pydata__xarray-4687.sup.patch +33 -0
  181. package/src/swe-arena/fixtures/rejudge.jsonl +15 -0
  182. package/src/swe-arena/fixtures/rematch.jsonl +3 -0
  183. package/src/swe-arena/fixtures/rematch2.jsonl +3 -0
  184. package/src/swe-arena/fixtures/rematch3.jsonl +3 -0
  185. package/src/swe-arena/fixtures/run-report/README.md +43 -0
  186. package/src/swe-arena/fixtures/run-report/factory-agent-eval-309-FSUP0.json +173 -0
  187. package/src/swe-arena/fixtures/run-report/factory-agent-eval-309-FSUP0.md +100 -0
  188. package/src/swe-arena/fixtures/run-report/gen3-rollup.json +551 -0
  189. package/src/swe-arena/fixtures/run-report/gen3-rollup.md +64 -0
  190. package/src/swe-arena/fixtures/sup-journal-true.json +19 -0
  191. package/src/swe-arena/fixtures/verify/astropy__astropy-13033.sh +48 -0
  192. package/src/swe-arena/fixtures/verify/django__django-11532.sh +50 -0
  193. package/src/swe-arena/fixtures/verify/matplotlib__matplotlib-20826.sh +76 -0
  194. package/src/swe-arena/fixtures/verify/pydata__xarray-4687.sh +44 -0
  195. package/src/swe-arena/fixtures/verify/pytest-dev__pytest-6197.sh +32 -0
  196. package/src/swe-arena/fixtures/verify/sphinx-doc__sphinx-9658.sh +51 -0
  197. package/src/swe-arena/fixtures/worker-tokens.json +42 -0
  198. package/src/swe-arena/fixtures.ts +237 -0
  199. package/src/swe-arena/gepa-seat.mts +583 -0
  200. package/src/swe-arena/gepa-seat.test.mts +635 -0
  201. package/src/swe-arena/holdout-certify.mts +408 -0
  202. package/src/swe-arena/holdout-certify.test.mts +160 -0
  203. package/src/swe-arena/judge-child.mts +37 -0
  204. package/src/swe-arena/ledger-orphans.mts +77 -0
  205. package/src/swe-arena/ledger-orphans.test.mts +147 -0
  206. package/src/swe-arena/lineage-record.mts +164 -0
  207. package/src/swe-arena/lineage-record.test.mts +115 -0
  208. package/src/swe-arena/manifest.mts +293 -0
  209. package/src/swe-arena/manifest.test.mts +169 -0
  210. package/src/swe-arena/materialize.ts +142 -0
  211. package/src/swe-arena/outer-loop.mts +2795 -0
  212. package/src/swe-arena/outer-loop.test.mts +696 -0
  213. package/src/swe-arena/parity.test.mts +87 -0
  214. package/src/swe-arena/premeasured-from-cells.mts +281 -0
  215. package/src/swe-arena/premeasured-from-cells.test.mts +180 -0
  216. package/src/swe-arena/proc.test.mts +174 -0
  217. package/src/swe-arena/proc.ts +260 -0
  218. package/src/swe-arena/profiles/default-author.profile.json +4 -0
  219. package/src/swe-arena/proposer-fanout.mts +770 -0
  220. package/src/swe-arena/proposer-fanout.test.mts +619 -0
  221. package/src/swe-arena/proposer-provenance.mts +177 -0
  222. package/src/swe-arena/proposer-provenance.test.mts +106 -0
  223. package/src/swe-arena/reconcile.ts +0 -0
  224. package/src/swe-arena/replay.mts +183 -0
  225. package/src/swe-arena/replay.test.mts +300 -0
  226. package/src/swe-arena/run-experiment.mts +727 -0
  227. package/src/swe-arena/run-report.mts +75 -0
  228. package/src/swe-arena/run-supervisor.mjs +297 -0
  229. package/src/swe-arena/run-supervisor.test.mts +500 -0
  230. package/src/swe-arena/score-split.mts +140 -0
  231. package/src/swe-arena/score-split.test.mts +123 -0
  232. package/src/swe-arena/serialized-judge.ts +414 -0
  233. package/src/swe-arena/types.ts +218 -0
  234. package/src/swe-code-improve.mts +328 -0
  235. package/src/swe-emit-patch.mts +104 -0
  236. package/src/swe-improve.mts +232 -0
  237. package/src/swe-jail.ts +2 -2
  238. package/src/swe-local-proof.mts +169 -0
  239. package/src/swe-repro-calibrate.mts +446 -0
  240. package/src/swe-stream.mts +1497 -0
  241. package/src/swe-structural.mts +245 -837
  242. package/dist/chunk-LRRD7NAG.js.map +0 -1
  243. package/dist/chunk-PPYSEKFM.js.map +0 -1
  244. /package/dist/{chunk-CKUVRZ2T.js.map → chunk-3U5TXJZS.js.map} +0 -0
  245. /package/dist/{chunk-YCGY7UIZ.js.map → chunk-7GRVHU22.js.map} +0 -0
  246. /package/dist/{chunk-Z7ML6L77.js.map → chunk-HWST3SED.js.map} +0 -0
  247. /package/dist/{chunk-SYDW647C.js.map → chunk-IA2FBTWC.js.map} +0 -0
  248. /package/dist/{chunk-R67DFVLO.js.map → chunk-IFVINJ4B.js.map} +0 -0
  249. /package/dist/{chunk-R36V2VP7.js.map → chunk-IZ5M6OAC.js.map} +0 -0
  250. /package/dist/{chunk-ODT47UAY.js.map → chunk-K3BQGZCT.js.map} +0 -0
  251. /package/dist/{chunk-IFAV6KEM.js.map → chunk-KP5KD6EN.js.map} +0 -0
  252. /package/dist/{chunk-ZEWMTR5M.js.map → chunk-MQMRLGOG.js.map} +0 -0
  253. /package/dist/{chunk-TSWPNOYM.js.map → chunk-NQG5XDSB.js.map} +0 -0
  254. /package/dist/{chunk-7WSD27QQ.js.map → chunk-PB64GYIG.js.map} +0 -0
  255. /package/dist/{chunk-HBSWHQNJ.js.map → chunk-RCYQEFNX.js.map} +0 -0
  256. /package/dist/{chunk-J3KDJNX2.js.map → chunk-RH5F53JT.js.map} +0 -0
  257. /package/dist/{chunk-UAIOHCUK.js.map → chunk-SFLA7OH3.js.map} +0 -0
  258. /package/dist/{chunk-Y6O2OCUO.js.map → chunk-SHM6MRRF.js.map} +0 -0
  259. /package/dist/{chunk-KDIKRJGB.js.map → chunk-SHYIRB7I.js.map} +0 -0
  260. /package/dist/{chunk-HHXFIHXC.js.map → chunk-SVR2LKYI.js.map} +0 -0
  261. /package/dist/{chunk-5SBJCB6W.js.map → chunk-V7AEBY6U.js.map} +0 -0
  262. /package/dist/{chunk-2PVVP7GN.js.map → chunk-XKEFIFIC.js.map} +0 -0
  263. /package/dist/{chunk-JRWWGMK7.js.map → chunk-XYA4XSNU.js.map} +0 -0
  264. /package/dist/{chunk-X5YKXC6V.js.map → chunk-YSMEKBTD.js.map} +0 -0
  265. /package/dist/{chunk-2XU6OGEN.js.map → chunk-Z4TZ76N7.js.map} +0 -0
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env bash
2
+ # Self-repro verify for django__django-11532 — AUTHORED FROM THE PROBLEM
3
+ # STATEMENT ONLY (honesty firewall: gold patch never read by the author; it is
4
+ # applied mechanically by calibration). Exit 0 = fixed, nonzero = bug present.
5
+ #
6
+ # Issue: email messages crash with UnicodeEncodeError when the hostname
7
+ # (DNS_NAME) is non-ASCII and the email encoding is non-unicode
8
+ # (iso-8859-1); the domain should be converted to punycode. The issue's own
9
+ # acceptance test: with DNS_NAME patched to "漢字", the Message-ID header must
10
+ # contain the punycode form 'xn--p8s937b'.
11
+ set -euo pipefail
12
+ IMG="swebench/sweb.eval.x86_64.django_1776_django-11532:latest"
13
+ WS="${1:-$PWD}"
14
+ TMP="$(mktemp -d)"
15
+ trap 'rm -rf "$TMP"' EXIT
16
+ cat > "$TMP/repro.py" <<'PY'
17
+ import sys
18
+ from unittest.mock import patch
19
+
20
+ from django.conf import settings
21
+
22
+ settings.configure()
23
+
24
+ from django.core.mail import EmailMessage
25
+
26
+ # Simulate the issue's exact trigger — "Set hostname to non iso-8859-1 value
27
+ # (i.e. hostname 正宗)" — at its true source: DNS_NAME lazily derives the
28
+ # domain from socket.getfqdn() on first use, so patching getfqdn BEFORE the
29
+ # first message build runs the full production path through whatever
30
+ # conversion the fix adds.
31
+ try:
32
+ with patch('socket.getfqdn', return_value='漢字'):
33
+ email = EmailMessage('subject', '', 'from@example.com', ['to@example.com'])
34
+ email.encoding = 'iso-8859-1'
35
+ message = email.message()
36
+ msgid = str(message['Message-ID'])
37
+ print("Message-ID:", msgid)
38
+ if 'xn--p8s937b' in msgid:
39
+ print("VERIFY PASS: non-ASCII hostname converted to punycode in Message-ID")
40
+ sys.exit(0)
41
+ print("VERIFY FAIL: Message-ID does not contain the punycode domain")
42
+ sys.exit(1)
43
+ except UnicodeEncodeError as e:
44
+ print("VERIFY FAIL: UnicodeEncodeError (bug present):", e)
45
+ sys.exit(1)
46
+ PY
47
+ exec timeout -k 10 240 docker run --rm --network none \
48
+ -v "$WS":/testbed:ro -v "$TMP":/repro:ro -w /testbed \
49
+ -e PYTHONDONTWRITEBYTECODE=1 \
50
+ "$IMG" bash -lc 'source /opt/miniconda3/etc/profile.d/conda.sh && conda activate testbed && cd /testbed && timeout -s KILL 180 env PYTHONPATH=/testbed python /repro/repro.py'
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env bash
2
+ # Self-repro verify for matplotlib__matplotlib-20826 — AUTHORED FROM THE
3
+ # PROBLEM STATEMENT ONLY (honesty firewall: gold patch never read by the
4
+ # author; it is applied mechanically by calibration). Exit 0 = fixed,
5
+ # nonzero = bug present.
6
+ #
7
+ # Issue: on shared axes (plt.subplots(2, 2, sharex=True, sharey=True)),
8
+ # ax.clear() un-hides tick labels that sharing should hide and adds extra
9
+ # top/right ticks. The problem statement's own control: with the clear() call
10
+ # removed, the plot is identical to the correct output. So the check is a
11
+ # paired comparison — per-subplot tick/label visibility state must be
12
+ # IDENTICAL between a cleared and an uncleared figure.
13
+ set -euo pipefail
14
+ IMG="swebench/sweb.eval.x86_64.matplotlib_1776_matplotlib-20826:latest"
15
+ WS="${1:-$PWD}"
16
+ TMP="$(mktemp -d)"
17
+ trap 'rm -rf "$TMP"' EXIT
18
+ cat > "$TMP/repro.py" <<'PY'
19
+ import sys
20
+
21
+ import matplotlib
22
+ matplotlib.use('Agg')
23
+ import matplotlib.pyplot as plt
24
+ import numpy as np
25
+
26
+ x = np.arange(0.0, 2 * np.pi, 0.01)
27
+ y = np.sin(x)
28
+
29
+
30
+ def make(clear):
31
+ fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
32
+ for ax in axes.flatten():
33
+ if clear:
34
+ ax.clear()
35
+ ax.plot(x, y)
36
+ fig.canvas.draw()
37
+ return fig, axes
38
+
39
+
40
+ def tick_state(ax):
41
+ def axis_state(axis):
42
+ return [
43
+ (
44
+ bool(t.tick1line.get_visible()),
45
+ bool(t.tick2line.get_visible()),
46
+ bool(t.label1.get_visible()),
47
+ bool(t.label2.get_visible()),
48
+ )
49
+ for t in axis.get_major_ticks()
50
+ ]
51
+ return {'x': axis_state(ax.xaxis), 'y': axis_state(ax.yaxis)}
52
+
53
+
54
+ fig_ref, axes_ref = make(clear=False)
55
+ fig_test, axes_test = make(clear=True)
56
+
57
+ mismatches = []
58
+ for (i, j) in [(0, 0), (0, 1), (1, 0), (1, 1)]:
59
+ ref = tick_state(axes_ref[i][j])
60
+ test = tick_state(axes_test[i][j])
61
+ if ref != test:
62
+ mismatches.append((i, j, ref, test))
63
+
64
+ if mismatches:
65
+ for i, j, ref, test in mismatches:
66
+ print(f"VERIFY FAIL: axes[{i}][{j}] tick/label visibility differs after clear()")
67
+ print(" without clear:", ref)
68
+ print(" with clear: ", test)
69
+ sys.exit(1)
70
+ print("VERIFY PASS: clear() preserves shared-axis tick/label visibility")
71
+ sys.exit(0)
72
+ PY
73
+ exec timeout -k 10 240 docker run --rm --network none \
74
+ -v "$WS":/testbed:ro -v "$TMP":/repro:ro -w /testbed \
75
+ -e PYTHONDONTWRITEBYTECODE=1 \
76
+ "$IMG" bash -lc 'source /opt/miniconda3/etc/profile.d/conda.sh && conda activate testbed && cd /testbed && timeout -s KILL 180 env PYTHONPATH=/testbed python /repro/repro.py'
@@ -0,0 +1,44 @@
1
+ set -euo pipefail
2
+ IMG="swebench/sweb.eval.x86_64.pydata_1776_xarray-4687:latest"
3
+ WS="${1:-$PWD}"
4
+ TMP="$(mktemp -d)"
5
+ trap 'rm -rf "$TMP"' EXIT
6
+ cat > "$TMP/repro.py" <<'PY'
7
+ import sys
8
+
9
+ import xarray as xr
10
+
11
+ # Issue: xr.where drops the attributes of its DataArray argument. Expected
12
+ # behavior per the report: "Attributes should be preserved or at least there
13
+ # should be a choice (e.g. ... keep_attrs=True)". Accept either design: attrs
14
+ # preserved on a plain call (from whichever DataArray argument carries them),
15
+ # or preserved when explicitly requested via keep_attrs=True. At the buggy
16
+ # base ALL variants drop attrs (and keep_attrs is not accepted), so this
17
+ # fails; a fix satisfying the issue makes at least one variant preserve them.
18
+ da = xr.DataArray(1)
19
+ da.attrs['foo'] = 'bar'
20
+
21
+ def attempts():
22
+ yield 'default, attrs on y', lambda: xr.where(da == 0, -1, da)
23
+ yield 'default, attrs on x', lambda: xr.where(da == 1, da, -1)
24
+ yield 'keep_attrs=True, attrs on y', lambda: xr.where(da == 0, -1, da, keep_attrs=True)
25
+ yield 'keep_attrs=True, attrs on x', lambda: xr.where(da == 1, da, -1, keep_attrs=True)
26
+
27
+ for label, call in attempts():
28
+ try:
29
+ res = call()
30
+ except TypeError as err:
31
+ print(f"variant skipped ({label}): {err}")
32
+ continue
33
+ if res.attrs.get('foo') == 'bar':
34
+ print(f"VERIFY PASS: xr.where preserves DataArray attributes ({label})")
35
+ sys.exit(0)
36
+ print(f"variant dropped attrs ({label}): got {dict(res.attrs)!r}")
37
+
38
+ print("VERIFY FAIL: no xr.where invocation preserves DataArray attributes")
39
+ sys.exit(1)
40
+ PY
41
+ exec timeout -k 10 240 docker run --rm --network none \
42
+ -v "$WS":/testbed:ro -v "$TMP":/repro:ro -w /testbed \
43
+ -e PYTHONDONTWRITEBYTECODE=1 \
44
+ "$IMG" bash -lc 'source /opt/miniconda3/etc/profile.d/conda.sh && conda activate testbed && cd /testbed && timeout -s KILL 180 env PYTHONPATH=/testbed python /repro/repro.py'
@@ -0,0 +1,32 @@
1
+ set -euo pipefail
2
+ IMG="swebench/sweb.eval.x86_64.pytest-dev_1776_pytest-6197:latest"
3
+ WS="${1:-$PWD}"
4
+ TMP="$(mktemp -d)"
5
+ trap 'rm -rf "$TMP"' EXIT
6
+ cat > "$TMP/repro.sh" <<'SH'
7
+ set -u
8
+ # Issue repro: a non-test package __init__.py under rootdir must NOT be
9
+ # imported during collection. At the regressed base, `pytest` errors out
10
+ # collecting foobar/__init__.py (assert False) and exits nonzero.
11
+ PROJ="$(mktemp -d)"
12
+ cd "$PROJ"
13
+ mkdir foobar
14
+ echo 'assert False' > foobar/__init__.py
15
+ cat > test_foo.py <<'EOF'
16
+ def test_foo():
17
+ assert True
18
+ EOF
19
+ # pytest 5.2.x is a src layout; put the workspace checkout first on the path.
20
+ PYTHONPATH=/testbed/src python -m pytest -p no:cacheprovider
21
+ rc=$?
22
+ if [ "$rc" -ne 0 ]; then
23
+ echo "VERIFY FAIL: pytest collected/imported foobar/__init__.py (rc=$rc)"
24
+ exit 1
25
+ fi
26
+ echo "VERIFY PASS: pytest ran the test without touching the stray __init__.py"
27
+ exit 0
28
+ SH
29
+ exec timeout -k 10 240 docker run --rm --network none \
30
+ -v "$WS":/testbed:ro -v "$TMP":/repro:ro -w /testbed \
31
+ -e PYTHONDONTWRITEBYTECODE=1 \
32
+ "$IMG" bash -lc 'source /opt/miniconda3/etc/profile.d/conda.sh && conda activate testbed && timeout -s KILL 180 bash /repro/repro.sh'
@@ -0,0 +1,51 @@
1
+ set -euo pipefail
2
+ IMG="swebench/sweb.eval.x86_64.sphinx-doc_1776_sphinx-9658:latest"
3
+ WS="${1:-$PWD}"
4
+ TMP="$(mktemp -d)"
5
+ trap 'rm -rf "$TMP"' EXIT
6
+ mkdir -p "$TMP/proj"
7
+ cat > "$TMP/proj/conf.py" <<'PY'
8
+ import os
9
+ import sys
10
+
11
+ sys.path.insert(0, os.path.abspath('.'))
12
+ extensions = ['sphinx.ext.autodoc']
13
+ # The issue: a class inheriting from a MOCKED base is documented with a
14
+ # truncated "Bases" entry ("mocklib.nn." instead of "mocklib.nn.Module").
15
+ autodoc_mock_imports = ['mocklib']
16
+ PY
17
+ cat > "$TMP/proj/mymod.py" <<'PY'
18
+ import mocklib
19
+
20
+
21
+ class DeepKernel(mocklib.nn.Module):
22
+ """A kernel inheriting a mocked torch-style base class."""
23
+ PY
24
+ cat > "$TMP/proj/index.rst" <<'RST'
25
+ Test
26
+ ====
27
+
28
+ .. autoclass:: mymod.DeepKernel
29
+ :show-inheritance:
30
+ RST
31
+ cat > "$TMP/repro.sh" <<'SH'
32
+ set -u
33
+ PROJ="$(mktemp -d)"
34
+ cp /repro/proj/* "$PROJ"/
35
+ OUT="$(mktemp -d)"
36
+ PYTHONPATH=/testbed python -m sphinx -b text -q "$PROJ" "$OUT" || {
37
+ echo "VERIFY FAIL: sphinx build errored"
38
+ exit 1
39
+ }
40
+ cat "$OUT/index.txt"
41
+ if grep -q 'mocklib\.nn\.Module' "$OUT/index.txt"; then
42
+ echo "VERIFY PASS: mocked base class documented as mocklib.nn.Module"
43
+ exit 0
44
+ fi
45
+ echo "VERIFY FAIL: Bases entry does not name mocklib.nn.Module (mocked base truncated)"
46
+ exit 1
47
+ SH
48
+ exec timeout -k 10 240 docker run --rm --network none \
49
+ -v "$WS":/testbed:ro -v "$TMP":/repro:ro -w /testbed \
50
+ -e PYTHONDONTWRITEBYTECODE=1 \
51
+ "$IMG" bash -lc 'source /opt/miniconda3/etc/profile.d/conda.sh && conda activate testbed && timeout -s KILL 180 bash /repro/repro.sh'
@@ -0,0 +1,42 @@
1
+ {
2
+ "astropy__astropy-13033": {
3
+ "worker_sessions": 3,
4
+ "worker_tok": 180000
5
+ },
6
+ "django__django-11532": {
7
+ "worker_sessions": 4,
8
+ "worker_tok": 287038
9
+ },
10
+ "matplotlib__matplotlib-20826": {
11
+ "worker_sessions": 3,
12
+ "worker_tok": 242121
13
+ },
14
+ "pallets__flask-5014": {
15
+ "worker_sessions": 1,
16
+ "worker_tok": 46737
17
+ },
18
+ "psf__requests-1766": {
19
+ "worker_sessions": 2,
20
+ "worker_tok": 67541
21
+ },
22
+ "psf__requests-2317": {
23
+ "worker_sessions": 1,
24
+ "worker_tok": 57555
25
+ },
26
+ "psf__requests-2931": {
27
+ "worker_sessions": 2,
28
+ "worker_tok": 124545
29
+ },
30
+ "pydata__xarray-4687": {
31
+ "worker_sessions": 1,
32
+ "worker_tok": 64243
33
+ },
34
+ "sympy__sympy-14976": {
35
+ "worker_sessions": 1,
36
+ "worker_tok": 55937
37
+ },
38
+ "sympy__sympy-23534": {
39
+ "worker_sessions": 1,
40
+ "worker_tok": 36119
41
+ }
42
+ }
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Pinned fixture loaders. All artifacts live under `./fixtures/` (copied
3
+ * from the live experiment's scratchpad on 2026-07-15 so the replay survives
4
+ * scratchpad deletion). Loaders fail loud on shape drift — a silent default
5
+ * here would let the pinned reproduction pass against corrupted fixtures.
6
+ */
7
+
8
+ import { readdirSync, readFileSync } from 'node:fs'
9
+ import { join } from 'node:path'
10
+ import { fileURLToPath } from 'node:url'
11
+ import type {
12
+ FactoryInstance,
13
+ HoldoutEntry,
14
+ HoldoutRegistry,
15
+ LedgerRow,
16
+ RejudgeRow,
17
+ RematchRow,
18
+ WorkerTokens,
19
+ } from './types'
20
+
21
+ const fixturePath = (name: string): string =>
22
+ fileURLToPath(new URL(`./fixtures/${name}`, import.meta.url))
23
+
24
+ export function readFixture(name: string): string {
25
+ return readFileSync(fixturePath(name), 'utf8')
26
+ }
27
+
28
+ function parseJsonl<T>(name: string): T[] {
29
+ return readFixture(name)
30
+ .split('\n')
31
+ .filter((l) => l.trim().length > 0)
32
+ .map((l, i) => {
33
+ try {
34
+ return JSON.parse(l) as T
35
+ } catch (err) {
36
+ throw new Error(`${name}:${i + 1}: invalid JSON — ${(err as Error).message}`)
37
+ }
38
+ })
39
+ }
40
+
41
+ export function loadLedger(): LedgerRow[] {
42
+ const rows = parseJsonl<LedgerRow>('ledger.jsonl')
43
+ for (const r of rows) {
44
+ if (typeof r.iid !== 'string' || typeof r.solo_resolved !== 'boolean') {
45
+ throw new Error(`ledger.jsonl: malformed row ${JSON.stringify(r).slice(0, 80)}`)
46
+ }
47
+ }
48
+ return rows
49
+ }
50
+
51
+ export function loadRejudge(): RejudgeRow[] {
52
+ const rows = parseJsonl<RejudgeRow>('rejudge.jsonl')
53
+ for (const r of rows) {
54
+ if (typeof r.iid !== 'string' || typeof r.tag !== 'string') {
55
+ throw new Error(`rejudge.jsonl: malformed row ${JSON.stringify(r).slice(0, 80)}`)
56
+ }
57
+ }
58
+ return rows
59
+ }
60
+
61
+ /** Evolution rounds in order: SUP2, SUP3, SUP4. */
62
+ export function loadRematchRounds(): RematchRow[][] {
63
+ return ['rematch.jsonl', 'rematch2.jsonl', 'rematch3.jsonl'].map((f) => parseJsonl<RematchRow>(f))
64
+ }
65
+
66
+ export function loadHoldout(): HoldoutRegistry {
67
+ const entries = JSON.parse(readFixture('holdout.json')) as HoldoutEntry[]
68
+ if (!Array.isArray(entries) || entries.length === 0) {
69
+ throw new Error('holdout.json: expected a non-empty array')
70
+ }
71
+ const commits = new Set(entries.map((e) => e.selected_at_commit))
72
+ if (commits.size !== 1) {
73
+ throw new Error(`holdout.json: expected one selection commit, got ${[...commits].join(', ')}`)
74
+ }
75
+ return { entries, selectedAtCommit: entries[0].selected_at_commit }
76
+ }
77
+
78
+ export function loadPreregisterLog(): string[] {
79
+ return readFixture('holdout-preregister.log')
80
+ .split('\n')
81
+ .filter((l) => l.trim().length > 0)
82
+ }
83
+
84
+ // ---------------------------------------------------------------------------
85
+ // Factory-bench instance source (manifest dirs, one per harvested PR).
86
+ // The 3 calibrated pilots ship under ./fixtures/factory/; any directory with
87
+ // the same layout (manifest.json + spec.md) loads identically.
88
+ // ---------------------------------------------------------------------------
89
+
90
+ /** Default shipped instance root: `./fixtures/factory`. */
91
+ export const FACTORY_INSTANCES_DIR = fixturePath('factory')
92
+
93
+ /**
94
+ * A FactoryInstance plus what the runner needs beyond the raw manifest: its
95
+ * directory (the judge child re-loads it by path), the spec text, and the
96
+ * calibrated judge-test denominator parsed from `resolved_criterion` — kept
97
+ * OUT of vitest's reported total so a judge file that fails to collect still
98
+ * scores against the full calibrated count instead of shrinking the divisor.
99
+ */
100
+ export interface LoadedFactoryInstance extends FactoryInstance {
101
+ dir: string
102
+ spec: string
103
+ judgeTestTotal: number
104
+ }
105
+
106
+ const SHA_RE = /^[0-9a-f]{40}$/
107
+ const IMAGE_DIGEST_RE = /^.+@sha256:[0-9a-f]{64}$/
108
+
109
+ function requireStringArray(dir: string, field: string, v: unknown, minLen: number): string[] {
110
+ if (!Array.isArray(v) || v.length < minLen || v.some((x) => typeof x !== 'string' || x.length === 0)) {
111
+ throw new Error(`${dir}/manifest.json: ${field} must be a string[] with ≥${minLen} non-empty entries`)
112
+ }
113
+ return v as string[]
114
+ }
115
+
116
+ /** Load + validate one instance dir (fail-loud on any shape drift). */
117
+ export function loadFactoryInstance(dir: string): LoadedFactoryInstance {
118
+ const manifestPath = join(dir, 'manifest.json')
119
+ let raw: unknown
120
+ try {
121
+ raw = JSON.parse(readFileSync(manifestPath, 'utf8'))
122
+ } catch (err) {
123
+ throw new Error(`${manifestPath}: unreadable or invalid JSON — ${(err as Error).message}`)
124
+ }
125
+ const m = raw as Record<string, unknown>
126
+ for (const field of [
127
+ 'id',
128
+ 'repo',
129
+ 'repo_local_mirror',
130
+ 'base_commit',
131
+ 'judge_ref',
132
+ 'spec_md',
133
+ 'command_image',
134
+ 'resolved_criterion',
135
+ ] as const) {
136
+ if (typeof m[field] !== 'string' || (m[field] as string).length === 0) {
137
+ throw new Error(`${manifestPath}: missing or empty required string field '${field}'`)
138
+ }
139
+ }
140
+ if (!(m.id as string).startsWith('factory.')) {
141
+ throw new Error(`${manifestPath}: id '${m.id as string}' must start with 'factory.'`)
142
+ }
143
+ for (const field of ['base_commit', 'judge_ref'] as const) {
144
+ if (!SHA_RE.test(m[field] as string)) {
145
+ throw new Error(`${manifestPath}: ${field} '${m[field] as string}' is not a full 40-hex sha`)
146
+ }
147
+ }
148
+ if (!IMAGE_DIGEST_RE.test(m.command_image as string)) {
149
+ throw new Error(
150
+ `${manifestPath}: command_image must be pinned as '<image>@sha256:<64 hex>'`,
151
+ )
152
+ }
153
+ const judge_tests = requireStringArray(dir, 'judge_tests', m.judge_tests, 1)
154
+ const excluded_tests = requireStringArray(dir, 'excluded_tests', m.excluded_tests ?? [], 0)
155
+ const setup_cmds = requireStringArray(dir, 'setup_cmds', m.setup_cmds ?? [], 0)
156
+ const judge_cmds = requireStringArray(dir, 'judge_cmds', m.judge_cmds, 1)
157
+ if (typeof m.timeout_s !== 'number' || !Number.isFinite(m.timeout_s) || m.timeout_s <= 0) {
158
+ throw new Error(`${manifestPath}: timeout_s must be a positive number`)
159
+ }
160
+ const totalMatch = /passed\s*\/\s*(\d+)/.exec(m.resolved_criterion as string)
161
+ const judgeTestTotal = totalMatch ? Number(totalMatch[1]) : 0
162
+ if (judgeTestTotal <= 0) {
163
+ throw new Error(
164
+ `${manifestPath}: resolved_criterion '${m.resolved_criterion as string}' must state the calibrated ` +
165
+ `denominator as 'passed/<N>' — partial credit needs a stable divisor`,
166
+ )
167
+ }
168
+ const specPath = join(dir, m.spec_md as string)
169
+ let spec: string
170
+ try {
171
+ spec = readFileSync(specPath, 'utf8')
172
+ } catch (err) {
173
+ throw new Error(`${specPath}: unreadable spec — ${(err as Error).message}`)
174
+ }
175
+ if (spec.trim().length === 0) throw new Error(`${specPath}: spec is empty`)
176
+ return {
177
+ id: m.id as string,
178
+ repo: m.repo as string,
179
+ repo_local_mirror: m.repo_local_mirror as string,
180
+ base_commit: m.base_commit as string,
181
+ judge_ref: m.judge_ref as string,
182
+ spec_md: m.spec_md as string,
183
+ judge_tests,
184
+ excluded_tests,
185
+ command_image: m.command_image as string,
186
+ setup_cmds,
187
+ judge_cmds,
188
+ resolved_criterion: m.resolved_criterion as string,
189
+ timeout_s: m.timeout_s,
190
+ ...(typeof m.worker_visible_paths_note === 'string' ? { worker_visible_paths_note: m.worker_visible_paths_note } : {}),
191
+ ...(typeof m.runtime === 'string' ? { runtime: m.runtime } : {}),
192
+ ...(m.calibration !== undefined ? { calibration: m.calibration as FactoryInstance['calibration'] } : {}),
193
+ dir,
194
+ spec,
195
+ judgeTestTotal,
196
+ }
197
+ }
198
+
199
+ /** Load every `manifest.json` instance dir under `rootDir`. Fail-loud, ids must be unique. */
200
+ export function loadFactoryInstances(rootDir: string = FACTORY_INSTANCES_DIR): LoadedFactoryInstance[] {
201
+ const entries = readdirSync(rootDir, { withFileTypes: true })
202
+ .filter((e) => e.isDirectory())
203
+ .map((e) => join(rootDir, e.name))
204
+ .sort()
205
+ const instances = entries.map((dir) => loadFactoryInstance(dir))
206
+ if (instances.length === 0) throw new Error(`${rootDir}: no factory instance directories found`)
207
+ const ids = new Set<string>()
208
+ for (const inst of instances) {
209
+ if (ids.has(inst.id)) throw new Error(`${rootDir}: duplicate instance id ${inst.id}`)
210
+ ids.add(inst.id)
211
+ }
212
+ return instances
213
+ }
214
+
215
+ /** Per-instance worker-session token spend (instances with 0 workers are absent). */
216
+ export function loadWorkerTokens(): Record<string, WorkerTokens> {
217
+ return JSON.parse(readFixture('worker-tokens.json')) as Record<string, WorkerTokens>
218
+ }
219
+
220
+ /**
221
+ * Journal-true supervisor brain tokens per instance — extracted from the
222
+ * supervisor journals' `metered` events with the same logic as
223
+ * `analyze.py::_true_sup_tok`, captured into a fixture because the raw
224
+ * journals (runs/) are too large to commit. `null` = no journal found.
225
+ */
226
+ export function loadSupJournalTrue(): Record<string, number | null> {
227
+ const raw = JSON.parse(readFixture('sup-journal-true.json')) as Record<string, unknown>
228
+ const out: Record<string, number | null> = {}
229
+ for (const [k, v] of Object.entries(raw)) {
230
+ if (k === '_provenance') continue
231
+ if (v !== null && typeof v !== 'number') {
232
+ throw new Error(`sup-journal-true.json: ${k} must be number|null`)
233
+ }
234
+ out[k] = v as number | null
235
+ }
236
+ return out
237
+ }