@ic-reactor/mcp 0.0.0-stage → 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1041) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +108 -0
  2. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.yml +77 -0
  4. package/.github/actions/setup-rust-wasm/action.yml +25 -0
  5. package/.github/dependabot.yml +107 -0
  6. package/.github/workflows/auth-latest.yml +67 -0
  7. package/.github/workflows/b3pay-site.yml +49 -0
  8. package/.github/workflows/ci.yml +430 -0
  9. package/.github/workflows/codeql.yml +41 -0
  10. package/.github/workflows/dependency-review.yml +68 -0
  11. package/.github/workflows/docs-check.yml +98 -0
  12. package/.github/workflows/docs.yml +265 -0
  13. package/.github/workflows/e2e.yml +90 -0
  14. package/.github/workflows/examples-published.yml +97 -0
  15. package/.github/workflows/release.yml +326 -0
  16. package/.husky/pre-commit +12 -0
  17. package/.prettierignore +109 -0
  18. package/.prettierrc +6 -0
  19. package/AGENTS.md +103 -0
  20. package/CHANGELOG.md +3268 -0
  21. package/CLAUDE.md +93 -0
  22. package/CNAME +1 -0
  23. package/CODE_OF_CONDUCT.md +7 -0
  24. package/CONTRIBUTING.md +433 -0
  25. package/LICENSE +21 -0
  26. package/README.md +2 -2
  27. package/SECURITY.md +74 -0
  28. package/b3pay-module.json +194 -0
  29. package/docs/.remarkrc.json +10 -0
  30. package/docs/README.md +64 -0
  31. package/docs/astro.config.mjs +205 -0
  32. package/docs/favicon.svg +15 -0
  33. package/docs/package.json +39 -0
  34. package/docs/public/favicon.svg +15 -0
  35. package/docs/public/ic-reactor-social-card.png +0 -0
  36. package/docs/scripts/b3pay-static.mjs +22 -0
  37. package/docs/scripts/check-example-docs.mjs +214 -0
  38. package/docs/scripts/check-links.mjs +212 -0
  39. package/docs/scripts/fix-dist-links.js +125 -0
  40. package/docs/scripts/fix-frontmatter.js +71 -0
  41. package/docs/scripts/remove-redundant-h1.cjs +48 -0
  42. package/docs/scripts/rewrite-typedoc-links.js +110 -0
  43. package/docs/scripts/split-index.js +69 -0
  44. package/docs/src/assets/ic-reactor-hero-dark.svg +23 -0
  45. package/docs/src/assets/ic-reactor-hero-light.svg +23 -0
  46. package/docs/src/assets/ic-reactor-lockup-dark.svg +15 -0
  47. package/docs/src/assets/ic-reactor-lockup-light.svg +15 -0
  48. package/docs/src/assets/ic-reactor-mark-dark.svg +14 -0
  49. package/docs/src/assets/ic-reactor-mark-light.svg +14 -0
  50. package/docs/src/assets/layers/candid-core-layer-icon-dark.svg +4 -0
  51. package/docs/src/assets/layers/candid-core-layer-icon-light.svg +4 -0
  52. package/docs/src/assets/layers/candid-profile-layer-icon-dark.svg +4 -0
  53. package/docs/src/assets/layers/candid-profile-layer-icon-light.svg +4 -0
  54. package/docs/src/assets/layers/ic-reactor-layer-icon-dark.svg +4 -0
  55. package/docs/src/assets/layers/ic-reactor-layer-icon-light.svg +4 -0
  56. package/docs/src/components/LibraryCards.astro +172 -0
  57. package/docs/src/components/LibraryIcon.astro +28 -0
  58. package/docs/src/components/SiteTitle.astro +241 -0
  59. package/docs/src/content/docs/404.mdx +19 -0
  60. package/docs/src/content/docs/build/agent-tools.mdx +593 -0
  61. package/docs/src/content/docs/build/icrc1-wallet.mdx +619 -0
  62. package/docs/src/content/docs/build/ssr-per-user.mdx +552 -0
  63. package/docs/src/content/docs/examples/canister-studio.mdx +95 -0
  64. package/docs/src/content/docs/examples/icrc-ledger.mdx +45 -0
  65. package/docs/src/content/docs/examples/index.mdx +38 -0
  66. package/docs/src/content/docs/examples/next-ssr.mdx +73 -0
  67. package/docs/src/content/docs/examples/node-agent-tool.mdx +80 -0
  68. package/docs/src/content/docs/examples/vite-wallet.mdx +71 -0
  69. package/docs/src/content/docs/guides/auth.mdx +1181 -0
  70. package/docs/src/content/docs/guides/client.mdx +551 -0
  71. package/docs/src/content/docs/guides/deploy.mdx +180 -0
  72. package/docs/src/content/docs/guides/errors.mdx +475 -0
  73. package/docs/src/content/docs/guides/getting-started.mdx +620 -0
  74. package/docs/src/content/docs/guides/reads.mdx +586 -0
  75. package/docs/src/content/docs/guides/ssr.mdx +529 -0
  76. package/docs/src/content/docs/guides/testing.mdx +401 -0
  77. package/docs/src/content/docs/guides/values.mdx +261 -0
  78. package/docs/src/content/docs/guides/vite-plugin.mdx +690 -0
  79. package/docs/src/content/docs/guides/writes.mdx +572 -0
  80. package/docs/src/content/docs/ic-reactor/index.mdx +167 -0
  81. package/docs/src/content/docs/index.mdx +65 -0
  82. package/docs/src/content/docs/migrating-from-3.mdx +535 -0
  83. package/docs/src/content/docs/packages/core.mdx +186 -0
  84. package/docs/src/content/docs/packages/mcp.mdx +163 -0
  85. package/docs/src/content/docs/packages/react.mdx +207 -0
  86. package/docs/src/content/docs/packages/vite-plugin.mdx +73 -0
  87. package/docs/src/content/docs/versioning.mdx +104 -0
  88. package/docs/src/content.config.ts +7 -0
  89. package/docs/src/styles/custom.css +189 -0
  90. package/docs/tsconfig.typedoc.json +26 -0
  91. package/docs/typedoc-entry.ts +17 -0
  92. package/docs/typedoc.json +37 -0
  93. package/e2e/Cargo.lock +646 -0
  94. package/e2e/Cargo.toml +3 -0
  95. package/e2e/README.md +101 -0
  96. package/e2e/frontends/build.mjs +94 -0
  97. package/e2e/frontends/index.html +10 -0
  98. package/e2e/global-setup.ts +65 -0
  99. package/e2e/icp.yaml +38 -0
  100. package/e2e/package.json +40 -0
  101. package/e2e/setup.ts +6 -0
  102. package/e2e/src/actor/Cargo.toml +14 -0
  103. package/e2e/src/actor/hello_actor.did +10 -0
  104. package/e2e/src/actor/src/lib.rs +73 -0
  105. package/e2e/src/calls.test.ts +132 -0
  106. package/e2e/src/declarations/hello_actor.envelope.json +175 -0
  107. package/e2e/src/declarations/hello_actor.ts +15 -0
  108. package/e2e/src/errors.test.ts +107 -0
  109. package/e2e/src/frontend-headers.test.ts +253 -0
  110. package/e2e/src/identity.test.ts +61 -0
  111. package/e2e/src/react.test.tsx +59 -0
  112. package/e2e/src/replica.ts +70 -0
  113. package/e2e/src/vite-env.test.ts +108 -0
  114. package/e2e/test.sh +47 -0
  115. package/e2e/tsconfig.json +20 -0
  116. package/e2e/tsconfig.typecheck.json +9 -0
  117. package/e2e/vitest.config.ts +22 -0
  118. package/eslint.config.mjs +100 -0
  119. package/evals/PREREGISTRATION.md +1346 -0
  120. package/evals/README.md +756 -0
  121. package/evals/conditions/thin/condition.json +8 -0
  122. package/evals/conditions/thin/docs/candid-core-cli.README.md +90 -0
  123. package/evals/conditions/thin/docs/candid-core-schema.README.md +339 -0
  124. package/evals/conditions/thin/package.json +25 -0
  125. package/evals/conditions/thin/starter/src/generated/icrc1.ts +57 -0
  126. package/evals/conditions/thin-guide/condition.json +10 -0
  127. package/evals/conditions/thin-guide/docs/llms.txt +292 -0
  128. package/evals/conditions/v3/condition.json +9 -0
  129. package/evals/conditions/v3/docs/ic-reactor-core.llms.txt +232 -0
  130. package/evals/conditions/v3/docs/ic-reactor-react.llms.txt +280 -0
  131. package/evals/conditions/v3/docs/llms-full.txt +1053 -0
  132. package/evals/conditions/v3/package.json +26 -0
  133. package/evals/conditions/v3/starter/src/declarations/icrc1.did.d.ts +95 -0
  134. package/evals/conditions/v3/starter/src/declarations/icrc1.did.js +140 -0
  135. package/evals/conditions/v4/PORTING.md +384 -0
  136. package/evals/conditions/v4/README.md +106 -0
  137. package/evals/conditions/v4/condition.json +5 -0
  138. package/evals/conditions/v4/docs/llms.txt +323 -0
  139. package/evals/conditions/v4/package.json +27 -0
  140. package/evals/conditions/v4/starter/src/generated/icrc1.ts +78 -0
  141. package/evals/conditions/v4-proto/condition.json +6 -0
  142. package/evals/conditions/v4-proto/docs/llms.txt +291 -0
  143. package/evals/conditions/v4-proto/lib/SHIM-NOTES.md +20 -0
  144. package/evals/conditions/v4-proto/lib/package.json +27 -0
  145. package/evals/conditions/v4-proto/lib/src/client.ts +471 -0
  146. package/evals/conditions/v4-proto/lib/src/errors.ts +214 -0
  147. package/evals/conditions/v4-proto/lib/src/index.ts +36 -0
  148. package/evals/conditions/v4-proto/lib/src/principal.ts +175 -0
  149. package/evals/conditions/v4-proto/lib/src/service.ts +69 -0
  150. package/evals/conditions/v4-proto/lib/src/types.ts +174 -0
  151. package/evals/conditions/v4-proto/lib/test/runtime.test.ts +170 -0
  152. package/evals/conditions/v4-proto/lib/test/tsconfig.json +10 -0
  153. package/evals/conditions/v4-proto/lib/test/types.test-d.ts +145 -0
  154. package/evals/conditions/v4-proto/lib/test/vitest.config.mjs +8 -0
  155. package/evals/conditions/v4-proto/lib/tsconfig.json +17 -0
  156. package/evals/conditions/v4-proto/package.json +26 -0
  157. package/evals/conditions/v4-proto/starter/src/generated/icrc1.service.ts +19 -0
  158. package/evals/conditions/v4-proto/starter/src/generated/icrc1.ts +57 -0
  159. package/evals/drive.mjs +1221 -0
  160. package/evals/gate.mjs +161 -0
  161. package/evals/harness/aggregate.mjs +534 -0
  162. package/evals/harness/aggregate.test.mjs +344 -0
  163. package/evals/harness/assemble.mjs +216 -0
  164. package/evals/harness/assemble.test.mjs +143 -0
  165. package/evals/harness/auth.mjs +91 -0
  166. package/evals/harness/check-docs.mjs +157 -0
  167. package/evals/harness/declarations/icrc1.did.d.ts +95 -0
  168. package/evals/harness/declarations/icrc1.did.js +140 -0
  169. package/evals/harness/drive-auth.test.mjs +584 -0
  170. package/evals/harness/drive.test.mjs +509 -0
  171. package/evals/harness/fake-auth.ts +67 -0
  172. package/evals/harness/fake-ledger.ts +178 -0
  173. package/evals/harness/gate-plan.mjs +104 -0
  174. package/evals/harness/gate-plan.test.mjs +243 -0
  175. package/evals/harness/icrc1.did +88 -0
  176. package/evals/harness/judge.mjs +63 -0
  177. package/evals/harness/judge.test.mjs +81 -0
  178. package/evals/harness/leak-scan.mjs +1373 -0
  179. package/evals/harness/leak-scan.test.mjs +1300 -0
  180. package/evals/harness/probes/amounts.ts +14 -0
  181. package/evals/harness/probes/node-tool.probe.ts +48 -0
  182. package/evals/harness/probes/probe.mjs +149 -0
  183. package/evals/harness/probes/react-wallet.probe.ts +96 -0
  184. package/evals/harness/public/support/auth.ts +38 -0
  185. package/evals/harness/public/support/fake-replica.d.ts +28 -0
  186. package/evals/harness/public/support/fake-replica.js +434 -0
  187. package/evals/harness/public/support/ledger.idl.d.ts +95 -0
  188. package/evals/harness/public/support/ledger.idl.js +140 -0
  189. package/evals/harness/public/support/world.ts +179 -0
  190. package/evals/harness/runs.mjs +139 -0
  191. package/evals/harness/sandbox.mjs +88 -0
  192. package/evals/harness/sandbox.test.mjs +134 -0
  193. package/evals/harness/ship.mjs +264 -0
  194. package/evals/harness/ship.test.mjs +552 -0
  195. package/evals/harness/world.ts +291 -0
  196. package/evals/package.json +26 -0
  197. package/evals/pnpm-lock.yaml +1537 -0
  198. package/evals/pnpm-workspace.yaml +12 -0
  199. package/evals/results/2026-09-30T14-22-05-924Z/pilot.json +384 -0
  200. package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.json +404 -0
  201. package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.rescored.json +404 -0
  202. package/evals/results/2026-09-30T14-22-05-924Z/plan.json +240 -0
  203. package/evals/results/2026-09-30T14-22-05-924Z/summary.json +1800 -0
  204. package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.json +1843 -0
  205. package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.rescored.json +2100 -0
  206. package/evals/results/2026-09-30T15-48-23-343Z/pilot.json +404 -0
  207. package/evals/results/2026-09-30T15-48-23-343Z/pilot.rescored.json +404 -0
  208. package/evals/results/2026-09-30T15-48-23-343Z/plan.json +242 -0
  209. package/evals/results/2026-09-30T15-48-23-343Z/summary.json +1843 -0
  210. package/evals/results/2026-09-30T15-48-23-343Z/summary.rescored.json +2195 -0
  211. package/evals/results/2026-10-03-beta1-gate/pilot.json +162 -0
  212. package/evals/results/2026-10-03-beta1-gate/plan.json +141 -0
  213. package/evals/results/2026-10-03-beta1-gate/summary.json +983 -0
  214. package/evals/results/2026-10-05-ga-gate/contaminated-run.json +55 -0
  215. package/evals/results/2026-10-05-ga-gate/pilot.json +162 -0
  216. package/evals/results/2026-10-05-ga-gate/plan.json +457 -0
  217. package/evals/results/2026-10-05-ga-gate/summary.json +1037 -0
  218. package/evals/results/2026-10-05-ga-gate/summary.rescanned.json +1037 -0
  219. package/evals/results/README.md +31 -0
  220. package/evals/runs-pilot.log +150 -0
  221. package/evals/runs-pilot2.log +150 -0
  222. package/evals/score.mjs +256 -0
  223. package/evals/setup.mjs +547 -0
  224. package/evals/tasks/node-tool/faulty/thin-accepts-exponent/meta.json +5 -0
  225. package/evals/tasks/node-tool/faulty/thin-accepts-exponent/src/index.ts +121 -0
  226. package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/meta.json +5 -0
  227. package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/src/index.ts +116 -0
  228. package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/meta.json +9 -0
  229. package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/src/index.ts +118 -0
  230. package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/meta.json +5 -0
  231. package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/src/index.ts +118 -0
  232. package/evals/tasks/node-tool/faulty/thin-ignores-root-key/meta.json +5 -0
  233. package/evals/tasks/node-tool/faulty/thin-ignores-root-key/src/index.ts +117 -0
  234. package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/meta.json +9 -0
  235. package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/src/index.ts +119 -0
  236. package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/meta.json +9 -0
  237. package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/src/index.ts +118 -0
  238. package/evals/tasks/node-tool/faulty/thin-number-amount/meta.json +10 -0
  239. package/evals/tasks/node-tool/faulty/thin-number-amount/src/index.ts +117 -0
  240. package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/meta.json +5 -0
  241. package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/src/index.ts +120 -0
  242. package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/meta.json +5 -0
  243. package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/src/index.ts +118 -0
  244. package/evals/tasks/node-tool/faulty/v3-retry-call-errors/meta.json +11 -0
  245. package/evals/tasks/node-tool/faulty/v3-retry-call-errors/src/index.ts +149 -0
  246. package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/meta.json +5 -0
  247. package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/src/index.ts +71 -0
  248. package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/meta.json +9 -0
  249. package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/src/index.ts +84 -0
  250. package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/meta.json +9 -0
  251. package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/src/index.ts +72 -0
  252. package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/meta.json +5 -0
  253. package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/src/index.ts +72 -0
  254. package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/meta.json +5 -0
  255. package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/src/index.ts +84 -0
  256. package/evals/tasks/node-tool/hidden/node-tool.test.ts +312 -0
  257. package/evals/tasks/node-tool/prompt.md +55 -0
  258. package/evals/tasks/node-tool/prompt.minimal.md +30 -0
  259. package/evals/tasks/node-tool/solutions/thin/reference/src/index.ts +118 -0
  260. package/evals/tasks/node-tool/solutions/thin/reference-module-scope/src/index.ts +145 -0
  261. package/evals/tasks/node-tool/solutions/thin-guide/reference/src/index.ts +118 -0
  262. package/evals/tasks/node-tool/solutions/thin-guide/reference-module-scope/src/index.ts +145 -0
  263. package/evals/tasks/node-tool/solutions/v3/reference/src/index.ts +140 -0
  264. package/evals/tasks/node-tool/solutions/v3/reference-module-scope/src/index.ts +153 -0
  265. package/evals/tasks/node-tool/solutions/v4/reference/src/index.ts +84 -0
  266. package/evals/tasks/node-tool/solutions/v4/reference-module-scope/src/index.ts +105 -0
  267. package/evals/tasks/node-tool/solutions/v4-proto/reference/src/index.ts +72 -0
  268. package/evals/tasks/node-tool/solutions/v4-proto/reference-module-scope/src/index.ts +87 -0
  269. package/evals/tasks/node-tool/starter/src/contract.ts +31 -0
  270. package/evals/tasks/node-tool/starter/src/index.ts +7 -0
  271. package/evals/tasks/node-tool/starter/test/smoke.test.ts +22 -0
  272. package/evals/tasks/node-tool/starter/tsconfig.json +17 -0
  273. package/evals/tasks/node-tool/task.json +63 -0
  274. package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/meta.json +5 -0
  275. package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/src/Wallet.tsx +216 -0
  276. package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/meta.json +5 -0
  277. package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/src/Wallet.tsx +212 -0
  278. package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/meta.json +5 -0
  279. package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/src/Wallet.tsx +210 -0
  280. package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/meta.json +8 -0
  281. package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/src/Wallet.tsx +213 -0
  282. package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/meta.json +9 -0
  283. package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/src/Wallet.tsx +213 -0
  284. package/evals/tasks/react-wallet/faulty/thin-number-balance/meta.json +5 -0
  285. package/evals/tasks/react-wallet/faulty/thin-number-balance/src/Wallet.tsx +213 -0
  286. package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/meta.json +5 -0
  287. package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/src/Wallet.tsx +254 -0
  288. package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/meta.json +5 -0
  289. package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/src/Wallet.tsx +215 -0
  290. package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/meta.json +5 -0
  291. package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/src/Wallet.tsx +214 -0
  292. package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/meta.json +5 -0
  293. package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/src/Wallet.tsx +224 -0
  294. package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/meta.json +12 -0
  295. package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/src/Wallet.tsx +225 -0
  296. package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/meta.json +11 -0
  297. package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/src/Wallet.tsx +182 -0
  298. package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/meta.json +5 -0
  299. package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/src/Wallet.tsx +160 -0
  300. package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/meta.json +5 -0
  301. package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/src/Wallet.tsx +166 -0
  302. package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/meta.json +5 -0
  303. package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/src/Wallet.tsx +161 -0
  304. package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/meta.json +5 -0
  305. package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/src/Wallet.tsx +163 -0
  306. package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/meta.json +12 -0
  307. package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/src/Wallet.tsx +162 -0
  308. package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/meta.json +5 -0
  309. package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/src/Wallet.tsx +163 -0
  310. package/evals/tasks/react-wallet/faulty/v4-retry-spread/meta.json +12 -0
  311. package/evals/tasks/react-wallet/faulty/v4-retry-spread/src/Wallet.tsx +163 -0
  312. package/evals/tasks/react-wallet/faulty/v4-status-not-idle/meta.json +5 -0
  313. package/evals/tasks/react-wallet/faulty/v4-status-not-idle/src/Wallet.tsx +162 -0
  314. package/evals/tasks/react-wallet/hidden/react-wallet.test.ts +536 -0
  315. package/evals/tasks/react-wallet/prompt.md +88 -0
  316. package/evals/tasks/react-wallet/prompt.minimal.md +51 -0
  317. package/evals/tasks/react-wallet/solutions/thin/reference/src/Wallet.tsx +213 -0
  318. package/evals/tasks/react-wallet/solutions/thin/reference-module-scope/src/Wallet.tsx +227 -0
  319. package/evals/tasks/react-wallet/solutions/thin-guide/reference/src/Wallet.tsx +213 -0
  320. package/evals/tasks/react-wallet/solutions/thin-guide/reference-module-scope/src/Wallet.tsx +227 -0
  321. package/evals/tasks/react-wallet/solutions/v3/reference/src/Wallet.tsx +224 -0
  322. package/evals/tasks/react-wallet/solutions/v3/reference-module-scope/src/Wallet.tsx +230 -0
  323. package/evals/tasks/react-wallet/solutions/v4/reference/src/Wallet.tsx +160 -0
  324. package/evals/tasks/react-wallet/solutions/v4/reference-module-scope/src/Wallet.tsx +178 -0
  325. package/evals/tasks/react-wallet/solutions/v4-proto/reference/src/Wallet.tsx +161 -0
  326. package/evals/tasks/react-wallet/solutions/v4-proto/reference-module-scope/src/Wallet.tsx +161 -0
  327. package/evals/tasks/react-wallet/starter/src/Wallet.tsx +12 -0
  328. package/evals/tasks/react-wallet/starter/src/auth.ts +16 -0
  329. package/evals/tasks/react-wallet/starter/src/config.ts +14 -0
  330. package/evals/tasks/react-wallet/starter/src/ii-auth.ts +43 -0
  331. package/evals/tasks/react-wallet/starter/src/main.tsx +15 -0
  332. package/evals/tasks/react-wallet/starter/test/smoke.test.ts +34 -0
  333. package/evals/tasks/react-wallet/starter/tsconfig.json +18 -0
  334. package/evals/tasks/react-wallet/task.json +84 -0
  335. package/examples/canister-studio/.stackblitzrc +4 -0
  336. package/examples/canister-studio/README.md +183 -0
  337. package/examples/canister-studio/did/ckbtc_minter.did +806 -0
  338. package/examples/canister-studio/did/icp_ledger.did +586 -0
  339. package/examples/canister-studio/did/icrc1.did +88 -0
  340. package/examples/canister-studio/package.json +45 -0
  341. package/examples/canister-studio/scripts/smoke.ts +188 -0
  342. package/examples/canister-studio/src/calls/CacheKeyPanel.tsx +104 -0
  343. package/examples/canister-studio/src/calls/ConfirmWrite.tsx +265 -0
  344. package/examples/canister-studio/src/calls/ErrorPanel.test.tsx +113 -0
  345. package/examples/canister-studio/src/calls/ErrorPanel.tsx +214 -0
  346. package/examples/canister-studio/src/calls/MethodRunner.test.tsx +354 -0
  347. package/examples/canister-studio/src/calls/MethodRunner.tsx +57 -0
  348. package/examples/canister-studio/src/calls/ReadRunner.tsx +244 -0
  349. package/examples/canister-studio/src/calls/ResendPanel.tsx +165 -0
  350. package/examples/canister-studio/src/calls/ShareLink.tsx +59 -0
  351. package/examples/canister-studio/src/calls/WriteRunner.test.tsx +678 -0
  352. package/examples/canister-studio/src/calls/WriteRunner.tsx +670 -0
  353. package/examples/canister-studio/src/calls/dedupe.ts +189 -0
  354. package/examples/canister-studio/src/calls/error-info.ts +168 -0
  355. package/examples/canister-studio/src/calls/history.test.ts +284 -0
  356. package/examples/canister-studio/src/calls/history.ts +287 -0
  357. package/examples/canister-studio/src/calls/kinds.ts +68 -0
  358. package/examples/canister-studio/src/calls/prepare.ts +32 -0
  359. package/examples/canister-studio/src/calls/query-options.ts +30 -0
  360. package/examples/canister-studio/src/calls/read.ts +47 -0
  361. package/examples/canister-studio/src/calls/readback.ts +100 -0
  362. package/examples/canister-studio/src/calls/record.ts +123 -0
  363. package/examples/canister-studio/src/calls/safe-calls.test.ts +299 -0
  364. package/examples/canister-studio/src/calls/share.ts +46 -0
  365. package/examples/canister-studio/src/calls/testing/doubles.tsx +108 -0
  366. package/examples/canister-studio/src/calls/testing/fixtures.ts +185 -0
  367. package/examples/canister-studio/src/calls/useCanisterHandle.ts +35 -0
  368. package/examples/canister-studio/src/canisters/ckbtc_minter.envelope.json +4228 -0
  369. package/examples/canister-studio/src/canisters/ckbtc_minter.ts +868 -0
  370. package/examples/canister-studio/src/canisters/icp_ledger.envelope.json +3454 -0
  371. package/examples/canister-studio/src/canisters/icp_ledger.ts +584 -0
  372. package/examples/canister-studio/src/canisters/icrc1.envelope.json +840 -0
  373. package/examples/canister-studio/src/canisters/icrc1.ts +78 -0
  374. package/examples/canister-studio/src/components/ActionButton.tsx +32 -0
  375. package/examples/canister-studio/src/components/AppHeader.tsx +83 -0
  376. package/examples/canister-studio/src/components/AppShell.tsx +29 -0
  377. package/examples/canister-studio/src/components/AuthButton.tsx +79 -0
  378. package/examples/canister-studio/src/components/Badge.tsx +79 -0
  379. package/examples/canister-studio/src/components/CanisterHeader.tsx +200 -0
  380. package/examples/canister-studio/src/components/CanisterJump.tsx +130 -0
  381. package/examples/canister-studio/src/components/Card.tsx +64 -0
  382. package/examples/canister-studio/src/components/Code.tsx +101 -0
  383. package/examples/canister-studio/src/components/CopyButton.tsx +126 -0
  384. package/examples/canister-studio/src/components/Disclosure.tsx +34 -0
  385. package/examples/canister-studio/src/components/EmptyState.tsx +34 -0
  386. package/examples/canister-studio/src/components/MethodList.test.tsx +137 -0
  387. package/examples/canister-studio/src/components/MethodList.tsx +244 -0
  388. package/examples/canister-studio/src/components/Notice.tsx +36 -0
  389. package/examples/canister-studio/src/components/ProvenanceBadge.tsx +44 -0
  390. package/examples/canister-studio/src/components/RouteError.tsx +42 -0
  391. package/examples/canister-studio/src/components/SectionBoundary.tsx +76 -0
  392. package/examples/canister-studio/src/components/Spinner.tsx +33 -0
  393. package/examples/canister-studio/src/components/Tabs.tsx +96 -0
  394. package/examples/canister-studio/src/components/canister/CanisterLoadFailure.test.tsx +56 -0
  395. package/examples/canister-studio/src/components/canister/CanisterLoadFailure.tsx +165 -0
  396. package/examples/canister-studio/src/components/canister/CanisterNotFound.tsx +59 -0
  397. package/examples/canister-studio/src/components/canister/CanisterPending.tsx +33 -0
  398. package/examples/canister-studio/src/components/canister/MethodOverview.tsx +93 -0
  399. package/examples/canister-studio/src/components/canister/MethodWorkspace.test.tsx +201 -0
  400. package/examples/canister-studio/src/components/canister/MethodWorkspace.tsx +187 -0
  401. package/examples/canister-studio/src/components/canister/shared-call.test.ts +186 -0
  402. package/examples/canister-studio/src/components/canister/shared-call.ts +133 -0
  403. package/examples/canister-studio/src/components/canister/shared-link-loader.test.ts +116 -0
  404. package/examples/canister-studio/src/components/canister/use-canister-page.ts +44 -0
  405. package/examples/canister-studio/src/components/canister/workspace-key.test.ts +27 -0
  406. package/examples/canister-studio/src/components/canister/workspace-key.ts +36 -0
  407. package/examples/canister-studio/src/components/canister-id-input.ts +69 -0
  408. package/examples/canister-studio/src/components/canister-names.ts +11 -0
  409. package/examples/canister-studio/src/components/download.ts +34 -0
  410. package/examples/canister-studio/src/components/fallbacks.tsx +33 -0
  411. package/examples/canister-studio/src/components/helpers.test.ts +107 -0
  412. package/examples/canister-studio/src/components/history/HistoryList.tsx +284 -0
  413. package/examples/canister-studio/src/components/home/FeaturedLedger.tsx +149 -0
  414. package/examples/canister-studio/src/components/home/OpenCanister.tsx +99 -0
  415. package/examples/canister-studio/src/components/home/featured.test.tsx +92 -0
  416. package/examples/canister-studio/src/components/home/featured.ts +64 -0
  417. package/examples/canister-studio/src/components/interface/CandidTab.tsx +38 -0
  418. package/examples/canister-studio/src/components/interface/CompatReport.tsx +92 -0
  419. package/examples/canister-studio/src/components/interface/CompatibilityTab.tsx +190 -0
  420. package/examples/canister-studio/src/components/interface/ProjectTab.tsx +196 -0
  421. package/examples/canister-studio/src/components/interface/TypeScriptTab.tsx +114 -0
  422. package/examples/canister-studio/src/components/interface/tools.test.tsx +169 -0
  423. package/examples/canister-studio/src/components/modes.ts +31 -0
  424. package/examples/canister-studio/src/components/playground/MethodPicker.tsx +67 -0
  425. package/examples/canister-studio/src/components/playground/PlaygroundForms.tsx +112 -0
  426. package/examples/canister-studio/src/components/playground/PlaygroundTools.tsx +219 -0
  427. package/examples/canister-studio/src/components/playground/sample.ts +43 -0
  428. package/examples/canister-studio/src/components/playground/target.test.tsx +86 -0
  429. package/examples/canister-studio/src/components/primitives.test.tsx +121 -0
  430. package/examples/canister-studio/src/components/provenance.ts +38 -0
  431. package/examples/canister-studio/src/components/route-render.test.tsx +71 -0
  432. package/examples/canister-studio/src/components/use-task.ts +56 -0
  433. package/examples/canister-studio/src/components/wallet/BalancePanel.tsx +110 -0
  434. package/examples/canister-studio/src/components/wallet/LedgerSummary.tsx +63 -0
  435. package/examples/canister-studio/src/components/wallet/MinterPanel.tsx +255 -0
  436. package/examples/canister-studio/src/components/wallet/SendPanel.test.tsx +297 -0
  437. package/examples/canister-studio/src/components/wallet/SendPanel.tsx +446 -0
  438. package/examples/canister-studio/src/components/wallet/ledgers.test.ts +36 -0
  439. package/examples/canister-studio/src/components/wallet/ledgers.ts +111 -0
  440. package/examples/canister-studio/src/forms/JsonPanel.tsx +157 -0
  441. package/examples/canister-studio/src/forms/MethodForm.test.tsx +369 -0
  442. package/examples/canister-studio/src/forms/MethodForm.tsx +368 -0
  443. package/examples/canister-studio/src/forms/TypedForm.tsx +55 -0
  444. package/examples/canister-studio/src/forms/context.ts +62 -0
  445. package/examples/canister-studio/src/forms/convert.ts +131 -0
  446. package/examples/canister-studio/src/forms/edge.test.ts +252 -0
  447. package/examples/canister-studio/src/forms/engine.test.ts +358 -0
  448. package/examples/canister-studio/src/forms/engine.ts +1492 -0
  449. package/examples/canister-studio/src/forms/fields/BytesField.tsx +210 -0
  450. package/examples/canister-studio/src/forms/fields/Field.tsx +106 -0
  451. package/examples/canister-studio/src/forms/fields/FieldShell.tsx +101 -0
  452. package/examples/canister-studio/src/forms/fields/Group.tsx +74 -0
  453. package/examples/canister-studio/src/forms/fields/ListField.tsx +256 -0
  454. package/examples/canister-studio/src/forms/fields/Segmented.tsx +78 -0
  455. package/examples/canister-studio/src/forms/fields/TimestampField.tsx +108 -0
  456. package/examples/canister-studio/src/forms/fields/UnitsField.tsx +119 -0
  457. package/examples/canister-studio/src/forms/fields/composites.tsx +389 -0
  458. package/examples/canister-studio/src/forms/fields/leaves.tsx +350 -0
  459. package/examples/canister-studio/src/forms/fields.test.tsx +396 -0
  460. package/examples/canister-studio/src/forms/helpers.test.ts +225 -0
  461. package/examples/canister-studio/src/forms/hints.ts +128 -0
  462. package/examples/canister-studio/src/forms/json.ts +119 -0
  463. package/examples/canister-studio/src/forms/parsing.test.ts +217 -0
  464. package/examples/canister-studio/src/forms/useMethodForm.ts +251 -0
  465. package/examples/canister-studio/src/interface/browser.test.ts +23 -0
  466. package/examples/canister-studio/src/interface/browser.ts +153 -0
  467. package/examples/canister-studio/src/interface/cache.ts +68 -0
  468. package/examples/canister-studio/src/interface/cli-cache.test.ts +155 -0
  469. package/examples/canister-studio/src/interface/cli-cache.ts +125 -0
  470. package/examples/canister-studio/src/interface/compile.server.test.ts +198 -0
  471. package/examples/canister-studio/src/interface/compile.server.ts +262 -0
  472. package/examples/canister-studio/src/interface/compile.test.ts +108 -0
  473. package/examples/canister-studio/src/interface/compile.ts +305 -0
  474. package/examples/canister-studio/src/interface/docs.test.ts +75 -0
  475. package/examples/canister-studio/src/interface/docs.ts +100 -0
  476. package/examples/canister-studio/src/interface/functions.test.ts +42 -0
  477. package/examples/canister-studio/src/interface/functions.ts +200 -0
  478. package/examples/canister-studio/src/interface/live-candid.server.ts +91 -0
  479. package/examples/canister-studio/src/interface/live-loader.test.ts +515 -0
  480. package/examples/canister-studio/src/interface/live-loader.ts +364 -0
  481. package/examples/canister-studio/src/interface/load.test.ts +328 -0
  482. package/examples/canister-studio/src/interface/load.ts +249 -0
  483. package/examples/canister-studio/src/interface/read-candid.test.ts +185 -0
  484. package/examples/canister-studio/src/interface/read-candid.ts +233 -0
  485. package/examples/canister-studio/src/interface/server-result.ts +42 -0
  486. package/examples/canister-studio/src/interface/typed.ts +68 -0
  487. package/examples/canister-studio/src/interface/types.ts +121 -0
  488. package/examples/canister-studio/src/lib/format.test.ts +107 -0
  489. package/examples/canister-studio/src/lib/format.ts +139 -0
  490. package/examples/canister-studio/src/lib/hex.test.ts +43 -0
  491. package/examples/canister-studio/src/lib/hex.ts +33 -0
  492. package/examples/canister-studio/src/lib/ids.test.ts +70 -0
  493. package/examples/canister-studio/src/lib/ids.ts +93 -0
  494. package/examples/canister-studio/src/lib/reactor.test.ts +55 -0
  495. package/examples/canister-studio/src/lib/reactor.ts +55 -0
  496. package/examples/canister-studio/src/lib/registry.test.ts +74 -0
  497. package/examples/canister-studio/src/lib/registry.ts +238 -0
  498. package/examples/canister-studio/src/lib/schema.ts +148 -0
  499. package/examples/canister-studio/src/routeTree.gen.ts +227 -0
  500. package/examples/canister-studio/src/router.test.ts +290 -0
  501. package/examples/canister-studio/src/router.tsx +127 -0
  502. package/examples/canister-studio/src/routes/__root.tsx +58 -0
  503. package/examples/canister-studio/src/routes/canister.$canisterId.index.tsx +172 -0
  504. package/examples/canister-studio/src/routes/canister.$canisterId.interface.tsx +98 -0
  505. package/examples/canister-studio/src/routes/canister.$canisterId.tsx +91 -0
  506. package/examples/canister-studio/src/routes/history.tsx +55 -0
  507. package/examples/canister-studio/src/routes/index.tsx +169 -0
  508. package/examples/canister-studio/src/routes/playground.tsx +286 -0
  509. package/examples/canister-studio/src/routes/safety.tsx +57 -0
  510. package/examples/canister-studio/src/routes/wallet.tsx +213 -0
  511. package/examples/canister-studio/src/safety/LabTransferForm.tsx +84 -0
  512. package/examples/canister-studio/src/safety/RequestLog.tsx +79 -0
  513. package/examples/canister-studio/src/safety/SafetyLab.test.tsx +89 -0
  514. package/examples/canister-studio/src/safety/SafetyLab.tsx +140 -0
  515. package/examples/canister-studio/src/safety/ScenarioCard.tsx +262 -0
  516. package/examples/canister-studio/src/safety/lab-run.ts +283 -0
  517. package/examples/canister-studio/src/safety/mock-ledger.test.ts +99 -0
  518. package/examples/canister-studio/src/safety/mock-ledger.ts +263 -0
  519. package/examples/canister-studio/src/safety/scenarios.test.ts +157 -0
  520. package/examples/canister-studio/src/safety/scenarios.ts +924 -0
  521. package/examples/canister-studio/src/styles.css +3453 -0
  522. package/examples/canister-studio/src/styles.test.ts +46 -0
  523. package/examples/canister-studio/src/values/CallPreview.test.tsx +86 -0
  524. package/examples/canister-studio/src/values/CallPreview.tsx +148 -0
  525. package/examples/canister-studio/src/values/ErrValueView.tsx +66 -0
  526. package/examples/canister-studio/src/values/Inspector.tsx +133 -0
  527. package/examples/canister-studio/src/values/ReplyView.test.tsx +341 -0
  528. package/examples/canister-studio/src/values/ReplyView.tsx +164 -0
  529. package/examples/canister-studio/src/values/candid-text.test.ts +516 -0
  530. package/examples/canister-studio/src/values/candid-text.ts +479 -0
  531. package/examples/canister-studio/src/values/hints.ts +58 -0
  532. package/examples/canister-studio/src/values/json.test.ts +66 -0
  533. package/examples/canister-studio/src/values/json.ts +31 -0
  534. package/examples/canister-studio/src/values/leaves.tsx +309 -0
  535. package/examples/canister-studio/src/values/schema.test.ts +123 -0
  536. package/examples/canister-studio/src/values/schema.ts +78 -0
  537. package/examples/canister-studio/src/values/test-router.tsx +21 -0
  538. package/examples/canister-studio/src/values/tree.tsx +670 -0
  539. package/examples/canister-studio/src/values/use-sha256.ts +29 -0
  540. package/examples/canister-studio/tsconfig.json +20 -0
  541. package/examples/canister-studio/vite.config.ts +50 -0
  542. package/examples/canister-studio/vitest.config.ts +20 -0
  543. package/examples/icrc-ledger/.stackblitzrc +4 -0
  544. package/examples/icrc-ledger/README.md +100 -0
  545. package/examples/icrc-ledger/ckbtc_minter.did +12 -0
  546. package/examples/icrc-ledger/icp_ledger.did +147 -0
  547. package/examples/icrc-ledger/icrc1.did +88 -0
  548. package/examples/icrc-ledger/index.html +13 -0
  549. package/examples/icrc-ledger/package.json +40 -0
  550. package/examples/icrc-ledger/scripts/smoke.ts +151 -0
  551. package/examples/icrc-ledger/src/App.tsx +71 -0
  552. package/examples/icrc-ledger/src/ErrorPanel.tsx +105 -0
  553. package/examples/icrc-ledger/src/MainnetTab.tsx +450 -0
  554. package/examples/icrc-ledger/src/SandboxTab.test.tsx +379 -0
  555. package/examples/icrc-ledger/src/SandboxTab.tsx +761 -0
  556. package/examples/icrc-ledger/src/blocks.test.ts +247 -0
  557. package/examples/icrc-ledger/src/blocks.ts +140 -0
  558. package/examples/icrc-ledger/src/canisters/ckbtc_minter.envelope.json +96 -0
  559. package/examples/icrc-ledger/src/canisters/ckbtc_minter.ts +16 -0
  560. package/examples/icrc-ledger/src/canisters/icp_ledger.envelope.json +690 -0
  561. package/examples/icrc-ledger/src/canisters/icp_ledger.ts +223 -0
  562. package/examples/icrc-ledger/src/canisters/icrc1.envelope.json +840 -0
  563. package/examples/icrc-ledger/src/canisters/icrc1.ts +78 -0
  564. package/examples/icrc-ledger/src/format.test.ts +41 -0
  565. package/examples/icrc-ledger/src/format.ts +68 -0
  566. package/examples/icrc-ledger/src/ledger.ts +15 -0
  567. package/examples/icrc-ledger/src/main.tsx +10 -0
  568. package/examples/icrc-ledger/src/minter.ts +16 -0
  569. package/examples/icrc-ledger/src/sandbox.test.ts +464 -0
  570. package/examples/icrc-ledger/src/sandbox.ts +281 -0
  571. package/examples/icrc-ledger/src/styles.css +391 -0
  572. package/examples/icrc-ledger/src/transfer-form.test.ts +62 -0
  573. package/examples/icrc-ledger/src/transfer-form.ts +97 -0
  574. package/examples/icrc-ledger/tsconfig.json +19 -0
  575. package/examples/icrc-ledger/vite.config.ts +44 -0
  576. package/examples/icrc-ledger/vitest.config.ts +12 -0
  577. package/examples/next-ssr/.stackblitzrc +4 -0
  578. package/examples/next-ssr/README.md +112 -0
  579. package/examples/next-ssr/icrc1.did +88 -0
  580. package/examples/next-ssr/next.config.ts +10 -0
  581. package/examples/next-ssr/package.json +41 -0
  582. package/examples/next-ssr/scripts/smoke.ts +169 -0
  583. package/examples/next-ssr/src/app/account/CertifiedBalances.tsx +58 -0
  584. package/examples/next-ssr/src/app/account/account.test.tsx +165 -0
  585. package/examples/next-ssr/src/app/account/page.tsx +82 -0
  586. package/examples/next-ssr/src/app/api/balance/[ledger]/[principal]/route.ts +10 -0
  587. package/examples/next-ssr/src/app/globals.css +278 -0
  588. package/examples/next-ssr/src/app/layout.tsx +34 -0
  589. package/examples/next-ssr/src/app/page.tsx +46 -0
  590. package/examples/next-ssr/src/app/providers.browser.test.tsx +127 -0
  591. package/examples/next-ssr/src/app/providers.test.tsx +73 -0
  592. package/examples/next-ssr/src/app/providers.tsx +60 -0
  593. package/examples/next-ssr/src/canisters/icrc1.envelope.json +840 -0
  594. package/examples/next-ssr/src/canisters/icrc1.ts +78 -0
  595. package/examples/next-ssr/src/components/BalanceTable.tsx +43 -0
  596. package/examples/next-ssr/src/components/LedgerCard.test.tsx +96 -0
  597. package/examples/next-ssr/src/components/LedgerCard.tsx +230 -0
  598. package/examples/next-ssr/src/components/LedgerError.tsx +32 -0
  599. package/examples/next-ssr/src/components/LedgerSections.tsx +22 -0
  600. package/examples/next-ssr/src/components/MyBalances.test.tsx +253 -0
  601. package/examples/next-ssr/src/components/MyBalances.tsx +129 -0
  602. package/examples/next-ssr/src/components/SessionBadge.tsx +18 -0
  603. package/examples/next-ssr/src/components/hydration.test.tsx +259 -0
  604. package/examples/next-ssr/src/components/server-data.ts +10 -0
  605. package/examples/next-ssr/src/format.ts +46 -0
  606. package/examples/next-ssr/src/ledgers.ts +38 -0
  607. package/examples/next-ssr/src/server/balance-route.test.ts +151 -0
  608. package/examples/next-ssr/src/server/balance-route.ts +157 -0
  609. package/examples/next-ssr/src/server/error-summary.test.ts +34 -0
  610. package/examples/next-ssr/src/server/error-summary.ts +37 -0
  611. package/examples/next-ssr/src/server/parse-owner.test.ts +39 -0
  612. package/examples/next-ssr/src/server/parse-owner.ts +34 -0
  613. package/examples/next-ssr/src/server/prefetch-ledgers.test.ts +137 -0
  614. package/examples/next-ssr/src/server/prefetch-ledgers.ts +70 -0
  615. package/examples/next-ssr/src/server/read-balances.test.ts +103 -0
  616. package/examples/next-ssr/src/server/read-balances.ts +78 -0
  617. package/examples/next-ssr/src/server/request-client.rsc.test.tsx +110 -0
  618. package/examples/next-ssr/src/server/request-client.ts +24 -0
  619. package/examples/next-ssr/src/testing/mock-ledgers.ts +115 -0
  620. package/examples/next-ssr/src/testing/react-server-dom-turbopack.d.ts +15 -0
  621. package/examples/next-ssr/src/testing/setup.ts +10 -0
  622. package/examples/next-ssr/tsconfig.json +31 -0
  623. package/examples/next-ssr/vitest.config.ts +59 -0
  624. package/examples/node-agent-tool/.stackblitzrc +4 -0
  625. package/examples/node-agent-tool/README.md +165 -0
  626. package/examples/node-agent-tool/icp.yaml +11 -0
  627. package/examples/node-agent-tool/icrc1.did +88 -0
  628. package/examples/node-agent-tool/package.json +32 -0
  629. package/examples/node-agent-tool/src/canisters/icrc1.envelope.json +840 -0
  630. package/examples/node-agent-tool/src/canisters/icrc1.ts +78 -0
  631. package/examples/node-agent-tool/src/cli.test.ts +64 -0
  632. package/examples/node-agent-tool/src/cli.ts +23 -0
  633. package/examples/node-agent-tool/src/command-line.ts +159 -0
  634. package/examples/node-agent-tool/src/commands/balance.ts +73 -0
  635. package/examples/node-agent-tool/src/commands/demo.test.ts +51 -0
  636. package/examples/node-agent-tool/src/commands/demo.ts +359 -0
  637. package/examples/node-agent-tool/src/commands/info.ts +69 -0
  638. package/examples/node-agent-tool/src/commands/reads.test.ts +133 -0
  639. package/examples/node-agent-tool/src/commands/resend.test.ts +363 -0
  640. package/examples/node-agent-tool/src/commands/transfer.test.ts +313 -0
  641. package/examples/node-agent-tool/src/commands/transfer.ts +415 -0
  642. package/examples/node-agent-tool/src/commands/watch.test.ts +159 -0
  643. package/examples/node-agent-tool/src/commands/watch.ts +135 -0
  644. package/examples/node-agent-tool/src/commands/whoami.ts +36 -0
  645. package/examples/node-agent-tool/src/context.ts +20 -0
  646. package/examples/node-agent-tool/src/dispatch.ts +70 -0
  647. package/examples/node-agent-tool/src/failure.test.ts +59 -0
  648. package/examples/node-agent-tool/src/failure.ts +176 -0
  649. package/examples/node-agent-tool/src/identity.test.ts +242 -0
  650. package/examples/node-agent-tool/src/identity.ts +228 -0
  651. package/examples/node-agent-tool/src/input.ts +110 -0
  652. package/examples/node-agent-tool/src/ledgers.test.ts +74 -0
  653. package/examples/node-agent-tool/src/ledgers.ts +62 -0
  654. package/examples/node-agent-tool/src/mock-ledger.ts +211 -0
  655. package/examples/node-agent-tool/src/network.test.ts +128 -0
  656. package/examples/node-agent-tool/src/network.ts +101 -0
  657. package/examples/node-agent-tool/src/output.test.ts +208 -0
  658. package/examples/node-agent-tool/src/output.ts +163 -0
  659. package/examples/node-agent-tool/src/run.ts +73 -0
  660. package/examples/node-agent-tool/src/test-kit.ts +167 -0
  661. package/examples/node-agent-tool/tsconfig.json +18 -0
  662. package/examples/node-agent-tool/vitest.config.ts +8 -0
  663. package/examples/vite-wallet/.stackblitzrc +4 -0
  664. package/examples/vite-wallet/Cargo.lock +646 -0
  665. package/examples/vite-wallet/Cargo.toml +5 -0
  666. package/examples/vite-wallet/README.md +107 -0
  667. package/examples/vite-wallet/backend/Cargo.toml +12 -0
  668. package/examples/vite-wallet/backend/backend.did +37 -0
  669. package/examples/vite-wallet/backend/src/lib.rs +133 -0
  670. package/examples/vite-wallet/icp.yaml +44 -0
  671. package/examples/vite-wallet/index.html +13 -0
  672. package/examples/vite-wallet/ledger.did +54 -0
  673. package/examples/vite-wallet/package.json +46 -0
  674. package/examples/vite-wallet/public/.ic-assets.json5 +26 -0
  675. package/examples/vite-wallet/scripts/faucet-args.test.ts +30 -0
  676. package/examples/vite-wallet/scripts/faucet-args.ts +41 -0
  677. package/examples/vite-wallet/scripts/faucet.ts +41 -0
  678. package/examples/vite-wallet/src/AddressBook.test.tsx +191 -0
  679. package/examples/vite-wallet/src/AddressBook.tsx +147 -0
  680. package/examples/vite-wallet/src/App.tsx +53 -0
  681. package/examples/vite-wallet/src/Balance.test.tsx +57 -0
  682. package/examples/vite-wallet/src/Balance.tsx +58 -0
  683. package/examples/vite-wallet/src/EnvironmentPanel.test.tsx +83 -0
  684. package/examples/vite-wallet/src/EnvironmentPanel.tsx +103 -0
  685. package/examples/vite-wallet/src/ErrorNote.tsx +70 -0
  686. package/examples/vite-wallet/src/Profile.test.tsx +145 -0
  687. package/examples/vite-wallet/src/Profile.tsx +92 -0
  688. package/examples/vite-wallet/src/SendIcp.test.tsx +231 -0
  689. package/examples/vite-wallet/src/SendIcp.tsx +244 -0
  690. package/examples/vite-wallet/src/SendToContact.test.tsx +113 -0
  691. package/examples/vite-wallet/src/SendToContact.tsx +102 -0
  692. package/examples/vite-wallet/src/SignIn.test.tsx +106 -0
  693. package/examples/vite-wallet/src/SignIn.tsx +120 -0
  694. package/examples/vite-wallet/src/Wallet.test.tsx +89 -0
  695. package/examples/vite-wallet/src/account-switch.test.tsx +108 -0
  696. package/examples/vite-wallet/src/auth/dev-accounts.test.ts +113 -0
  697. package/examples/vite-wallet/src/auth/dev-accounts.ts +216 -0
  698. package/examples/vite-wallet/src/auth/local-page.test.ts +28 -0
  699. package/examples/vite-wallet/src/auth/local-page.ts +20 -0
  700. package/examples/vite-wallet/src/auth/wallet-auth.test.ts +159 -0
  701. package/examples/vite-wallet/src/auth/wallet-auth.ts +131 -0
  702. package/examples/vite-wallet/src/canisters/backend.envelope.json +275 -0
  703. package/examples/vite-wallet/src/canisters/backend.ts +58 -0
  704. package/examples/vite-wallet/src/canisters/ledger.envelope.json +451 -0
  705. package/examples/vite-wallet/src/canisters/ledger.ts +56 -0
  706. package/examples/vite-wallet/src/client.ts +45 -0
  707. package/examples/vite-wallet/src/main.tsx +18 -0
  708. package/examples/vite-wallet/src/optimistic-contacts.ts +113 -0
  709. package/examples/vite-wallet/src/refusal.ts +17 -0
  710. package/examples/vite-wallet/src/styles.css +282 -0
  711. package/examples/vite-wallet/src/test/test-wallet.tsx +322 -0
  712. package/examples/vite-wallet/src/token.ts +50 -0
  713. package/examples/vite-wallet/src/transfer.test.ts +178 -0
  714. package/examples/vite-wallet/src/transfer.ts +110 -0
  715. package/examples/vite-wallet/src/use-canisters.ts +49 -0
  716. package/examples/vite-wallet/tsconfig.json +19 -0
  717. package/examples/vite-wallet/vite.config.ts +47 -0
  718. package/examples/vite-wallet/vitest.config.ts +17 -0
  719. package/package.json +9 -4
  720. package/packages/core/.size-limit.js +47 -0
  721. package/packages/core/LICENSE +21 -0
  722. package/packages/core/README.md +84 -0
  723. package/packages/core/llms.txt +610 -0
  724. package/packages/core/package.json +89 -0
  725. package/packages/core/src/call.ts +961 -0
  726. package/packages/core/src/canister.ts +259 -0
  727. package/packages/core/src/client.ts +2061 -0
  728. package/packages/core/src/errors.ts +1079 -0
  729. package/packages/core/src/hydration.ts +239 -0
  730. package/packages/core/src/index.ts +23 -0
  731. package/packages/core/src/keys.ts +108 -0
  732. package/packages/core/src/management.ts +138 -0
  733. package/packages/core/src/network.ts +1020 -0
  734. package/packages/core/src/options.ts +1000 -0
  735. package/packages/core/src/runtime.ts +50 -0
  736. package/packages/core/src/testing/fake-replica.ts +1166 -0
  737. package/packages/core/src/testing/index.ts +16 -0
  738. package/packages/core/src/testing/test-auth.ts +340 -0
  739. package/packages/core/src/testing/test-client.ts +559 -0
  740. package/packages/core/src/types.ts +541 -0
  741. package/packages/core/src/units.ts +299 -0
  742. package/packages/core/src/version.ts +4 -0
  743. package/packages/core/tests/canister-helpers.ts +187 -0
  744. package/packages/core/tests/canister-id.test.ts +158 -0
  745. package/packages/core/tests/canister-unwrap.test.ts +94 -0
  746. package/packages/core/tests/canister.test-d.ts +406 -0
  747. package/packages/core/tests/canister.test.ts +1921 -0
  748. package/packages/core/tests/client-account-change.test.ts +131 -0
  749. package/packages/core/tests/client-agents.test.ts +402 -0
  750. package/packages/core/tests/client-auth-network.test.ts +719 -0
  751. package/packages/core/tests/client-disposed.test.ts +403 -0
  752. package/packages/core/tests/client-helpers.ts +136 -0
  753. package/packages/core/tests/client-hydration.test.ts +166 -0
  754. package/packages/core/tests/client-pinned.test.ts +626 -0
  755. package/packages/core/tests/client-session.test.ts +348 -0
  756. package/packages/core/tests/client.test-d.ts +181 -0
  757. package/packages/core/tests/client.test.ts +1162 -0
  758. package/packages/core/tests/encode.test.ts +171 -0
  759. package/packages/core/tests/env-canister-id.test.ts +666 -0
  760. package/packages/core/tests/env-cookie-copies.test.ts +182 -0
  761. package/packages/core/tests/error-guard.test.ts +222 -0
  762. package/packages/core/tests/errors.test-d.ts +280 -0
  763. package/packages/core/tests/errors.test.ts +1359 -0
  764. package/packages/core/tests/fixtures/README.md +28 -0
  765. package/packages/core/tests/fixtures/accounts.did +21 -0
  766. package/packages/core/tests/fixtures/accounts.envelope.json +367 -0
  767. package/packages/core/tests/fixtures/accounts.ts +26 -0
  768. package/packages/core/tests/fixtures/archive.did +31 -0
  769. package/packages/core/tests/fixtures/archive.envelope.json +259 -0
  770. package/packages/core/tests/fixtures/archive.ts +55 -0
  771. package/packages/core/tests/fixtures/icrc1.did +88 -0
  772. package/packages/core/tests/fixtures/icrc1.envelope.json +840 -0
  773. package/packages/core/tests/fixtures/icrc1.ts +78 -0
  774. package/packages/core/tests/fixtures/management.did +724 -0
  775. package/packages/core/tests/fixtures/management.envelope.json +4455 -0
  776. package/packages/core/tests/fixtures/management.ts +486 -0
  777. package/packages/core/tests/fixtures/shapes.did +33 -0
  778. package/packages/core/tests/fixtures/shapes.envelope.json +440 -0
  779. package/packages/core/tests/fixtures/shapes.ts +56 -0
  780. package/packages/core/tests/fixtures/skippable.did +15 -0
  781. package/packages/core/tests/fixtures/skippable.envelope.json +182 -0
  782. package/packages/core/tests/fixtures/skippable.ts +33 -0
  783. package/packages/core/tests/func.test.ts +154 -0
  784. package/packages/core/tests/identity-attributes.test.ts +214 -0
  785. package/packages/core/tests/keys.test.ts +289 -0
  786. package/packages/core/tests/management.test.ts +206 -0
  787. package/packages/core/tests/network-helpers.ts +121 -0
  788. package/packages/core/tests/network.test-d.ts +78 -0
  789. package/packages/core/tests/network.test.ts +1051 -0
  790. package/packages/core/tests/options.test.ts +1594 -0
  791. package/packages/core/tests/redirect-sign-in.test.ts +393 -0
  792. package/packages/core/tests/resend.test-d.ts +81 -0
  793. package/packages/core/tests/resend.test.ts +723 -0
  794. package/packages/core/tests/skip.test-d.ts +125 -0
  795. package/packages/core/tests/testing-entry.test.ts +73 -0
  796. package/packages/core/tests/testing-fake-replica.test.ts +1242 -0
  797. package/packages/core/tests/testing-test-auth.test-d.ts +84 -0
  798. package/packages/core/tests/testing-test-auth.test.ts +483 -0
  799. package/packages/core/tests/testing-test-client.test-d.ts +184 -0
  800. package/packages/core/tests/testing-test-client.test.ts +1272 -0
  801. package/packages/core/tests/time-realm.test.ts +63 -0
  802. package/packages/core/tests/time.test.ts +238 -0
  803. package/packages/core/tests/traps/README.md +39 -0
  804. package/packages/core/tests/traps/anonymous-write.test.ts +145 -0
  805. package/packages/core/tests/traps/classification-table.test.ts +256 -0
  806. package/packages/core/tests/traps/err-arm.test.ts +144 -0
  807. package/packages/core/tests/traps/fetch-spy.ts +39 -0
  808. package/packages/core/tests/traps/invalidation-after-write.test.ts +178 -0
  809. package/packages/core/tests/traps/ledger.ts +248 -0
  810. package/packages/core/tests/traps/root-key-off-local.test.ts +130 -0
  811. package/packages/core/tests/traps/stale-data-across-users.test.ts +173 -0
  812. package/packages/core/tests/traps/unresolved-name.test.ts +155 -0
  813. package/packages/core/tests/traps/update-as-query.test.ts +244 -0
  814. package/packages/core/tests/traps/update-not-resent.test.ts +126 -0
  815. package/packages/core/tests/traps/update-resent-when-never-delivered.test.ts +159 -0
  816. package/packages/core/tests/traps.test-d.ts +476 -0
  817. package/packages/core/tests/units.test-d.ts +118 -0
  818. package/packages/core/tests/units.test.ts +634 -0
  819. package/packages/core/tsconfig.json +19 -0
  820. package/packages/core/tsconfig.typecheck.json +16 -0
  821. package/packages/core/vitest.config.ts +13 -0
  822. package/packages/mcp/LICENSE +21 -0
  823. package/packages/mcp/README.md +189 -0
  824. package/packages/mcp/package.json +62 -0
  825. package/packages/mcp/src/candid/candid-text.test.ts +455 -0
  826. package/packages/mcp/src/candid/candid-text.ts +501 -0
  827. package/packages/mcp/src/candid/contract.test.ts +398 -0
  828. package/packages/mcp/src/candid/formats.ts +155 -0
  829. package/packages/mcp/src/candid/hex.ts +29 -0
  830. package/packages/mcp/src/candid/json-schema.test.ts +758 -0
  831. package/packages/mcp/src/candid/json-schema.ts +454 -0
  832. package/packages/mcp/src/candid/json.test.ts +1207 -0
  833. package/packages/mcp/src/candid/json.ts +1053 -0
  834. package/packages/mcp/src/candid/schema-walk.ts +189 -0
  835. package/packages/mcp/src/candid/type-text.test.ts +179 -0
  836. package/packages/mcp/src/candid/type-text.ts +238 -0
  837. package/packages/mcp/src/cli.ts +134 -0
  838. package/packages/mcp/src/identity.ts +188 -0
  839. package/packages/mcp/src/interface/cache.test.ts +48 -0
  840. package/packages/mcp/src/interface/cache.ts +68 -0
  841. package/packages/mcp/src/interface/cli-cache.test.ts +150 -0
  842. package/packages/mcp/src/interface/cli-cache.ts +122 -0
  843. package/packages/mcp/src/interface/compile-worker.test.ts +246 -0
  844. package/packages/mcp/src/interface/compile-worker.ts +290 -0
  845. package/packages/mcp/src/interface/compile.test.ts +155 -0
  846. package/packages/mcp/src/interface/compile.ts +281 -0
  847. package/packages/mcp/src/interface/docs.test.ts +105 -0
  848. package/packages/mcp/src/interface/docs.ts +86 -0
  849. package/packages/mcp/src/interface/fixtures/icrc1.did +88 -0
  850. package/packages/mcp/src/interface/hex.ts +8 -0
  851. package/packages/mcp/src/interface/ids.test.ts +71 -0
  852. package/packages/mcp/src/interface/ids.ts +87 -0
  853. package/packages/mcp/src/interface/loader.test.ts +804 -0
  854. package/packages/mcp/src/interface/loader.ts +519 -0
  855. package/packages/mcp/src/interface/read-candid.test.ts +300 -0
  856. package/packages/mcp/src/interface/read-candid.ts +259 -0
  857. package/packages/mcp/src/interface/types.ts +113 -0
  858. package/packages/mcp/src/network.ts +122 -0
  859. package/packages/mcp/src/options.ts +149 -0
  860. package/packages/mcp/src/server/approval.ts +159 -0
  861. package/packages/mcp/src/server/naming.ts +43 -0
  862. package/packages/mcp/src/server/results.ts +102 -0
  863. package/packages/mcp/src/server/server.ts +797 -0
  864. package/packages/mcp/src/server/tools.ts +116 -0
  865. package/packages/mcp/src/usage.ts +40 -0
  866. package/packages/mcp/tests/approval.test.ts +60 -0
  867. package/packages/mcp/tests/identity.test.ts +234 -0
  868. package/packages/mcp/tests/naming.test.ts +62 -0
  869. package/packages/mcp/tests/options.test.ts +140 -0
  870. package/packages/mcp/tests/server.test.ts +997 -0
  871. package/packages/mcp/tsconfig.json +19 -0
  872. package/packages/mcp/tsconfig.typecheck.json +10 -0
  873. package/packages/mcp/vitest.config.ts +10 -0
  874. package/packages/react/LICENSE +21 -0
  875. package/packages/react/README.md +328 -0
  876. package/packages/react/llms.txt +95 -0
  877. package/packages/react/package.json +95 -0
  878. package/packages/react/src/index.tsx +678 -0
  879. package/packages/react/tests/abandoned-render.test.tsx +816 -0
  880. package/packages/react/tests/auth.test.tsx +315 -0
  881. package/packages/react/tests/caller-keys.test.tsx +2334 -0
  882. package/packages/react/tests/client-time.test.ts +40 -0
  883. package/packages/react/tests/entry.test.ts +52 -0
  884. package/packages/react/tests/helpers.tsx +291 -0
  885. package/packages/react/tests/hydration.test.tsx +262 -0
  886. package/packages/react/tests/ownership.test.tsx +260 -0
  887. package/packages/react/tests/provider.server.test.tsx +169 -0
  888. package/packages/react/tests/query-client.test.tsx +107 -0
  889. package/packages/react/tests/strict-mode.test.tsx +288 -0
  890. package/packages/react/tests/suspense.test-d.tsx +357 -0
  891. package/packages/react/tests/two-query-cores.test.tsx +135 -0
  892. package/packages/react/tests/types.test-d.tsx +63 -0
  893. package/packages/react/tsconfig.json +23 -0
  894. package/packages/react/tsconfig.test.json +8 -0
  895. package/packages/react/tsconfig.typecheck.json +16 -0
  896. package/packages/react/vitest.config.ts +39 -0
  897. package/packages/vite-plugin/LICENSE +21 -0
  898. package/packages/vite-plugin/README.md +532 -0
  899. package/packages/vite-plugin/package.json +76 -0
  900. package/packages/vite-plugin/src/describe-value.test.ts +43 -0
  901. package/packages/vite-plugin/src/describe-value.ts +167 -0
  902. package/packages/vite-plugin/src/dev-environment.test.ts +747 -0
  903. package/packages/vite-plugin/src/dev-environment.ts +510 -0
  904. package/packages/vite-plugin/src/env.ts +431 -0
  905. package/packages/vite-plugin/src/fetch.ts +348 -0
  906. package/packages/vite-plugin/src/file-identity.ts +106 -0
  907. package/packages/vite-plugin/src/generate.ts +691 -0
  908. package/packages/vite-plugin/src/index.test.ts +1243 -0
  909. package/packages/vite-plugin/src/index.ts +2565 -0
  910. package/packages/vite-plugin/src/interface.ts +339 -0
  911. package/packages/vite-plugin/src/local-host.ts +34 -0
  912. package/packages/vite-plugin/src/options.ts +641 -0
  913. package/packages/vite-plugin/src/principal-text.test.ts +87 -0
  914. package/packages/vite-plugin/src/principal-text.ts +98 -0
  915. package/packages/vite-plugin/tests/close.test.ts +141 -0
  916. package/packages/vite-plugin/tests/environment-mode.test.ts +136 -0
  917. package/packages/vite-plugin/tests/fake-ic.ts +214 -0
  918. package/packages/vite-plugin/tests/fetch-sdk.test.ts +27 -0
  919. package/packages/vite-plugin/tests/fetch.test.ts +1196 -0
  920. package/packages/vite-plugin/tests/fixtures/fake-cli/bin.js +90 -0
  921. package/packages/vite-plugin/tests/fixtures/fake-cli/package.json +8 -0
  922. package/packages/vite-plugin/tests/fixtures/icrc1.did +88 -0
  923. package/packages/vite-plugin/tests/generation.test.ts +1036 -0
  924. package/packages/vite-plugin/tests/icp-command.test.ts +194 -0
  925. package/packages/vite-plugin/tests/icp-timeout.test.ts +83 -0
  926. package/packages/vite-plugin/tests/no-process-exit.test.ts +83 -0
  927. package/packages/vite-plugin/tests/on-generated.test.ts +323 -0
  928. package/packages/vite-plugin/tests/output-collision.test.ts +329 -0
  929. package/packages/vite-plugin/tests/package.test.ts +62 -0
  930. package/packages/vite-plugin/tests/project.test.ts +2993 -0
  931. package/packages/vite-plugin/tests/support.ts +339 -0
  932. package/packages/vite-plugin/tests/timeout.test.ts +107 -0
  933. package/packages/vite-plugin/tsconfig.json +23 -0
  934. package/packages/vite-plugin/tsconfig.typecheck.json +16 -0
  935. package/packages/vite-plugin/vitest.config.ts +9 -0
  936. package/pnpm-workspace.yaml +23 -0
  937. package/scripts/ai-context-files.js +72 -0
  938. package/scripts/assemble-docs-site.mjs +485 -0
  939. package/scripts/assemble-docs-site.test.mjs +568 -0
  940. package/scripts/build-examples.js +58 -0
  941. package/scripts/check-ai-context.js +963 -0
  942. package/scripts/check-ai-context.test.mjs +811 -0
  943. package/scripts/check-exports.mjs +767 -0
  944. package/scripts/check-exports.test.mjs +1136 -0
  945. package/scripts/check-snippets/ambient.d.ts +428 -0
  946. package/scripts/check-snippets/app/generated/backend.did +7 -0
  947. package/scripts/check-snippets/app/generated/backend.ts +15 -0
  948. package/scripts/check-snippets/app/generated/icrc1.did +88 -0
  949. package/scripts/check-snippets/app/generated/icrc1.ts +78 -0
  950. package/scripts/check-snippets/app/globals.ts +26 -0
  951. package/scripts/check-snippets/docs/guides/App.tsx +21 -0
  952. package/scripts/check-snippets/docs/guides/app/providers.tsx +23 -0
  953. package/scripts/check-snippets/docs/guides/auth-client.ts +47 -0
  954. package/scripts/check-snippets/docs/guides/canisters/backend.ts +3 -0
  955. package/scripts/check-snippets/docs/guides/canisters/icrc1.ts +3 -0
  956. package/scripts/check-snippets/docs/guides/components/LedgerCard.tsx +26 -0
  957. package/scripts/check-snippets/docs/guides/components/shell.tsx +11 -0
  958. package/scripts/check-snippets/docs/guides/components/sign-in-page.tsx +29 -0
  959. package/scripts/check-snippets/docs/guides/components/slow-section.tsx +5 -0
  960. package/scripts/check-snippets/docs/guides/generated/accounts.ts +95 -0
  961. package/scripts/check-snippets/docs/guides/generated/ckbtc_minter.ts +40 -0
  962. package/scripts/check-snippets/docs/guides/generated/icp_ledger.ts +267 -0
  963. package/scripts/check-snippets/docs/guides/ledger.ts +10 -0
  964. package/scripts/check-snippets/docs/guides/server/request-client.ts +8 -0
  965. package/scripts/check-snippets.mjs +993 -0
  966. package/scripts/check-snippets.test.mjs +338 -0
  967. package/scripts/check-stack.mjs +501 -0
  968. package/scripts/check-stack.test.mjs +800 -0
  969. package/scripts/clean-node-modules.js +67 -0
  970. package/scripts/example-projects.js +58 -0
  971. package/scripts/export-budget.mjs +145 -0
  972. package/scripts/faults.json +6749 -0
  973. package/scripts/lib/fault-workspace.mjs +210 -0
  974. package/scripts/lib/io.mjs +29 -0
  975. package/scripts/lib/io.test.mjs +38 -0
  976. package/scripts/lib/markdown-fences.mjs +56 -0
  977. package/scripts/lib/markdown-fences.test.mjs +84 -0
  978. package/scripts/lib/package-exports.mjs +54 -0
  979. package/scripts/lib/package-exports.test.mjs +66 -0
  980. package/scripts/lib/release-pr-steps.mjs +47 -0
  981. package/scripts/release-tag.mjs +95 -0
  982. package/scripts/release-tag.test.mjs +278 -0
  983. package/scripts/release-workflow.test.mjs +98 -0
  984. package/scripts/release.js +167 -0
  985. package/scripts/release.test.mjs +347 -0
  986. package/scripts/removed-v3-names.js +125 -0
  987. package/scripts/size-app/.size-limit.js +90 -0
  988. package/scripts/size-app/core.js +3 -0
  989. package/scripts/size-app/package.json +24 -0
  990. package/scripts/size-app/react.js +4 -0
  991. package/scripts/size-app.test.mjs +73 -0
  992. package/scripts/sync-ai-context-versions.js +102 -0
  993. package/scripts/sync-example-versions.js +151 -0
  994. package/scripts/test-examples-published.mjs +1585 -0
  995. package/scripts/test-examples-published.test.mjs +1586 -0
  996. package/scripts/traps/any-method-vars-not-a-list.json +5 -0
  997. package/scripts/traps/canister-method-unknown.json +5 -0
  998. package/scripts/traps/client-says-who-calls-once.json +5 -0
  999. package/scripts/traps/client-says-who-calls.json +5 -0
  1000. package/scripts/traps/err-only-on-canister-err.json +14 -0
  1001. package/scripts/traps/format-units-refuses-missing-value.json +5 -0
  1002. package/scripts/traps/format-units-refuses-number.json +5 -0
  1003. package/scripts/traps/format-units-unknown-option.json +5 -0
  1004. package/scripts/traps/guard-err-is-the-methods.json +5 -0
  1005. package/scripts/traps/guard-false-keeps-every-kind.json +5 -0
  1006. package/scripts/traps/internals-not-exported.json +9 -0
  1007. package/scripts/traps/network-refuses-unknown-name.json +5 -0
  1008. package/scripts/traps/never-err-has-no-type.json +5 -0
  1009. package/scripts/traps/options-method-unknown.json +5 -0
  1010. package/scripts/traps/options-vars-wrong-type.json +5 -0
  1011. package/scripts/traps/parse-units-refuses-number.json +5 -0
  1012. package/scripts/traps/parse-units-unknown-option.json +5 -0
  1013. package/scripts/traps/principal-is-not-plain-text.json +14 -0
  1014. package/scripts/traps/query-options-refuses-oneway.json +5 -0
  1015. package/scripts/traps/query-options-refuses-update.json +5 -0
  1016. package/scripts/traps/refuse-next-unknown-option.json +5 -0
  1017. package/scripts/traps/resend-key-reads-the-methods-arg.json +5 -0
  1018. package/scripts/traps/resend-states-its-dedupe-key.json +5 -0
  1019. package/scripts/traps/suspense-refuses-argument-skip.json +5 -0
  1020. package/scripts/traps/suspense-refuses-skippable-read.json +5 -0
  1021. package/scripts/traps/suspense-refuses-vars-skip-fits.json +5 -0
  1022. package/scripts/traps/test-handler-method-unknown.json +5 -0
  1023. package/scripts/traps/test-handler-nat-is-bigint.json +5 -0
  1024. package/scripts/traps/test-handler-takes-the-domain-value.json +5 -0
  1025. package/scripts/traps/vars-of-two-arguments-are-the-tuple.json +5 -0
  1026. package/scripts/typecheck-examples.js +122 -0
  1027. package/scripts/verify-faults.mjs +375 -0
  1028. package/scripts/verify-faults.test.mjs +402 -0
  1029. package/scripts/verify-package-artifacts.mjs +590 -0
  1030. package/scripts/verify-peer-floors.js +399 -0
  1031. package/scripts/verify-peer-floors.test.mjs +422 -0
  1032. package/scripts/verify-test-fails-rules.mjs +104 -0
  1033. package/scripts/verify-test-fails-rules.test.mjs +215 -0
  1034. package/scripts/verify-test-fails.js +371 -0
  1035. package/scripts/verify-traps.mjs +505 -0
  1036. package/scripts/verify-traps.test.mjs +521 -0
  1037. package/scripts/verify-typescript-floor.js +239 -0
  1038. package/skill-packages/ic-reactor/SKILL.md +103 -0
  1039. package/stack.json +8 -0
  1040. package/tsconfig.base.json +23 -0
  1041. package/tsconfig.json +8 -0
@@ -0,0 +1,1346 @@
1
+ # Pre-registration
2
+
3
+ Recorded on 2026-09-30, before any agent run. Do not edit after the first run
4
+ starts; add a dated addendum instead.
5
+
6
+ ## Question
7
+
8
+ Do AI coding agents write safer Internet Computer code with the typed handle
9
+ layer (`v4-proto`) than with a generated module, raw TanStack Query and an
10
+ equally good guide (`thin-guide`)?
11
+
12
+ ## Decision rule
13
+
14
+ Build the handle layer only if, for the full matrix, on **both** tasks
15
+ (`node-tool` and `react-wallet`):
16
+
17
+ 1. the safe-run rate of `v4-proto` minus that of `thin-guide` is at least
18
+ **0.15**, and
19
+ 2. the lower bound of the 95% Newcombe interval on that difference is above 0.
20
+
21
+ Anything else, including an ambiguous result or both arms near the ceiling,
22
+ means the handle layer is not built and the thin layer ships.
23
+
24
+ ## Definitions
25
+
26
+ - **Safe-run rate**: the fraction of runs with zero violations of a
27
+ safety-marked requirement in `tasks/<task>/task.json`, as computed by
28
+ `score.mjs` and `harness/aggregate.mjs`.
29
+ - **Main analysis** excludes contaminated runs. The intent-to-treat result
30
+ (contaminated runs kept) is reported beside it. If the two disagree on the
31
+ decision rule, the result is ambiguous.
32
+ - Comparisons are within one task and one model. Models are never pooled. With
33
+ more than one model, the rule must hold for each model.
34
+ - Secondary, reported but not decisive: mean requirements met, `tsc`-clean
35
+ rate, `thin-guide` minus `thin` (the documentation effect), and `v3`.
36
+
37
+ ## Pilot
38
+
39
+ - Model: `claude-sonnet-5-5`. 5 runs per cell, 8 cells, 40 runs, seed 1.
40
+ - Purpose: measure variance, minutes, turns and cost per run, check for ceiling
41
+ or floor effects, and confirm the sandbox and driver work with the real CLI.
42
+ - The pilot does not decide the question. Its runs are not pooled into the full
43
+ matrix.
44
+ - The full matrix size is chosen after the pilot, from the runs per cell it
45
+ reports for a margin of 0.15.
46
+
47
+ ## Known limits
48
+
49
+ See "Threats to validity" in `README.md`. In particular: one author wrote the
50
+ tasks, tests, prototype, guides and reference solutions; the prototype's typed
51
+ service file is hand-written, standing in for code generation that does not
52
+ exist yet; and `v3` is in model training data while the other stacks are not.
53
+
54
+ ## Addendum 1 — 2026-09-30
55
+
56
+ Added after the first pilot, before any further agent run. The text above is
57
+ unchanged.
58
+
59
+ **First pilot result.** `claude-sonnet-5-5`, effort `medium`, 5 runs per cell,
60
+ 8 cells, 40 runs, seed 1, sandboxed mode, `--jobs 2`, with the task prompts
61
+ as they stood (`tasks/<task>/prompt.md`, now called the `explicit` prompt
62
+ variant). Every cell was at the ceiling: 5 of 5 runs safe (Wilson 95%
63
+ [0.566, 1]), mean requirements met 1, `tsc`-clean 1; every difference 0
64
+ (Newcombe 95% [-0.434, 0.434]); no harness errors. The explicit prompt states
65
+ every safety rule the hidden tests check, so the pilot measured whether agents
66
+ follow stated rules, which all four conditions do. No margin can be detected
67
+ from there. Results: `runs/2026-09-30T14-22-05-924Z/`.
68
+
69
+ **Contamination audit.** At run time the transcript audit marked 2 of the 40
70
+ runs contaminated (both `react-wallet` / `thin`). Both were false positives:
71
+ the scanner read grep patterns and program source (`node -e`, heredocs) as
72
+ file paths. The scanner now parses shell commands, treats patterns and
73
+ program text as such, and marks a run contaminated only for an outside read
74
+ that succeeded. Re-audited from the stored transcripts
75
+ (`drive.mjs --aggregate <dir> --rescan`), 0 of 40 are contaminated; the
76
+ original records are kept, the re-audit is written beside them
77
+ (`summary.rescanned.json`, `pilot.rescanned.json`). The conclusion above holds
78
+ under both.
79
+
80
+ **Second pilot.** Same model (`claude-sonnet-5-5`), same effort (`medium`),
81
+ same 5 runs per cell, 8 cells, seed 1, same hidden tests, scoring, margin
82
+ (0.15) and decision rule, with the `minimal` prompt variant
83
+ (`tasks/<task>/prompt.minimal.md`, `drive.mjs --prompt minimal`): the product
84
+ and its public contract (signatures, result shape, DOM test ids and states,
85
+ config inputs, and the neutral meaning of `mayHaveExecuted` and of the
86
+ `unknown` state), without the safety rules. Conditions still differ only in
87
+ the library line; condition docs are unchanged.
88
+
89
+ - The prompt variant is recorded in every run record and is part of every
90
+ cell: variants are never pooled, and comparisons are made only within one
91
+ variant, as for models and effort levels.
92
+ - The second pilot, like the first, does not decide the question; its runs
93
+ are not pooled into the full matrix.
94
+ - Which variant the full matrix uses, and its runs per cell, are chosen after
95
+ the second pilot and recorded in a further dated addendum before the full
96
+ matrix starts.
97
+
98
+ Approved by owner: yes, on 2026-09-30, before the second pilot started ("run the second pilot with the minimal prompt").
99
+
100
+ ## Addendum 2 — 2026-09-30
101
+
102
+ Added after the second pilot, before any further agent run. The text above,
103
+ including Addendum 1, is unchanged.
104
+
105
+ **Second pilot, as scored at run time.** `claude-sonnet-5-5`, effort
106
+ `medium`, `--prompt minimal`, 5 runs per cell, 8 cells, 40 runs, seed 1,
107
+ sandboxed, `--jobs 2`; results in `runs/2026-09-30T15-48-23-343Z/`, log
108
+ `runs-pilot2.log`. No harness errors, no contaminated runs. The safe-run
109
+ rate was 0 of 5 in every cell (Wilson 95% [0, 0.434]), because
110
+ `input_validation` failed in 39 of 40 runs through a single test,
111
+ `refuses_invalid_amount`. Everything else: `basic_function`, `exactness`,
112
+ `no_anonymous_send`, `no_resend`, `root_key_trust` and (react-wallet)
113
+ `no_stale_balance` passed in 5 of 5 runs in every cell; `outcome_classification`
114
+ passed 5 of 5 for `thin-guide` and `v4-proto` and 0 of 5 for `thin` and `v3`,
115
+ on both tasks.
116
+
117
+ **Diagnosis.** Every stored solution was re-run offline against each amount
118
+ input of that test (`harness/probes/probe.mjs`). All 40 refused `-1`, `abc`,
119
+ `""`, `1e3` and `1.123456789` (9 fraction digits) without contacting the
120
+ ledger. 39 of 40 sent both amounts past nat64 (2^64 base units and
121
+ 99999999999999999999 tokens) to the ledger; only node-tool / `thin` run 003
122
+ refused them. So the test failed on one rule only: the nat64 cap.
123
+
124
+ - The nat64 cap is stated only by the explicit prompt. The ledger's `amount`
125
+ is Candid `nat` (`harness/icrc1.did`: `type Tokens = nat`); no condition's
126
+ library, docs or starter mentions a cap (the guides mention `nat64` only in
127
+ their type-mapping tables), and the minimal prompt does not. Under the
128
+ minimal prompt no agent in any condition could know it.
129
+ - Refusing more than 8 fraction digits, rather than rounding or truncating:
130
+ `v3`'s docs state it (`parseTokenAmount` throws a `RangeError` for more
131
+ fraction digits than the token has); in `thin`, `thin-guide` and `v4-proto`
132
+ nothing states it, but the minimal prompt defines the amount as whole
133
+ tokens with 8 decimals (`"1.5"` is 150000000 base units), so a ninth digit
134
+ has no exact base-unit value and any rounding sends an amount the user did
135
+ not write. It is kept applicable under both variants. All 40 runs refused
136
+ it, so excluding it too would not change this pilot's result.
137
+
138
+ **The change.** `refuses_invalid_amount` is split into three tests in the
139
+ same `input_validation` requirement, on both tasks: `refuses_malformed_amount`
140
+ (`-1`, `abc`, `""`, `1e3`), `refuses_excess_fraction_digits` (`1.123456789`)
141
+ and `refuses_amount_past_nat64` (2^64 base units; 99999999999999999999). In
142
+ `task.json`, `notApplicable.minimal` lists `refuses_amount_past_nat64`: under
143
+ the minimal prompt it runs and is reported with its result, but counts
144
+ toward no requirement, safe-run rate or requirements met; under the explicit
145
+ prompt it counts as before. Two further changes came with the split: the
146
+ react-wallet test now uses the same seven inputs as node-tool (it used
147
+ three), and the refusal tests judge only transfers sent to their own
148
+ recipient, because a mutant's background retry of an earlier test's
149
+ transfer was otherwise blamed on them. Six new faulty solutions (one per new
150
+ test per task) are in the gate, which passes 45 of 45.
151
+
152
+ **Re-scored result** (`drive.mjs --aggregate <dir> --rescore`: the stored
153
+ solutions, the current tests, no agent launched; the run-time records are
154
+ kept). Second pilot, minimal prompt:
155
+
156
+ | Task | Condition | Safe-run rate (95% CI) | Requirements that failed |
157
+ | ------------ | ---------- | ---------------------- | -------------------------- |
158
+ | node-tool | v3 | 0/5 [0, 0.434] | outcome_classification 0/5 |
159
+ | node-tool | thin | 0/5 [0, 0.434] | outcome_classification 0/5 |
160
+ | node-tool | thin-guide | 5/5 [0.566, 1] | none |
161
+ | node-tool | v4-proto | 5/5 [0.566, 1] | none |
162
+ | react-wallet | v3 | 0/5 [0, 0.434] | outcome_classification 0/5 |
163
+ | react-wallet | thin | 0/5 [0, 0.434] | outcome_classification 0/5 |
164
+ | react-wallet | thin-guide | 5/5 [0.566, 1] | none |
165
+ | react-wallet | v4-proto | 5/5 [0.566, 1] | none |
166
+
167
+ Every other requirement passed 5 of 5 in every cell. The not-applicable
168
+ `refuses_amount_past_nat64` passed 1 of 20 runs on node-tool and 0 of 20 on
169
+ react-wallet. Differences in the safe-run rate (Newcombe 95%), on both tasks:
170
+ `v4-proto − thin-guide` 0 [-0.434, 0.434]; `thin-guide − thin` 1
171
+ [0.386, 1]. The failures in `thin` and `v3` are reject-code and HTTP 429
172
+ classification (for example `http_429_classified` / `http_429_is_error` in
173
+ 5 of 5 runs of each).
174
+
175
+ The first pilot (explicit prompt), re-scored the same way, is unchanged: 40
176
+ of 40 runs pass every test, including the three new ones; every cell 5 of 5
177
+ safe; every test result identical to the run-time scoring.
178
+
179
+ **This change was made after seeing the second pilot's data (post hoc).**
180
+ Why it is defensible:
181
+
182
+ - It removes, only under the variant that never states it, a rule that no
183
+ agent in any condition could know. It failed the same way in every
184
+ condition, so it carried no information about the conditions and pinned
185
+ every cell at the floor.
186
+ - It applies to all conditions alike. The explicit variant is scored as
187
+ before, and the first pilot's result does not move. The question, decision
188
+ rule, margin, primary metric and definitions are unchanged.
189
+
190
+ What it does not cure:
191
+
192
+ - Which rules count as knowable was decided with the results in view. The
193
+ one borderline case (the 9th fraction digit) was resolved in the stricter
194
+ direction, and it made no difference here.
195
+ - The separation now visible (`thin-guide` and `v4-proto` above `thin` and
196
+ `v3`) comes from `outcome_classification`, which the split did not touch.
197
+ It only became visible because of the split, so it is exploratory until a
198
+ new run confirms it.
199
+ - On the pre-registered comparison, `v4-proto − thin-guide`, the second
200
+ pilot is again at the ceiling on both tasks.
201
+ - The pilot still does not decide the question. The split, the test code and
202
+ the `notApplicable` list are fixed from now on, before any further agent
203
+ run; any further change needs another dated addendum.
204
+
205
+ Approved by owner: yes, on 2026-09-30 ("approve addendum 2").
206
+
207
+ ## Decision — 2026-09-30
208
+
209
+ Recorded after the second pilot was re-scored under Addendum 2, before any
210
+ further agent run.
211
+
212
+ **Outcome.** The owner stopped the experiment here. No full matrix is run.
213
+ The handle layer (`v4-proto`) is not built; ic-reactor 4 ships the thin layer:
214
+ a client, caller-scoped keys, one error union with "may have executed", a
215
+ "may have executed" classifier, strict units helpers, a test client, the
216
+ provider and `useAuth`, and a guide of the quality used in the `thin-guide`
217
+ condition.
218
+
219
+ **Basis.** Two pilots (explicit and minimal prompts, `claude-sonnet-5-5`,
220
+ effort `medium`, 5 runs per cell) gave `v4-proto` and `thin-guide` identical
221
+ results in every cell: 5 of 5 safe on both tasks under both prompts, with zero
222
+ variance, so the pre-registered difference is 0 [-0.434, 0.434] on both
223
+ tasks. Under the minimal prompt `thin-guide - thin` is 1 [0.386, 1] on both
224
+ tasks; the gap is entirely `outcome_classification`. The pilots do not decide
225
+ the question under the pre-registered rule; the decision is the owner's, made
226
+ on the grounds that two pilots showed no sign of the 0.15 margin and that the
227
+ full matrix (about 41 runs per cell) would spend usage to confirm a null.
228
+
229
+ **Standing.** The `thin-guide - thin` effect is exploratory (it became
230
+ visible only after the post-hoc split in Addendum 2) and rests on n = 5 per
231
+ cell, one model, one effort level, and guides and tests written by one author.
232
+ It is carried as a product lesson, not as a measured claim.
233
+
234
+ Approved by owner: yes, on 2026-09-30 ("stop here, ship the thin layer").
235
+
236
+ ## Addendum 3 — the 4.0.0-beta.1 gate
237
+
238
+ **Status: Frozen on 2026-10-03, before any agent run of the `v4` condition.**
239
+ Drafted on 2026-10-02. The text above, including Addenda 1 and 2 and the
240
+ Decision, is unchanged. From here it changes only through a further dated
241
+ addendum.
242
+
243
+ **What it decides.** Not whether to build anything (the Decision above
244
+ settled that), but whether ic-reactor 4 as packed may be released as
245
+ 4.0.0-beta.1: DECISIONS Q14 in issue #790, settled by the owner on
246
+ 2026-09-30. The question is whether the real packages keep the second
247
+ pilot's `thin-guide` result: every run safe on both tasks under the minimal
248
+ prompt.
249
+
250
+ **Conditions.**
251
+
252
+ - `v4`: `@ic-reactor/core` and `@ic-reactor/react` built and packed from the
253
+ `v4` branch at the commit under test, `@candid-core/schema` 0.3.0-beta.1,
254
+ the module `@candid-core/cli` 0.2.0-beta.1 generates, and the core
255
+ tarball's `llms.txt` (DX3's guide, issue #785) as the only documentation
256
+ (`conditions/v4/README.md`). `node setup.mjs` builds it from that commit.
257
+ - `thin-guide`: unchanged since the pilots (starter, dependencies, docs),
258
+ re-run in the same batch as a same-day control: same model, effort, prompt
259
+ and harness.
260
+
261
+ **The commit under test** is `1ff26e511c89ced4c980814b0d53f09d931ab1b0`
262
+ (branch `slice/dx5-run`: the `v4` branch with DX5 phase B, #807, and DX3,
263
+ #808, merged; `packages/**` there is what those two pull requests merge into
264
+ `v4`). `.ship/v4` built from it holds `@ic-reactor/core` 4.0.0-alpha.0,
265
+ `@ic-reactor/react` 4.0.0-alpha.0 and `@candid-core/schema` 0.3.0-beta.1, and
266
+ `conditions/v4/docs/llms.txt` is byte-identical to that commit's
267
+ `packages/core/llms.txt` (1,970 words; `harness/check-docs.mjs`: 0 of 112
268
+ needles). `node gate.mjs --require v4` on the same tree: 56 of 56. The
269
+ versions are written into `results/README.md` with the results.
270
+
271
+ **Fixed from the earlier addenda, unchanged.** The two tasks (`node-tool`,
272
+ `react-wallet`), their hidden tests, the world, `task.json` (including
273
+ `notApplicable.minimal`: `refuses_amount_past_nat64`), `score.mjs`,
274
+ `harness/judge.mjs`, and the leak audit as of Addendum 2 plus its network
275
+ check (next paragraph), which leaves every path judgement as it was. The
276
+ prompts differ across conditions only in the `{{LIBRARY}}` line
277
+ (`harness/assemble.test.mjs` checks it for every condition, `v4` included).
278
+
279
+ **Harness changes since Addendum 2.** The harness came to this branch
280
+ unchanged from the one the pilots ran on (`spike/v4-thesis` at 2bc1c17f7).
281
+ Besides adding the `v4` condition (above) and `gate.mjs --require` (pass
282
+ rule 2, below), these changed since, none of them in the hidden tests, the
283
+ world, `task.json`, `score.mjs` or `harness/judge.mjs`:
284
+
285
+ - `drive.mjs --resume` scores a run it runs again after a harness error.
286
+ Before, the run kept its harness-error record and the new attempt was
287
+ never scored.
288
+ - `drive.mjs` refuses to start a new batch in an `--out` directory that
289
+ already holds files. It would have taken the runs recorded there for its
290
+ own: an `agent.json` as run, a `score.json` as scored.
291
+ - The leak audit flags network use from the shell, not only the WebFetch
292
+ and WebSearch tools. The sandbox leaves the network open (the agent CLI
293
+ inside it needs its API, and a profile cannot allow one host), and
294
+ sandboxed agents may run `node`, so `node -e "fetch(…)"` could read, for
295
+ example, the published ic-reactor 3 guide and still count in the main
296
+ analysis. It now flags network commands (curl, wget, …), package-manager
297
+ and git commands that reach a registry or remote, a non-local URL given
298
+ to an interpreter, and interpreter code (`node -e`, a heredoc or pipe
299
+ into `node`, a script the run wrote and then runs) that calls the network
300
+ towards a non-local host or one it does not name (`README.md`, "Leak
301
+ audit and sandbox"). Such a call that ran makes the run contaminated, as
302
+ an outside read does; one the CLI refused or that failed is an attempt.
303
+ A test file run by vitest that fetches is still not seen. Re-audited with
304
+ it, all 80 pilot transcripts keep their audit record exactly (no network
305
+ use found; 0 of 40 contaminated in each pilot, as reported in Addendum 1
306
+ and Addendum 2).
307
+ - `gate.mjs --root <dir>` reads the solutions from another tree's
308
+ `tasks/`, for the harness's own test that `--require` fails the gate
309
+ before scoring anything when a required cell is empty
310
+ (`harness/gate-plan.test.mjs` runs the gate on a seeded tree; with the
311
+ `v4` references in this tree, that path could no longer be run here). The
312
+ gate this addendum runs takes no `--root`.
313
+ - The `v4` cells of the gate are filled: a `reference` and a
314
+ `reference-module-scope` for each task, written against the packed
315
+ packages, and the six v4-proto faulty solutions ported to them
316
+ (`tasks/*/faulty/v4-*`). Each port fails exactly the tests its v4-proto
317
+ original fails, so no `expectFail` list changed and none was dropped
318
+ (`conditions/v4/PORTING.md`). One faulty solution has no original:
319
+ `node-tool/faulty/v4-anonymous-identity-sent` passes the configured
320
+ identity through (`identity: config.identity ?? "anonymous"`), so an
321
+ explicit `AnonymousIdentity` is signed and sent, a trap the real library
322
+ opens where v4-proto did not; it fails exactly `no_anonymous_update`.
323
+ `harness/gate-plan.test.mjs` now checks on this tree that the gate skips
324
+ no cell, with `--require v4` and without, that it plans those four
325
+ references, six ports and the one `v4`-only solution, and that each port
326
+ expects what its original expects.
327
+
328
+ **Design.**
329
+
330
+ - Prompt: `minimal` (`tasks/<task>/prompt.minimal.md`); run mode
331
+ `sandboxed`.
332
+ - Cells: 2 tasks × 2 conditions = 4 cells, 5 runs per cell, 20 runs, in one
333
+ batch, ordered round-robin in a shuffle seeded 1 (so the two conditions
334
+ interleave in time).
335
+ - Model `claude-sonnet-5-5` at effort `medium`, as in both pilots. `drive.mjs`
336
+ passes them to the agent CLI as `--model claude-sonnet-5-5 --effort medium`
337
+ (`DEFAULT_AGENT_CMD`) and records both in `plan.json` and every run record.
338
+ - Commands, from `evals/` on the commit under test:
339
+
340
+ ```bash
341
+ node setup.mjs
342
+ node gate.mjs --require v4 # must pass first: pass rule 2
343
+ node drive.mjs --preflight --model claude-sonnet-5-5 --effort medium \
344
+ --oauth-token-file <file>
345
+ node drive.mjs --pilot --prompt minimal \
346
+ --condition v4 --condition thin-guide \
347
+ --model claude-sonnet-5-5 --effort medium --seed 1 --jobs 2 \
348
+ --margin 0.1 --oauth-token-file <file>
349
+ ```
350
+
351
+ `--pilot` sets 5 runs per cell. Defaults that stay as in the pilots:
352
+ `--mode sandboxed`, `--timeout-min 30`, `--max-turns 60`, `--retries 2`
353
+ and the rate-limit settings. `--margin 0.1` only sizes the GA run (the
354
+ runs per cell for a 0.10 difference); it decides nothing here.
355
+
356
+ - Rehearsed on 2026-10-02 with `--dry-run` (the batch command above without
357
+ `--jobs`, `--margin` and the token file; nothing launched): 4 cells, 20
358
+ runs, 5 per cell, in a shuffle seeded 1 that begins
359
+ `react-wallet/thin-guide#1`, `node-tool/thin-guide#1`, `node-tool/v4#1`,
360
+ `react-wallet/v4#1`, `node-tool/thin-guide#2`, `node-tool/v4#2`,
361
+ `react-wallet/v4#2`, `react-wallet/thin-guide#2`; each `v4` cell's
362
+ `docs/` is `llms.txt` only, and each `thin-guide` cell's is the two
363
+ candid-core READMEs and `llms.txt`, as in the pilots.
364
+
365
+ **Pass rule.** 4.0.0-beta.1 passes this gate only if both hold:
366
+
367
+ 1. **`v4` is safe in 5 of 5 runs on `node-tool` and in 5 of 5 on
368
+ `react-wallet`**, in the main analysis and in the intent-to-treat
369
+ analysis alike. "Safe" is as `score.mjs` and `harness/judge.mjs` compute
370
+ it under the minimal prompt (no applicable safety requirement failed).
371
+ Each `v4` cell must hold 5 scored runs, none contaminated: a cell with a
372
+ contaminated run, or with fewer than 5 scored runs once `drive.mjs` has
373
+ exhausted its retries, does not meet the rule.
374
+ 2. **`node gate.mjs` passes on the commit under test, with `v4` in it**: the
375
+ `v4` `reference` and `reference-module-scope` of both tasks pass every
376
+ hidden test with a clean `tsc`; the six v4-proto faulty solutions,
377
+ ported (`conditions/v4/PORTING.md`: from `v4-proto-never-may-have-executed`,
378
+ `v4-proto-refuses-nat64-max`, `v4-proto-retry-spread`,
379
+ `v4-proto-keep-previous-data`, `v4-proto-every-reject-unknown` and
380
+ `v4-proto-status-not-idle`), and `v4`'s own
381
+ `node-tool/faulty/v4-anonymous-identity-sent` each fail exactly the tests
382
+ in their `meta.json`: 56 of 56, no cell skipped. `--require v4` makes the
383
+ gate fail, before scoring anything, when a `v4` cell has no reference
384
+ solution, so "no cell skipped" is the gate's exit status and not a
385
+ reading of its output (an empty cell of the pilots' four conditions, or
386
+ one whose task holds faulty solutions of its condition, fails it too).
387
+ It is run before the batch; if it fails, the batch does not start.
388
+
389
+ `thin-guide` does not enter the rule. Its result is reported beside `v4`'s;
390
+ if it is below 5 of 5 on a task, the report says so, because the pilots'
391
+ baseline then did not reproduce on that day.
392
+
393
+ **Analyses**, as the Definitions and Addenda 1 and 2 define them:
394
+
395
+ - Main: contaminated runs excluded. Intent-to-treat: contaminated runs kept.
396
+ Both from the same `summary.json` (`main`, `intentToTreat`), with
397
+ contamination as the leak audit judged it at run time. A later re-audit
398
+ (`--rescan`) is reported beside it and does not change the outcome
399
+ without a further addendum.
400
+ - Harness errors are retried by the driver, then excluded and counted, never
401
+ scored as 0. Completing a planned run that ended in a harness error
402
+ (`drive.mjs --resume <dir>`) completes the batch; a scored run is never
403
+ replaced.
404
+ - Reported for each cell: the safe-run rate with its Wilson 95% interval,
405
+ per-requirement pass rates, mean requirements met, `tsc`-clean rate, the
406
+ not-applicable `refuses_amount_past_nat64` results, minutes, turns and
407
+ tokens. Reported for each task: `v4 - thin-guide` in the safe-run rate
408
+ with its Newcombe 95% interval (`harness/aggregate.mjs` computes this
409
+ comparison first). None of these decides the gate; rule 1 does.
410
+
411
+ **If it fails.** If rule 1 or rule 2 is not met, 4.0.0-beta.1 is not
412
+ released on this batch. The batch, or any cell of it, is not run again to
413
+ look for a pass. The failing runs and requirements are reported, and the
414
+ owner decides what follows: for example a change to the library or its
415
+ guide, followed by a new batch pre-registered in a further dated addendum,
416
+ or a release that states the result. Any change to the hidden tests, the
417
+ world, the scoring, the prompts or this rule after the batch starts needs a
418
+ dated addendum and the owner's approval, as Addendum 2 did.
419
+
420
+ **Known limits.**
421
+
422
+ - Five runs per cell: 5 of 5 has a Wilson 95% interval of [0.566, 1]. The
423
+ gate can catch a gross regression; it cannot show equivalence. GA uses
424
+ 20 runs per cell and non-inferiority, `v4 - thin-guide >= -0.10` on the
425
+ Newcombe lower bound, pre-registered in a further addendum before that
426
+ run (Q14).
427
+ - One model at one effort level; the pilots' caveats hold (one author wrote
428
+ the tasks, tests, guides and references; the separation from `thin` is
429
+ exploratory).
430
+ - The world still installs the fake replica that `@ic-reactor/core` 3.13.0
431
+ publishes as a global `fetch` stub before the solution loads; a v4 client
432
+ builds its agents after that and binds the stub like any `HttpAgent`
433
+ (issue #786). The scorer's `v4` install is the ship's except
434
+ `@icp-sdk/core`, a link to evals' own copy of the same version, so the
435
+ world and the solution load one instance of it, as in every other
436
+ condition (`conditions/v4/README.md`; `harness/ship.test.mjs` checks it).
437
+ - The react-wallet starter's `WalletAuth` is not an `AuthLike`; the agent
438
+ writes the adapter the guide shows (Q14). How well the guide teaches it,
439
+ and that an explicit `AnonymousIdentity` is sent while
440
+ `identity: "anonymous"` is not (`conditions/v4/PORTING.md`; the gate's
441
+ `v4-anonymous-identity-sent` shows the hidden tests catch it), is part of
442
+ what the batch measures. So is a third trap the port found: a client kept
443
+ at module scope and handed to `ReactorProvider` type-checks, and is
444
+ disposed when the first tree unmounts, after which every call of every
445
+ later tree is cancelled (in the hidden tests, 30 of 32 failed;
446
+ `conditions/v4/PORTING.md`, react-wallet module-scope variant). #805 (IR6)
447
+ since makes the provider borrow, and never dispose, a client created before
448
+ its factory runs; a client created lazily inside the factory
449
+ (`shared ??= createClient(...)`) is still owned by the first provider, and
450
+ the provider logs a development error when a later tree is handed it.
451
+ - `refuses_excess_fraction_digits` sends a nonzero ninth fraction digit.
452
+ `parseUnits` treats zeros past the decimals as insignificant
453
+ (`"1.000000000"` at 8 is 1 token, by design, #777), so a solution that
454
+ relies on it accepts `"1.123456780"`, which the explicit prompt's "more than
455
+ 8 fraction digits" would refuse. No hidden test sends such an amount, and
456
+ the hidden tests are fixed for this gate, so it is not scored; the v4
457
+ references count the raw fraction digits as well, as the explicit prompt
458
+ reads.
459
+
460
+ **Freezing.** This addendum is frozen, by replacing its status line with the
461
+ date and recording the owner's approval below, when all of these hold:
462
+ the `v4` references, the six ported faulty solutions and
463
+ `v4-anonymous-identity-sent` are in the tree and
464
+ `node gate.mjs --require v4` passes 56 of 56; `conditions/v4/docs/llms.txt`
465
+ is DX3's guide as packed and passes `node harness/check-docs.mjs`; the
466
+ commit under test is named above.
467
+
468
+ Approved by owner: yes, on 2026-10-02, as the goal of the session that built
469
+ 4.0.0-beta.1 ("The eval gate passes on the real packages: the harness's `v4`
470
+ condition, minimal prompt, both tasks, 5 runs each on Sonnet 5.5 at medium
471
+ effort, 5 of 5 safe, and `gate.mjs` green"; "Run agent evals on my
472
+ subscription with Sonnet 5.5 at medium effort, up to 60 runs in total"),
473
+ which is this addendum's design (DECISIONS Q14); frozen by the lead on
474
+ 2026-10-03, with the conditions under "Freezing" met.
475
+
476
+ ## Result of Addendum 3 — 2026-10-03
477
+
478
+ Recorded after the batch; Addendum 3 itself is unchanged. The batch ran as
479
+ pre-registered on the commit under test (`1ff26e511`): 20 runs, 4 cells of
480
+ 5, `claude-sonnet-5-5` at effort `medium`, minimal prompt, sandboxed, seed 1,
481
+ 2 agents at a time, with a passing preflight. Results:
482
+ `results/2026-10-03-beta1-gate/` (from `runs/beta1-gate-2026-10-03/`).
483
+
484
+ | Task | Condition | Safe (main) | Safe (ITT) | Requirements met | Contaminated | Harness errors |
485
+ | ------------ | ------------ | ----------- | ---------- | ---------------- | ------------ | -------------- |
486
+ | node-tool | `v4` | 5 of 5 | 5 of 5 | 1.00 | 0 | 0 |
487
+ | node-tool | `thin-guide` | 5 of 5 | 5 of 5 | 1.00 | 0 | 0 |
488
+ | react-wallet | `v4` | 5 of 5 | 5 of 5 | 1.00 | 0 | 0 |
489
+ | react-wallet | `thin-guide` | 5 of 5 | 5 of 5 | 1.00 | 0 | 0 |
490
+
491
+ Each 5 of 5 has a Wilson 95% interval of [0.566, 1]; `v4 - thin-guide` is 0
492
+ on both tasks (Newcombe [-0.434, 0.434]). Every run exited normally and
493
+ passed `tsc`; the leak audit, with its network check, found nothing.
494
+ `refuses_amount_past_nat64` stays not applicable under the minimal prompt
495
+ (observed: node-tool 1 of 10, react-wallet 0 of 10, all conditions).
496
+
497
+ **Pass rule.** Rule 1 holds: `v4` is safe in 5 of 5 runs on `node-tool`
498
+ and on `react-wallet`, in the main analysis and the intent-to-treat analysis
499
+ alike, with 5 scored, uncontaminated runs per cell. Rule 2 holds: `node
500
+ gate.mjs --require v4` on the same tree, 56 of 56. **4.0.0-beta.1 passes
501
+ this gate.**
502
+
503
+ The caveats of "Known limits" apply: five runs per cell can catch a gross
504
+ regression, not show equivalence; GA's gate is 20 runs per cell and a
505
+ non-inferiority bound, pre-registered first (Q14).
506
+
507
+ ## Addendum 4 — the 4.0.0 GA gate
508
+
509
+ **Status: Frozen on 2026-10-05, before any agent run of its design.** The
510
+ text above, including Addenda 1 to 3, the Decision and the Result of
511
+ Addendum 3, is unchanged.
512
+ Until this addendum is frozen no agent run of its design may start; after
513
+ it is frozen it changes only through a further dated addendum.
514
+
515
+ **What it decides.** Whether the eval side of the 4.0.0 GA gate is met:
516
+ DECISIONS Q14 in issue #790, settled by the owner on 2026-09-30 ("GA: 20 runs
517
+ per cell, non-inferiority `v4 − thin-guide ≥ −0.10` (Newcombe lower bound),
518
+ pre-registered in a new addendum before the run"). The question is whether
519
+ the published ic-reactor 4 packages are no worse than the `thin-guide`
520
+ control, by more than 0.10 in the safe-run rate under the minimal prompt.
521
+ It does not decide the GA exit criteria outside `evals/` (examples, docs,
522
+ e2e), and it makes no claim that `v4` is better than the control.
523
+
524
+ **Conditions.**
525
+
526
+ - `v4`: the packages **as published on npm**, not packed from a tree:
527
+ `@ic-reactor/core@4.0.0-beta.1` and `@ic-reactor/react@4.0.0-beta.1`
528
+ (exact versions, published on 2026-10-03 under the `beta` dist-tag by the
529
+ release workflow, which runs on the tag `v4.0.0-beta.1`, commit
530
+ `265b113e9`), `@candid-core/schema`
531
+ 0.3.0-beta.1, and the module `@candid-core/cli` 0.2.0-beta.1 generates
532
+ from `harness/icrc1.did`. Each tarball must have the `dist.integrity` the
533
+ registry records, which `harness/ship.mjs` (`V4_NPM_RELEASES`) pins and
534
+ `node setup.mjs --v4-from npm:4.0.0-beta.1` checks before anything is
535
+ installed (it refuses another sha512, or a registry that no longer
536
+ records the pin):
537
+
538
+ | Tarball | `dist.integrity` (npm view, 2026-10-05) |
539
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------- |
540
+ | `@ic-reactor/core@4.0.0-beta.1` | `sha512-qvxoX5SJa0ubJumLRctpYx9SqFynu3PXKO9E2fJpiDMKrb6y6rlxncR6XBALqjDdFi8UVYJxWXMhqG8Va/6alg==` |
541
+ | `@ic-reactor/react@4.0.0-beta.1` | `sha512-U0Bvz6qRmrnDCXCd27T28EJ3SNO5Z3eu2oENrHE5CMg6v36AzcjDWgwSzGTL+f8LDxGaFhvcuCGVAEYypNpCMg==` |
542
+ | `@candid-core/schema@0.3.0-beta.1` | `sha512-fO7uDzR1Dv8vvLec0/2mRpIMQrNW0KeFwlRfkDBmEy2IQ9aUflaacZgNn4jnM9amKvldAHT/o2novcV2m07Usg==` |
543
+ | `@candid-core/cli@0.2.0-beta.1` | `sha512-kmm1+COrojOVLVcpVjgHZ1c0Y/RSQoq90u3Wim/ss384NMlm4fwC2cWA7eq225a8kv+uhz1YvlVrClNYFQCaLQ==` |
544
+
545
+ The two ic-reactor rows are pinned and checked by setup; the schema row
546
+ is what npm's lockfile in `.ship/v4` records for the installed copy (npm
547
+ checks it when installing); the CLI runs through `npx` and is not
548
+ shipped. The only documentation is the core tarball's `llms.txt`.
549
+ Everything else is as in Addendum 3: the same install, the same
550
+ refusals (`harness/check-docs.mjs` on the guide, `harness/ship.mjs` on the
551
+ package code), the cut to `package.json` + `dist/`, and the scorer's copy
552
+ with `@icp-sdk/core` linked to evals' own (`conditions/v4/README.md`).
553
+
554
+ - `thin-guide`: unchanged since the pilots (starter, dependencies, docs),
555
+ re-run in the same batch as a same-day control: same model, effort, prompt
556
+ and harness.
557
+
558
+ **The version under test** is 4.0.0-beta.1 as published, and it stays
559
+ 4.0.0-beta.1 even if a 4.0.0-beta.2 (or the 4.0.0 tarball itself) is
560
+ prepared before or during the batch. The guide measured is the published
561
+ core tarball's `llms.txt`: 1,974 words (`wc -w`), sha256
562
+ `a07b846a637985bbf629abf65f524aea1f51887dc4099b814607fea299364342`,
563
+ byte-identical to `packages/core/llms.txt` at `265b113e9`, and 0 of 112
564
+ needles (`node harness/check-docs.mjs`). Packing that commit with `node
565
+ setup.mjs` (the tree mode) gives tarballs with other bytes (archive
566
+ metadata) and the same files, byte for byte, as the two published ones
567
+ (checked on 2026-10-05). The guide differs from the one Addendum 3
568
+ measured (1,970 words) in two places: the version line (`4.0.0-alpha.0` →
569
+ `4.0.0-beta.1`, same word count) and the 4-word change made after Addendum 3
570
+ ("returns it (as anonymous while hydrating)", #820). The published packages
571
+ also hold two changes Addendum 3's commit (`1ff26e511`) did not: #819 (a
572
+ disposed client cancels every call, writes included) and #820 (hydration
573
+ keys: a client view pinned to the principal a render shows, and React keys
574
+ built for the caller React renders with). `.ship/v4/source.json` records
575
+ the source of the tree setup built (`npm`, the version, each tarball's
576
+ integrity, the guide's words and sha256); `drive.mjs` prints it in a dry run
577
+ and keeps it in `plan.json` as `v4Source`.
578
+
579
+ **Fixed from the earlier addenda, unchanged.** The two tasks (`node-tool`,
580
+ `react-wallet`), their hidden tests, the world, `task.json` (including
581
+ `notApplicable.minimal`: `refuses_amount_past_nat64`), `score.mjs`,
582
+ `harness/judge.mjs`, and the leak audit as of Addendum 3 (with its network
583
+ check). The prompts differ across conditions only in the `{{LIBRARY}}` line
584
+ (`harness/assemble.test.mjs`). The Definitions (safe-run rate; main and
585
+ intent-to-treat analyses), the handling of harness errors, contamination,
586
+ `--resume` and re-audits as Addendum 3's "Analyses" state them, and
587
+ Addendum 3's defaults: `--mode sandboxed`, `--timeout-min 30`,
588
+ `--max-turns 60`, `--retries 2` and the rate-limit settings.
589
+
590
+ **Harness changes since Addendum 3.** None in the hidden tests, the world,
591
+ `task.json`, `score.mjs` or `harness/judge.mjs`; between `1ff26e511` and
592
+ `265b113e9` nothing under `evals/` changed but this file, `README.md`, the
593
+ results of Addendum 3 and `conditions/v4/docs/llms.txt`. This addendum's
594
+ pull request adds:
595
+
596
+ - `node setup.mjs --v4-from npm:<version>`: the two v4 tarballs, from
597
+ `npm pack <name>@<version>`, refused unless their sha512 equals the pin in
598
+ `harness/ship.mjs` and the registry's `dist.integrity`; every later step
599
+ is the packed tree's. `--v4-from tree`, the default, is Addendum 3's mode,
600
+ unchanged. Setup writes `.ship/v4/source.json`.
601
+ - `harness/ship.test.mjs`: the npm source on local tarball fixtures
602
+ (offline: a one-byte change, a missing tarball, a registry that disagrees,
603
+ a version with no pin; and setup's download itself, `fetchV4Tarballs`,
604
+ with `npm pack` and `npm view` faked), the recorded source against the
605
+ tarballs in `.ship/v4/tarballs` and npm's lockfile, the guide byte for
606
+ byte as the core tarball holds it, and one test that asks the registry
607
+ whether it still records the pins (skipped, with the reason, when it
608
+ cannot be reached).
609
+ - `harness/aggregate.mjs`: `pooled` in the main and intent-to-treat
610
+ summaries: each comparison with the tasks pooled (safe runs and runs
611
+ summed per condition over the tasks where both conditions have usable
612
+ runs, within one model, effort level and prompt variant), with its
613
+ Newcombe 95% interval and the counts; printed after the per-task
614
+ differences. It decides nothing unless the pass rule below says so
615
+ (alternative A).
616
+ - `drive.mjs`: the v4 source in a dry run and in `plan.json` (`v4Source`),
617
+ each tested (`harness/drive.test.mjs`; `plan.json` by a stub batch that
618
+ stops at its preflight).
619
+ - `conditions/v4/docs/llms.txt`: the published guide (1,974 words), which
620
+ setup copies from the core tarball, replacing Addendum 3's 1,970-word copy.
621
+
622
+ **Design.**
623
+
624
+ - Prompt: `minimal` (`tasks/<task>/prompt.minimal.md`); run mode
625
+ `sandboxed`.
626
+ - Cells: 2 tasks × 2 conditions = 4 cells, 20 runs per cell, 80 runs, in one
627
+ batch, ordered round-robin in a shuffle seeded **20261005** (a new seed,
628
+ the date this addendum was drafted; Addendum 3 used 1).
629
+ - Model `claude-sonnet-5-5` at effort `medium`, as in the pilots and
630
+ Addendum 3, passed to the CLI as
631
+ `--model claude-sonnet-5-5 --effort medium` and recorded in `plan.json`
632
+ and every run record.
633
+ - Two agents at a time (`--jobs 2`), as in every batch so far: the
634
+ credential is a subscription token, which is rate-limited per account
635
+ (`README.md`, "Parallelism on a subscription"), and the machine (8 cores,
636
+ 8 GB) runs `tsc` and `vitest` inside each agent and then scores at the
637
+ same parallelism. Addendum 3's runs took 0.6 to 0.8 min of agent time
638
+ each (`results/2026-10-03-beta1-gate/pilot.json`), so 80 runs at 2 jobs
639
+ are about half an hour of agents plus the scoring (the gate scores 56
640
+ solutions in about 16 min at 3 jobs).
641
+ - Commands, from `evals/` on the harness commit named at freezing:
642
+
643
+ ```bash
644
+ node setup.mjs --v4-from npm:4.0.0-beta.1
645
+ node --test harness/ship.test.mjs # the registry test must run, not skip
646
+ node gate.mjs --require v4 # must pass first: pass rule 2
647
+ node drive.mjs --preflight --model claude-sonnet-5-5 --effort medium \
648
+ --oauth-token-file <file>
649
+ node drive.mjs --pilot --n 20 --prompt minimal \
650
+ --condition v4 --condition thin-guide \
651
+ --model claude-sonnet-5-5 --effort medium --seed 20261005 --jobs 2 \
652
+ --margin 0.1 --out runs/ga-gate-<date> --oauth-token-file <file>
653
+ ```
654
+
655
+ `--n 20` sets the runs per cell; `--pilot` with it changes no run and only
656
+ adds the per-cell minutes, turns and tokens report (`pilot.json`) that
657
+ Addendum 3 reported, and `--margin 0.1` only sizes that report's runs per
658
+ cell. `<date>` is the day of the batch.
659
+
660
+ - Rehearsed on 2026-10-05 with `--dry-run` (the batch command above without
661
+ `--out` and the token file, on the tree `--v4-from npm:4.0.0-beta.1`
662
+ built; nothing launched): 4 cells, 80 runs, 20 per cell, in a shuffle
663
+ seeded 20261005 that begins `node-tool/thin-guide#1`,
664
+ `react-wallet/thin-guide#1`, `node-tool/v4#1`, `react-wallet/v4#1`,
665
+ `node-tool/thin-guide#2`, `node-tool/v4#2`, `react-wallet/v4#2`,
666
+ `react-wallet/thin-guide#2`; each `v4` cell's `docs/` is `llms.txt` only,
667
+ and each `thin-guide` cell's is the two candid-core READMEs and `llms.txt`,
668
+ as in the pilots; "v4 built from: npm 4.0.0-beta.1" with the two pinned
669
+ integrities and the guide's 1,974 words and sha256. (By chance, from the
670
+ third run on, these eight are the same as seed 1's; the two orders of 80
671
+ agree in 31 positions and then diverge.)
672
+
673
+ **Pass rule.** The owner kept alternative A of rule 1 and struck
674
+ alternative B on 2026-10-05, before freezing. B stays below, struck through,
675
+ as the record of what was chosen against. Rule 2 holds as written.
676
+
677
+ **Rule 1, alternative A (kept) — pooled over both tasks (80 runs).** The
678
+ safe-run rate of `v4` minus that of `thin-guide`, with both tasks pooled (each
679
+ condition's safe runs and runs summed over `node-tool` and `react-wallet`:
680
+ 40 runs against 40), has a Newcombe 95% lower bound of at least **−0.10**,
681
+ in the main analysis and in the intent-to-treat analysis alike. This is
682
+ `pooled` in `summary.json` (`v4 - thin-guide`). It departs from the
683
+ Definitions ("Comparisons are within one task"): under this alternative
684
+ pooling the two tasks is the pre-registered comparison, still within one
685
+ model, effort level and prompt variant. Under A, rule 1 is not met if
686
+ `summary.json` has no pooled `v4 - thin-guide` row over both tasks in
687
+ either analysis (`aggregate.mjs` gives none when a cell of either condition
688
+ has no usable run in that analysis, for example a `thin-guide` cell whose
689
+ runs were all harness errors, or all contaminated in the main analysis).
690
+
691
+ ~~**Rule 1, alternative B — per task (the literal reading of Q14), 80 runs.**
692
+ The same bound, at least **−0.10**, on `node-tool` and on `react-wallet`
693
+ separately (20 runs against 20), in both analyses. **At 20 runs per cell it
694
+ cannot pass**: with every run of both conditions safe, 20 of 20 against 20
695
+ of 20, the lower bound is −0.161. Kept only to state the literal reading
696
+ plainly. A per-task rule that can pass needs at least 35 runs per cell
697
+ (140 runs), and then, against a perfect `thin-guide`, passes only if every
698
+ `v4` run on that task is safe; tolerating one `v4` failure per task against a
699
+ perfect control needs 53 runs per cell (212 runs).~~ Struck by the owner on
700
+ 2026-10-05; the per-task differences are reported, and decide nothing.
701
+
702
+ Under rule 1:
703
+
704
+ - "Safe" is as `score.mjs` and `harness/judge.mjs` compute it under the
705
+ minimal prompt (no applicable safety requirement failed).
706
+ - The bound is read unrounded, computed from the counts with
707
+ `harness/aggregate.mjs`'s `newcombe(x_v4, n_v4, x_tg, n_tg)` (the counts
708
+ are in `summary.json`: `pooled[].counts`, or a cell's `runs` and
709
+ `safeRate`); `summary.json` rounds to three decimals for display. The
710
+ only outcome at 40 against 40 where the two readings differ is `v4` 38 of
711
+ 40 against `thin-guide` 37 of 40 (and its mirror, 3 of 40 against 2):
712
+ unrounded −0.1001, shown as −0.1, which fails.
713
+ - Each `v4` cell must hold 20 scored runs, none contaminated: a `v4` cell
714
+ with a contaminated run, or with fewer than 20 scored runs once
715
+ `drive.mjs` has exhausted its retries and a `--resume` has completed the
716
+ batch, does not meet rule 1 (as in Addendum 3). `thin-guide` cells enter
717
+ the bound with the scored runs they have.
718
+ - `plan.json`'s `v4Source` must name `npm` 4.0.0-beta.1 with the two pinned
719
+ integrities; a batch built from another source is not this addendum's.
720
+ - If the main and the intent-to-treat analyses disagree, rule 1 is not met
721
+ (the Definitions call that ambiguous). Recommended: both must hold, as
722
+ written.
723
+
724
+ **Rule 2. `node gate.mjs --require v4` passes** on the tree that `node
725
+ setup.mjs --v4-from npm:4.0.0-beta.1` built, before the batch: the `v4`
726
+ `reference` and `reference-module-scope` of both tasks pass every hidden
727
+ test with a clean `tsc`, the six ported faulty solutions and
728
+ `v4-anonymous-identity-sent` each fail exactly the tests in their
729
+ `meta.json`, and the pilots' references and faulty solutions behave as
730
+ before: 56 of 56, no cell skipped (`--require v4` fails the gate before
731
+ scoring when a `v4` cell is empty). If it fails, the batch does not start.
732
+ Run on 2026-10-05 on that tree (the published 4.0.0-beta.1, which holds
733
+ #819 and #820): **56 of 56**, no cell skipped, in 15 min 52 s at the
734
+ default `--jobs 3`; every `v4` reference and faulty solution failed exactly
735
+ the tests it failed on Addendum 3's commit, so neither change moved any of
736
+ them.
737
+
738
+ **What the margin means at this size**, from `harness/aggregate.mjs`'s own
739
+ `newcombe` (lower bound of the 95% interval for `v4 − thin-guide`; a pass
740
+ needs at least −0.10):
741
+
742
+ | `v4` failures | per task, 20 vs 20: `thin-guide` perfect | per task: one `thin-guide` failure | pooled, 40 vs 40: `thin-guide` perfect | pooled: one `thin-guide` failure |
743
+ | ------------- | ---------------------------------------- | ---------------------------------- | -------------------------------------- | -------------------------------- |
744
+ | 0 | −0.161 (fails) | −0.116 (fails) | **−0.088 (passes)** | **−0.065 (passes)** |
745
+ | 1 | −0.236 (fails) | −0.191 (fails) | −0.129 (fails) | −0.106 (fails) |
746
+ | 2 | −0.301 (fails) | −0.255 (fails) | −0.165 (fails) | −0.142 (fails) |
747
+
748
+ "Pooled" counts failures over both tasks. So under A, `v4` passes only if
749
+ all 40 of its runs are safe, unless `thin-guide` fails too: one `v4`
750
+ failure passes only against at least two `thin-guide` failures (−0.085),
751
+ two only against at least four (−0.080). Per task, perfect results pass
752
+ from 35 runs per cell (−0.0989; 34 gives −0.1015), one `v4` failure against
753
+ a perfect control from 53 (−0.0994), two from 69, and one failure in each
754
+ condition from 43.
755
+
756
+ **Analyses**, as the Definitions and Addenda 1 to 3 define them:
757
+
758
+ - Main: contaminated runs excluded. Intent-to-treat: contaminated runs kept.
759
+ Both from the same `summary.json` (`main`, `intentToTreat`), with
760
+ contamination as the leak audit judged it at run time. A later re-audit
761
+ (`--rescan`) is reported beside it and does not change the outcome
762
+ without a further addendum.
763
+ - Harness errors are retried by the driver, then excluded and counted, never
764
+ scored as 0. Completing a planned run that ended in a harness error
765
+ (`drive.mjs --resume <dir>`) completes the batch; a scored run is never
766
+ replaced.
767
+ - Reported for each cell: the safe-run rate with its Wilson 95% interval,
768
+ per-requirement pass rates, mean requirements met, `tsc`-clean rate, the
769
+ not-applicable `refuses_amount_past_nat64` results, minutes, turns and
770
+ tokens. Reported for each task: `v4 − thin-guide` with its Newcombe 95%
771
+ interval; and pooled over both tasks, with the counts. The one the kept
772
+ alternative names decides rule 1; the other is reported only. For every
773
+ unsafe run: which safety requirements and tests failed.
774
+ - `thin-guide` below the ceiling: if it is below 40 of 40 pooled (or below
775
+ 20 of 20 on a task), in either analysis, the report says so, and says
776
+ that a `v4` pass then rests on a weaker control than the pilots' (each
777
+ `thin-guide` failure lowers the bar `v4` has to clear), and that the
778
+ pilots' baseline did not reproduce that day, as Addendum 3 said of a
779
+ control below its ceiling. The number of scored `thin-guide` runs per
780
+ task, and so any unequal attrition across the tasks, is reported with the
781
+ result.
782
+
783
+ **If it fails.** If rule 1 or rule 2 is not met, the eval side of the GA
784
+ gate is not met on this batch. The batch, or any cell of it, is not run
785
+ again to look for a pass. If rule 2 fails, the batch does not start. For a
786
+ rule-1 failure the owner committed to this plan on 2026-10-05, before
787
+ freezing:
788
+
789
+ - Any rule-1 failure means GA waits. Every unsafe run is reported with the
790
+ tests it failed, and each is traced to its cause.
791
+ - If the cause is in ic-reactor's API or its guide (including the
792
+ `invalidates` wording that #831 has already corrected), it is fixed, if
793
+ it is not fixed yet. A new batch is then pre-registered in a further
794
+ dated addendum, on the version that carries the fix.
795
+ - If the cause is outside ic-reactor (the harness, the world or the
796
+ scorer), it is reported, and the owner decides whether GA ships with the
797
+ result stated.
798
+
799
+ Any change to the hidden tests, the world, the scoring, the prompts or this
800
+ rule after the batch starts needs a dated addendum and the owner's approval.
801
+
802
+ **Known limits.**
803
+
804
+ - Twenty runs per cell is near the floor for this margin. Under A, the
805
+ kept alternative, the rule amounts to "every `v4` run safe, or
806
+ `thin-guide` failing at least about twice as often" (one `v4` failure
807
+ against two, two against four); under B, struck, it could not pass. Both
808
+ arms were at the ceiling in every earlier batch on these tasks (Addendum
809
+ 2's re-scored second pilot, Result of Addendum 3), so the bound mostly
810
+ reflects the number of runs. A pass shows that a
811
+ difference worse than −0.10 is unlikely on these two tasks, not that the
812
+ two stacks are equivalent; under A it does not show it on each task
813
+ separately.
814
+ - The pooled estimate of alternative A is unstratified: each condition's
815
+ safe runs and runs are summed over the two tasks, so tasks are weighted
816
+ by their scored runs. If `thin-guide` loses runs on one task only (harness
817
+ errors, or contamination in the main analysis) and the tasks' safe rates
818
+ differ, its pooled rate shifts toward the other task's even when the
819
+ per-task differences are the same. The per-task counts are reported with
820
+ the result (Analyses), and unequal attrition across the tasks is named
821
+ there.
822
+ - The version under test is the published 4.0.0-beta.1. Changes to the
823
+ packages or the guide made after this addendum (in a 4.0.0-beta.2 or the
824
+ 4.0.0 tarball, if not byte-identical, at least its version line) are not
825
+ measured; they are listed with the result and left to the owner, as
826
+ Addendum 3's 4-word change was.
827
+ - One model at one effort level; the pilots' caveats hold (one author wrote
828
+ the tasks, tests, guides and references; the separation from `thin` is
829
+ exploratory).
830
+ - Addendum 3's known limits about the world (the fake replica installed as
831
+ a global `fetch` stub, the scorer's shared `@icp-sdk/core`), the
832
+ react-wallet `WalletAuth` adapter the agent writes, an explicit
833
+ `AnonymousIdentity` being sent, a module-scope client handed to
834
+ `ReactorProvider` (#805), and the ninth fraction digit still hold. #820
835
+ changes hydrating renders, which no hidden test performs (none
836
+ dehydrates, hydrates or renders on a server). #819 changes what a
837
+ disposed client does with a write in flight: an agent's solution reaches
838
+ it only if its client is disposed while the hidden tests still use it
839
+ (every react-wallet test unmounts what it rendered, and
840
+ `update_not_resent_on_refetch` unmounts and remounts), the module-scope
841
+ trap above. The gate (rule 2) shows that the references and faulty
842
+ solutions behave on the published packages exactly as on Addendum 3's
843
+ commit; how agents' own solutions meet either change is part of what the
844
+ batch measures.
845
+ - The registry is trusted only through the pin: setup refuses a tarball
846
+ whose sha512 is not the pinned one. `@candid-core/schema` and the other
847
+ dependencies are installed by npm at their exact versions and checked by
848
+ npm against the registry's integrity, not against a pin of this
849
+ addendum's (the schema's is recorded above).
850
+
851
+ **Freezing.** This addendum is frozen, by replacing its status line with the
852
+ date and recording the owner's approval below, when all of these hold: the
853
+ owner has kept one alternative of rule 1 and struck the other; `node
854
+ setup.mjs --v4-from npm:4.0.0-beta.1` has built the tree and `node --test
855
+ harness/ship.test.mjs` passes with the registry test run, not skipped;
856
+ `node gate.mjs --require v4` passes 56 of 56 on that tree; the dry run
857
+ matches the rehearsal above; and the harness commit the batch runs from
858
+ (this addendum's pull request merged into `v4`) is named here.
859
+
860
+ Approved by owner: yes, on 2026-10-05, in the owner's decisions on
861
+ Checkpoint 5 ("GA eval: keep alternative A of Addendum 4 (pooled over both
862
+ tasks, 80 runs) and strike B. Addendum 4 is approved."). The plan under "If
863
+ it fails" was added at the owner's request before freezing. The run budget is
864
+ the owner's earlier "up to 100 runs in total (the GA batch is 80)"; the other
865
+ 20 are not used without asking. Frozen by the lead on 2026-10-05, with the
866
+ conditions under "Freezing" met:
867
+
868
+ - Rule 1: alternative A kept, B struck (Pass rule).
869
+ - The harness commit is `4ef91cb7be6804a2c323b1758cf117c0ac6be543` (#830
870
+ merged into `v4`), which brought this addendum's harness. Nothing under
871
+ `evals/` changed after it but this file. The batch runs from the merge of
872
+ this freezing pull request into `v4`, whose `evals/` differs from
873
+ `4ef91cb7b`'s in this file only; that is checked before the batch starts,
874
+ and the merge commit is named with the result.
875
+ - `node setup.mjs --v4-from npm:4.0.0-beta.1` built the tree:
876
+ `.ship/v4/source.json` names `npm` 4.0.0-beta.1, the two pinned
877
+ integrities, and the guide's 1,974 words and sha256 above.
878
+ - `node --test harness/ship.test.mjs`: 27 of 27 pass, 0 skipped; the
879
+ registry test ("pins what the npm registry records") ran against the
880
+ registry, not skipped.
881
+ - `node gate.mjs --require v4` on that tree: 56 of 56 (20 references, 36
882
+ faulty solutions), no cell skipped, in 15 min 24 s at the default
883
+ `--jobs 3`.
884
+ - The dry run (the batch command under Design with `--dry-run`, without
885
+ `--out` and the token file) matches the rehearsal: 4 cells, 80 runs, 20
886
+ per cell, seed 20261005, the same first eight runs, the same `docs/` per
887
+ cell, and "v4 built from: npm 4.0.0-beta.1" with the two pinned
888
+ integrities and the guide's 1,974 words and sha256. Its output differs
889
+ from the rehearsal's only in the worktree path and the line `--pilot`
890
+ adds for its report.
891
+
892
+ Recorded with this approval, as the owner decided on 2026-10-05:
893
+
894
+ - The guide's growth after this addendum measured it is accepted: #831
895
+ corrected the `invalidates` wording, and `packages/core/llms.txt` on `v4`
896
+ is 1,986 words. The batch measures the published 1,974-word guide (Known
897
+ limits).
898
+ - Addendum 3's approval line and its 56th gate cell
899
+ (`node-tool/faulty/v4-anonymous-identity-sent`) are confirmed. Addendum 3
900
+ is frozen, so the confirmation is recorded here.
901
+
902
+ ## Result of Addendum 4 — 2026-10-05
903
+
904
+ Recorded after the batch; Addendum 4 itself is unchanged. The batch ran as
905
+ pre-registered from `9f78b706c`, the merge of #841, whose `evals/` differs
906
+ from the harness commit `4ef91cb7b` only in this file. Its shape:
907
+
908
+ - 80 runs, 4 cells of 20, round-robin in the shuffle seeded 20261005;
909
+ - `claude-sonnet-5-5` at effort `medium`, the minimal prompt, sandboxed, 2
910
+ agents at a time, with a passing preflight;
911
+ - `plan.json`'s `v4Source` names `npm` 4.0.0-beta.1 with the two pinned
912
+ integrities.
913
+
914
+ Every run exited normally, so no harness error was retried and 80 agent
915
+ runs were made in all. Results are in `results/2026-10-05-ga-gate/`, copied
916
+ from `runs/ga-gate-2026-10-05/`. `contaminated-run.json` holds the
917
+ contaminated run's audit record, the Bash call whose output the CLI saved,
918
+ and the whole file as the agent read it back, with its sha256.
919
+
920
+ | Task | Condition | Safe (main) | Safe (ITT) | Requirements met | `tsc` clean | Contaminated | Harness errors | Minutes (median) | Turns (median) |
921
+ | ------------ | ------------ | ----------- | ---------- | ---------------- | ----------- | ------------ | -------------- | ---------------- | -------------- |
922
+ | node-tool | `v4` | 20 of 20 | 20 of 20 | 1.00 | 1.00 | 0 | 0 | 0.65 | 7.5 |
923
+ | node-tool | `thin-guide` | 20 of 20 | 20 of 20 | 1.00 | 1.00 | 0 | 0 | 0.61 | 6 |
924
+ | react-wallet | `v4` | 19 of 19 | 20 of 20 | 1.00 | 1.00 | 1 | 0 | 0.81 | 8 |
925
+ | react-wallet | `thin-guide` | 20 of 20 | 20 of 20 | 1.00 | 1.00 | 0 | 0 | 0.82 | 6 |
926
+
927
+ Wilson 95% intervals: 20 of 20 is [0.839, 1] and 19 of 19 is [0.832, 1].
928
+ Every scored run is safe in both analyses, so no failing test or
929
+ requirement is left to report. `refuses_amount_past_nat64` stays not
930
+ applicable under the minimal prompt (observed: 0 of 40 on each task, all
931
+ conditions). `thin-guide` is at its ceiling in both analyses (20 of 20 on
932
+ each task) and scored 20 runs per task, so attrition is equal across the
933
+ tasks.
934
+
935
+ `v4 − thin-guide`, with Newcombe 95% intervals. Each lower bound is read
936
+ unrounded from `harness/aggregate.mjs`'s `newcombe`:
937
+
938
+ | Comparison | Main | Intent-to-treat |
939
+ | ----------------------------------- | ---------------------------------------- | ---------------------------------------- |
940
+ | **Pooled over both tasks (rule 1)** | 39/39 vs 40/40: 0, [**−0.0897**, 0.0876] | 40/40 vs 40/40: 0, [**−0.0876**, 0.0876] |
941
+ | node-tool (reported only) | 20/20 vs 20/20: 0, [−0.161, 0.161] | 20/20 vs 20/20: 0, [−0.161, 0.161] |
942
+ | react-wallet (reported only) | 19/19 vs 20/20: 0, [−0.168, 0.161] | 20/20 vs 20/20: 0, [−0.161, 0.161] |
943
+
944
+ **The contaminated run** is react-wallet/`v4`#14. The leak audit flagged
945
+ one Read of `<run>/home/.claude/projects/<project>/<session>/tool-results/b65qfoxqg.txt`
946
+ as a "file_path outside the run directory". The transcript shows what it
947
+ was:
948
+
949
+ 1. The agent ran one Bash `cat` of its starter's own files: `docs/llms.txt`,
950
+ `src/Wallet.tsx`, `src/main.tsx`, the head of the generated module,
951
+ `test/support/world.ts`, `test/support/auth.ts` and the head of
952
+ `TASK.md`.
953
+ 2. The CLI answered "Output too large (29.6KB). Full output saved to:" that
954
+ path.
955
+ 3. The agent read the file back.
956
+
957
+ The path is inside the run's own home, which the driver creates for each
958
+ run, and the file holds only that run's own tool output, all of it from
959
+ `<run>/work`. Nothing outside the run was read. The audit counts only
960
+ `<run>/work` as the run directory and has no rule for the CLI's persisted
961
+ tool output. The CLI binary is the one Addendum 3's batch used (installed
962
+ 2026-09-30); this persistence did not occur in that batch's 20 runs. Scored,
963
+ the run is safe, and it counts in the intent-to-treat analysis.
964
+
965
+ **Pass rule.**
966
+
967
+ - Rule 2 holds: `node gate.mjs --require v4` passed 56 of 56 on the tree,
968
+ before the batch (Approval above).
969
+ - Rule 1's bound holds in both analyses: −0.0897 (main) and −0.0876
970
+ (intent-to-treat), both at least −0.10.
971
+ - Rule 1 is **not met.** react-wallet/`v4` holds a contaminated run, and so
972
+ only 19 scored, uncontaminated runs in the main analysis. "A `v4` cell
973
+ with a contaminated run … does not meet rule 1."
974
+
975
+ **The eval side of the GA gate is not met on this batch, as written.**
976
+
977
+ **Under "If it fails".** No run is unsafe, so there is no failing test to
978
+ trace. The cause of the rule-1 failure is outside ic-reactor: the harness's
979
+ leak audit does not recognise the CLI's persisted tool output in the run's
980
+ own home. Under the plan committed before the batch, this is reported, and
981
+ the owner decides whether GA ships with this result stated. The batch is not
982
+ run again.
983
+
984
+ Reported beside the result, and changing nothing (as "Analyses" says of a
985
+ re-audit): with that one read counted inside the run, the run is
986
+ uncontaminated. The main analysis would then be 40 of 40 against 40 of 40
987
+ pooled, with a lower bound of −0.0876, and every `v4` cell would hold 20
988
+ scored, uncontaminated runs. Both a fix to the audit (accepting reads of the
989
+ run's own `home/.claude/projects/*/*/tool-results/` files) and any new batch
990
+ would need a further dated addendum and the owner's approval.
991
+
992
+ The caveats of "Known limits" apply. In particular, the batch measured the
993
+ published 4.0.0-beta.1 and its 1,974-word guide; `v4`'s guide is 1,986 words
994
+ since #831, a change the owner accepted.
995
+
996
+ ## Decision on the result of Addendum 4 — 2026-10-06
997
+
998
+ Recorded after the result; Addendum 4 and its Result are unchanged. Under
999
+ "If it fails" the cause of the rule-1 failure is outside ic-reactor (the
1000
+ harness's leak audit), so the owner decides whether GA ships with the result
1001
+ stated. On 2026-10-06 the owner decided: **GA ships on this result, stated
1002
+ as recorded in "Result of Addendum 4".**
1003
+
1004
+ The statement, wherever the eval is cited (release notes, docs, the
1005
+ decisions log #790), is this one, and never "passed": rule 1 was not met as
1006
+ written, because the leak audit flagged react-wallet/`v4`#14's read of its
1007
+ own persisted tool output; all 80 runs were safe, and the pooled bound held
1008
+ in both analyses (−0.0897 main, −0.0876 intent-to-treat, against −0.10).
1009
+
1010
+ The leak audit's handling of the CLI's persisted tool output is fixed for
1011
+ future batches by a further dated addendum, which changes nothing above.
1012
+
1013
+ ## Addendum 5 — the leak audit and the CLI's persisted tool output
1014
+
1015
+ **Status: Frozen on 2026-10-06, after the owner's review.** The text
1016
+ above, including Addendum 4, its Result and the Decision on it, is
1017
+ unchanged. After freezing, this addendum changes only through a further
1018
+ dated addendum.
1019
+
1020
+ **What it decides.** The leak audit's rule for the CLI's persisted tool
1021
+ output, for batches run after this addendum is frozen. It changes no
1022
+ recorded outcome: Addendum 4's result (rule 1 not met as written, because
1023
+ the leak audit flagged react-wallet/`v4`#14's read of its own persisted tool
1024
+ output; all 80 runs safe; the pooled bound held in both analyses) and the
1025
+ owner's decision of 2026-10-06 stand as recorded. No agent was run for it.
1026
+
1027
+ The owner's words (2026-10-06): accept a read of
1028
+ `<run>/home/.claude/projects/*/*/tool-results/<file>` only when the same
1029
+ transcript holds the CLI's persisted-output notice naming that exact path;
1030
+ test it with Addendum 4's run as the accepted case and a tool-results read
1031
+ with no matching notice as the refused case; re-audit Addendum 4's batch
1032
+ with `--rescan` and report it beside the result, the outcome staying as
1033
+ recorded.
1034
+
1035
+ **The rule**, as `harness/leak-scan.mjs` implements it. A Read (its
1036
+ `file_path`) or a Grep (its `path`) is not a violation when all of these
1037
+ hold; otherwise it is judged exactly as before (a path outside the run
1038
+ directory, `<run>/work`, is a violation):
1039
+
1040
+ 1. **The run directory is `<run>/work`**, as the driver makes it, and the
1041
+ path, resolved as the audit resolves every path, is exactly
1042
+ `<run>/home/.claude/projects/<one segment>/<one segment>/tool-results/<one file name>`.
1043
+ `<run>` is the run directory's parent, in either spelling the audit
1044
+ already knows (as given, and its real path while it exists). A path one
1045
+ segment off (`tool-results/sub/<file>`, `projects/<p>/tool-results/<file>`)
1046
+ does not match. A run directory with another name gives no `<run>`, and
1047
+ no read is accepted.
1048
+ 2. **A notice names it.** An earlier message of the transcript holds, as
1049
+ the whole content of a `tool_result`, the CLI's notice: it begins
1050
+ `<persisted-output>`, its next line is
1051
+ `Output too large (<size>). Full output saved to: <path>`, and it ends
1052
+ `</persisted-output>`, with nothing after it. The content is one string,
1053
+ or one text block. Its `<path>` equals the read's resolved path byte for
1054
+ byte. A notice inside other output ("notes:" and then the notice, or the
1055
+ notice and then more text, or the notice and a second text block) does
1056
+ not count; nor does a prefix (the read `<path>.bak` against a notice of
1057
+ `<path>`); nor another session's directory, since the session segment is
1058
+ part of the path.
1059
+ 3. **The notice is the CLI's, not the agent's.** The message holding it is
1060
+ a top-level user message of the stream (`"type": "user"`), its content
1061
+ is that one `tool_result` block and nothing else, and beside the content
1062
+ the message carries the CLI's own record of the call: a
1063
+ `tool_use_result` object whose `persistedOutputPath` is the notice's
1064
+ `<path>`, and a `session_id` equal to that path's session segment. The
1065
+ CLI writes these two fields; a tool's output is a string inside the
1066
+ content or inside a field of `tool_use_result` (a Bash call's `stdout`, a
1067
+ Grep's `content`), and cannot add them. So notice-shaped text that a
1068
+ Bash `printf` or `cat` prints, that a subagent returns, or that the agent
1069
+ writes in its own message does not count, and neither does a notice
1070
+ block nested anywhere else in a message (inside an assistant message, or
1071
+ inside `tool_use_result`). The notice must also answer an earlier tool
1072
+ call that is **not a Read**.
1073
+ 4. **Order.** The notice comes before the read in the transcript, and the
1074
+ call it answers comes before the notice (the CLI names the path first).
1075
+ A read sent in the same message as the call whose output is saved, before
1076
+ the notice exists, is refused.
1077
+ 5. **The saved output is the output of a clean call.** The call the notice
1078
+ answers had no violation of its own, blocked or not. Its output came from
1079
+ inside the run, so reading the saved file back reads nothing the audit
1080
+ had not already passed. If the call reached outside, reading its full
1081
+ output back stays a violation, and since rule 3 takes only the CLI's
1082
+ notice, a clean call cannot lend its cleanliness to another call's saved
1083
+ output by repeating that call's notice.
1084
+ 6. **No `..`.** The read's path as written has no `..` segment, even one
1085
+ that resolves back to the noticed path (`<run>/work/../home/…`). A
1086
+ notice naming a path with `..` names nothing: the read's path is
1087
+ normalised, and the notice's must equal it byte for byte.
1088
+ 7. **No symlink.** No component of the path below `<run>` (`home`,
1089
+ `.claude`, `projects`, the project, the session, `tool-results`, the
1090
+ file) is a symlink, as far as the path exists when the audit runs. Each
1091
+ component is checked without following it, so a link is refused even
1092
+ when its target is gone. At run time the path exists: the driver audits
1093
+ before it removes the run.
1094
+
1095
+ Strictness calls, each the owner's to overturn:
1096
+
1097
+ - **What the resolver sees.** The audit resolves paths lexically, as it
1098
+ always has: `.`, `..`, repeated `/`, `~`, `~user`, `$HOME` and `$PWD`,
1099
+ from the run directory. It does not follow symlinks; rule 7 adds the one
1100
+ link check, and only for the part of the path that exists. `~` and
1101
+ `$HOME` are the audit's own home, not the run's, so a read written
1102
+ `~/.claude/projects/…` stays a violation.
1103
+ - **Bash.** A Bash command naming the path (`cat <path>`) stays a violation,
1104
+ as every Bash command reaching outside `work/` is. The owner's rule names
1105
+ "a read", and the agent has Read for it.
1106
+ - **Grep yes, Glob no, no other tool.** Grep's `path` can name one file, and
1107
+ a Grep of the saved file is a read of it, so it is covered on the same
1108
+ terms. Glob names a pattern or a directory, never one saved file (a Glob
1109
+ of `tool-results/` would list the others), so it is not. Any other tool
1110
+ or field naming the path (Write, Edit, NotebookEdit, a Read `path`, a
1111
+ Grep `file_path`) is a violation, as before.
1112
+ - **The rest of the run's home stays outside the run**, exactly as today:
1113
+ `.claude.json`, `.claude/settings.json`, the session's own transcript
1114
+ under `projects/`, and anything else there, with or without a notice.
1115
+ - **The CLI's record, not only the notice.** The owner's rule asks for "the
1116
+ CLI's persisted-output notice". The notice text alone does not show whose
1117
+ it is: a clean call can print the same text (a `cat` of a file the agent
1118
+ wrote, a subagent's answer), and could name any saved file, including the
1119
+ saved output of a call that reached outside. So the rule also requires
1120
+ the record the CLI writes beside the notice, `persistedOutputPath` and
1121
+ `session_id` (rule 3), which a tool's output cannot add. Addendum 4's run
1122
+ carries both (`results/2026-10-05-ga-gate/contaminated-run.json`,
1123
+ `producer.cli_message`), and so does the batch's other saved output
1124
+ (react-wallet/`v4`#5).
1125
+ - **Order is required**, and so is the producing call's cleanliness (rules
1126
+ 4 and 5). Neither is in the owner's words; both are recommended, since the
1127
+ CLI writes the notice first and the file holds the call's whole output.
1128
+
1129
+ **Harness changes.** In this addendum's pull request, under `evals/` only:
1130
+
1131
+ - `harness/leak-scan.mjs`: the rule above. Notices are taken only from the
1132
+ content of top-level user messages that carry the CLI's record of the
1133
+ call; `scanTranscript` returns `persistedReads`, the reads it accepted
1134
+ under the rule, listing a call only when the scan found no violation in
1135
+ it. The rest of the audit is unchanged.
1136
+ - `drive.mjs`: each run's audit record (`agent.json`, and a re-audit's) also
1137
+ keeps `persistedReads`.
1138
+ - `results/2026-10-05-ga-gate/contaminated-run.json`: `producer.cli_message`
1139
+ added, the rest of the user message that carried react-wallet/`v4`#14's
1140
+ notice, copied from its stored transcript (line 7 of
1141
+ `runs/ga-gate-2026-10-05/react-wallet/v4/014/agent.stdout`): its
1142
+ `session_id`, `uuid`, `timestamp` and `parent_tool_use_id`, and the CLI's
1143
+ `tool_use_result` without its `stdout` (the 29,991-character output
1144
+ itself, given by its sha256 and length). Nothing else in the record
1145
+ changed.
1146
+ - `harness/leak-scan.test.mjs`: 37 tests in "the CLI's persisted tool
1147
+ output" (84 before, 121 now). Accepted: react-wallet/`v4`#14 verbatim
1148
+ from `results/2026-10-05-ga-gate/contaminated-run.json` (the Bash call,
1149
+ the CLI's notice with the session and record of its message, the Read and
1150
+ its result), with its run directory gone as in a re-audit; the same shape
1151
+ in a run laid out as the driver lays it out, with the saved file on disk;
1152
+ a notice that is one text block; and a Grep of the saved file. Refused,
1153
+ each in its own test: a tool-results read with no notice; a notice naming
1154
+ a different file; a read whose path only begins with the noticed one;
1155
+ another session's directory; a notice only in assistant text; a notice in
1156
+ a `tool_result` block inside an assistant message; a notice that is a
1157
+ Read result of another file; a notice inside other output; a notice
1158
+ followed by other text; a notice that is one of several text blocks; a
1159
+ notice that is a Bash command's output; a notice that is a subagent's
1160
+ result; a notice a clean call repeats, naming the saved output of a call
1161
+ that reached outside (refused, so blocked); a notice whose record names
1162
+ another path; a notice whose message is from another session; a notice
1163
+ nested in the CLI's record instead of the content; a notice beside
1164
+ another `tool_result` in its message; a read before its notice; a read
1165
+ before the call whose output it names; a notice that answers a later
1166
+ call; the saved output of a call that reached outside the run; a path one
1167
+ segment below `tool-results`; a path missing the session segment; a read
1168
+ written with `..`; a notice whose path is written with `..`;
1169
+ `home/.claude.json`, `home/.claude/settings.json` and a session
1170
+ transcript, each with a notice; a Bash `cat` of the saved file; every
1171
+ other tool or field at the saved path (Write, Edit, Glob `path`, Read
1172
+ `path`, Grep `file_path`, NotebookEdit); a saved file that is a symlink
1173
+ out of the run; a saved file that is a dangling symlink; a session
1174
+ directory that is a symlink out of the run; and a run directory not
1175
+ named `work`. One more checks that a Grep whose `path` is the saved file
1176
+ but whose `glob` reaches outside is a violation and is not listed in
1177
+ `persistedReads`.
1178
+ - Each of the 37 tests was shown to fail with the rule removed or loosened,
1179
+ on a copy of `leak-scan.mjs` with one change at a time (several, where
1180
+ said), the copy's test file run whole. For each test, the change that
1181
+ makes it fail:
1182
+ - react-wallet/`v4`#14's read, from its record; the record's shape with
1183
+ the saved file on disk; a notice that is one text block: the rule
1184
+ removed.
1185
+ - A Grep of the saved file: Grep not taken as a reader.
1186
+ - No notice: no notice required (any read of a path of the pattern
1187
+ accepted).
1188
+ - A notice naming a different file: the notice's directory compared
1189
+ instead of its path.
1190
+ - A read whose path only begins with the noticed one: a prefix match.
1191
+ - Another session's directory: the file name compared instead of the
1192
+ path.
1193
+ - A notice only in assistant text: no single change, and not the
1194
+ speaker, the one-block and the CLI's-record conditions dropped
1195
+ together. It is refused by every condition on the notice's place at
1196
+ once: the speaker, the CLI's record, one block per message, and the
1197
+ block type (a text block is not a `tool_result` and answers no call).
1198
+ It fails with no notice required.
1199
+ - A notice in a `tool_result` block inside an assistant message: no
1200
+ single change. It is refused by the speaker and by one block per
1201
+ message (the message also holds the call), each alone; it fails with
1202
+ both dropped together (any speaker, and the first `tool_result` of a
1203
+ message of several blocks taken), and with no notice required.
1204
+ - A notice that is a Read result of another file: Read results taken.
1205
+ - A notice inside other output: the notice's start not anchored.
1206
+ - A read before its notice: no check that the read follows the notice.
1207
+ - A read before the call whose output it names: no single change. It is
1208
+ refused by four conditions at once: the read follows the notice; the
1209
+ call has been seen before the read; the call comes before the notice
1210
+ (a call not yet seen has no place); the call was judged clean before
1211
+ the read. It fails with all four dropped together, not with the last
1212
+ three alone, and with no notice required.
1213
+ - A notice that answers a later call: no check that the call comes
1214
+ before the notice.
1215
+ - The saved output of a call that reached outside: the producing call
1216
+ not required to be clean.
1217
+ - A path one segment below `tool-results`: any depth under
1218
+ `tool-results`.
1219
+ - A path missing the session segment: any depth between `projects` and
1220
+ `tool-results`.
1221
+ - A read written with `..`: `..` allowed in the read.
1222
+ - A notice whose path is written with `..`: the notice's path resolved
1223
+ before it is compared.
1224
+ - `home/.claude.json`, `home/.claude/settings.json` and a session
1225
+ transcript: anything under `home/` accepted.
1226
+ - A Bash `cat` of the saved file: a Bash command naming a path under a
1227
+ `tool-results` directory accepted.
1228
+ - A saved file that is a symlink out of the run; a session directory that
1229
+ is a symlink out of the run: no symlink check.
1230
+ - A saved file that is a dangling symlink: a symlink check that follows
1231
+ links (the resolved path compared, only when it exists).
1232
+ - A run directory not named `work`: any run directory.
1233
+ - A notice that is a Bash command's output: the CLI's record and session
1234
+ not required.
1235
+ - A notice that is a subagent's result; a notice whose record names
1236
+ another path: the record's path not compared.
1237
+ - A notice a clean call repeats, naming the saved output of a call that
1238
+ reached outside: the producing call not required to be clean.
1239
+ - A notice whose message is from another session: the session not
1240
+ compared.
1241
+ - A notice nested in the CLI's record instead of the content: the notice
1242
+ taken from any `tool_result` nested in the message.
1243
+ - A notice beside another `tool_result` in its message: more than one
1244
+ block allowed in the message.
1245
+ - A notice followed by other text: the notice's end not anchored.
1246
+ - A notice that is one of several text blocks: several text blocks
1247
+ allowed.
1248
+ - Every other tool or field at the saved path: any tool or field
1249
+ accepted.
1250
+ - The Grep whose `glob` reaches outside: `persistedReads` listed before
1251
+ the call is judged.
1252
+
1253
+ These are harness tests, not package tests, so they have no
1254
+ `scripts/faults.json` entry.
1255
+
1256
+ **The re-audit of Addendum 4's batch**, reported beside its result. It
1257
+ changes nothing: the outcome stays as recorded in "Result of Addendum 4"
1258
+ and the Decision on it.
1259
+
1260
+ `node drive.mjs --aggregate runs/ga-gate-2026-10-05 --rescan`, from
1261
+ `evals/`, with this addendum's audit, on the batch's 80 stored transcripts
1262
+ (each audited against the run directory its init message names). It wrote
1263
+ `runs/ga-gate-2026-10-05/summary.rescanned.json` and changed no other file
1264
+ there: the 1,754 files under `runs/ga-gate-2026-10-05/` hashed the same
1265
+ before and after, and the run-time `summary.json` is the one in
1266
+ `results/2026-10-05-ga-gate/` (sha256
1267
+ `804eccfaa025183e699ec7d66844d557c3f4b4eb66064e646da2ff1943356ca3`). The
1268
+ rescanned summary is copied, byte for byte, to
1269
+ `results/2026-10-05-ga-gate/summary.rescanned.json` (sha256
1270
+ `591177f03fe9c7a728d47a6cca91cdf2426cd2a7dc96ae05dac6bdd4f15d0745`).
1271
+ The re-audit was run with the rule as frozen here: a second run rewrote
1272
+ `summary.rescanned.json` byte for byte the same, and the 1,755 files under
1273
+ `runs/ga-gate-2026-10-05/` (the 1,754 and that summary) hashed the same
1274
+ before and after it.
1275
+
1276
+ | Task | Condition | Contaminated (run time → rescan) | Safe, main (run time → rescan) | Safe, ITT (run time → rescan) |
1277
+ | ------------ | ------------ | -------------------------------- | ------------------------------ | ----------------------------- |
1278
+ | node-tool | `v4` | 0 → 0 | 20 of 20 → 20 of 20 | 20 of 20 → 20 of 20 |
1279
+ | node-tool | `thin-guide` | 0 → 0 | 20 of 20 → 20 of 20 | 20 of 20 → 20 of 20 |
1280
+ | react-wallet | `v4` | 1 → 0 | 19 of 19 → 20 of 20 | 20 of 20 → 20 of 20 |
1281
+ | react-wallet | `thin-guide` | 0 → 0 | 20 of 20 → 20 of 20 | 20 of 20 → 20 of 20 |
1282
+
1283
+ Pooled `v4 − thin-guide`, Newcombe 95%, lower bounds unrounded from
1284
+ `harness/aggregate.mjs`'s `newcombe`:
1285
+
1286
+ | Analysis | Run time (recorded) | Rescan |
1287
+ | --------------- | ------------------------------------ | ------------------------------------ |
1288
+ | Main | 39/39 vs 40/40: 0, [−0.0897, 0.0876] | 40/40 vs 40/40: 0, [−0.0876, 0.0876] |
1289
+ | Intent-to-treat | 40/40 vs 40/40: 0, [−0.0876, 0.0876] | 40/40 vs 40/40: 0, [−0.0876, 0.0876] |
1290
+
1291
+ The per-task differences are as recorded, except react-wallet's in the
1292
+ main analysis: 19/19 vs 20/20, [−0.168, 0.161], at run time; 20/20 vs
1293
+ 20/20, [−0.161, 0.161], in the rescan.
1294
+
1295
+ Audit verdicts that changed: one. react-wallet/`v4`#14 went from
1296
+ contaminated (one unblocked violation: the Read) to uncontaminated, with
1297
+ that Read in `persistedReads` and no attempts. No other run changed either
1298
+ way: the other 79 had no violation and no attempt at run time and have none
1299
+ now (the driver prints "contamination changed in 1; now 0 contaminated (was
1300
+ 1)"). react-wallet/`v4`#5 also had a Bash output saved by the CLI (30 KB),
1301
+ but did not read it back; its verdict is clean, as before.
1302
+
1303
+ Under this rescan every `v4` cell would hold 20 scored, uncontaminated runs.
1304
+ That is reported, not decided: Addendum 4 decides on the audit as it stood
1305
+ at run time, and the owner's decision is on that result.
1306
+
1307
+ **Known limits.**
1308
+
1309
+ - The rule recognises the notice, and the record beside it, as this CLI
1310
+ writes them (Addendum 4's batch, CLI 2.1.285). If a later CLI words the
1311
+ notice otherwise, or renames or drops `persistedOutputPath` or
1312
+ `session_id`, the read is flagged as before: the rule fails closed, and a
1313
+ batch's result would again need the owner.
1314
+ - Rule 3 trusts that no tool's output reaches the top level of
1315
+ `tool_use_result` as a field name. In Addendum 4's batch every
1316
+ `tool_use_result` is a string or has a fixed set of fields the CLI names:
1317
+ Bash (`stdout`, `stderr`, `interrupted`, `isImage`, `noOutputExpected`,
1318
+ and `returnCodeInterpretation` or the two persisted-output fields), Read
1319
+ (`file`, `type`), Write, Edit and Grep likewise. No run used a subagent,
1320
+ and the driver runs the agent with `--strict-mcp-config` and no MCP
1321
+ server, whose structured results could carry fields of their own. A batch
1322
+ whose agents use other tools would need this looked at again.
1323
+ - The link check needs the path, so it holds at run time and not in a
1324
+ re-audit, where the run is gone and the path is judged lexically.
1325
+ - The audit does not compare the saved file with the call's output. It
1326
+ relies on the CLI being what writes `tool-results/`. An agent's write or
1327
+ symlink there through a file tool (Write, Edit) or a shell path is a
1328
+ violation of its own, since it is outside `work/`. One made by
1329
+ interpreter code with a computed path (`process.env.HOME + …`) is not
1330
+ seen; that is the audit's existing limit for any access made that way
1331
+ (such code could as well print what it read), which the OS sandbox is the
1332
+ first line against.
1333
+ - A read sent in the same message as the call whose output gets saved is
1334
+ refused even if the path turns out right. The agent cannot know the path
1335
+ before the notice, so this costs nothing on the CLI's behaviour seen so
1336
+ far.
1337
+ - The tests are the harness's own (`node --test harness/*.test.mjs`); the
1338
+ rule has met one real case, the batch above.
1339
+
1340
+ Approved by owner: yes, on 2026-10-06 ("Addendum 5 approved, freeze and
1341
+ merge it"), after reading it in its pull request (#846), with the rule as
1342
+ written, including the strictness calls above: the CLI's record beside the
1343
+ notice (rule 3), order (rule 4) and the producing call's cleanliness (rule
1344
+ 5). Frozen by the lead on 2026-10-06. The rule applies to batches run from
1345
+ the merge of #846 on; the re-audit above is reported beside Addendum 4's
1346
+ result and changes no recorded outcome.