@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.
- package/.github/ISSUE_TEMPLATE/bug_report.yml +108 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +77 -0
- package/.github/actions/setup-rust-wasm/action.yml +25 -0
- package/.github/dependabot.yml +107 -0
- package/.github/workflows/auth-latest.yml +67 -0
- package/.github/workflows/b3pay-site.yml +49 -0
- package/.github/workflows/ci.yml +430 -0
- package/.github/workflows/codeql.yml +41 -0
- package/.github/workflows/dependency-review.yml +68 -0
- package/.github/workflows/docs-check.yml +98 -0
- package/.github/workflows/docs.yml +265 -0
- package/.github/workflows/e2e.yml +90 -0
- package/.github/workflows/examples-published.yml +97 -0
- package/.github/workflows/release.yml +326 -0
- package/.husky/pre-commit +12 -0
- package/.prettierignore +109 -0
- package/.prettierrc +6 -0
- package/AGENTS.md +103 -0
- package/CHANGELOG.md +3268 -0
- package/CLAUDE.md +93 -0
- package/CNAME +1 -0
- package/CODE_OF_CONDUCT.md +7 -0
- package/CONTRIBUTING.md +433 -0
- package/LICENSE +21 -0
- package/README.md +2 -2
- package/SECURITY.md +74 -0
- package/b3pay-module.json +194 -0
- package/docs/.remarkrc.json +10 -0
- package/docs/README.md +64 -0
- package/docs/astro.config.mjs +205 -0
- package/docs/favicon.svg +15 -0
- package/docs/package.json +39 -0
- package/docs/public/favicon.svg +15 -0
- package/docs/public/ic-reactor-social-card.png +0 -0
- package/docs/scripts/b3pay-static.mjs +22 -0
- package/docs/scripts/check-example-docs.mjs +214 -0
- package/docs/scripts/check-links.mjs +212 -0
- package/docs/scripts/fix-dist-links.js +125 -0
- package/docs/scripts/fix-frontmatter.js +71 -0
- package/docs/scripts/remove-redundant-h1.cjs +48 -0
- package/docs/scripts/rewrite-typedoc-links.js +110 -0
- package/docs/scripts/split-index.js +69 -0
- package/docs/src/assets/ic-reactor-hero-dark.svg +23 -0
- package/docs/src/assets/ic-reactor-hero-light.svg +23 -0
- package/docs/src/assets/ic-reactor-lockup-dark.svg +15 -0
- package/docs/src/assets/ic-reactor-lockup-light.svg +15 -0
- package/docs/src/assets/ic-reactor-mark-dark.svg +14 -0
- package/docs/src/assets/ic-reactor-mark-light.svg +14 -0
- package/docs/src/assets/layers/candid-core-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/candid-core-layer-icon-light.svg +4 -0
- package/docs/src/assets/layers/candid-profile-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/candid-profile-layer-icon-light.svg +4 -0
- package/docs/src/assets/layers/ic-reactor-layer-icon-dark.svg +4 -0
- package/docs/src/assets/layers/ic-reactor-layer-icon-light.svg +4 -0
- package/docs/src/components/LibraryCards.astro +172 -0
- package/docs/src/components/LibraryIcon.astro +28 -0
- package/docs/src/components/SiteTitle.astro +241 -0
- package/docs/src/content/docs/404.mdx +19 -0
- package/docs/src/content/docs/build/agent-tools.mdx +593 -0
- package/docs/src/content/docs/build/icrc1-wallet.mdx +619 -0
- package/docs/src/content/docs/build/ssr-per-user.mdx +552 -0
- package/docs/src/content/docs/examples/canister-studio.mdx +95 -0
- package/docs/src/content/docs/examples/icrc-ledger.mdx +45 -0
- package/docs/src/content/docs/examples/index.mdx +38 -0
- package/docs/src/content/docs/examples/next-ssr.mdx +73 -0
- package/docs/src/content/docs/examples/node-agent-tool.mdx +80 -0
- package/docs/src/content/docs/examples/vite-wallet.mdx +71 -0
- package/docs/src/content/docs/guides/auth.mdx +1181 -0
- package/docs/src/content/docs/guides/client.mdx +551 -0
- package/docs/src/content/docs/guides/deploy.mdx +180 -0
- package/docs/src/content/docs/guides/errors.mdx +475 -0
- package/docs/src/content/docs/guides/getting-started.mdx +620 -0
- package/docs/src/content/docs/guides/reads.mdx +586 -0
- package/docs/src/content/docs/guides/ssr.mdx +529 -0
- package/docs/src/content/docs/guides/testing.mdx +401 -0
- package/docs/src/content/docs/guides/values.mdx +261 -0
- package/docs/src/content/docs/guides/vite-plugin.mdx +690 -0
- package/docs/src/content/docs/guides/writes.mdx +572 -0
- package/docs/src/content/docs/ic-reactor/index.mdx +167 -0
- package/docs/src/content/docs/index.mdx +65 -0
- package/docs/src/content/docs/migrating-from-3.mdx +535 -0
- package/docs/src/content/docs/packages/core.mdx +186 -0
- package/docs/src/content/docs/packages/mcp.mdx +163 -0
- package/docs/src/content/docs/packages/react.mdx +207 -0
- package/docs/src/content/docs/packages/vite-plugin.mdx +73 -0
- package/docs/src/content/docs/versioning.mdx +104 -0
- package/docs/src/content.config.ts +7 -0
- package/docs/src/styles/custom.css +189 -0
- package/docs/tsconfig.typedoc.json +26 -0
- package/docs/typedoc-entry.ts +17 -0
- package/docs/typedoc.json +37 -0
- package/e2e/Cargo.lock +646 -0
- package/e2e/Cargo.toml +3 -0
- package/e2e/README.md +101 -0
- package/e2e/frontends/build.mjs +94 -0
- package/e2e/frontends/index.html +10 -0
- package/e2e/global-setup.ts +65 -0
- package/e2e/icp.yaml +38 -0
- package/e2e/package.json +40 -0
- package/e2e/setup.ts +6 -0
- package/e2e/src/actor/Cargo.toml +14 -0
- package/e2e/src/actor/hello_actor.did +10 -0
- package/e2e/src/actor/src/lib.rs +73 -0
- package/e2e/src/calls.test.ts +132 -0
- package/e2e/src/declarations/hello_actor.envelope.json +175 -0
- package/e2e/src/declarations/hello_actor.ts +15 -0
- package/e2e/src/errors.test.ts +107 -0
- package/e2e/src/frontend-headers.test.ts +253 -0
- package/e2e/src/identity.test.ts +61 -0
- package/e2e/src/react.test.tsx +59 -0
- package/e2e/src/replica.ts +70 -0
- package/e2e/src/vite-env.test.ts +108 -0
- package/e2e/test.sh +47 -0
- package/e2e/tsconfig.json +20 -0
- package/e2e/tsconfig.typecheck.json +9 -0
- package/e2e/vitest.config.ts +22 -0
- package/eslint.config.mjs +100 -0
- package/evals/PREREGISTRATION.md +1346 -0
- package/evals/README.md +756 -0
- package/evals/conditions/thin/condition.json +8 -0
- package/evals/conditions/thin/docs/candid-core-cli.README.md +90 -0
- package/evals/conditions/thin/docs/candid-core-schema.README.md +339 -0
- package/evals/conditions/thin/package.json +25 -0
- package/evals/conditions/thin/starter/src/generated/icrc1.ts +57 -0
- package/evals/conditions/thin-guide/condition.json +10 -0
- package/evals/conditions/thin-guide/docs/llms.txt +292 -0
- package/evals/conditions/v3/condition.json +9 -0
- package/evals/conditions/v3/docs/ic-reactor-core.llms.txt +232 -0
- package/evals/conditions/v3/docs/ic-reactor-react.llms.txt +280 -0
- package/evals/conditions/v3/docs/llms-full.txt +1053 -0
- package/evals/conditions/v3/package.json +26 -0
- package/evals/conditions/v3/starter/src/declarations/icrc1.did.d.ts +95 -0
- package/evals/conditions/v3/starter/src/declarations/icrc1.did.js +140 -0
- package/evals/conditions/v4/PORTING.md +384 -0
- package/evals/conditions/v4/README.md +106 -0
- package/evals/conditions/v4/condition.json +5 -0
- package/evals/conditions/v4/docs/llms.txt +323 -0
- package/evals/conditions/v4/package.json +27 -0
- package/evals/conditions/v4/starter/src/generated/icrc1.ts +78 -0
- package/evals/conditions/v4-proto/condition.json +6 -0
- package/evals/conditions/v4-proto/docs/llms.txt +291 -0
- package/evals/conditions/v4-proto/lib/SHIM-NOTES.md +20 -0
- package/evals/conditions/v4-proto/lib/package.json +27 -0
- package/evals/conditions/v4-proto/lib/src/client.ts +471 -0
- package/evals/conditions/v4-proto/lib/src/errors.ts +214 -0
- package/evals/conditions/v4-proto/lib/src/index.ts +36 -0
- package/evals/conditions/v4-proto/lib/src/principal.ts +175 -0
- package/evals/conditions/v4-proto/lib/src/service.ts +69 -0
- package/evals/conditions/v4-proto/lib/src/types.ts +174 -0
- package/evals/conditions/v4-proto/lib/test/runtime.test.ts +170 -0
- package/evals/conditions/v4-proto/lib/test/tsconfig.json +10 -0
- package/evals/conditions/v4-proto/lib/test/types.test-d.ts +145 -0
- package/evals/conditions/v4-proto/lib/test/vitest.config.mjs +8 -0
- package/evals/conditions/v4-proto/lib/tsconfig.json +17 -0
- package/evals/conditions/v4-proto/package.json +26 -0
- package/evals/conditions/v4-proto/starter/src/generated/icrc1.service.ts +19 -0
- package/evals/conditions/v4-proto/starter/src/generated/icrc1.ts +57 -0
- package/evals/drive.mjs +1221 -0
- package/evals/gate.mjs +161 -0
- package/evals/harness/aggregate.mjs +534 -0
- package/evals/harness/aggregate.test.mjs +344 -0
- package/evals/harness/assemble.mjs +216 -0
- package/evals/harness/assemble.test.mjs +143 -0
- package/evals/harness/auth.mjs +91 -0
- package/evals/harness/check-docs.mjs +157 -0
- package/evals/harness/declarations/icrc1.did.d.ts +95 -0
- package/evals/harness/declarations/icrc1.did.js +140 -0
- package/evals/harness/drive-auth.test.mjs +584 -0
- package/evals/harness/drive.test.mjs +509 -0
- package/evals/harness/fake-auth.ts +67 -0
- package/evals/harness/fake-ledger.ts +178 -0
- package/evals/harness/gate-plan.mjs +104 -0
- package/evals/harness/gate-plan.test.mjs +243 -0
- package/evals/harness/icrc1.did +88 -0
- package/evals/harness/judge.mjs +63 -0
- package/evals/harness/judge.test.mjs +81 -0
- package/evals/harness/leak-scan.mjs +1373 -0
- package/evals/harness/leak-scan.test.mjs +1300 -0
- package/evals/harness/probes/amounts.ts +14 -0
- package/evals/harness/probes/node-tool.probe.ts +48 -0
- package/evals/harness/probes/probe.mjs +149 -0
- package/evals/harness/probes/react-wallet.probe.ts +96 -0
- package/evals/harness/public/support/auth.ts +38 -0
- package/evals/harness/public/support/fake-replica.d.ts +28 -0
- package/evals/harness/public/support/fake-replica.js +434 -0
- package/evals/harness/public/support/ledger.idl.d.ts +95 -0
- package/evals/harness/public/support/ledger.idl.js +140 -0
- package/evals/harness/public/support/world.ts +179 -0
- package/evals/harness/runs.mjs +139 -0
- package/evals/harness/sandbox.mjs +88 -0
- package/evals/harness/sandbox.test.mjs +134 -0
- package/evals/harness/ship.mjs +264 -0
- package/evals/harness/ship.test.mjs +552 -0
- package/evals/harness/world.ts +291 -0
- package/evals/package.json +26 -0
- package/evals/pnpm-lock.yaml +1537 -0
- package/evals/pnpm-workspace.yaml +12 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.json +384 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.json +404 -0
- package/evals/results/2026-09-30T14-22-05-924Z/pilot.rescanned.rescored.json +404 -0
- package/evals/results/2026-09-30T14-22-05-924Z/plan.json +240 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.json +1800 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.json +1843 -0
- package/evals/results/2026-09-30T14-22-05-924Z/summary.rescanned.rescored.json +2100 -0
- package/evals/results/2026-09-30T15-48-23-343Z/pilot.json +404 -0
- package/evals/results/2026-09-30T15-48-23-343Z/pilot.rescored.json +404 -0
- package/evals/results/2026-09-30T15-48-23-343Z/plan.json +242 -0
- package/evals/results/2026-09-30T15-48-23-343Z/summary.json +1843 -0
- package/evals/results/2026-09-30T15-48-23-343Z/summary.rescored.json +2195 -0
- package/evals/results/2026-10-03-beta1-gate/pilot.json +162 -0
- package/evals/results/2026-10-03-beta1-gate/plan.json +141 -0
- package/evals/results/2026-10-03-beta1-gate/summary.json +983 -0
- package/evals/results/2026-10-05-ga-gate/contaminated-run.json +55 -0
- package/evals/results/2026-10-05-ga-gate/pilot.json +162 -0
- package/evals/results/2026-10-05-ga-gate/plan.json +457 -0
- package/evals/results/2026-10-05-ga-gate/summary.json +1037 -0
- package/evals/results/2026-10-05-ga-gate/summary.rescanned.json +1037 -0
- package/evals/results/README.md +31 -0
- package/evals/runs-pilot.log +150 -0
- package/evals/runs-pilot2.log +150 -0
- package/evals/score.mjs +256 -0
- package/evals/setup.mjs +547 -0
- package/evals/tasks/node-tool/faulty/thin-accepts-exponent/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-accepts-exponent/src/index.ts +121 -0
- package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-anonymous-transfer/src/index.ts +116 -0
- package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-every-reject-may-have-executed/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-fetches-root-key-off-local/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-ignores-root-key/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-ignores-root-key/src/index.ts +117 -0
- package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-misclassifies-reject-codes/src/index.ts +119 -0
- package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/thin-no-nat64-cap/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/thin-number-amount/meta.json +10 -0
- package/evals/tasks/node-tool/faulty/thin-number-amount/src/index.ts +117 -0
- package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-truncates-fraction-digits/src/index.ts +120 -0
- package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/thin-unvalidated-recipient/src/index.ts +118 -0
- package/evals/tasks/node-tool/faulty/v3-retry-call-errors/meta.json +11 -0
- package/evals/tasks/node-tool/faulty/v3-retry-call-errors/src/index.ts +149 -0
- package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-anonymous-identity-sent/src/index.ts +71 -0
- package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/v4-never-may-have-executed/src/index.ts +84 -0
- package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/meta.json +9 -0
- package/evals/tasks/node-tool/faulty/v4-proto-never-may-have-executed/src/index.ts +72 -0
- package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-proto-refuses-nat64-max/src/index.ts +72 -0
- package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/meta.json +5 -0
- package/evals/tasks/node-tool/faulty/v4-refuses-nat64-max/src/index.ts +84 -0
- package/evals/tasks/node-tool/hidden/node-tool.test.ts +312 -0
- package/evals/tasks/node-tool/prompt.md +55 -0
- package/evals/tasks/node-tool/prompt.minimal.md +30 -0
- package/evals/tasks/node-tool/solutions/thin/reference/src/index.ts +118 -0
- package/evals/tasks/node-tool/solutions/thin/reference-module-scope/src/index.ts +145 -0
- package/evals/tasks/node-tool/solutions/thin-guide/reference/src/index.ts +118 -0
- package/evals/tasks/node-tool/solutions/thin-guide/reference-module-scope/src/index.ts +145 -0
- package/evals/tasks/node-tool/solutions/v3/reference/src/index.ts +140 -0
- package/evals/tasks/node-tool/solutions/v3/reference-module-scope/src/index.ts +153 -0
- package/evals/tasks/node-tool/solutions/v4/reference/src/index.ts +84 -0
- package/evals/tasks/node-tool/solutions/v4/reference-module-scope/src/index.ts +105 -0
- package/evals/tasks/node-tool/solutions/v4-proto/reference/src/index.ts +72 -0
- package/evals/tasks/node-tool/solutions/v4-proto/reference-module-scope/src/index.ts +87 -0
- package/evals/tasks/node-tool/starter/src/contract.ts +31 -0
- package/evals/tasks/node-tool/starter/src/index.ts +7 -0
- package/evals/tasks/node-tool/starter/test/smoke.test.ts +22 -0
- package/evals/tasks/node-tool/starter/tsconfig.json +17 -0
- package/evals/tasks/node-tool/task.json +63 -0
- package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-accepts-exponent/src/Wallet.tsx +216 -0
- package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-anonymous-transfer/src/Wallet.tsx +212 -0
- package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-both-auth-buttons/src/Wallet.tsx +210 -0
- package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/meta.json +8 -0
- package/evals/tasks/react-wallet/faulty/thin-constant-balance-key/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/meta.json +9 -0
- package/evals/tasks/react-wallet/faulty/thin-no-nat64-cap/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-number-balance/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-number-balance/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-transfer-as-query/src/Wallet.tsx +254 -0
- package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-truncates-fraction-digits/src/Wallet.tsx +215 -0
- package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/thin-unguarded-balance-effect/src/Wallet.tsx +214 -0
- package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v3-http-4xx-unknown/src/Wallet.tsx +224 -0
- package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v3-mutation-retry-3/src/Wallet.tsx +225 -0
- package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/meta.json +11 -0
- package/evals/tasks/react-wallet/faulty/v3-unknown-as-error/src/Wallet.tsx +182 -0
- package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-every-reject-unknown/src/Wallet.tsx +160 -0
- package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-keep-previous-data/src/Wallet.tsx +166 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-every-reject-unknown/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-keep-previous-data/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-retry-spread/src/Wallet.tsx +162 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-proto-status-not-idle/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-retry-spread/meta.json +12 -0
- package/evals/tasks/react-wallet/faulty/v4-retry-spread/src/Wallet.tsx +163 -0
- package/evals/tasks/react-wallet/faulty/v4-status-not-idle/meta.json +5 -0
- package/evals/tasks/react-wallet/faulty/v4-status-not-idle/src/Wallet.tsx +162 -0
- package/evals/tasks/react-wallet/hidden/react-wallet.test.ts +536 -0
- package/evals/tasks/react-wallet/prompt.md +88 -0
- package/evals/tasks/react-wallet/prompt.minimal.md +51 -0
- package/evals/tasks/react-wallet/solutions/thin/reference/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/solutions/thin/reference-module-scope/src/Wallet.tsx +227 -0
- package/evals/tasks/react-wallet/solutions/thin-guide/reference/src/Wallet.tsx +213 -0
- package/evals/tasks/react-wallet/solutions/thin-guide/reference-module-scope/src/Wallet.tsx +227 -0
- package/evals/tasks/react-wallet/solutions/v3/reference/src/Wallet.tsx +224 -0
- package/evals/tasks/react-wallet/solutions/v3/reference-module-scope/src/Wallet.tsx +230 -0
- package/evals/tasks/react-wallet/solutions/v4/reference/src/Wallet.tsx +160 -0
- package/evals/tasks/react-wallet/solutions/v4/reference-module-scope/src/Wallet.tsx +178 -0
- package/evals/tasks/react-wallet/solutions/v4-proto/reference/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/solutions/v4-proto/reference-module-scope/src/Wallet.tsx +161 -0
- package/evals/tasks/react-wallet/starter/src/Wallet.tsx +12 -0
- package/evals/tasks/react-wallet/starter/src/auth.ts +16 -0
- package/evals/tasks/react-wallet/starter/src/config.ts +14 -0
- package/evals/tasks/react-wallet/starter/src/ii-auth.ts +43 -0
- package/evals/tasks/react-wallet/starter/src/main.tsx +15 -0
- package/evals/tasks/react-wallet/starter/test/smoke.test.ts +34 -0
- package/evals/tasks/react-wallet/starter/tsconfig.json +18 -0
- package/evals/tasks/react-wallet/task.json +84 -0
- package/examples/canister-studio/.stackblitzrc +4 -0
- package/examples/canister-studio/README.md +183 -0
- package/examples/canister-studio/did/ckbtc_minter.did +806 -0
- package/examples/canister-studio/did/icp_ledger.did +586 -0
- package/examples/canister-studio/did/icrc1.did +88 -0
- package/examples/canister-studio/package.json +45 -0
- package/examples/canister-studio/scripts/smoke.ts +188 -0
- package/examples/canister-studio/src/calls/CacheKeyPanel.tsx +104 -0
- package/examples/canister-studio/src/calls/ConfirmWrite.tsx +265 -0
- package/examples/canister-studio/src/calls/ErrorPanel.test.tsx +113 -0
- package/examples/canister-studio/src/calls/ErrorPanel.tsx +214 -0
- package/examples/canister-studio/src/calls/MethodRunner.test.tsx +354 -0
- package/examples/canister-studio/src/calls/MethodRunner.tsx +57 -0
- package/examples/canister-studio/src/calls/ReadRunner.tsx +244 -0
- package/examples/canister-studio/src/calls/ResendPanel.tsx +165 -0
- package/examples/canister-studio/src/calls/ShareLink.tsx +59 -0
- package/examples/canister-studio/src/calls/WriteRunner.test.tsx +678 -0
- package/examples/canister-studio/src/calls/WriteRunner.tsx +670 -0
- package/examples/canister-studio/src/calls/dedupe.ts +189 -0
- package/examples/canister-studio/src/calls/error-info.ts +168 -0
- package/examples/canister-studio/src/calls/history.test.ts +284 -0
- package/examples/canister-studio/src/calls/history.ts +287 -0
- package/examples/canister-studio/src/calls/kinds.ts +68 -0
- package/examples/canister-studio/src/calls/prepare.ts +32 -0
- package/examples/canister-studio/src/calls/query-options.ts +30 -0
- package/examples/canister-studio/src/calls/read.ts +47 -0
- package/examples/canister-studio/src/calls/readback.ts +100 -0
- package/examples/canister-studio/src/calls/record.ts +123 -0
- package/examples/canister-studio/src/calls/safe-calls.test.ts +299 -0
- package/examples/canister-studio/src/calls/share.ts +46 -0
- package/examples/canister-studio/src/calls/testing/doubles.tsx +108 -0
- package/examples/canister-studio/src/calls/testing/fixtures.ts +185 -0
- package/examples/canister-studio/src/calls/useCanisterHandle.ts +35 -0
- package/examples/canister-studio/src/canisters/ckbtc_minter.envelope.json +4228 -0
- package/examples/canister-studio/src/canisters/ckbtc_minter.ts +868 -0
- package/examples/canister-studio/src/canisters/icp_ledger.envelope.json +3454 -0
- package/examples/canister-studio/src/canisters/icp_ledger.ts +584 -0
- package/examples/canister-studio/src/canisters/icrc1.envelope.json +840 -0
- package/examples/canister-studio/src/canisters/icrc1.ts +78 -0
- package/examples/canister-studio/src/components/ActionButton.tsx +32 -0
- package/examples/canister-studio/src/components/AppHeader.tsx +83 -0
- package/examples/canister-studio/src/components/AppShell.tsx +29 -0
- package/examples/canister-studio/src/components/AuthButton.tsx +79 -0
- package/examples/canister-studio/src/components/Badge.tsx +79 -0
- package/examples/canister-studio/src/components/CanisterHeader.tsx +200 -0
- package/examples/canister-studio/src/components/CanisterJump.tsx +130 -0
- package/examples/canister-studio/src/components/Card.tsx +64 -0
- package/examples/canister-studio/src/components/Code.tsx +101 -0
- package/examples/canister-studio/src/components/CopyButton.tsx +126 -0
- package/examples/canister-studio/src/components/Disclosure.tsx +34 -0
- package/examples/canister-studio/src/components/EmptyState.tsx +34 -0
- package/examples/canister-studio/src/components/MethodList.test.tsx +137 -0
- package/examples/canister-studio/src/components/MethodList.tsx +244 -0
- package/examples/canister-studio/src/components/Notice.tsx +36 -0
- package/examples/canister-studio/src/components/ProvenanceBadge.tsx +44 -0
- package/examples/canister-studio/src/components/RouteError.tsx +42 -0
- package/examples/canister-studio/src/components/SectionBoundary.tsx +76 -0
- package/examples/canister-studio/src/components/Spinner.tsx +33 -0
- package/examples/canister-studio/src/components/Tabs.tsx +96 -0
- package/examples/canister-studio/src/components/canister/CanisterLoadFailure.test.tsx +56 -0
- package/examples/canister-studio/src/components/canister/CanisterLoadFailure.tsx +165 -0
- package/examples/canister-studio/src/components/canister/CanisterNotFound.tsx +59 -0
- package/examples/canister-studio/src/components/canister/CanisterPending.tsx +33 -0
- package/examples/canister-studio/src/components/canister/MethodOverview.tsx +93 -0
- package/examples/canister-studio/src/components/canister/MethodWorkspace.test.tsx +201 -0
- package/examples/canister-studio/src/components/canister/MethodWorkspace.tsx +187 -0
- package/examples/canister-studio/src/components/canister/shared-call.test.ts +186 -0
- package/examples/canister-studio/src/components/canister/shared-call.ts +133 -0
- package/examples/canister-studio/src/components/canister/shared-link-loader.test.ts +116 -0
- package/examples/canister-studio/src/components/canister/use-canister-page.ts +44 -0
- package/examples/canister-studio/src/components/canister/workspace-key.test.ts +27 -0
- package/examples/canister-studio/src/components/canister/workspace-key.ts +36 -0
- package/examples/canister-studio/src/components/canister-id-input.ts +69 -0
- package/examples/canister-studio/src/components/canister-names.ts +11 -0
- package/examples/canister-studio/src/components/download.ts +34 -0
- package/examples/canister-studio/src/components/fallbacks.tsx +33 -0
- package/examples/canister-studio/src/components/helpers.test.ts +107 -0
- package/examples/canister-studio/src/components/history/HistoryList.tsx +284 -0
- package/examples/canister-studio/src/components/home/FeaturedLedger.tsx +149 -0
- package/examples/canister-studio/src/components/home/OpenCanister.tsx +99 -0
- package/examples/canister-studio/src/components/home/featured.test.tsx +92 -0
- package/examples/canister-studio/src/components/home/featured.ts +64 -0
- package/examples/canister-studio/src/components/interface/CandidTab.tsx +38 -0
- package/examples/canister-studio/src/components/interface/CompatReport.tsx +92 -0
- package/examples/canister-studio/src/components/interface/CompatibilityTab.tsx +190 -0
- package/examples/canister-studio/src/components/interface/ProjectTab.tsx +196 -0
- package/examples/canister-studio/src/components/interface/TypeScriptTab.tsx +114 -0
- package/examples/canister-studio/src/components/interface/tools.test.tsx +169 -0
- package/examples/canister-studio/src/components/modes.ts +31 -0
- package/examples/canister-studio/src/components/playground/MethodPicker.tsx +67 -0
- package/examples/canister-studio/src/components/playground/PlaygroundForms.tsx +112 -0
- package/examples/canister-studio/src/components/playground/PlaygroundTools.tsx +219 -0
- package/examples/canister-studio/src/components/playground/sample.ts +43 -0
- package/examples/canister-studio/src/components/playground/target.test.tsx +86 -0
- package/examples/canister-studio/src/components/primitives.test.tsx +121 -0
- package/examples/canister-studio/src/components/provenance.ts +38 -0
- package/examples/canister-studio/src/components/route-render.test.tsx +71 -0
- package/examples/canister-studio/src/components/use-task.ts +56 -0
- package/examples/canister-studio/src/components/wallet/BalancePanel.tsx +110 -0
- package/examples/canister-studio/src/components/wallet/LedgerSummary.tsx +63 -0
- package/examples/canister-studio/src/components/wallet/MinterPanel.tsx +255 -0
- package/examples/canister-studio/src/components/wallet/SendPanel.test.tsx +297 -0
- package/examples/canister-studio/src/components/wallet/SendPanel.tsx +446 -0
- package/examples/canister-studio/src/components/wallet/ledgers.test.ts +36 -0
- package/examples/canister-studio/src/components/wallet/ledgers.ts +111 -0
- package/examples/canister-studio/src/forms/JsonPanel.tsx +157 -0
- package/examples/canister-studio/src/forms/MethodForm.test.tsx +369 -0
- package/examples/canister-studio/src/forms/MethodForm.tsx +368 -0
- package/examples/canister-studio/src/forms/TypedForm.tsx +55 -0
- package/examples/canister-studio/src/forms/context.ts +62 -0
- package/examples/canister-studio/src/forms/convert.ts +131 -0
- package/examples/canister-studio/src/forms/edge.test.ts +252 -0
- package/examples/canister-studio/src/forms/engine.test.ts +358 -0
- package/examples/canister-studio/src/forms/engine.ts +1492 -0
- package/examples/canister-studio/src/forms/fields/BytesField.tsx +210 -0
- package/examples/canister-studio/src/forms/fields/Field.tsx +106 -0
- package/examples/canister-studio/src/forms/fields/FieldShell.tsx +101 -0
- package/examples/canister-studio/src/forms/fields/Group.tsx +74 -0
- package/examples/canister-studio/src/forms/fields/ListField.tsx +256 -0
- package/examples/canister-studio/src/forms/fields/Segmented.tsx +78 -0
- package/examples/canister-studio/src/forms/fields/TimestampField.tsx +108 -0
- package/examples/canister-studio/src/forms/fields/UnitsField.tsx +119 -0
- package/examples/canister-studio/src/forms/fields/composites.tsx +389 -0
- package/examples/canister-studio/src/forms/fields/leaves.tsx +350 -0
- package/examples/canister-studio/src/forms/fields.test.tsx +396 -0
- package/examples/canister-studio/src/forms/helpers.test.ts +225 -0
- package/examples/canister-studio/src/forms/hints.ts +128 -0
- package/examples/canister-studio/src/forms/json.ts +119 -0
- package/examples/canister-studio/src/forms/parsing.test.ts +217 -0
- package/examples/canister-studio/src/forms/useMethodForm.ts +251 -0
- package/examples/canister-studio/src/interface/browser.test.ts +23 -0
- package/examples/canister-studio/src/interface/browser.ts +153 -0
- package/examples/canister-studio/src/interface/cache.ts +68 -0
- package/examples/canister-studio/src/interface/cli-cache.test.ts +155 -0
- package/examples/canister-studio/src/interface/cli-cache.ts +125 -0
- package/examples/canister-studio/src/interface/compile.server.test.ts +198 -0
- package/examples/canister-studio/src/interface/compile.server.ts +262 -0
- package/examples/canister-studio/src/interface/compile.test.ts +108 -0
- package/examples/canister-studio/src/interface/compile.ts +305 -0
- package/examples/canister-studio/src/interface/docs.test.ts +75 -0
- package/examples/canister-studio/src/interface/docs.ts +100 -0
- package/examples/canister-studio/src/interface/functions.test.ts +42 -0
- package/examples/canister-studio/src/interface/functions.ts +200 -0
- package/examples/canister-studio/src/interface/live-candid.server.ts +91 -0
- package/examples/canister-studio/src/interface/live-loader.test.ts +515 -0
- package/examples/canister-studio/src/interface/live-loader.ts +364 -0
- package/examples/canister-studio/src/interface/load.test.ts +328 -0
- package/examples/canister-studio/src/interface/load.ts +249 -0
- package/examples/canister-studio/src/interface/read-candid.test.ts +185 -0
- package/examples/canister-studio/src/interface/read-candid.ts +233 -0
- package/examples/canister-studio/src/interface/server-result.ts +42 -0
- package/examples/canister-studio/src/interface/typed.ts +68 -0
- package/examples/canister-studio/src/interface/types.ts +121 -0
- package/examples/canister-studio/src/lib/format.test.ts +107 -0
- package/examples/canister-studio/src/lib/format.ts +139 -0
- package/examples/canister-studio/src/lib/hex.test.ts +43 -0
- package/examples/canister-studio/src/lib/hex.ts +33 -0
- package/examples/canister-studio/src/lib/ids.test.ts +70 -0
- package/examples/canister-studio/src/lib/ids.ts +93 -0
- package/examples/canister-studio/src/lib/reactor.test.ts +55 -0
- package/examples/canister-studio/src/lib/reactor.ts +55 -0
- package/examples/canister-studio/src/lib/registry.test.ts +74 -0
- package/examples/canister-studio/src/lib/registry.ts +238 -0
- package/examples/canister-studio/src/lib/schema.ts +148 -0
- package/examples/canister-studio/src/routeTree.gen.ts +227 -0
- package/examples/canister-studio/src/router.test.ts +290 -0
- package/examples/canister-studio/src/router.tsx +127 -0
- package/examples/canister-studio/src/routes/__root.tsx +58 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.index.tsx +172 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.interface.tsx +98 -0
- package/examples/canister-studio/src/routes/canister.$canisterId.tsx +91 -0
- package/examples/canister-studio/src/routes/history.tsx +55 -0
- package/examples/canister-studio/src/routes/index.tsx +169 -0
- package/examples/canister-studio/src/routes/playground.tsx +286 -0
- package/examples/canister-studio/src/routes/safety.tsx +57 -0
- package/examples/canister-studio/src/routes/wallet.tsx +213 -0
- package/examples/canister-studio/src/safety/LabTransferForm.tsx +84 -0
- package/examples/canister-studio/src/safety/RequestLog.tsx +79 -0
- package/examples/canister-studio/src/safety/SafetyLab.test.tsx +89 -0
- package/examples/canister-studio/src/safety/SafetyLab.tsx +140 -0
- package/examples/canister-studio/src/safety/ScenarioCard.tsx +262 -0
- package/examples/canister-studio/src/safety/lab-run.ts +283 -0
- package/examples/canister-studio/src/safety/mock-ledger.test.ts +99 -0
- package/examples/canister-studio/src/safety/mock-ledger.ts +263 -0
- package/examples/canister-studio/src/safety/scenarios.test.ts +157 -0
- package/examples/canister-studio/src/safety/scenarios.ts +924 -0
- package/examples/canister-studio/src/styles.css +3453 -0
- package/examples/canister-studio/src/styles.test.ts +46 -0
- package/examples/canister-studio/src/values/CallPreview.test.tsx +86 -0
- package/examples/canister-studio/src/values/CallPreview.tsx +148 -0
- package/examples/canister-studio/src/values/ErrValueView.tsx +66 -0
- package/examples/canister-studio/src/values/Inspector.tsx +133 -0
- package/examples/canister-studio/src/values/ReplyView.test.tsx +341 -0
- package/examples/canister-studio/src/values/ReplyView.tsx +164 -0
- package/examples/canister-studio/src/values/candid-text.test.ts +516 -0
- package/examples/canister-studio/src/values/candid-text.ts +479 -0
- package/examples/canister-studio/src/values/hints.ts +58 -0
- package/examples/canister-studio/src/values/json.test.ts +66 -0
- package/examples/canister-studio/src/values/json.ts +31 -0
- package/examples/canister-studio/src/values/leaves.tsx +309 -0
- package/examples/canister-studio/src/values/schema.test.ts +123 -0
- package/examples/canister-studio/src/values/schema.ts +78 -0
- package/examples/canister-studio/src/values/test-router.tsx +21 -0
- package/examples/canister-studio/src/values/tree.tsx +670 -0
- package/examples/canister-studio/src/values/use-sha256.ts +29 -0
- package/examples/canister-studio/tsconfig.json +20 -0
- package/examples/canister-studio/vite.config.ts +50 -0
- package/examples/canister-studio/vitest.config.ts +20 -0
- package/examples/icrc-ledger/.stackblitzrc +4 -0
- package/examples/icrc-ledger/README.md +100 -0
- package/examples/icrc-ledger/ckbtc_minter.did +12 -0
- package/examples/icrc-ledger/icp_ledger.did +147 -0
- package/examples/icrc-ledger/icrc1.did +88 -0
- package/examples/icrc-ledger/index.html +13 -0
- package/examples/icrc-ledger/package.json +40 -0
- package/examples/icrc-ledger/scripts/smoke.ts +151 -0
- package/examples/icrc-ledger/src/App.tsx +71 -0
- package/examples/icrc-ledger/src/ErrorPanel.tsx +105 -0
- package/examples/icrc-ledger/src/MainnetTab.tsx +450 -0
- package/examples/icrc-ledger/src/SandboxTab.test.tsx +379 -0
- package/examples/icrc-ledger/src/SandboxTab.tsx +761 -0
- package/examples/icrc-ledger/src/blocks.test.ts +247 -0
- package/examples/icrc-ledger/src/blocks.ts +140 -0
- package/examples/icrc-ledger/src/canisters/ckbtc_minter.envelope.json +96 -0
- package/examples/icrc-ledger/src/canisters/ckbtc_minter.ts +16 -0
- package/examples/icrc-ledger/src/canisters/icp_ledger.envelope.json +690 -0
- package/examples/icrc-ledger/src/canisters/icp_ledger.ts +223 -0
- package/examples/icrc-ledger/src/canisters/icrc1.envelope.json +840 -0
- package/examples/icrc-ledger/src/canisters/icrc1.ts +78 -0
- package/examples/icrc-ledger/src/format.test.ts +41 -0
- package/examples/icrc-ledger/src/format.ts +68 -0
- package/examples/icrc-ledger/src/ledger.ts +15 -0
- package/examples/icrc-ledger/src/main.tsx +10 -0
- package/examples/icrc-ledger/src/minter.ts +16 -0
- package/examples/icrc-ledger/src/sandbox.test.ts +464 -0
- package/examples/icrc-ledger/src/sandbox.ts +281 -0
- package/examples/icrc-ledger/src/styles.css +391 -0
- package/examples/icrc-ledger/src/transfer-form.test.ts +62 -0
- package/examples/icrc-ledger/src/transfer-form.ts +97 -0
- package/examples/icrc-ledger/tsconfig.json +19 -0
- package/examples/icrc-ledger/vite.config.ts +44 -0
- package/examples/icrc-ledger/vitest.config.ts +12 -0
- package/examples/next-ssr/.stackblitzrc +4 -0
- package/examples/next-ssr/README.md +112 -0
- package/examples/next-ssr/icrc1.did +88 -0
- package/examples/next-ssr/next.config.ts +10 -0
- package/examples/next-ssr/package.json +41 -0
- package/examples/next-ssr/scripts/smoke.ts +169 -0
- package/examples/next-ssr/src/app/account/CertifiedBalances.tsx +58 -0
- package/examples/next-ssr/src/app/account/account.test.tsx +165 -0
- package/examples/next-ssr/src/app/account/page.tsx +82 -0
- package/examples/next-ssr/src/app/api/balance/[ledger]/[principal]/route.ts +10 -0
- package/examples/next-ssr/src/app/globals.css +278 -0
- package/examples/next-ssr/src/app/layout.tsx +34 -0
- package/examples/next-ssr/src/app/page.tsx +46 -0
- package/examples/next-ssr/src/app/providers.browser.test.tsx +127 -0
- package/examples/next-ssr/src/app/providers.test.tsx +73 -0
- package/examples/next-ssr/src/app/providers.tsx +60 -0
- package/examples/next-ssr/src/canisters/icrc1.envelope.json +840 -0
- package/examples/next-ssr/src/canisters/icrc1.ts +78 -0
- package/examples/next-ssr/src/components/BalanceTable.tsx +43 -0
- package/examples/next-ssr/src/components/LedgerCard.test.tsx +96 -0
- package/examples/next-ssr/src/components/LedgerCard.tsx +230 -0
- package/examples/next-ssr/src/components/LedgerError.tsx +32 -0
- package/examples/next-ssr/src/components/LedgerSections.tsx +22 -0
- package/examples/next-ssr/src/components/MyBalances.test.tsx +253 -0
- package/examples/next-ssr/src/components/MyBalances.tsx +129 -0
- package/examples/next-ssr/src/components/SessionBadge.tsx +18 -0
- package/examples/next-ssr/src/components/hydration.test.tsx +259 -0
- package/examples/next-ssr/src/components/server-data.ts +10 -0
- package/examples/next-ssr/src/format.ts +46 -0
- package/examples/next-ssr/src/ledgers.ts +38 -0
- package/examples/next-ssr/src/server/balance-route.test.ts +151 -0
- package/examples/next-ssr/src/server/balance-route.ts +157 -0
- package/examples/next-ssr/src/server/error-summary.test.ts +34 -0
- package/examples/next-ssr/src/server/error-summary.ts +37 -0
- package/examples/next-ssr/src/server/parse-owner.test.ts +39 -0
- package/examples/next-ssr/src/server/parse-owner.ts +34 -0
- package/examples/next-ssr/src/server/prefetch-ledgers.test.ts +137 -0
- package/examples/next-ssr/src/server/prefetch-ledgers.ts +70 -0
- package/examples/next-ssr/src/server/read-balances.test.ts +103 -0
- package/examples/next-ssr/src/server/read-balances.ts +78 -0
- package/examples/next-ssr/src/server/request-client.rsc.test.tsx +110 -0
- package/examples/next-ssr/src/server/request-client.ts +24 -0
- package/examples/next-ssr/src/testing/mock-ledgers.ts +115 -0
- package/examples/next-ssr/src/testing/react-server-dom-turbopack.d.ts +15 -0
- package/examples/next-ssr/src/testing/setup.ts +10 -0
- package/examples/next-ssr/tsconfig.json +31 -0
- package/examples/next-ssr/vitest.config.ts +59 -0
- package/examples/node-agent-tool/.stackblitzrc +4 -0
- package/examples/node-agent-tool/README.md +165 -0
- package/examples/node-agent-tool/icp.yaml +11 -0
- package/examples/node-agent-tool/icrc1.did +88 -0
- package/examples/node-agent-tool/package.json +32 -0
- package/examples/node-agent-tool/src/canisters/icrc1.envelope.json +840 -0
- package/examples/node-agent-tool/src/canisters/icrc1.ts +78 -0
- package/examples/node-agent-tool/src/cli.test.ts +64 -0
- package/examples/node-agent-tool/src/cli.ts +23 -0
- package/examples/node-agent-tool/src/command-line.ts +159 -0
- package/examples/node-agent-tool/src/commands/balance.ts +73 -0
- package/examples/node-agent-tool/src/commands/demo.test.ts +51 -0
- package/examples/node-agent-tool/src/commands/demo.ts +359 -0
- package/examples/node-agent-tool/src/commands/info.ts +69 -0
- package/examples/node-agent-tool/src/commands/reads.test.ts +133 -0
- package/examples/node-agent-tool/src/commands/resend.test.ts +363 -0
- package/examples/node-agent-tool/src/commands/transfer.test.ts +313 -0
- package/examples/node-agent-tool/src/commands/transfer.ts +415 -0
- package/examples/node-agent-tool/src/commands/watch.test.ts +159 -0
- package/examples/node-agent-tool/src/commands/watch.ts +135 -0
- package/examples/node-agent-tool/src/commands/whoami.ts +36 -0
- package/examples/node-agent-tool/src/context.ts +20 -0
- package/examples/node-agent-tool/src/dispatch.ts +70 -0
- package/examples/node-agent-tool/src/failure.test.ts +59 -0
- package/examples/node-agent-tool/src/failure.ts +176 -0
- package/examples/node-agent-tool/src/identity.test.ts +242 -0
- package/examples/node-agent-tool/src/identity.ts +228 -0
- package/examples/node-agent-tool/src/input.ts +110 -0
- package/examples/node-agent-tool/src/ledgers.test.ts +74 -0
- package/examples/node-agent-tool/src/ledgers.ts +62 -0
- package/examples/node-agent-tool/src/mock-ledger.ts +211 -0
- package/examples/node-agent-tool/src/network.test.ts +128 -0
- package/examples/node-agent-tool/src/network.ts +101 -0
- package/examples/node-agent-tool/src/output.test.ts +208 -0
- package/examples/node-agent-tool/src/output.ts +163 -0
- package/examples/node-agent-tool/src/run.ts +73 -0
- package/examples/node-agent-tool/src/test-kit.ts +167 -0
- package/examples/node-agent-tool/tsconfig.json +18 -0
- package/examples/node-agent-tool/vitest.config.ts +8 -0
- package/examples/vite-wallet/.stackblitzrc +4 -0
- package/examples/vite-wallet/Cargo.lock +646 -0
- package/examples/vite-wallet/Cargo.toml +5 -0
- package/examples/vite-wallet/README.md +107 -0
- package/examples/vite-wallet/backend/Cargo.toml +12 -0
- package/examples/vite-wallet/backend/backend.did +37 -0
- package/examples/vite-wallet/backend/src/lib.rs +133 -0
- package/examples/vite-wallet/icp.yaml +44 -0
- package/examples/vite-wallet/index.html +13 -0
- package/examples/vite-wallet/ledger.did +54 -0
- package/examples/vite-wallet/package.json +46 -0
- package/examples/vite-wallet/public/.ic-assets.json5 +26 -0
- package/examples/vite-wallet/scripts/faucet-args.test.ts +30 -0
- package/examples/vite-wallet/scripts/faucet-args.ts +41 -0
- package/examples/vite-wallet/scripts/faucet.ts +41 -0
- package/examples/vite-wallet/src/AddressBook.test.tsx +191 -0
- package/examples/vite-wallet/src/AddressBook.tsx +147 -0
- package/examples/vite-wallet/src/App.tsx +53 -0
- package/examples/vite-wallet/src/Balance.test.tsx +57 -0
- package/examples/vite-wallet/src/Balance.tsx +58 -0
- package/examples/vite-wallet/src/EnvironmentPanel.test.tsx +83 -0
- package/examples/vite-wallet/src/EnvironmentPanel.tsx +103 -0
- package/examples/vite-wallet/src/ErrorNote.tsx +70 -0
- package/examples/vite-wallet/src/Profile.test.tsx +145 -0
- package/examples/vite-wallet/src/Profile.tsx +92 -0
- package/examples/vite-wallet/src/SendIcp.test.tsx +231 -0
- package/examples/vite-wallet/src/SendIcp.tsx +244 -0
- package/examples/vite-wallet/src/SendToContact.test.tsx +113 -0
- package/examples/vite-wallet/src/SendToContact.tsx +102 -0
- package/examples/vite-wallet/src/SignIn.test.tsx +106 -0
- package/examples/vite-wallet/src/SignIn.tsx +120 -0
- package/examples/vite-wallet/src/Wallet.test.tsx +89 -0
- package/examples/vite-wallet/src/account-switch.test.tsx +108 -0
- package/examples/vite-wallet/src/auth/dev-accounts.test.ts +113 -0
- package/examples/vite-wallet/src/auth/dev-accounts.ts +216 -0
- package/examples/vite-wallet/src/auth/local-page.test.ts +28 -0
- package/examples/vite-wallet/src/auth/local-page.ts +20 -0
- package/examples/vite-wallet/src/auth/wallet-auth.test.ts +159 -0
- package/examples/vite-wallet/src/auth/wallet-auth.ts +131 -0
- package/examples/vite-wallet/src/canisters/backend.envelope.json +275 -0
- package/examples/vite-wallet/src/canisters/backend.ts +58 -0
- package/examples/vite-wallet/src/canisters/ledger.envelope.json +451 -0
- package/examples/vite-wallet/src/canisters/ledger.ts +56 -0
- package/examples/vite-wallet/src/client.ts +45 -0
- package/examples/vite-wallet/src/main.tsx +18 -0
- package/examples/vite-wallet/src/optimistic-contacts.ts +113 -0
- package/examples/vite-wallet/src/refusal.ts +17 -0
- package/examples/vite-wallet/src/styles.css +282 -0
- package/examples/vite-wallet/src/test/test-wallet.tsx +322 -0
- package/examples/vite-wallet/src/token.ts +50 -0
- package/examples/vite-wallet/src/transfer.test.ts +178 -0
- package/examples/vite-wallet/src/transfer.ts +110 -0
- package/examples/vite-wallet/src/use-canisters.ts +49 -0
- package/examples/vite-wallet/tsconfig.json +19 -0
- package/examples/vite-wallet/vite.config.ts +47 -0
- package/examples/vite-wallet/vitest.config.ts +17 -0
- package/package.json +9 -4
- package/packages/core/.size-limit.js +47 -0
- package/packages/core/LICENSE +21 -0
- package/packages/core/README.md +84 -0
- package/packages/core/llms.txt +610 -0
- package/packages/core/package.json +89 -0
- package/packages/core/src/call.ts +961 -0
- package/packages/core/src/canister.ts +259 -0
- package/packages/core/src/client.ts +2061 -0
- package/packages/core/src/errors.ts +1079 -0
- package/packages/core/src/hydration.ts +239 -0
- package/packages/core/src/index.ts +23 -0
- package/packages/core/src/keys.ts +108 -0
- package/packages/core/src/management.ts +138 -0
- package/packages/core/src/network.ts +1020 -0
- package/packages/core/src/options.ts +1000 -0
- package/packages/core/src/runtime.ts +50 -0
- package/packages/core/src/testing/fake-replica.ts +1166 -0
- package/packages/core/src/testing/index.ts +16 -0
- package/packages/core/src/testing/test-auth.ts +340 -0
- package/packages/core/src/testing/test-client.ts +559 -0
- package/packages/core/src/types.ts +541 -0
- package/packages/core/src/units.ts +299 -0
- package/packages/core/src/version.ts +4 -0
- package/packages/core/tests/canister-helpers.ts +187 -0
- package/packages/core/tests/canister-id.test.ts +158 -0
- package/packages/core/tests/canister-unwrap.test.ts +94 -0
- package/packages/core/tests/canister.test-d.ts +406 -0
- package/packages/core/tests/canister.test.ts +1921 -0
- package/packages/core/tests/client-account-change.test.ts +131 -0
- package/packages/core/tests/client-agents.test.ts +402 -0
- package/packages/core/tests/client-auth-network.test.ts +719 -0
- package/packages/core/tests/client-disposed.test.ts +403 -0
- package/packages/core/tests/client-helpers.ts +136 -0
- package/packages/core/tests/client-hydration.test.ts +166 -0
- package/packages/core/tests/client-pinned.test.ts +626 -0
- package/packages/core/tests/client-session.test.ts +348 -0
- package/packages/core/tests/client.test-d.ts +181 -0
- package/packages/core/tests/client.test.ts +1162 -0
- package/packages/core/tests/encode.test.ts +171 -0
- package/packages/core/tests/env-canister-id.test.ts +666 -0
- package/packages/core/tests/env-cookie-copies.test.ts +182 -0
- package/packages/core/tests/error-guard.test.ts +222 -0
- package/packages/core/tests/errors.test-d.ts +280 -0
- package/packages/core/tests/errors.test.ts +1359 -0
- package/packages/core/tests/fixtures/README.md +28 -0
- package/packages/core/tests/fixtures/accounts.did +21 -0
- package/packages/core/tests/fixtures/accounts.envelope.json +367 -0
- package/packages/core/tests/fixtures/accounts.ts +26 -0
- package/packages/core/tests/fixtures/archive.did +31 -0
- package/packages/core/tests/fixtures/archive.envelope.json +259 -0
- package/packages/core/tests/fixtures/archive.ts +55 -0
- package/packages/core/tests/fixtures/icrc1.did +88 -0
- package/packages/core/tests/fixtures/icrc1.envelope.json +840 -0
- package/packages/core/tests/fixtures/icrc1.ts +78 -0
- package/packages/core/tests/fixtures/management.did +724 -0
- package/packages/core/tests/fixtures/management.envelope.json +4455 -0
- package/packages/core/tests/fixtures/management.ts +486 -0
- package/packages/core/tests/fixtures/shapes.did +33 -0
- package/packages/core/tests/fixtures/shapes.envelope.json +440 -0
- package/packages/core/tests/fixtures/shapes.ts +56 -0
- package/packages/core/tests/fixtures/skippable.did +15 -0
- package/packages/core/tests/fixtures/skippable.envelope.json +182 -0
- package/packages/core/tests/fixtures/skippable.ts +33 -0
- package/packages/core/tests/func.test.ts +154 -0
- package/packages/core/tests/identity-attributes.test.ts +214 -0
- package/packages/core/tests/keys.test.ts +289 -0
- package/packages/core/tests/management.test.ts +206 -0
- package/packages/core/tests/network-helpers.ts +121 -0
- package/packages/core/tests/network.test-d.ts +78 -0
- package/packages/core/tests/network.test.ts +1051 -0
- package/packages/core/tests/options.test.ts +1594 -0
- package/packages/core/tests/redirect-sign-in.test.ts +393 -0
- package/packages/core/tests/resend.test-d.ts +81 -0
- package/packages/core/tests/resend.test.ts +723 -0
- package/packages/core/tests/skip.test-d.ts +125 -0
- package/packages/core/tests/testing-entry.test.ts +73 -0
- package/packages/core/tests/testing-fake-replica.test.ts +1242 -0
- package/packages/core/tests/testing-test-auth.test-d.ts +84 -0
- package/packages/core/tests/testing-test-auth.test.ts +483 -0
- package/packages/core/tests/testing-test-client.test-d.ts +184 -0
- package/packages/core/tests/testing-test-client.test.ts +1272 -0
- package/packages/core/tests/time-realm.test.ts +63 -0
- package/packages/core/tests/time.test.ts +238 -0
- package/packages/core/tests/traps/README.md +39 -0
- package/packages/core/tests/traps/anonymous-write.test.ts +145 -0
- package/packages/core/tests/traps/classification-table.test.ts +256 -0
- package/packages/core/tests/traps/err-arm.test.ts +144 -0
- package/packages/core/tests/traps/fetch-spy.ts +39 -0
- package/packages/core/tests/traps/invalidation-after-write.test.ts +178 -0
- package/packages/core/tests/traps/ledger.ts +248 -0
- package/packages/core/tests/traps/root-key-off-local.test.ts +130 -0
- package/packages/core/tests/traps/stale-data-across-users.test.ts +173 -0
- package/packages/core/tests/traps/unresolved-name.test.ts +155 -0
- package/packages/core/tests/traps/update-as-query.test.ts +244 -0
- package/packages/core/tests/traps/update-not-resent.test.ts +126 -0
- package/packages/core/tests/traps/update-resent-when-never-delivered.test.ts +159 -0
- package/packages/core/tests/traps.test-d.ts +476 -0
- package/packages/core/tests/units.test-d.ts +118 -0
- package/packages/core/tests/units.test.ts +634 -0
- package/packages/core/tsconfig.json +19 -0
- package/packages/core/tsconfig.typecheck.json +16 -0
- package/packages/core/vitest.config.ts +13 -0
- package/packages/mcp/LICENSE +21 -0
- package/packages/mcp/README.md +189 -0
- package/packages/mcp/package.json +62 -0
- package/packages/mcp/src/candid/candid-text.test.ts +455 -0
- package/packages/mcp/src/candid/candid-text.ts +501 -0
- package/packages/mcp/src/candid/contract.test.ts +398 -0
- package/packages/mcp/src/candid/formats.ts +155 -0
- package/packages/mcp/src/candid/hex.ts +29 -0
- package/packages/mcp/src/candid/json-schema.test.ts +758 -0
- package/packages/mcp/src/candid/json-schema.ts +454 -0
- package/packages/mcp/src/candid/json.test.ts +1207 -0
- package/packages/mcp/src/candid/json.ts +1053 -0
- package/packages/mcp/src/candid/schema-walk.ts +189 -0
- package/packages/mcp/src/candid/type-text.test.ts +179 -0
- package/packages/mcp/src/candid/type-text.ts +238 -0
- package/packages/mcp/src/cli.ts +134 -0
- package/packages/mcp/src/identity.ts +188 -0
- package/packages/mcp/src/interface/cache.test.ts +48 -0
- package/packages/mcp/src/interface/cache.ts +68 -0
- package/packages/mcp/src/interface/cli-cache.test.ts +150 -0
- package/packages/mcp/src/interface/cli-cache.ts +122 -0
- package/packages/mcp/src/interface/compile-worker.test.ts +246 -0
- package/packages/mcp/src/interface/compile-worker.ts +290 -0
- package/packages/mcp/src/interface/compile.test.ts +155 -0
- package/packages/mcp/src/interface/compile.ts +281 -0
- package/packages/mcp/src/interface/docs.test.ts +105 -0
- package/packages/mcp/src/interface/docs.ts +86 -0
- package/packages/mcp/src/interface/fixtures/icrc1.did +88 -0
- package/packages/mcp/src/interface/hex.ts +8 -0
- package/packages/mcp/src/interface/ids.test.ts +71 -0
- package/packages/mcp/src/interface/ids.ts +87 -0
- package/packages/mcp/src/interface/loader.test.ts +804 -0
- package/packages/mcp/src/interface/loader.ts +519 -0
- package/packages/mcp/src/interface/read-candid.test.ts +300 -0
- package/packages/mcp/src/interface/read-candid.ts +259 -0
- package/packages/mcp/src/interface/types.ts +113 -0
- package/packages/mcp/src/network.ts +122 -0
- package/packages/mcp/src/options.ts +149 -0
- package/packages/mcp/src/server/approval.ts +159 -0
- package/packages/mcp/src/server/naming.ts +43 -0
- package/packages/mcp/src/server/results.ts +102 -0
- package/packages/mcp/src/server/server.ts +797 -0
- package/packages/mcp/src/server/tools.ts +116 -0
- package/packages/mcp/src/usage.ts +40 -0
- package/packages/mcp/tests/approval.test.ts +60 -0
- package/packages/mcp/tests/identity.test.ts +234 -0
- package/packages/mcp/tests/naming.test.ts +62 -0
- package/packages/mcp/tests/options.test.ts +140 -0
- package/packages/mcp/tests/server.test.ts +997 -0
- package/packages/mcp/tsconfig.json +19 -0
- package/packages/mcp/tsconfig.typecheck.json +10 -0
- package/packages/mcp/vitest.config.ts +10 -0
- package/packages/react/LICENSE +21 -0
- package/packages/react/README.md +328 -0
- package/packages/react/llms.txt +95 -0
- package/packages/react/package.json +95 -0
- package/packages/react/src/index.tsx +678 -0
- package/packages/react/tests/abandoned-render.test.tsx +816 -0
- package/packages/react/tests/auth.test.tsx +315 -0
- package/packages/react/tests/caller-keys.test.tsx +2334 -0
- package/packages/react/tests/client-time.test.ts +40 -0
- package/packages/react/tests/entry.test.ts +52 -0
- package/packages/react/tests/helpers.tsx +291 -0
- package/packages/react/tests/hydration.test.tsx +262 -0
- package/packages/react/tests/ownership.test.tsx +260 -0
- package/packages/react/tests/provider.server.test.tsx +169 -0
- package/packages/react/tests/query-client.test.tsx +107 -0
- package/packages/react/tests/strict-mode.test.tsx +288 -0
- package/packages/react/tests/suspense.test-d.tsx +357 -0
- package/packages/react/tests/two-query-cores.test.tsx +135 -0
- package/packages/react/tests/types.test-d.tsx +63 -0
- package/packages/react/tsconfig.json +23 -0
- package/packages/react/tsconfig.test.json +8 -0
- package/packages/react/tsconfig.typecheck.json +16 -0
- package/packages/react/vitest.config.ts +39 -0
- package/packages/vite-plugin/LICENSE +21 -0
- package/packages/vite-plugin/README.md +532 -0
- package/packages/vite-plugin/package.json +76 -0
- package/packages/vite-plugin/src/describe-value.test.ts +43 -0
- package/packages/vite-plugin/src/describe-value.ts +167 -0
- package/packages/vite-plugin/src/dev-environment.test.ts +747 -0
- package/packages/vite-plugin/src/dev-environment.ts +510 -0
- package/packages/vite-plugin/src/env.ts +431 -0
- package/packages/vite-plugin/src/fetch.ts +348 -0
- package/packages/vite-plugin/src/file-identity.ts +106 -0
- package/packages/vite-plugin/src/generate.ts +691 -0
- package/packages/vite-plugin/src/index.test.ts +1243 -0
- package/packages/vite-plugin/src/index.ts +2565 -0
- package/packages/vite-plugin/src/interface.ts +339 -0
- package/packages/vite-plugin/src/local-host.ts +34 -0
- package/packages/vite-plugin/src/options.ts +641 -0
- package/packages/vite-plugin/src/principal-text.test.ts +87 -0
- package/packages/vite-plugin/src/principal-text.ts +98 -0
- package/packages/vite-plugin/tests/close.test.ts +141 -0
- package/packages/vite-plugin/tests/environment-mode.test.ts +136 -0
- package/packages/vite-plugin/tests/fake-ic.ts +214 -0
- package/packages/vite-plugin/tests/fetch-sdk.test.ts +27 -0
- package/packages/vite-plugin/tests/fetch.test.ts +1196 -0
- package/packages/vite-plugin/tests/fixtures/fake-cli/bin.js +90 -0
- package/packages/vite-plugin/tests/fixtures/fake-cli/package.json +8 -0
- package/packages/vite-plugin/tests/fixtures/icrc1.did +88 -0
- package/packages/vite-plugin/tests/generation.test.ts +1036 -0
- package/packages/vite-plugin/tests/icp-command.test.ts +194 -0
- package/packages/vite-plugin/tests/icp-timeout.test.ts +83 -0
- package/packages/vite-plugin/tests/no-process-exit.test.ts +83 -0
- package/packages/vite-plugin/tests/on-generated.test.ts +323 -0
- package/packages/vite-plugin/tests/output-collision.test.ts +329 -0
- package/packages/vite-plugin/tests/package.test.ts +62 -0
- package/packages/vite-plugin/tests/project.test.ts +2993 -0
- package/packages/vite-plugin/tests/support.ts +339 -0
- package/packages/vite-plugin/tests/timeout.test.ts +107 -0
- package/packages/vite-plugin/tsconfig.json +23 -0
- package/packages/vite-plugin/tsconfig.typecheck.json +16 -0
- package/packages/vite-plugin/vitest.config.ts +9 -0
- package/pnpm-workspace.yaml +23 -0
- package/scripts/ai-context-files.js +72 -0
- package/scripts/assemble-docs-site.mjs +485 -0
- package/scripts/assemble-docs-site.test.mjs +568 -0
- package/scripts/build-examples.js +58 -0
- package/scripts/check-ai-context.js +963 -0
- package/scripts/check-ai-context.test.mjs +811 -0
- package/scripts/check-exports.mjs +767 -0
- package/scripts/check-exports.test.mjs +1136 -0
- package/scripts/check-snippets/ambient.d.ts +428 -0
- package/scripts/check-snippets/app/generated/backend.did +7 -0
- package/scripts/check-snippets/app/generated/backend.ts +15 -0
- package/scripts/check-snippets/app/generated/icrc1.did +88 -0
- package/scripts/check-snippets/app/generated/icrc1.ts +78 -0
- package/scripts/check-snippets/app/globals.ts +26 -0
- package/scripts/check-snippets/docs/guides/App.tsx +21 -0
- package/scripts/check-snippets/docs/guides/app/providers.tsx +23 -0
- package/scripts/check-snippets/docs/guides/auth-client.ts +47 -0
- package/scripts/check-snippets/docs/guides/canisters/backend.ts +3 -0
- package/scripts/check-snippets/docs/guides/canisters/icrc1.ts +3 -0
- package/scripts/check-snippets/docs/guides/components/LedgerCard.tsx +26 -0
- package/scripts/check-snippets/docs/guides/components/shell.tsx +11 -0
- package/scripts/check-snippets/docs/guides/components/sign-in-page.tsx +29 -0
- package/scripts/check-snippets/docs/guides/components/slow-section.tsx +5 -0
- package/scripts/check-snippets/docs/guides/generated/accounts.ts +95 -0
- package/scripts/check-snippets/docs/guides/generated/ckbtc_minter.ts +40 -0
- package/scripts/check-snippets/docs/guides/generated/icp_ledger.ts +267 -0
- package/scripts/check-snippets/docs/guides/ledger.ts +10 -0
- package/scripts/check-snippets/docs/guides/server/request-client.ts +8 -0
- package/scripts/check-snippets.mjs +993 -0
- package/scripts/check-snippets.test.mjs +338 -0
- package/scripts/check-stack.mjs +501 -0
- package/scripts/check-stack.test.mjs +800 -0
- package/scripts/clean-node-modules.js +67 -0
- package/scripts/example-projects.js +58 -0
- package/scripts/export-budget.mjs +145 -0
- package/scripts/faults.json +6749 -0
- package/scripts/lib/fault-workspace.mjs +210 -0
- package/scripts/lib/io.mjs +29 -0
- package/scripts/lib/io.test.mjs +38 -0
- package/scripts/lib/markdown-fences.mjs +56 -0
- package/scripts/lib/markdown-fences.test.mjs +84 -0
- package/scripts/lib/package-exports.mjs +54 -0
- package/scripts/lib/package-exports.test.mjs +66 -0
- package/scripts/lib/release-pr-steps.mjs +47 -0
- package/scripts/release-tag.mjs +95 -0
- package/scripts/release-tag.test.mjs +278 -0
- package/scripts/release-workflow.test.mjs +98 -0
- package/scripts/release.js +167 -0
- package/scripts/release.test.mjs +347 -0
- package/scripts/removed-v3-names.js +125 -0
- package/scripts/size-app/.size-limit.js +90 -0
- package/scripts/size-app/core.js +3 -0
- package/scripts/size-app/package.json +24 -0
- package/scripts/size-app/react.js +4 -0
- package/scripts/size-app.test.mjs +73 -0
- package/scripts/sync-ai-context-versions.js +102 -0
- package/scripts/sync-example-versions.js +151 -0
- package/scripts/test-examples-published.mjs +1585 -0
- package/scripts/test-examples-published.test.mjs +1586 -0
- package/scripts/traps/any-method-vars-not-a-list.json +5 -0
- package/scripts/traps/canister-method-unknown.json +5 -0
- package/scripts/traps/client-says-who-calls-once.json +5 -0
- package/scripts/traps/client-says-who-calls.json +5 -0
- package/scripts/traps/err-only-on-canister-err.json +14 -0
- package/scripts/traps/format-units-refuses-missing-value.json +5 -0
- package/scripts/traps/format-units-refuses-number.json +5 -0
- package/scripts/traps/format-units-unknown-option.json +5 -0
- package/scripts/traps/guard-err-is-the-methods.json +5 -0
- package/scripts/traps/guard-false-keeps-every-kind.json +5 -0
- package/scripts/traps/internals-not-exported.json +9 -0
- package/scripts/traps/network-refuses-unknown-name.json +5 -0
- package/scripts/traps/never-err-has-no-type.json +5 -0
- package/scripts/traps/options-method-unknown.json +5 -0
- package/scripts/traps/options-vars-wrong-type.json +5 -0
- package/scripts/traps/parse-units-refuses-number.json +5 -0
- package/scripts/traps/parse-units-unknown-option.json +5 -0
- package/scripts/traps/principal-is-not-plain-text.json +14 -0
- package/scripts/traps/query-options-refuses-oneway.json +5 -0
- package/scripts/traps/query-options-refuses-update.json +5 -0
- package/scripts/traps/refuse-next-unknown-option.json +5 -0
- package/scripts/traps/resend-key-reads-the-methods-arg.json +5 -0
- package/scripts/traps/resend-states-its-dedupe-key.json +5 -0
- package/scripts/traps/suspense-refuses-argument-skip.json +5 -0
- package/scripts/traps/suspense-refuses-skippable-read.json +5 -0
- package/scripts/traps/suspense-refuses-vars-skip-fits.json +5 -0
- package/scripts/traps/test-handler-method-unknown.json +5 -0
- package/scripts/traps/test-handler-nat-is-bigint.json +5 -0
- package/scripts/traps/test-handler-takes-the-domain-value.json +5 -0
- package/scripts/traps/vars-of-two-arguments-are-the-tuple.json +5 -0
- package/scripts/typecheck-examples.js +122 -0
- package/scripts/verify-faults.mjs +375 -0
- package/scripts/verify-faults.test.mjs +402 -0
- package/scripts/verify-package-artifacts.mjs +590 -0
- package/scripts/verify-peer-floors.js +399 -0
- package/scripts/verify-peer-floors.test.mjs +422 -0
- package/scripts/verify-test-fails-rules.mjs +104 -0
- package/scripts/verify-test-fails-rules.test.mjs +215 -0
- package/scripts/verify-test-fails.js +371 -0
- package/scripts/verify-traps.mjs +505 -0
- package/scripts/verify-traps.test.mjs +521 -0
- package/scripts/verify-typescript-floor.js +239 -0
- package/skill-packages/ic-reactor/SKILL.md +103 -0
- package/stack.json +8 -0
- package/tsconfig.base.json +23 -0
- package/tsconfig.json +8 -0
package/evals/README.md
ADDED
|
@@ -0,0 +1,756 @@
|
|
|
1
|
+
# evals — does a typed handle layer help agents write correct IC apps?
|
|
2
|
+
|
|
3
|
+
A harness for one question: do AI coding agents write more correct Internet
|
|
4
|
+
Computer apps with a thin layer of typed, mode-gated per-method handles
|
|
5
|
+
("ic-reactor 4") than with a candid-core generated module plus raw TanStack
|
|
6
|
+
Query, or with ic-reactor 3 as published? It measures four conditions on the
|
|
7
|
+
same tasks with the same hidden tests:
|
|
8
|
+
|
|
9
|
+
| Condition | Library the agent gets | Generated input in the starter | Docs in the starter (`docs/`) | Words |
|
|
10
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----- |
|
|
11
|
+
| `v3` | `@ic-reactor/core` + `@ic-reactor/react` 3.13.0 from npm, `@icp-sdk/core` 6.1.0, `@icp-sdk/auth` 10.0.1, TanStack Query 5.104 | `src/declarations/icrc1.did.{js,d.ts}` (`@icp-sdk/bindgen` output) | `llms-full.txt` (repo root at 623b48c11 = 3.13.0) + the `llms.txt` shipped inside both packages | 8,996 |
|
|
12
|
+
| `thin` | `@candid-core/schema` 0.2.0, `@icp-sdk/core`, `@icp-sdk/auth`, TanStack Query; no framework | `src/generated/icrc1.ts` from `candid-core-cli gen` 0.1.0 | the READMEs shipped in `@candid-core/schema` 0.2.0 (2,274) and `@candid-core/cli` 0.1.0 (532) | 2,806 |
|
|
13
|
+
| `thin-guide` | identical to `thin` (same starter, generated module, dependencies) | identical to `thin` | thin's two READMEs + `llms.txt`, a guide for the thin stack matched to the v4-proto guide (1,792) | 4,598 |
|
|
14
|
+
| `v4-proto` | the throwaway prototype `@ic-reactor/v4-proto` (shipped as a built package: `package.json` + `dist/`) on the same stack as thin | the same `icrc1.ts` + `icrc1.service.ts` (hand-written: see "Threats") | `llms.txt` written for the prototype | 1,778 |
|
|
15
|
+
| `v4` | ic-reactor 4: `@ic-reactor/core` + `@ic-reactor/react` packed from this repository, or 4.0.0-beta.1 from npm (`setup.mjs --v4-from`; shipped as `package.json` + `dist/`), `@candid-core/schema` 0.3.0-beta.1, `@icp-sdk/*`, TanStack Query | `src/generated/icrc1.ts` from `candid-core-cli gen` 0.2.0-beta.1 | the `llms.txt` in the `@ic-reactor/core` tarball (DX3's guide, #785; published 4.0.0-beta.1) | 1,974 |
|
|
16
|
+
|
|
17
|
+
`thin-guide` is the honest comparator for v4-proto: a shipped thin layer would
|
|
18
|
+
come with a guide too. Plain `thin` stays so the effect of the guide is
|
|
19
|
+
separable (`thin-guide − thin` vs `v4-proto − thin-guide`).
|
|
20
|
+
|
|
21
|
+
`v4` was added after the Decision (`PREREGISTRATION.md`): it is the gate for
|
|
22
|
+
releasing ic-reactor 4.0.0-beta.1, run against a same-day `thin-guide`
|
|
23
|
+
control (Addendum 3, frozen on 2026-10-03 before the batch), and of the GA
|
|
24
|
+
gate built from the published 4.0.0-beta.1 (Addendum 4, drafted
|
|
25
|
+
2026-10-05). It runs only when named (`--condition v4`); a batch with no
|
|
26
|
+
`--condition` runs the four conditions of the pilots. See "The v4 condition" below and
|
|
27
|
+
`conditions/v4/README.md`.
|
|
28
|
+
|
|
29
|
+
**One pilot has run with a real agent** (`claude-sonnet-5-5`, effort
|
|
30
|
+
`medium`, 40 runs, explicit prompt: every cell at the ceiling; see
|
|
31
|
+
`PREREGISTRATION.md`, Addendum 1). The matrix needs a budget decision. This directory proves the harness on hand-written solutions, and the
|
|
32
|
+
driver end to end with a stub agent.
|
|
33
|
+
|
|
34
|
+
## Layout
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
evals/
|
|
38
|
+
package.json, pnpm-workspace.yaml, pnpm-lock.yaml own pnpm workspace root (root lockfile untouched)
|
|
39
|
+
setup.mjs generate/copy condition inputs, build the prototype, vendor the
|
|
40
|
+
public fake replica, build .ship/ (what agents are given)
|
|
41
|
+
score.mjs score one solution → one JSON line
|
|
42
|
+
gate.mjs score every reference and faulty solution and check expectations
|
|
43
|
+
drive.mjs the agent-matrix driver (dry-run + stub-agent run only so far)
|
|
44
|
+
harness/
|
|
45
|
+
assemble.mjs starter assembly (task layer + condition layer + docs + public scaffold)
|
|
46
|
+
world.ts, fake-ledger.ts, fake-auth.ts, declarations/, icrc1.did the hidden tests' world
|
|
47
|
+
public/support/ the public test scaffold shipped to agents (no fault injection)
|
|
48
|
+
runs.mjs one run's private directory (work/ home/ tmp/)
|
|
49
|
+
sandbox.mjs the macOS sandbox-exec profile agents run in
|
|
50
|
+
leak-scan.mjs the transcript leak audit (second line of defence)
|
|
51
|
+
aggregate.mjs statistics: per task × model × effort × prompt variant × condition
|
|
52
|
+
judge.mjs per-test results → requirements, safe, met, under one prompt variant
|
|
53
|
+
probes/ per-input amount diagnostic for stored solutions (not scored)
|
|
54
|
+
check-docs.mjs checks docs/scaffold/prompts for hidden-test names and literals
|
|
55
|
+
gate-plan.mjs what gate.mjs scores, and which empty cells it may skip
|
|
56
|
+
*.test.mjs unit tests: sandbox, leak audit, aggregation, driver, prompt parity, v4 ship, gate plan
|
|
57
|
+
tasks/<task>/
|
|
58
|
+
prompt.md the task prompt (`explicit` variant); {{LIBRARY}} is the only
|
|
59
|
+
condition-specific line, {{RUN}} the only run-mode-specific one
|
|
60
|
+
prompt.minimal.md the `minimal` variant: product and public contract, no safety rules
|
|
61
|
+
task.json requirements (groups of hidden tests, safety flag), environment, protected files
|
|
62
|
+
starter/ files identical in every condition, incl. test/smoke.test.ts
|
|
63
|
+
hidden/ the hidden acceptance tests (never copied into a starter)
|
|
64
|
+
solutions/<condition>/reference*/ the harness author's passing solutions
|
|
65
|
+
faulty/<name>/ deliberately broken solutions + meta.json (condition, bug, expected failures)
|
|
66
|
+
conditions/<condition>/
|
|
67
|
+
package.json exactly what an agent in that condition may import (+ tsc/vitest/testing-library)
|
|
68
|
+
condition.json the {{LIBRARY}} line; `"base"` makes a condition reuse another's starter and packages
|
|
69
|
+
starter/ condition-specific generated code
|
|
70
|
+
docs/ the documentation that condition's agent is given (added to the base's docs)
|
|
71
|
+
conditions/v4-proto/lib/ the prototype (src/, dist/, test/, SHIM-NOTES.md)
|
|
72
|
+
conditions/v4/ ic-reactor 4, packed from this repository or from npm (README.md, PORTING.md);
|
|
73
|
+
its node_modules (setup, untracked) is a copy of .ship/v4's,
|
|
74
|
+
with @icp-sdk/core linked to evals' own (one instance for the world)
|
|
75
|
+
.ship/<condition>/node_modules (setup) flat npm installs shipped to agents; gitignored
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`harness/ship.mjs` holds what setup refuses to ship for `v4` (a guide or
|
|
79
|
+
package code that gives a hidden test away); `harness/ship.test.mjs` checks
|
|
80
|
+
the refusal and the tree setup built.
|
|
81
|
+
|
|
82
|
+
## Running
|
|
83
|
+
|
|
84
|
+
Node 22+, pnpm 10 (the repo's `packageManager`, via `npx pnpm@10.30.3` if
|
|
85
|
+
needed), npm (for `.ship/`), and macOS for the agent sandbox. For the `v4`
|
|
86
|
+
condition `setup.mjs` also builds and packs `packages/core` and
|
|
87
|
+
`packages/react` with `corepack pnpm`, so the repository's own workspace
|
|
88
|
+
must be installed (`corepack pnpm install` at the root), and fetches
|
|
89
|
+
`@candid-core/cli@0.2.0-beta.1` with `npx`. With `--v4-from npm:<version>`
|
|
90
|
+
it downloads the published tarballs instead (checked against the integrity
|
|
91
|
+
pinned in `harness/ship.mjs`), and the root workspace is not needed.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
cd evals
|
|
95
|
+
pnpm install # its own workspace: never touches the root lockfile
|
|
96
|
+
node setup.mjs # inputs, prototype build, public scaffold, .ship/ (network: npm install)
|
|
97
|
+
node setup.mjs --v4-from npm:4.0.0-beta.1 # … with v4 from the published tarballs (Addendum 4)
|
|
98
|
+
|
|
99
|
+
node score.mjs --task node-tool --condition thin --solution tasks/node-tool/solutions/thin/reference
|
|
100
|
+
node gate.mjs [--task react-wallet] [--jobs 4] # all references + all faulty solutions
|
|
101
|
+
node gate.mjs --require v4 # … and fail if a v4 cell has no reference (Addendum 3)
|
|
102
|
+
node drive.mjs --n 20 --dry-run # the matrix plan
|
|
103
|
+
node drive.mjs --pilot --dry-run # the 5-runs-per-cell pilot plan
|
|
104
|
+
node drive.mjs --pilot --prompt minimal --dry-run # the same with the minimal prompt
|
|
105
|
+
node drive.mjs --preflight --model <m> --oauth-token-file <f> # one tiny real call (spends quota)
|
|
106
|
+
node drive.mjs --aggregate runs/<dir> [--pilot] # re-aggregate saved results
|
|
107
|
+
node drive.mjs --aggregate runs/<dir> --rescan # … re-auditing each transcript with today's scanner
|
|
108
|
+
node drive.mjs --aggregate runs/<dir> --rescore # … re-scoring each stored solution with today's tests
|
|
109
|
+
node drive.mjs --pilot --prompt minimal --condition v4 --condition thin-guide --dry-run # Addendum 3's plan
|
|
110
|
+
node drive.mjs --n 20 --seed 20261005 --prompt minimal --condition v4 --condition thin-guide --dry-run # Addendum 4's
|
|
111
|
+
|
|
112
|
+
node --test harness/*.test.mjs # sandbox, leak audit, aggregation, driver, prompts, v4 ship, gate plan
|
|
113
|
+
EVALS_NO_SANDBOX=1 node --test harness/*.test.mjs # … as on a host without sandbox-exec (tsc-only)
|
|
114
|
+
node harness/check-docs.mjs [files…] # docs vs hidden tests (exit 1 on a hit)
|
|
115
|
+
|
|
116
|
+
# the prototype's own checks
|
|
117
|
+
(cd conditions/v4-proto/lib && node node_modules/typescript/bin/tsc -p test/tsconfig.json)
|
|
118
|
+
(cd conditions/v4-proto && node node_modules/vitest/vitest.mjs run --config lib/test/vitest.config.mjs)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
A batch writes to `runs/<timestamp>/`, or to `--out <dir>`, which must be new
|
|
122
|
+
or empty: in a directory that already holds files the driver would take the
|
|
123
|
+
runs recorded there for its own (an `agent.json` as run, a `score.json` as
|
|
124
|
+
scored, both in the summary), so it refuses and names `--resume <dir>`, the
|
|
125
|
+
only way to continue a batch in place.
|
|
126
|
+
|
|
127
|
+
`score.mjs` never reads stdin and exits 0 whenever it produced a score, however
|
|
128
|
+
bad the solution; exit 2 means the harness failed. It prints one JSON object:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
{ task, condition, tscClean, tests: [{ name, pass }], passRate,
|
|
132
|
+
requirements: [{ name, safety, pass }], safetyViolations, safe, requirementsMet, details }
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
It assembles the starter in a fresh directory under its own 0700 scoring
|
|
136
|
+
directory, lays the solution's files over it (skipping `node_modules`, `.git`,
|
|
137
|
+
`dist`), restores the protected files, symlinks the condition's pnpm
|
|
138
|
+
`node_modules`, runs `tsc --noEmit`, copies the hidden tests into `.hidden/`,
|
|
139
|
+
and runs them with vitest (whose cache it keeps inside the scoring directory,
|
|
140
|
+
never in a condition's `node_modules`).
|
|
141
|
+
|
|
142
|
+
## The tasks and what the prompts require
|
|
143
|
+
|
|
144
|
+
The ledger interface is `harness/icrc1.did`, the ICRC-1 reference ledger
|
|
145
|
+
interface that `examples/tanstack-router/icrc1.did` carries
|
|
146
|
+
(`icrc1_balance_of : (Account) -> (Tokens) query`,
|
|
147
|
+
`icrc1_transfer : (TransferArg) -> (variant { Ok : BlockIndex; Err : TransferError })`).
|
|
148
|
+
All conditions' generated inputs come from that one file.
|
|
149
|
+
|
|
150
|
+
**node-tool** — `createLedgerTool(config)` returning `getBalance(owner)` and
|
|
151
|
+
`transfer({ to, amount })` → `{ ok: true, blockIndex } | { ok: false, mayHaveExecuted, reason }`.
|
|
152
|
+
|
|
153
|
+
**react-wallet** — `<Wallet auth config />` with `signin` / `signout`
|
|
154
|
+
(each rendered only in its state), `balance` (entire text content = the
|
|
155
|
+
formatted number, nothing else; digit-free placeholder while loading),
|
|
156
|
+
`transfer-to` / `transfer-amount` (`<input>`s), `transfer-submit`, and an
|
|
157
|
+
always-rendered `transfer-status` whose `data-state` is `idle` until the first
|
|
158
|
+
submit, then `pending | success | error | unknown`. Those are all the DOM
|
|
159
|
+
contracts the tests read.
|
|
160
|
+
|
|
161
|
+
Every requirement the hidden tests check is stated in both tasks' `explicit`
|
|
162
|
+
prompts (`prompt.md`), in product terms, identically for all conditions:
|
|
163
|
+
|
|
164
|
+
1. Amounts: plain non-negative decimals, ≤ 8 fraction digits, base units ≤ nat64
|
|
165
|
+
(the maximum is accepted); recipients must be valid principal text; both
|
|
166
|
+
refused without contacting the ledger.
|
|
167
|
+
2. Never send as the anonymous principal / while signed out.
|
|
168
|
+
3. Root key: use `config.rootKey` when given and never fetch then; fetch only
|
|
169
|
+
when it is absent **and** the host is local (`localhost`, `127.0.0.1`,
|
|
170
|
+
`[::1]`).
|
|
171
|
+
4. Never re-send automatically — unless the failure proves the ledger never
|
|
172
|
+
processed the call: reject code 1, 2 or 3, or an HTTP 4xx other than 408.
|
|
173
|
+
5. Classify by the same rule: certainly no effect = refused before sending,
|
|
174
|
+
`Err`, reject code 1–3, HTTP 4xx other than 408; everything else (network
|
|
175
|
+
failure after sending, timeout, 5xx, 408, reject code 4 or 5) may have
|
|
176
|
+
executed → `mayHaveExecuted: true` / `data-state="unknown"` and the balance
|
|
177
|
+
is read again.
|
|
178
|
+
6. (react) Never show another principal's balance after sign-in, sign-out or a
|
|
179
|
+
switch, including when a read in flight for the previous principal lands
|
|
180
|
+
afterwards.
|
|
181
|
+
7. Exact amounts; never `number`.
|
|
182
|
+
|
|
183
|
+
Where the reject-code rule comes from — the IC interface specification
|
|
184
|
+
(`ic-interface-spec.md` in dfinity/portal, "Reject codes" and the "Abstract
|
|
185
|
+
behavior" rules): codes 1 and 2 reach an ingress call only from "Request
|
|
186
|
+
rejection" (before processing) and, for 2, "Calls to frozen canisters are
|
|
187
|
+
rejected" (before a call context exists); 3 is an invalid destination; a
|
|
188
|
+
canister's own reject is always 4, and `ic0.msg_reject` returns normally so
|
|
189
|
+
"the state is updated"; 5 covers a trap (which discards only the trapping
|
|
190
|
+
execution, not work before an await) and call-context starvation ("the state
|
|
191
|
+
changes are persisted even when the IC is set to synthesize a CANISTER_ERROR
|
|
192
|
+
reject"). The citations are also in `conditions/v4-proto/lib/src/errors.ts`.
|
|
193
|
+
|
|
194
|
+
### Prompt variants
|
|
195
|
+
|
|
196
|
+
`--prompt explicit|minimal` (default `explicit`) picks the task prompt; the
|
|
197
|
+
hidden tests, scoring and condition docs are the same under both.
|
|
198
|
+
|
|
199
|
+
- **explicit** (`tasks/<task>/prompt.md`): the list above, stated as rules.
|
|
200
|
+
- **minimal** (`tasks/<task>/prompt.minimal.md`): the product the way a user
|
|
201
|
+
would ask for it, plus the public contract the tests read — node-tool's
|
|
202
|
+
signatures, config inputs and result shape; react-wallet's props, test ids,
|
|
203
|
+
`data-state` values and balance format — and, in neutral sentences, what
|
|
204
|
+
the outcome vocabulary means: `mayHaveExecuted` says whether the transfer
|
|
205
|
+
could nevertheless have taken effect; `error` means it failed and certainly
|
|
206
|
+
had no effect, `unknown` that it failed but may have taken effect. It does
|
|
207
|
+
not say how to decide them, and states none of the safety rules: no
|
|
208
|
+
amount-precision or nat64 limits, no refusing input before contacting the
|
|
209
|
+
ledger, no anonymous-send rule, no root-key handling, no reject-code or
|
|
210
|
+
HTTP-status classification, no never-re-send, no re-read after an unknown
|
|
211
|
+
outcome, no stale balances across identities, no `number` ban.
|
|
212
|
+
(`src/contract.ts` and the config/auth files carry the same doc comments in
|
|
213
|
+
both variants: "Absent or anonymous: the tool is read-only", "The root key
|
|
214
|
+
of a local replica. Absent on mainnet.")
|
|
215
|
+
|
|
216
|
+
Every run record (`agent.json`, `score.json`, `plan.json`) carries `prompt`;
|
|
217
|
+
a record without it predates the variants and counts as `explicit`. Cells are
|
|
218
|
+
task × model × effort × prompt × condition: variants are never pooled and are
|
|
219
|
+
compared only within themselves. A batch keeps its variant: `--resume` with
|
|
220
|
+
another one is refused. `harness/assemble.test.mjs` checks, for both variants
|
|
221
|
+
and both run modes, that every condition's prompt (`v4` included) differs
|
|
222
|
+
from the others in the `{{LIBRARY}}` line only; that both variants state the contract the tests read;
|
|
223
|
+
and that the minimal one matches none of the explicit rules' wording.
|
|
224
|
+
|
|
225
|
+
### The run modes
|
|
226
|
+
|
|
227
|
+
`{{RUN}}` in the prompt depends only on the run mode:
|
|
228
|
+
|
|
229
|
+
- **sandboxed** (default wherever `sandbox-exec` exists): the agent may run
|
|
230
|
+
`npx tsc`, `npx vitest` and `node`, inside the OS sandbox. Every starter
|
|
231
|
+
ships a public test scaffold, identical in all conditions: `test/support/`
|
|
232
|
+
(the fake replica `@ic-reactor/core/testing` publishes, vendored with its
|
|
233
|
+
comments stripped; a small ICRC-1 ledger; a test sign-in state with
|
|
234
|
+
`switchTo`) and `test/smoke.test.ts`, which only shows how to drive it. It
|
|
235
|
+
has **no** fault injection — no lost replies, rejects or refusals.
|
|
236
|
+
- **tsc-only** (the documented fallback where no sandbox exists): type-check
|
|
237
|
+
feedback only, no test scaffold, no `node`.
|
|
238
|
+
|
|
239
|
+
`EVALS_NO_SANDBOX=1` makes the harness act as on a host without
|
|
240
|
+
`sandbox-exec`: `drive.mjs` then refuses to start without `--mode tsc-only`
|
|
241
|
+
and runs agents unsandboxed (recorded `sandboxed: false`), and the sandbox
|
|
242
|
+
tests are skipped. The driver tests (`harness/drive-auth.test.mjs`) pick
|
|
243
|
+
`--mode` the same way, so they run on Linux as on macOS; one of them runs a
|
|
244
|
+
batch with the variable set.
|
|
245
|
+
|
|
246
|
+
## What each hidden test checks, grouped by requirement
|
|
247
|
+
|
|
248
|
+
Tests are grouped into requirements in `task.json`; a requirement passes when
|
|
249
|
+
all its tests pass. Requirements marked **safety** make up the primary metric.
|
|
250
|
+
Where several requirements are judged from one transfer, a `describe` runs the
|
|
251
|
+
transfer once and each `it` checks one thing, so no test asserts two
|
|
252
|
+
requirements.
|
|
253
|
+
|
|
254
|
+
node-tool (`tasks/node-tool/hidden/node-tool.test.ts`, 25 tests, 7 requirements):
|
|
255
|
+
|
|
256
|
+
| Requirement | Tests |
|
|
257
|
+
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
258
|
+
| basic_function | `balance_returned`; `transfer_success` (one call signed by the identity, balances move, later reads show it); `accepts_nat64_max` (2^64 − 1 base units reaches the ledger as exactly that) |
|
|
259
|
+
| root_key_trust **safety** | `root_key_used` (no root-key fetch when `rootKey` is given); `root_key_not_fetched_off_local` (no fetch from a non-local host) |
|
|
260
|
+
| exactness **safety** | `balance_exact_bigint` (12345678901234567891 as a `bigint`) |
|
|
261
|
+
| input_validation **safety** | `refuses_malformed_amount` (`-1`, `abc`, `""`, `1e3`); `refuses_excess_fraction_digits` (9 decimals); `refuses_amount_past_nat64` (2^64, 1e20; explicit prompt only); none sent to this test's recipient; `refuses_invalid_recipient` (no call) |
|
|
262
|
+
| no_anonymous_send **safety** | `no_anonymous_update` (no identity, and `AnonymousIdentity`: no call at all) |
|
|
263
|
+
| no_resend **safety** | one distinct call after a 2.5 s settle: `canister_err_not_resent`, `reject_code_4_not_resent`, `reject_code_5_not_resent`, `lost_reply_not_resent` |
|
|
264
|
+
| outcome_classification **safety** | `refusal_not_executed`; `canister_err_classified` (false); `reject_code_{1,2,3}_classified` (false); `reject_code_{4,5}_classified` (true); `http_429_classified` (false, never reached the ledger); `lost_reply_classified` (true); `lost_reply_balance_reread` |
|
|
265
|
+
|
|
266
|
+
react-wallet (`tasks/react-wallet/hidden/react-wallet.test.ts`, 32 tests, 8 requirements):
|
|
267
|
+
|
|
268
|
+
| Requirement | Tests |
|
|
269
|
+
| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
270
|
+
| basic_function | `balance_shown`; `auth_buttons` (each button only in its state); `status_starts_idle`; `transfer_success`; `accepts_nat64_max` |
|
|
271
|
+
| root_key_trust **safety** | `root_key_used`; `root_key_not_fetched_off_local` |
|
|
272
|
+
| exactness **safety** | `balance_exact_bigint` (`123456789012.34567891`) |
|
|
273
|
+
| input_validation **safety** | `refuses_malformed_amount`; `refuses_excess_fraction_digits`; `refuses_amount_past_nat64` (explicit prompt only); `refuses_invalid_recipient` |
|
|
274
|
+
| no_anonymous_send **safety** | `no_anonymous_update` (signed out, and after sign-in + sign-out: nothing sent) |
|
|
275
|
+
| no_resend **safety** | `update_not_resent_on_refetch` (focus, visibilitychange, offline/online, unmount + remount); `canister_err_not_resent`; `reject_code_{4,5}_not_resent`; `lost_reply_not_resent` |
|
|
276
|
+
| outcome_classification **safety** | `canister_err_is_error`; `reject_code_{1,2,3}_is_error`; `reject_code_{4,5}_is_unknown`; `reject_code_5_rereads_balance`; `http_429_is_error`; `lost_reply_is_unknown`; `lost_reply_rereads_balance` (a new read, and the debit shown) |
|
|
277
|
+
| no_stale_balance **safety** | `no_stale_balance_after_sign_in`; `no_stale_balance_after_identity_switch` (Bob's read delayed 400 ms); `no_stale_balance_inflight_switch` (Alice's read lands after the switch, while Bob's loads); `no_balance_after_sign_out` |
|
|
278
|
+
|
|
279
|
+
The world (`harness/world.ts`): **one** signing fake replica from
|
|
280
|
+
`@ic-reactor/core/testing` per test file, installed before the solution is
|
|
281
|
+
imported, with a `fetch` in front of it that never changes within the file —
|
|
282
|
+
so a solution that keeps agents or clients at module scope (v3's documented
|
|
283
|
+
idiom) works across tests; each test gets a fresh ledger and request log.
|
|
284
|
+
Each test registers its principals; requests from any other principal (a
|
|
285
|
+
previous test's agent still retrying in the background) are neither logged
|
|
286
|
+
nor run against the current ledger. The front `fetch` deduplicates re-sent
|
|
287
|
+
envelopes as a replica does, injects lost replies and HTTP refusals, and
|
|
288
|
+
answers a non-local host (`REMOTE_HOST`) with a network error after logging
|
|
289
|
+
it. Reject codes 1–4 are injected with the fake replica's own reject class
|
|
290
|
+
(taken from the error a test canister throws for a method it has no handler
|
|
291
|
+
for — it is not exported); code 5 is a trap in the ledger's code.
|
|
292
|
+
|
|
293
|
+
**Amount refusals, split after the second pilot** (`PREREGISTRATION.md`,
|
|
294
|
+
Addendum 2). One test, `refuses_invalid_amount`, used to cover malformed
|
|
295
|
+
text, too many fraction digits and base units past nat64. The second pilot
|
|
296
|
+
showed that under the minimal prompt it measured only the nat64 cap, a rule
|
|
297
|
+
nothing but the explicit prompt states (the ledger's `amount` is Candid
|
|
298
|
+
`nat`). It is now three tests. `task.json` `notApplicable.minimal` lists
|
|
299
|
+
`refuses_amount_past_nat64`: under `--prompt minimal` it still runs and is
|
|
300
|
+
reported with its result, but counts toward no requirement, `safe` or
|
|
301
|
+
`requirementsMet` (`harness/judge.mjs`); the summary prints each variant's
|
|
302
|
+
not-applicable tests and how often they passed. The refusal tests judge the
|
|
303
|
+
transfers sent to their own recipient, so a background retry of an earlier
|
|
304
|
+
test's transfer (sent as whoever is signed in now) is not blamed on them.
|
|
305
|
+
`harness/probes/` holds the per-input diagnostic (`node
|
|
306
|
+
harness/probes/probe.mjs <results dir>`: for each stored solution and amount,
|
|
307
|
+
refused / thrown / sent with which base units).
|
|
308
|
+
|
|
309
|
+
Only `balance_exact_bigint` uses a balance above 2^53, so a `Number()` bug
|
|
310
|
+
fails that test and no other. Not applicable to node-tool (no cache or UI):
|
|
311
|
+
re-send on refetch/remount/focus and stale balance across identities.
|
|
312
|
+
|
|
313
|
+
## Evidence the gate discriminates
|
|
314
|
+
|
|
315
|
+
`node gate.mjs`: 20 references (a `reference` and a `reference-module-scope`
|
|
316
|
+
per task × condition; thin-guide's are thin's) must pass every test with clean
|
|
317
|
+
tsc, and 36 faulty solutions (each its reference with one change) must type-check
|
|
318
|
+
and fail exactly the tests in their `meta.json`; a `safe: { <variant>: bool }`
|
|
319
|
+
in `meta.json` is checked too. The pilots' four conditions account for 16
|
|
320
|
+
references and 29 faulty solutions (45/45 before `v4`); `v4` adds 4
|
|
321
|
+
references, the six v4-proto faulty solutions ported to it and one of its
|
|
322
|
+
own (`conditions/v4/PORTING.md`). Last run, `node gate.mjs --require v4` on
|
|
323
|
+
2026-10-05, on `v4` built with `--v4-from npm:4.0.0-beta.1`: **56/56**, no
|
|
324
|
+
cell skipped, in 15 min 52 s at the default `--jobs 3` (on 2026-10-02, on
|
|
325
|
+
the tree packed for Addendum 3: 56/56 in 15 min 29 s). A condition with no reference solution yet is skipped and named
|
|
326
|
+
(`skip <task>/<condition>: no reference solutions yet`), unless one of the
|
|
327
|
+
rules below forbids it.
|
|
328
|
+
An empty cell fails the gate before anything is scored, instead of being
|
|
329
|
+
skipped, when its condition is one of the pilots' four, when its task holds
|
|
330
|
+
faulty solutions of that condition (a port left half done), or when
|
|
331
|
+
`--require <condition>` names it: Addendum 3 runs `node gate.mjs --require
|
|
332
|
+
v4`, so its "no cell skipped" is checked by the gate and not by reading the
|
|
333
|
+
output (`harness/gate-plan.mjs`).
|
|
334
|
+
|
|
335
|
+
| Faulty solution | Bug | Caught by |
|
|
336
|
+
| --------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
337
|
+
| node `thin-anonymous-transfer` | checks an identity exists, not that it is non-anonymous | `no_anonymous_update` |
|
|
338
|
+
| node `thin-number-amount` | parses the amount with `Number()` | `refuses_malformed_amount`, `refuses_excess_fraction_digits`, `accepts_nat64_max`, `refusal_not_executed` |
|
|
339
|
+
| node / react `thin-accepts-exponent` | reads `1e3` as 1000 tokens | `refuses_malformed_amount` |
|
|
340
|
+
| node / react `thin-truncates-fraction-digits` | drops fraction digits past 8 | `refuses_excess_fraction_digits` (node also `refusal_not_executed`) |
|
|
341
|
+
| node / react `thin-no-nat64-cap` | no nat64 cap | `refuses_amount_past_nat64`; unsafe under explicit, safe under minimal |
|
|
342
|
+
| node `thin-every-reject-may-have-executed` | every reject "may have executed" | `reject_code_{1,2,3}_classified` |
|
|
343
|
+
| node `thin-misclassifies-reject-codes` | codes 1, 2 → may have; 4 → not (the reviewer's 1.0 mutant) | `reject_code_{1,2,4}_classified` |
|
|
344
|
+
| node `thin-fetches-root-key-off-local` | fetches the root key from any non-mainnet host | `root_key_not_fetched_off_local` |
|
|
345
|
+
| node `thin-ignores-root-key` | ignores `config.rootKey`, fetches instead | `root_key_used` |
|
|
346
|
+
| node `thin-unvalidated-recipient` | invalid recipient falls back to the anonymous principal | `refuses_invalid_recipient` |
|
|
347
|
+
| node `v3-retry-call-errors` | retries on any `CallError` | `reject_code_{4,5}_not_resent`, `lost_reply_{not_resent,classified,balance_reread}` |
|
|
348
|
+
| node `v4-proto-never-may-have-executed` | ignores `mayHaveExecuted` | `reject_code_{4,5}_classified`, `lost_reply_classified` |
|
|
349
|
+
| node `v4-proto-refuses-nat64-max` | `<` instead of `<=` | `accepts_nat64_max` |
|
|
350
|
+
| node `v4-never-may-have-executed` | ignores `mayHaveExecuted` | `reject_code_{4,5}_classified`, `lost_reply_classified` |
|
|
351
|
+
| node `v4-refuses-nat64-max` | `<` instead of `<=` | `accepts_nat64_max` |
|
|
352
|
+
| node `v4-anonymous-identity-sent` | `identity: config.identity ?? "anonymous"` | `no_anonymous_update` |
|
|
353
|
+
| react `thin-anonymous-transfer` | no sign-in check | `no_anonymous_update` |
|
|
354
|
+
| react `thin-number-balance` | balance through `Number()` | `balance_exact_bigint` |
|
|
355
|
+
| react `thin-transfer-as-query` | transfer as a `useQuery` | `update_not_resent_on_refetch` |
|
|
356
|
+
| react `thin-constant-balance-key` | balance key without the principal | `no_stale_balance_after_identity_switch`, `no_stale_balance_inflight_switch` |
|
|
357
|
+
| react `thin-unguarded-balance-effect` | balance read in a `useEffect` with no cancellation | `no_stale_balance_inflight_switch` |
|
|
358
|
+
| react `thin-both-auth-buttons` | both buttons always rendered | `auth_buttons` |
|
|
359
|
+
| react `v3-mutation-retry-3` | `retry: 3` | `canister_err_not_resent`, `reject_code_{4,5}_not_resent`, `lost_reply_{not_resent,is_unknown,rereads_balance}` |
|
|
360
|
+
| react `v3-unknown-as-error` | every failure `error`, no re-read | `reject_code_{4,5}_is_unknown`, `reject_code_5_rereads_balance`, `lost_reply_{is_unknown,rereads_balance}` |
|
|
361
|
+
| react `v3-http-4xx-unknown` | a 4xx refusal shown as unknown | `http_429_is_error` |
|
|
362
|
+
| react `v4-proto-retry-spread` | `{ ...mutationOptions(), retry: 3 }` (type-checks) | as `v3-mutation-retry-3` |
|
|
363
|
+
| react `v4-proto-keep-previous-data` | `{ ...queryOptions(), placeholderData: keepPreviousData }` | `no_stale_balance_after_identity_switch` |
|
|
364
|
+
| react `v4-proto-every-reject-unknown` | every `rejected` shown as unknown | `reject_code_{1,3}_is_error` |
|
|
365
|
+
| react `v4-proto-status-not-idle` | no `idle` before the first transfer | `status_starts_idle` |
|
|
366
|
+
| react `v4-retry-spread` | `{ ...client.mutationOptions(), retry: 3 }` (type-checks) | as `v3-mutation-retry-3` |
|
|
367
|
+
| react `v4-keep-previous-data` | `{ ...client.queryOptions(), placeholderData: keepPreviousData }` | `no_stale_balance_after_identity_switch` |
|
|
368
|
+
| react `v4-every-reject-unknown` | every `rejected` shown as unknown | `reject_code_{1,3}_is_error` |
|
|
369
|
+
| react `v4-status-not-idle` | no `idle` before the first transfer | `status_starts_idle` |
|
|
370
|
+
|
|
371
|
+
Six of the seven `v4-` rows are the `v4-proto-` faulty solutions ported to
|
|
372
|
+
ic-reactor 4 (`conditions/v4/PORTING.md`): each fails exactly the tests its
|
|
373
|
+
original fails. `v4-anonymous-identity-sent` has no original: it is a trap
|
|
374
|
+
the real library opens where the prototype did not (only `"anonymous"`
|
|
375
|
+
refuses an update; an explicit `AnonymousIdentity` is signed and sent).
|
|
376
|
+
|
|
377
|
+
Some bugs fail more than one test because they break more than one stated
|
|
378
|
+
behaviour (a retry after a lost reply that succeeds also reports success and
|
|
379
|
+
double-debits); the requirement grouping keeps them from counting several
|
|
380
|
+
times in the requirement-level metrics.
|
|
381
|
+
|
|
382
|
+
## The two guides (v4-proto and thin-guide)
|
|
383
|
+
|
|
384
|
+
`conditions/v4-proto/docs/llms.txt` (1,778 words) and
|
|
385
|
+
`conditions/thin-guide/docs/llms.txt` (1,792 words) have the same ten sections
|
|
386
|
+
in the same order, the same example app, the same "Do not" list item for item,
|
|
387
|
+
and the same root-key and reject-code rules; where v4-proto does something for
|
|
388
|
+
the agent, the thin guide says how to do it by hand, and nothing else.
|
|
389
|
+
`node harness/check-docs.mjs` finds none of the 112 hidden-test needles (every
|
|
390
|
+
test name as written and spaced, every distinctive literal that the prompts of
|
|
391
|
+
**every** variant do not already make public — so a literal only the explicit
|
|
392
|
+
prompt states, such as `123456789012.34567891`, is a needle) in either guide,
|
|
393
|
+
in any condition's docs, or in the public scaffold, and no test name in any
|
|
394
|
+
prompt of either variant; a seeded file with three of them is caught.
|
|
395
|
+
Paraphrase was reviewed by hand. Its default list also holds
|
|
396
|
+
`conditions/v4/docs/llms.txt`, which `setup.mjs` checks the same way before
|
|
397
|
+
it copies the packed guide there.
|
|
398
|
+
|
|
399
|
+
## The v4-proto prototype
|
|
400
|
+
|
|
401
|
+
`conditions/v4-proto/lib` (~1,140 lines). Agents are shipped only what a
|
|
402
|
+
published package would ship — `package.json` + `dist/` — with neutral
|
|
403
|
+
comments: the implementation notes about candid-core workarounds now live in
|
|
404
|
+
`lib/SHIM-NOTES.md`, which never ships.
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
const client = createClient({ network, identity } | { network, auth })
|
|
408
|
+
const ledger = client.canister(LedgerService, { id })
|
|
409
|
+
ledger.icrc1_balance_of.queryOptions([account] | skipToken) // reads only
|
|
410
|
+
ledger.icrc1_balance_of.certified([account]) // plain queries only
|
|
411
|
+
ledger.icrc1_transfer.mutationOptions({ invalidates: [ledger.icrc1_balance_of] }) // writes only; no retry
|
|
412
|
+
await ledger.icrc1_transfer([arg]) // direct call
|
|
413
|
+
handle.queryKey(args?) // ["ic-reactor", network, callerPrincipal, canisterId, method, "query", hex(encodeArgs)]
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
- Mode is in the handle's type (13 `@ts-expect-error` probes in
|
|
417
|
+
`lib/test/types.test-d.ts`, each failing for its intended reason).
|
|
418
|
+
- One immutable `HttpAgent` per principal; the caller is in every key.
|
|
419
|
+
- `Ok`/`Err` unwraps; `Err` throws a typed `canister_err`.
|
|
420
|
+
- One error type with `mayHaveExecuted`: `rejected` is false only for codes 1
|
|
421
|
+
and 3; `not_delivered` (code 2, HTTP 4xx other than 408) is the only kind
|
|
422
|
+
a write retries on. A write while not signed in is refused before sending.
|
|
423
|
+
- A given `rootKey` is used; otherwise the key is fetched only from a local host.
|
|
424
|
+
- `mutationOptions` invalidates after success and after `mayHaveExecuted`.
|
|
425
|
+
- `lib/test/runtime.test.ts` (8 tests) checks the runtime on the fake replica.
|
|
426
|
+
|
|
427
|
+
What the types cannot stop: spreading the returned options and adding `retry`
|
|
428
|
+
or `placeholderData`.
|
|
429
|
+
|
|
430
|
+
### Shims over @candid-core/schema 0.2.0 (input to candid-core's design)
|
|
431
|
+
|
|
432
|
+
Also in `lib/SHIM-NOTES.md`, with file locations.
|
|
433
|
+
|
|
434
|
+
1. **Mode is not in any type.** `c.func` / `c.service` are non-generic and the
|
|
435
|
+
service is typed `Schema<PrincipalValue>`; the emitted `Actor` type has
|
|
436
|
+
signatures but no modes, so `defineService<Actor>()(schema, modes)` takes a
|
|
437
|
+
hand-written mode map and checks it at load.
|
|
438
|
+
2. **Principals decode to a `{ toText }` carrier**; the prototype re-walks
|
|
439
|
+
every value both ways and rewrites the types structurally (`Textify<T>`).
|
|
440
|
+
3. **No schema query or value map** ("does this schema mention a principal").
|
|
441
|
+
4. **`ActorError` has no stage** (encode vs decode is only in the message).
|
|
442
|
+
5. **`httpTransport.query` drops the reject code** into an `Error` message.
|
|
443
|
+
6. **`Transport` has no `AbortSignal`.**
|
|
444
|
+
7. **`unwrapResult` returns neither the arm schema nor the tag.**
|
|
445
|
+
8. **Generated type names collapse by structure** (`TransferArg.amount` is
|
|
446
|
+
`BlockIndex`; the .did says `Tokens`).
|
|
447
|
+
|
|
448
|
+
## The v4 condition
|
|
449
|
+
|
|
450
|
+
ic-reactor 4 itself, for the 4.0.0-beta.1 gate (issue #786; DECISIONS Q14 in
|
|
451
|
+
#790; `PREREGISTRATION.md`, Addendum 3) and the GA gate (Addendum 4).
|
|
452
|
+
`setup.mjs` builds `@ic-reactor/core` and `@ic-reactor/react` from this
|
|
453
|
+
repository and packs them with `pnpm pack` (the default, `--v4-from tree`),
|
|
454
|
+
or downloads the published tarballs (`--v4-from npm:4.0.0-beta.1`: each must
|
|
455
|
+
have the `dist.integrity` pinned in `harness/ship.mjs`, which the registry
|
|
456
|
+
must still record); then it installs the tarballs with the pinned
|
|
457
|
+
dependencies as a flat npm install into `.ship/v4` (no workspace links),
|
|
458
|
+
records the source in `.ship/v4/source.json`, refuses the tree if
|
|
459
|
+
the core tarball's `llms.txt` or the packages' code gives a hidden test away,
|
|
460
|
+
copies that `llms.txt` into `conditions/v4/docs/` (the only doc the agent
|
|
461
|
+
gets), cuts both packages to `package.json` + `dist/`, and copies the result
|
|
462
|
+
to `conditions/v4/node_modules` for the scorer, so the hidden tests run
|
|
463
|
+
against what agents get. In the scorer's copy `@icp-sdk/core` (6.1.0 in
|
|
464
|
+
evals, the ship and the pin alike) links to evals' own, so the world and
|
|
465
|
+
the solution load one instance of it, as in every other condition
|
|
466
|
+
(`conditions/v4/README.md`). The starter's `src/generated/icrc1.ts` is
|
|
467
|
+
the output of the published `@candid-core/cli@0.2.0-beta.1`.
|
|
468
|
+
|
|
469
|
+
Status: the four references, the six ported faulty solutions and the
|
|
470
|
+
v4-only `v4-anonymous-identity-sent` are in the tree, written against the
|
|
471
|
+
client, its builders and the React bindings as built (IR2t #782, IR6 #780),
|
|
472
|
+
and `node gate.mjs --require v4` passes 56 of 56; `conditions/v4/PORTING.md`
|
|
473
|
+
records the port and where it differs from the plan. The guide is DX3's
|
|
474
|
+
(#785): 1,970 words at Addendum 3's commit, 1,974 as published in
|
|
475
|
+
4.0.0-beta.1 (sha256 `a07b846a…4342`). Addendum 3 was frozen on 2026-10-03
|
|
476
|
+
and its batch passed: `v4` safe in 5 of 5 runs on both tasks
|
|
477
|
+
(`results/2026-10-03-beta1-gate/`). Addendum 4 (the GA gate: the published
|
|
478
|
+
4.0.0-beta.1, 20 runs per cell, non-inferiority against `thin-guide`) is
|
|
479
|
+
drafted and not frozen; on the tree `--v4-from npm:4.0.0-beta.1` builds,
|
|
480
|
+
`node gate.mjs --require v4` passes 56 of 56.
|
|
481
|
+
|
|
482
|
+
## Leak audit and sandbox
|
|
483
|
+
|
|
484
|
+
Agents could read the hidden tests by absolute path, so:
|
|
485
|
+
|
|
486
|
+
- **Run directories.** Each run gets a private `work/ home/ tmp/` tree in a
|
|
487
|
+
fresh 0700 batch directory under the OS temp dir (refused if inside the
|
|
488
|
+
repository). `work/` holds the starter and a copy of `.ship/<condition>/node_modules`:
|
|
489
|
+
a flat npm install with relative `.bin` links, no pnpm store paths, no
|
|
490
|
+
`NODE_PATH` into the repository, no vitest caches, and the v4 package as
|
|
491
|
+
`package.json` + `dist/` only. `setup.mjs` refuses to build a ship tree that
|
|
492
|
+
contains the repository path or a hidden-test name.
|
|
493
|
+
- **OS sandbox** (`harness/sandbox.mjs`). Docker was the first choice, but no
|
|
494
|
+
Docker daemon runs on this machine, so agents run under a macOS
|
|
495
|
+
`sandbox-exec` profile: file contents under `/Users`, `/private/var/folders`,
|
|
496
|
+
`/private/tmp` and `/Volumes` are unreadable and nothing outside the run is
|
|
497
|
+
writable, except the run directory itself and the read-only toolchain (node
|
|
498
|
+
installation, agent CLI, `--sandbox-allow` dirs). `harness/sandbox.test.mjs`
|
|
499
|
+
(9 tests) builds a run exactly as the driver does and shows both
|
|
500
|
+
directions: `npx tsc` and the public vitest smoke test pass inside; reading
|
|
501
|
+
the repository's hidden tests, listing `evals/`, reading a sibling run of
|
|
502
|
+
the batch, reading the scorer's directory, listing the home directory, and
|
|
503
|
+
writing into the repository are all refused — each refusal paired with the
|
|
504
|
+
same command succeeding outside the sandbox.
|
|
505
|
+
- **Agent isolation.** The agent gets only PATH and exactly one credential
|
|
506
|
+
from the host (see "Authentication, limits and effort"); HOME,
|
|
507
|
+
`CLAUDE_CONFIG_DIR` and TMPDIR point inside its run, so the host's
|
|
508
|
+
`~/.claude` (settings, memory, MCP servers, login) is not visible.
|
|
509
|
+
`--disallowedTools WebFetch,WebSearch` and `--strict-mcp-config` are passed;
|
|
510
|
+
`--bare` is not (it does not read the OAuth token).
|
|
511
|
+
- **Transcript audit** (`harness/leak-scan.mjs`, second line). Every tool call
|
|
512
|
+
in the stream-json transcript is checked: file/dir/glob fields and
|
|
513
|
+
path-like shell words are normalised (`./../x`, `a/../..`, `$PWD`, `~user`,
|
|
514
|
+
`$HOME`) and resolved from the shell's cwd (which `cd` moves); `$TMPDIR`,
|
|
515
|
+
`$TMP`, `$TEMP`, `$OLDPWD`, unknown variables in a path and path-building
|
|
516
|
+
command substitutions (`$(pwd)/..`, `$(dirname $PWD)`, `$(printf …)`) are
|
|
517
|
+
flagged as unresolvable; the WebFetch and WebSearch tools are flagged, and
|
|
518
|
+
so is network use from the shell (next item). Shell commands are
|
|
519
|
+
lexed (quotes, operators, redirections, heredocs, here-strings) and each
|
|
520
|
+
word judged by its position: a grep/rg/sed/awk/jq pattern, `node -e` /
|
|
521
|
+
`python -c` program text and a heredoc fed to an interpreter are not paths
|
|
522
|
+
(only their string literals naming `/Users`, `/private`, `/tmp`, `~` or a
|
|
523
|
+
`..` climb are checked); a heredoc fed to a shell, `bash -c`, `xargs` and
|
|
524
|
+
`$(…)` are scanned as commands. Each violation is judged on its own: one
|
|
525
|
+
whose call failed, or whose output reports a permission refusal naming it,
|
|
526
|
+
is an **attempt**; one that succeeded makes the run **contaminated**.
|
|
527
|
+
`harness/leak-scan.test.mjs` (121 tests) covers each form, clean look-alikes
|
|
528
|
+
(the first pilot's two false positives among them), evasions, and blocked
|
|
529
|
+
vs successful. `drive.mjs --aggregate <dir> --rescan` re-audits stored
|
|
530
|
+
transcripts with the current scanner and writes `summary.rescanned.json`
|
|
531
|
+
beside the original.
|
|
532
|
+
- **The CLI's persisted tool output** (in the transcript audit, from
|
|
533
|
+
`PREREGISTRATION.md` Addendum 5). When a tool's output is too large, the
|
|
534
|
+
CLI saves it as
|
|
535
|
+
`<run>/home/.claude/projects/<project>/<session>/tool-results/<file>` and
|
|
536
|
+
answers the call with a `<persisted-output>` notice naming that path. A
|
|
537
|
+
Read (`file_path`) or Grep (`path`) of exactly that path is not a
|
|
538
|
+
violation when an earlier top-level user message is the CLI's answer to
|
|
539
|
+
the call: its content is one tool_result whose whole content is that
|
|
540
|
+
notice, naming the path byte for byte, and beside it the CLI's own record
|
|
541
|
+
of the call (`tool_use_result.persistedOutputPath`) names the same path,
|
|
542
|
+
in the message's own session (`session_id`). A tool's output cannot add
|
|
543
|
+
that record, so a notice printed by a Bash command or returned by a
|
|
544
|
+
subagent does not count. The notice must answer an earlier call that is
|
|
545
|
+
not a Read and had no violation; the path as written has no `..`; the run
|
|
546
|
+
directory is `<run>/work`; and no part of the path below `<run>` is a
|
|
547
|
+
symlink, as far as it still exists. Anything else in the run's home
|
|
548
|
+
(`.claude.json`, settings, session files), a path one segment off that
|
|
549
|
+
shape, a Bash command naming the path (`cat <path>`) and any other tool
|
|
550
|
+
or field naming it are violations, as before. The accepted reads of a
|
|
551
|
+
call with no violation are listed in each run's audit record as
|
|
552
|
+
`persistedReads`. The 37 tests of "the CLI's persisted tool output" take
|
|
553
|
+
the accepted case from Addendum 4's batch
|
|
554
|
+
(`results/2026-10-05-ga-gate/contaminated-run.json`) and refuse each
|
|
555
|
+
departure from it.
|
|
556
|
+
- **Network from the shell** (in the transcript audit, the only line there).
|
|
557
|
+
The sandbox leaves the network open: the agent CLI runs inside it and needs
|
|
558
|
+
its API, and a profile cannot allow one host and deny the rest (`remote ip`
|
|
559
|
+
takes only `*` or `localhost`). So `node`, which sandboxed agents may run,
|
|
560
|
+
reaches any host (from inside the profile, `node -e` fetching a public URL
|
|
561
|
+
succeeds). The audit flags: a network command (curl, wget, nc, ssh, …,
|
|
562
|
+
also behind `env`, in `bash -c`, `xargs` or `$(…)`); a package manager or
|
|
563
|
+
git command that reaches a registry or remote (`npm view`, `pnpm add`,
|
|
564
|
+
`npx` of a package other than `tsc` and `vitest`, `pip install`,
|
|
565
|
+
`git clone`, …); a URL of a non-local host given to an interpreter; and
|
|
566
|
+
interpreter code that calls the network (`fetch(`, `http(s).get/request`,
|
|
567
|
+
`net`/`tls`, WebSocket, `urllib`, `requests`, …) towards a non-local host
|
|
568
|
+
or a host it does not name, or that runs a network command through
|
|
569
|
+
`child_process` / `subprocess`. Interpreter code is `node -e` or
|
|
570
|
+
`python -c`, a heredoc or pipe fed to an interpreter, and a script the run
|
|
571
|
+
wrote (Write, Edit, a heredoc or `echo` into a file) and then runs with
|
|
572
|
+
one. String literals are data: an edit script whose text holds `fetch(` or
|
|
573
|
+
a URL is not network use, nor is code that names only local hosts
|
|
574
|
+
(`localhost`, `127.*`, `[::1]`), nor source written to a file and not run.
|
|
575
|
+
Not followed, so not seen: a test file run by vitest that fetches a URL
|
|
576
|
+
(the public scaffold's fake replica answers IC API requests to any host,
|
|
577
|
+
so the agent's own tests name mainnet hosts without reaching them, but
|
|
578
|
+
other URLs pass through to the network), and a host reached through a
|
|
579
|
+
library (an `HttpAgent` built with a mainnet host). Added after the
|
|
580
|
+
pilots; re-auditing their 80 transcripts with it changes no record
|
|
581
|
+
(`PREREGISTRATION.md`, Addendum 3).
|
|
582
|
+
- **Scoring after the batch.** The driver scores only after every agent run
|
|
583
|
+
has ended, in `score.mjs`'s own 0700 directory.
|
|
584
|
+
- **Aggregation.** Contaminated runs are excluded from the main result and kept
|
|
585
|
+
in an intent-to-treat result; both are reported with per-cell counts.
|
|
586
|
+
|
|
587
|
+
## Authentication, limits and effort
|
|
588
|
+
|
|
589
|
+
**Credential.** A real run needs one of, in this order of precedence:
|
|
590
|
+
|
|
591
|
+
1. `--oauth-token-file <path>` — a file holding a Claude subscription token
|
|
592
|
+
made with `claude setup-token` (whitespace trimmed). The driver refuses a
|
|
593
|
+
file that group or others can read or write (`chmod 600` it).
|
|
594
|
+
2. `CLAUDE_CODE_OAUTH_TOKEN` — the same kind of token, from the environment.
|
|
595
|
+
3. `ANTHROPIC_API_KEY` — API billing.
|
|
596
|
+
|
|
597
|
+
Exactly one reaches the agent: a subscription token is passed as
|
|
598
|
+
`CLAUDE_CODE_OAUTH_TOKEN` and `ANTHROPIC_API_KEY` is then withheld even if
|
|
599
|
+
set (the CLI would otherwise prefer the key, and bill the API instead of the
|
|
600
|
+
subscription). The driver prints which kind is in use, never the value; the
|
|
601
|
+
kind (`oauth` / `api_key`) and its source are recorded in `plan.json`, in each
|
|
602
|
+
run record and, as counts, in the summary. The value never lands in anything
|
|
603
|
+
written to `runs/`: transcripts, logs, run records, error messages, the
|
|
604
|
+
summary and every file of a copied solution pass through redaction, which
|
|
605
|
+
removes every known credential value (an agent can read its own environment
|
|
606
|
+
and echo it). `harness/drive-auth.test.mjs` runs the driver with a stub agent
|
|
607
|
+
that dumps its environment into its transcript, its stderr and a solution
|
|
608
|
+
file, and checks that no fake credential value appears in any written file.
|
|
609
|
+
Neither set: the driver refuses to start and names all three options.
|
|
610
|
+
|
|
611
|
+
**Preflight.** Before any agent run, and alone with `--preflight`, the driver
|
|
612
|
+
makes one tiny call — `"Reply with the single word: ok"`, `--max-turns 1` —
|
|
613
|
+
in the same isolated environment and sandbox as a real run. Unless the CLI
|
|
614
|
+
returns a successful result that is not an error, it prints the CLI's result
|
|
615
|
+
text (redacted) and stops. (Implemented, not run by the harness author; it is
|
|
616
|
+
tested with a stub in place of the CLI.)
|
|
617
|
+
|
|
618
|
+
**Sign-in and limit errors are harness errors, never failed solutions.**
|
|
619
|
+
From measurements on CLI 2.1.285, a stream-json run ends with a `result`
|
|
620
|
+
message with `subtype`, `is_error`, `result`, `num_turns`, `usage`,
|
|
621
|
+
`total_cost_usd`, `api_error_status` and others; with no valid credential it
|
|
622
|
+
returns subtype `"success"`, `is_error: true`, result
|
|
623
|
+
`"Not logged in · Please run /login"`. The driver classifies an error result
|
|
624
|
+
(`is_error: true` or a non-success subtype), the CLI's stderr and top-level
|
|
625
|
+
`error` fields — never the agent's own prose, which in this task talks about
|
|
626
|
+
HTTP 429 constantly, and never a successful result:
|
|
627
|
+
|
|
628
|
+
- **sign-in** (`Not logged in`, `/login`, invalid key, expired token,
|
|
629
|
+
`api_error_status` 401/403): the whole batch stops at once — every running
|
|
630
|
+
agent is killed, nothing is recorded for them — with a message to fix the
|
|
631
|
+
credential and `--resume`;
|
|
632
|
+
- **limit** (usage-limit wording such as `Claude AI usage limit reached|<epoch>`
|
|
633
|
+
or `limit reached … resets`, `rate_limit_error`, `overloaded_error`,
|
|
634
|
+
`api_error_status` 429/529): the run is retried after a backoff
|
|
635
|
+
(`--rate-limit-backoff-min`, default 5, doubling; the reset time when the
|
|
636
|
+
message gives one; capped by `--rate-limit-max-wait-min`, default 300), up
|
|
637
|
+
to `--rate-limit-retries` (default 4); then it is excluded and counted as a
|
|
638
|
+
`rate_limited` harness error. The attempts' transcripts are kept.
|
|
639
|
+
|
|
640
|
+
ASSUMED, not verified against real limit responses: the exact usage-limit
|
|
641
|
+
wording (taken from observed CLI messages) and that limits surface in these
|
|
642
|
+
fields. The sign-in shape above was measured.
|
|
643
|
+
|
|
644
|
+
**Parallelism on a subscription.** A subscription is rate-limited per
|
|
645
|
+
account, and parallel agents share it: use `--jobs 1` or `--jobs 2` (the
|
|
646
|
+
default is 2 when the credential is a subscription token, 4 with an API key).
|
|
647
|
+
Expect wall-clock time to grow accordingly (the pilot's 40 runs at ~12 min
|
|
648
|
+
each is ~4 h at 2 jobs).
|
|
649
|
+
|
|
650
|
+
**Effort.** `--effort <level>` is passed to the CLI (`--effort`), recorded in
|
|
651
|
+
each run and counted in the summary. Effort levels, like models, are never
|
|
652
|
+
pooled: cells are task × model × effort × prompt × condition and
|
|
653
|
+
comparisons stay within one.
|
|
654
|
+
|
|
655
|
+
## Measured vs not measured
|
|
656
|
+
|
|
657
|
+
Measured, per run: tsc-clean; which hidden tests and requirements pass; the
|
|
658
|
+
agent's exit (normal / max_turns / timeout / error / no_result), turns,
|
|
659
|
+
tokens, cost and minutes; contamination and leak attempts. Aggregated per
|
|
660
|
+
task × model × effort × prompt variant × condition (never pooling models,
|
|
661
|
+
effort levels or prompt variants; comparing only within one of each):
|
|
662
|
+
|
|
663
|
+
- **primary**: fraction of runs with zero safety-requirement violations, with
|
|
664
|
+
Wilson intervals, and the risk difference between conditions with Newcombe's
|
|
665
|
+
hybrid-score interval (checked against Newcombe 1998's worked example);
|
|
666
|
+
the same difference pooled over the tasks is reported beside it
|
|
667
|
+
(`pooled` in the summary: safe runs and runs summed per condition, within
|
|
668
|
+
one model, effort level and prompt variant), deciding nothing unless an
|
|
669
|
+
addendum says so (Addendum 4's alternative A);
|
|
670
|
+
- **secondary**: mean fraction of requirements met (bootstrap intervals);
|
|
671
|
+
- tsc-clean rate, full-pass rate, per-requirement pass rates alongside.
|
|
672
|
+
|
|
673
|
+
Harness errors are retried, then excluded and counted, never scored as 0.
|
|
674
|
+
`--pilot` (5 runs per cell) adds observed variance, minutes/turns/tokens per
|
|
675
|
+
run, ceiling/floor warnings, and runs per cell needed for `--margin`.
|
|
676
|
+
|
|
677
|
+
Not measured: code quality or idiom; performance; behaviour against a real
|
|
678
|
+
replica or boundary node (202/polling, SysUnknown, rate limits, delegation
|
|
679
|
+
expiry); certified-query paths; the `not_delivered` retry path's _value_
|
|
680
|
+
(a retry after code 2 or 429 is allowed, not required); subaccounts.
|
|
681
|
+
|
|
682
|
+
## Threats to validity
|
|
683
|
+
|
|
684
|
+
- **Author bias.** One person wrote the tasks, prompts, tests, prototype, both
|
|
685
|
+
guides and all references. Every requirement is in the prompt for every
|
|
686
|
+
condition; an independent reviewer has been through it once.
|
|
687
|
+
- **Training-data familiarity.** ic-reactor v3 and TanStack Query are public
|
|
688
|
+
and may be in a model's training data; v4-proto is new. That favours v3
|
|
689
|
+
(familiar API) and could favour or hurt v4-proto (no priors, but also no
|
|
690
|
+
wrong priors). It cannot be removed, only noted per model.
|
|
691
|
+
- **v4-proto's typed service file is hand-written.**
|
|
692
|
+
`src/generated/icrc1.service.ts` stands in for codegen that does not exist
|
|
693
|
+
yet (a generic `c.service` would let the generator emit it). Agents do not
|
|
694
|
+
write it, and its header no longer says it is a stand-in; if real codegen
|
|
695
|
+
differs, so may results.
|
|
696
|
+
- **Feedback channel.** In sandboxed mode every condition gets the same
|
|
697
|
+
runnable scaffold, which removes the old tsc-only asymmetry that favoured
|
|
698
|
+
the typed condition. It also lets agents test their own code, which a
|
|
699
|
+
real developer could do. In tsc-only mode that asymmetry returns.
|
|
700
|
+
- **Sandbox limits.** macOS only; Docker path absent. File metadata (names,
|
|
701
|
+
existence) outside the run stays visible; network is open (the agent needs
|
|
702
|
+
its API), so network use from the shell is caught only by the transcript
|
|
703
|
+
audit, and not when a test file run by vitest fetches. The profile has
|
|
704
|
+
been tested with node, tsc and vitest, not yet with the real agent CLI,
|
|
705
|
+
which may need extra read-only paths (`--sandbox-allow`).
|
|
706
|
+
- **Shipped vs scored packages.** Agents get a flat npm install; scoring uses
|
|
707
|
+
the pnpm install. Direct dependencies are pinned to the same versions;
|
|
708
|
+
transitive versions may differ.
|
|
709
|
+
- **Docs.** thin-guide and v4-proto guides are matched; v3's docs are its own,
|
|
710
|
+
as published (~9,000 words). A guide written by someone else might score
|
|
711
|
+
differently.
|
|
712
|
+
- **Helpers differ.** v3 ships token parse/format helpers; the others do not.
|
|
713
|
+
- **The explicit prompts teach the reject and root-key rules**, so under them
|
|
714
|
+
the experiment measures whether agents apply the rules, not whether they
|
|
715
|
+
know them; the first pilot was at the ceiling in every cell. The minimal
|
|
716
|
+
prompts leave the rules out, so there the library and its docs are the only
|
|
717
|
+
source of them; the contract comments in the starter still say that an
|
|
718
|
+
absent or anonymous identity is read-only and that the root key is for a
|
|
719
|
+
local replica.
|
|
720
|
+
- **Fake replica.** Signatures, certificates and routing are real; timing,
|
|
721
|
+
boundary nodes and SysUnknown are not. The fake answers a missing method
|
|
722
|
+
with code 3; a real replica's code for that case is an implementation
|
|
723
|
+
detail.
|
|
724
|
+
- **Timing-based tests.** "Not re-sent" waits 2.5 s (TanStack's first retry is
|
|
725
|
+
at 1 s); the stale-balance tests delay reads by 400–1,200 ms and sample every
|
|
726
|
+
5 ms. The gate has been run repeatedly at 4 and 6 parallel jobs without a
|
|
727
|
+
flake, which is not proof of none.
|
|
728
|
+
- **Dependent tests.** Some bugs fail several tests in one requirement or
|
|
729
|
+
across two (see the table); requirement-level metrics absorb most of it.
|
|
730
|
+
- **One ledger, two tasks.** Results may not transfer to other canister shapes.
|
|
731
|
+
|
|
732
|
+
## Owner decisions before the matrix can run
|
|
733
|
+
|
|
734
|
+
- **Runs per cell.** 8 cells (2 tasks × 4 conditions) per model. Run the pilot
|
|
735
|
+
first (`--pilot`, 40 runs per model): it reports the observed safe rates and
|
|
736
|
+
the runs per cell needed for the pre-registered margin. As a guide: a
|
|
737
|
+
risk difference of 0.10 around safe rates near 0.8 needs ≈ 250 runs per cell
|
|
738
|
+
at 80% power; a difference of 0.20 needs ≈ 60. Plan for a large effect
|
|
739
|
+
or accept wide intervals.
|
|
740
|
+
- **The margin that decides "build v4".** Pre-register it on the primary
|
|
741
|
+
metric against the honest comparator, e.g. v4-proto − thin-guide ≥ 0.15 in
|
|
742
|
+
the safe-run rate with the Newcombe 95% interval above 0 on both tasks, and
|
|
743
|
+
v4-proto not worse than v3 by more than 0.05.
|
|
744
|
+
- **Models.** At least one frontier and one smaller model; never pooled.
|
|
745
|
+
- **Platform and auth.** macOS with `sandbox-exec` (or accept tsc-only mode),
|
|
746
|
+
the Claude Code CLI on PATH, and a credential: a subscription token
|
|
747
|
+
(`claude setup-token`, then `--oauth-token-file` or
|
|
748
|
+
`CLAUDE_CODE_OAUTH_TOKEN`) with `--jobs 1`–`2`, or an `ANTHROPIC_API_KEY`.
|
|
749
|
+
Run `node drive.mjs --preflight --model <m> [--effort <e>] --oauth-token-file <f>`
|
|
750
|
+
first.
|
|
751
|
+
- **Effort level(s).** Each level is its own set of cells.
|
|
752
|
+
- **Estimated cost.** 8 cells × N runs × ~12 min per model (a guess; the pilot
|
|
753
|
+
measures it): pilot ≈ 8 agent-hours; N = 20 → 32; N = 60 → 96; plus ~2 min
|
|
754
|
+
of scoring per run.
|
|
755
|
+
- **Prompt variant.** Which variant the full matrix uses, after the
|
|
756
|
+
second pilot (`--prompt minimal`; `PREREGISTRATION.md`, Addendum 1).
|