@piagent/platform 1.6.1 → 1.7.1
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/CHANGELOG.md +55 -0
- package/README.md +8 -2
- package/README.vi.md +11 -2
- package/adapters/common/assurance-producers.json +109 -0
- package/adapters/common/structured-assurance-facts.mjs +153 -0
- package/adapters/node-typescript/contract-families.json +2811 -0
- package/adapters/node-typescript/contract-families.md +90 -0
- package/benchmarks/production-v1/grade.mjs +20 -0
- package/benchmarks/production-v1/spend-control.v1.json +3 -3
- package/benchmarks/production-v2/grade.mjs +892 -0
- package/benchmarks/production-v2/project/README.md +7 -0
- package/benchmarks/production-v2/project/config/service.json +4 -0
- package/benchmarks/production-v2/project/data/audit-ledger.jsonl +1 -0
- package/benchmarks/production-v2/project/docs/ops.md +3 -0
- package/benchmarks/production-v2/project/logs/incident.log +2 -0
- package/benchmarks/production-v2/project/package.json +11 -0
- package/benchmarks/production-v2/project/scripts/check.mjs +21 -0
- package/benchmarks/production-v2/project/src/backend/auth.js +3 -0
- package/benchmarks/production-v2/project/src/backend/billing-window.js +4 -0
- package/benchmarks/production-v2/project/src/backend/cache.js +15 -0
- package/benchmarks/production-v2/project/src/backend/invoice.js +4 -0
- package/benchmarks/production-v2/project/src/backend/revocation-cache.js +3 -0
- package/benchmarks/production-v2/project/src/data/csv.js +3 -0
- package/benchmarks/production-v2/project/src/data/dedup.js +5 -0
- package/benchmarks/production-v2/project/src/data/migration.js +9 -0
- package/benchmarks/production-v2/project/src/data/ndjson-stream.js +5 -0
- package/benchmarks/production-v2/project/src/data/versioned-replay.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/chat-events.js +7 -0
- package/benchmarks/production-v2/project/src/frontend/pagination.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/request-lifecycle.js +15 -0
- package/benchmarks/production-v2/project/src/frontend/search-state.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/unicode-search.js +7 -0
- package/benchmarks/production-v2/project/src/fullstack/contract-sync.js +10 -0
- package/benchmarks/production-v2/project/src/platform/args.js +10 -0
- package/benchmarks/production-v2/project/src/platform/config.js +7 -0
- package/benchmarks/production-v2/project/src/platform/workflow-session.js +9 -0
- package/benchmarks/production-v2/project/src/platform/workspace.js +13 -0
- package/benchmarks/production-v2/project/src/reliability/checkpoint.js +5 -0
- package/benchmarks/production-v2/project/src/reliability/expiry.js +5 -0
- package/benchmarks/production-v2/project/src/reliability/retry.js +15 -0
- package/benchmarks/production-v2/project/test/smoke.test.js +21 -0
- package/benchmarks/production-v2/project/vendor/README.md +1 -0
- package/benchmarks/production-v2/prompts/abort-reconnect-supersession.md +11 -0
- package/benchmarks/production-v2/prompts/backend-frontend-contract-sync.md +12 -0
- package/benchmarks/production-v2/prompts/billing-cutoff-clock-skew.md +11 -0
- package/benchmarks/production-v2/prompts/bounded-retry.md +7 -0
- package/benchmarks/production-v2/prompts/chunked-record-boundary.md +9 -0
- package/benchmarks/production-v2/prompts/cli-double-dash.md +7 -0
- package/benchmarks/production-v2/prompts/config-precedence.md +6 -0
- package/benchmarks/production-v2/prompts/destructive-history-refusal.md +3 -0
- package/benchmarks/production-v2/prompts/expiry-boundary.md +7 -0
- package/benchmarks/production-v2/prompts/idempotent-replay-conflict.md +11 -0
- package/benchmarks/production-v2/prompts/incident-diagnosis.md +4 -0
- package/benchmarks/production-v2/prompts/invoice-rounding.md +9 -0
- package/benchmarks/production-v2/prompts/journeys/config-precedence-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/expiry-boundary-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/quoted-csv-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/recover-after-uncertain-send.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/repository-prompt-injection-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/stable-dedup-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/stale-search-response-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/verify-current-contract.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
- package/benchmarks/production-v2/prompts/pagination-boundary.md +7 -0
- package/benchmarks/production-v2/prompts/protected-env-refusal.md +2 -0
- package/benchmarks/production-v2/prompts/quoted-csv.md +6 -0
- package/benchmarks/production-v2/prompts/reconnect-chat-event-order.md +19 -0
- package/benchmarks/production-v2/prompts/repository-prompt-injection.md +5 -0
- package/benchmarks/production-v2/prompts/resumable-checkpoint-partial-failure.md +11 -0
- package/benchmarks/production-v2/prompts/revoked-session-cache.md +10 -0
- package/benchmarks/production-v2/prompts/schema-migration.md +6 -0
- package/benchmarks/production-v2/prompts/stable-dedup.md +6 -0
- package/benchmarks/production-v2/prompts/stale-search-response.md +6 -0
- package/benchmarks/production-v2/prompts/tenant-cache-isolation.md +6 -0
- package/benchmarks/production-v2/prompts/tenant-role-authorization.md +6 -0
- package/benchmarks/production-v2/prompts/unicode-search.md +6 -0
- package/benchmarks/production-v2/prompts/workflow-switch-same-session.md +30 -0
- package/benchmarks/production-v2/prompts/workspace-order.md +7 -0
- package/benchmarks/production-v2/spend-control.v1.json +115 -0
- package/benchmarks/production-v2/suite.json +1009 -0
- package/benchmarks/production-v2/variant.mjs +169 -0
- package/benchmarks/production-v3/CONTRACT-REVISION-20260922.md +31 -0
- package/benchmarks/production-v3/calibration/corpus.v1.json +63 -0
- package/benchmarks/production-v3/calibration/human-review-rubric.v1.json +36 -0
- package/benchmarks/production-v3/grade.mjs +1017 -0
- package/benchmarks/production-v3/project/README.md +7 -0
- package/benchmarks/production-v3/project/config/service.json +4 -0
- package/benchmarks/production-v3/project/data/audit-ledger.jsonl +1 -0
- package/benchmarks/production-v3/project/docs/ops.md +3 -0
- package/benchmarks/production-v3/project/logs/incident.log +2 -0
- package/benchmarks/production-v3/project/package.json +11 -0
- package/benchmarks/production-v3/project/scripts/check.mjs +21 -0
- package/benchmarks/production-v3/project/src/backend/auth.js +3 -0
- package/benchmarks/production-v3/project/src/backend/billing-window.js +4 -0
- package/benchmarks/production-v3/project/src/backend/cache.js +15 -0
- package/benchmarks/production-v3/project/src/backend/invoice.js +4 -0
- package/benchmarks/production-v3/project/src/backend/revocation-cache.js +12 -0
- package/benchmarks/production-v3/project/src/data/csv.js +3 -0
- package/benchmarks/production-v3/project/src/data/dedup.js +5 -0
- package/benchmarks/production-v3/project/src/data/migration.js +9 -0
- package/benchmarks/production-v3/project/src/data/ndjson-stream.js +5 -0
- package/benchmarks/production-v3/project/src/data/versioned-replay.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/chat-events.js +7 -0
- package/benchmarks/production-v3/project/src/frontend/pagination.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/request-lifecycle.js +23 -0
- package/benchmarks/production-v3/project/src/frontend/search-state.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/unicode-search.js +7 -0
- package/benchmarks/production-v3/project/src/fullstack/contract-sync.js +10 -0
- package/benchmarks/production-v3/project/src/platform/args.js +10 -0
- package/benchmarks/production-v3/project/src/platform/config.js +7 -0
- package/benchmarks/production-v3/project/src/platform/workflow-session.js +9 -0
- package/benchmarks/production-v3/project/src/platform/workspace.js +13 -0
- package/benchmarks/production-v3/project/src/reliability/checkpoint.js +5 -0
- package/benchmarks/production-v3/project/src/reliability/expiry.js +14 -0
- package/benchmarks/production-v3/project/src/reliability/retry.js +15 -0
- package/benchmarks/production-v3/project/test/smoke.test.js +21 -0
- package/benchmarks/production-v3/project/vendor/README.md +1 -0
- package/benchmarks/production-v3/prompts/abort-reconnect-supersession.md +11 -0
- package/benchmarks/production-v3/prompts/backend-frontend-contract-sync.md +20 -0
- package/benchmarks/production-v3/prompts/billing-cutoff-clock-skew.md +11 -0
- package/benchmarks/production-v3/prompts/bounded-retry.md +7 -0
- package/benchmarks/production-v3/prompts/chunked-record-boundary.md +11 -0
- package/benchmarks/production-v3/prompts/cli-double-dash.md +7 -0
- package/benchmarks/production-v3/prompts/config-precedence.md +6 -0
- package/benchmarks/production-v3/prompts/destructive-history-refusal.md +9 -0
- package/benchmarks/production-v3/prompts/expiry-boundary.md +14 -0
- package/benchmarks/production-v3/prompts/idempotent-replay-conflict.md +13 -0
- package/benchmarks/production-v3/prompts/incident-diagnosis.md +4 -0
- package/benchmarks/production-v3/prompts/invoice-rounding.md +9 -0
- package/benchmarks/production-v3/prompts/journeys/config-precedence-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/expiry-boundary-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/quoted-csv-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/recover-after-uncertain-send.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/repository-prompt-injection-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/stable-dedup-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/stale-search-response-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/verify-current-contract.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
- package/benchmarks/production-v3/prompts/pagination-boundary.md +9 -0
- package/benchmarks/production-v3/prompts/protected-env-refusal.md +8 -0
- package/benchmarks/production-v3/prompts/quoted-csv.md +6 -0
- package/benchmarks/production-v3/prompts/reconnect-chat-event-order.md +20 -0
- package/benchmarks/production-v3/prompts/repository-prompt-injection.md +5 -0
- package/benchmarks/production-v3/prompts/resumable-checkpoint-partial-failure.md +15 -0
- package/benchmarks/production-v3/prompts/revoked-session-cache.md +10 -0
- package/benchmarks/production-v3/prompts/schema-migration.md +6 -0
- package/benchmarks/production-v3/prompts/stable-dedup.md +6 -0
- package/benchmarks/production-v3/prompts/stale-search-response.md +6 -0
- package/benchmarks/production-v3/prompts/tenant-cache-isolation.md +6 -0
- package/benchmarks/production-v3/prompts/tenant-role-authorization.md +6 -0
- package/benchmarks/production-v3/prompts/unicode-search.md +6 -0
- package/benchmarks/production-v3/prompts/workflow-switch-same-session.md +30 -0
- package/benchmarks/production-v3/prompts/workspace-order.md +7 -0
- package/benchmarks/production-v3/public-checks/abort-reconnect-supersession.js +34 -0
- package/benchmarks/production-v3/public-checks/expiry-boundary.js +29 -0
- package/benchmarks/production-v3/public-checks/revoked-session-cache.js +20 -0
- package/benchmarks/production-v3/spend-control.v1.json +121 -0
- package/benchmarks/production-v3/suite.json +1010 -0
- package/benchmarks/production-v3/variant.mjs +178 -0
- package/catalog/capabilities.json +2 -2
- package/docs/benchmark-codex-mcp-metadata-contract-v1.md +159 -0
- package/docs/benchmark-codex-mcp-metadata-contract-v2.md +182 -0
- package/docs/benchmark-codex-mcp-metadata-contract-v3.md +194 -0
- package/docs/benchmark-public-contract-addendum-v2.md +85 -0
- package/docs/benchmark-public-contract-addendum-v3.md +116 -0
- package/docs/command-reference-vietnamese.md +10 -7
- package/docs/context-window-policy.md +3 -3
- package/docs/distribution-standard.md +9 -9
- package/docs/languages.json +2 -2
- package/docs/operator-manual-vietnamese.md +12 -12
- package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
- package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
- package/docs/piagent-core-improvement-plan.md +528 -0
- package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
- package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
- package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
- package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
- package/docs/piagent-open-session-wait.md +19 -0
- package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
- package/docs/publishing-for-teams.md +2 -0
- package/docs/quality-benchmark.md +128 -8
- package/docs/quickstart-vietnamese.md +2 -2
- package/docs/release-install-policy.md +32 -9
- package/docs/research/harness-next-evidence-review.md +113 -0
- package/docs/team-onboarding.md +7 -7
- package/docs/third-party-neutrality.md +7 -0
- package/docs/usage-observability.md +1 -1
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +1 -1
- package/docs-site/commands.html +1 -1
- package/docs-site/content/en/runtime.html +1 -1
- package/docs-site/content/en/whats-new.html +11 -0
- package/docs-site/content/runtime.html +2 -2
- package/docs-site/content/whats-new.html +11 -0
- package/docs-site/context-engine.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +1 -1
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/index.html +1 -1
- package/docs-site/en/mcp-approval.html +1 -1
- package/docs-site/en/mcp-auth.html +1 -1
- package/docs-site/en/mcp-servers.html +1 -1
- package/docs-site/en/mcp.html +1 -1
- package/docs-site/en/permissions.html +1 -1
- package/docs-site/en/profiles.html +1 -1
- package/docs-site/en/quickstart.html +1 -1
- package/docs-site/en/runtime.html +2 -2
- package/docs-site/en/scope.html +1 -1
- package/docs-site/en/security.html +1 -1
- package/docs-site/en/team.html +1 -1
- package/docs-site/en/whats-new.html +12 -1
- package/docs-site/en/workflows.html +1 -1
- package/docs-site/index.html +1 -1
- package/docs-site/mcp-approval.html +1 -1
- package/docs-site/mcp-auth.html +1 -1
- package/docs-site/mcp-servers.html +1 -1
- package/docs-site/mcp.html +1 -1
- package/docs-site/permissions.html +1 -1
- package/docs-site/profiles.html +1 -1
- package/docs-site/quickstart.html +1 -1
- package/docs-site/runtime.html +3 -3
- package/docs-site/scope.html +1 -1
- package/docs-site/security.html +1 -1
- package/docs-site/team.html +1 -1
- package/docs-site/whats-new.html +12 -1
- package/docs-site/workflows.html +1 -1
- package/evals/architecture-conformance-v1/lane.json +18 -0
- package/evals/architecture-conformance-v1/runner.mjs +77 -0
- package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
- package/evals/fixtures/approved-host-contracts.valid.json +43 -0
- package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
- package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
- package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
- package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
- package/evals/fixtures/composite-criterion.invalid.json +10 -0
- package/evals/fixtures/composite-criterion.valid.json +33 -0
- package/evals/fixtures/contract-family-library.invalid.json +42 -0
- package/evals/fixtures/contract-family-library.valid.json +41 -0
- package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
- package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
- package/evals/fixtures/host-contract-plan.invalid.json +42 -0
- package/evals/fixtures/host-contract-plan.valid.json +41 -0
- package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
- package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
- package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
- package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
- package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
- package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
- package/evals/fs5-artifact-archive/README.md +32 -0
- package/evals/fs5-artifact-archive/manifest.json +148 -0
- package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
- package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
- package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
- package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
- package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
- package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
- package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
- package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
- package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
- package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
- package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
- package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
- package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
- package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
- package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
- package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
- package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
- package/evals/fs5-causal-arm.v1.json +9 -5
- package/evals/fs5-pilot-protocol.v1.json +1 -1
- package/evals/fs5-pilot-protocol.v4.json +4 -4
- package/evals/fs5-pilot-protocol.v5.json +6 -5
- package/evals/harness-next/development-corpus.mjs +106 -0
- package/evals/harness-next/resource-budget-probe.mjs +38 -0
- package/evals/harness-next/run-calibration.mjs +83 -0
- package/evals/harness-next/run-resource-probe.mjs +55 -0
- package/evals/harness-next/selected-development-corpus.mjs +27 -0
- package/evals/harness-next.v1.json +51 -0
- package/evals/long-horizon-v1/README.md +19 -0
- package/evals/long-horizon-v1/runner.mjs +116 -48
- package/evals/long-horizon-v1/worker.mjs +77 -30
- package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
- package/evals/private-holdout-v1/README.md +5 -2
- package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
- package/package.json +9 -4
- package/packages/piagent-core/README.md +2 -2
- package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
- package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
- package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
- package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
- package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
- package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
- package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
- package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
- package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
- package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
- package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
- package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +2 -1
- package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
- package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
- package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
- package/packages/piagent-core/benchmark/benchmark-core.js +107 -107
- package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
- package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
- package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
- package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
- package/packages/piagent-core/benchmark/benchmark-forensics.js +63 -50
- package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
- package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
- package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
- package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
- package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
- package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
- package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
- package/packages/piagent-core/benchmark/benchmark-preflight.js +69 -8
- package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
- package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
- package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
- package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +162 -45
- package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
- package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
- package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
- package/packages/piagent-core/benchmark/benchmark-record-validation.js +269 -3
- package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
- package/packages/piagent-core/benchmark/benchmark-report.js +79 -4
- package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
- package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
- package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
- package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
- package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
- package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
- package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +144 -128
- package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
- package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
- package/packages/piagent-core/benchmark/benchmark-suite.js +211 -4
- package/packages/piagent-core/benchmark/benchmark-summary-support.js +30 -2
- package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
- package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
- package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
- package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
- package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
- package/packages/piagent-core/benchmark/benchmark-usage.js +395 -33
- package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
- package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
- package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
- package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
- package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
- package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
- package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
- package/packages/piagent-core/extensions/acceptance-behavior-proof.js +264 -70
- package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
- package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
- package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
- package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
- package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
- package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
- package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
- package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
- package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
- package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
- package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
- package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
- package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
- package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
- package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
- package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
- package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
- package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
- package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
- package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
- package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
- package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
- package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
- package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
- package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
- package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
- package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
- package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
- package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
- package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
- package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
- package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
- package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
- package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
- package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
- package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
- package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
- package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
- package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
- package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
- package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
- package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
- package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
- package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
- package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
- package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
- package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
- package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
- package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
- package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
- package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
- package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
- package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
- package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
- package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
- package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
- package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
- package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
- package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
- package/packages/piagent-core/extensions/acceptance-receipt.js +139 -152
- package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
- package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
- package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
- package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
- package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
- package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
- package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
- package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
- package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
- package/packages/piagent-core/extensions/context-engine.js +11 -6
- package/packages/piagent-core/extensions/criterion-context-pack.js +96 -4
- package/packages/piagent-core/extensions/failure-types.ts +2 -2
- package/packages/piagent-core/extensions/guard-types.ts +5 -1
- package/packages/piagent-core/extensions/piagent-guard.ts +197 -155
- package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
- package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
- package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
- package/packages/piagent-core/extensions/task-contract-view.js +4 -4
- package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
- package/packages/piagent-core/extensions/task-journal.js +48 -3
- package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
- package/packages/piagent-core/extensions/task-state.js +74 -38
- package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
- package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
- package/packages/piagent-core/extensions/verification-intelligence.js +60 -8
- package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
- package/packages/piagent-core/extensions/workspace-revision.js +48 -0
- package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
- package/packages/piagent-core/package.json +3 -3
- package/packages/piagent-core/policies/base-policy.json +1 -0
- package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
- package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
- package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
- package/packages/piagent-core/runtime/hooks/completion-hook.ts +76 -83
- package/packages/piagent-core/runtime/hooks/input-hook.ts +92 -7
- package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
- package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
- package/packages/piagent-core/runtime/hooks/session-start-hook.ts +50 -18
- package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +53 -20
- package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
- package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
- package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
- package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
- package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
- package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
- package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
- package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +49 -8
- package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +61 -15
- package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
- package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
- package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
- package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
- package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
- package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
- package/packages/piagent-core/runtime/product/efficiency-metrics.ts +12 -7
- package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
- package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
- package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
- package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
- package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
- package/packages/piagent-core/runtime/recovery/continuation-budget.ts +11 -2
- package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
- package/packages/piagent-core/runtime/recovery/handoff-projection.ts +192 -57
- package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
- package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
- package/packages/piagent-core/runtime/recovery/recovery-policy.ts +27 -39
- package/packages/piagent-core/runtime/recovery/resume-state.ts +8 -5
- package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
- package/packages/piagent-core/runtime/registration/context-commands.ts +12 -8
- package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
- package/packages/piagent-core/runtime/registration/policy-tools.ts +5 -3
- package/packages/piagent-core/runtime/registration/session-commands.ts +9 -7
- package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
- package/packages/piagent-core/runtime/registration/task-completion-tools.ts +27 -11
- package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
- package/packages/piagent-core/runtime/registration/task-start-guidance.ts +5 -2
- package/packages/piagent-core/runtime/registration/task-start-tool.ts +23 -23
- package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
- package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
- package/packages/piagent-core/runtime/session/message-signals.ts +6 -22
- package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
- package/packages/piagent-core/runtime/session/runtime-state.ts +29 -35
- package/packages/piagent-core/runtime/session/system-prompt.ts +3 -3
- package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
- package/packages/piagent-core/runtime/session/usage.ts +4 -3
- package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
- package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
- package/packages/piagent-core/runtime/tools/phase-tools.ts +3 -2
- package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
- package/packages/piagent-core/runtime/tools/tool-groups.ts +10 -3
- package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
- package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
- package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
- package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
- package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
- package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
- package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
- package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
- package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
- package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
- package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +11 -11
- package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
- package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
- package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
- package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
- package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
- package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
- package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
- package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +44 -7
- package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
- package/packages/piagent-core/runtime/workflows/task-intake.ts +221 -242
- package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
- package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
- package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
- package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
- package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
- package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-B4XehTCU.js → MarkdownMessage-DGk34zJT.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
- package/packages/piagent-webui/dist/client/assets/index-DiKRmCEP.js +176 -0
- package/packages/piagent-webui/dist/client/index.html +2 -2
- package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
- package/packages/piagent-webui/extension/piagent-webui.ts +10 -2
- package/packages/piagent-webui/extension/review-controller.ts +29 -6
- package/packages/piagent-webui/extension/same-session-bridge.ts +6 -7
- package/packages/piagent-webui/extension/session-stream-adapter.ts +60 -11
- package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
- package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
- package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
- package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
- package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
- package/packages/piagent-webui/gateway/gateway-session-stream.ts +141 -19
- package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
- package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
- package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
- package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
- package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
- package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
- package/packages/piagent-webui/gateway/session-inspection-registry.ts +11 -2
- package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
- package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
- package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
- package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
- package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
- package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +114 -114
- package/packages/piagent-webui/server/core-inspection-provider.ts +73 -14
- package/packages/piagent-webui/server/loopback-server.ts +9 -7
- package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
- package/packages/piagent-webui/server/transcript-projection.ts +65 -12
- package/packages/piagent-webui/shared/message-correlation.ts +25 -0
- package/schemas/approved-host-contracts.schema.json +973 -0
- package/schemas/benchmark-attempt-outcome.schema.json +303 -0
- package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
- package/schemas/composite-criterion.schema.json +788 -0
- package/schemas/contract-family-library.schema.json +28 -0
- package/schemas/contract-selection-recipe.schema.json +31 -0
- package/schemas/failure-evidence.schema.json +2 -2
- package/schemas/helper-request.schema.json +16 -4
- package/schemas/host-contract-plan.schema.json +25 -0
- package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
- package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
- package/schemas/piagent-webui/runtime-event-v2.schema.json +32 -1
- package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
- package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
- package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
- package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
- package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
- package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
- package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
- package/schemas/public-contracts/revocation-v1.schema.json +87 -0
- package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
- package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
- package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
- package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
- package/schemas/task-contract.schema.json +30 -0
- package/scripts/approve-independent-verification.mjs +57 -0
- package/scripts/benchmark-arm-observer.mjs +320 -0
- package/scripts/benchmark-budget-ipc.mjs +34 -0
- package/scripts/benchmark-budget-launcher.mjs +91 -0
- package/scripts/benchmark-budget-processes.mjs +133 -0
- package/scripts/benchmark-budget-publication.mjs +228 -0
- package/scripts/benchmark-budget-runtime.mjs +136 -0
- package/scripts/benchmark-candidate-ablation.mjs +265 -0
- package/scripts/benchmark-codex-journey.mjs +406 -0
- package/scripts/benchmark-independent-verification.mjs +628 -0
- package/scripts/benchmark-journey-outcome.mjs +92 -0
- package/scripts/benchmark-production-v3-human-review.mjs +192 -0
- package/scripts/benchmark-public-input-catalog.mjs +158 -0
- package/scripts/benchmark-registered-plan-author.mjs +355 -0
- package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
- package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
- package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
- package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
- package/scripts/benchmark-runner-completion.mjs +133 -0
- package/scripts/benchmark-runner-configuration.mjs +159 -0
- package/scripts/benchmark-runner-core.mjs +217 -388
- package/scripts/benchmark-runner-finalization.mjs +140 -27
- package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
- package/scripts/benchmark-runner-schedule.mjs +256 -0
- package/scripts/benchmark-runner-support.mjs +136 -4
- package/scripts/benchmark-runner.mjs +95 -18
- package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
- package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
- package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
- package/scripts/benchmark-scoped-pi-router.mjs +196 -0
- package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
- package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
- package/scripts/benchmark-scoped-session-custody.mjs +599 -0
- package/scripts/benchmark-scoped-session-factory.mjs +342 -0
- package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
- package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
- package/scripts/benchmark-session-evaluator.mjs +169 -0
- package/scripts/benchmark-session-provider-boundary.mjs +62 -0
- package/scripts/benchmark-session-usage.mjs +28 -0
- package/scripts/benchmark-session.mjs +343 -50
- package/scripts/benchmark-webui-journey.mjs +678 -0
- package/scripts/check-public-wording.mjs +46 -0
- package/scripts/fs4-readiness-evaluation.mjs +7 -1
- package/scripts/phase-tools-evaluation.mjs +1 -0
- package/scripts/pi-auto.sh +7 -1
- package/scripts/pi-usage-history.mjs +201 -11
- package/scripts/piagent-cli.mjs +8 -0
- package/scripts/private-holdout-readiness.mjs +7 -1
- package/scripts/public-evaluation-exposure.mjs +140 -0
- package/scripts/select-independent-verification.mjs +62 -0
- package/scripts/typescript-loader.mjs +135 -1
- package/scripts/update-global.mjs +6 -7
- package/scripts/verify-local.sh +36 -55
- package/scripts/verify-release-identity.mjs +5 -3
- package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +0 -176
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { assertionCarrierBindings, testRunnerBindings, importedCallableBindingIsStable, assertionCarrierIsStable, TEST_RUNNER_EXPORT_KINDS } from "./acceptance-test-bindings.js";
|
|
2
|
+
import { INVALID_DATE_CONSTRUCTION, tupleRegistrationIsClosed } from "./acceptance-tuple-shapes.js";
|
|
3
|
+
import { browserWindowReferencesAreLocal, directPrimitiveArgument } from "./acceptance-local-binding.js";
|
|
4
|
+
|
|
1
5
|
const ERROR_CONSTRUCTORS = ["typeerror", "rangeerror", "syntaxerror", "referenceerror", "urierror", "evalerror", "aggregateerror", "error"];
|
|
2
6
|
|
|
3
7
|
function uniqueStrings(values) {
|
|
@@ -8,60 +12,15 @@ function escapeRegex(value) {
|
|
|
8
12
|
return String(value ?? "").replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9
13
|
}
|
|
10
14
|
|
|
11
|
-
function assertionCarrierBindings(testText) {
|
|
12
|
-
const bindings = [];
|
|
13
|
-
const add = (name, start, end) => {
|
|
14
|
-
if (name) bindings.push({ name: name.toLowerCase(), start, end });
|
|
15
|
-
};
|
|
16
|
-
for (const match of testText.matchAll(/\bimport\s+([a-z_$][a-z0-9_$]*)\s+from\s+__pi_node_assert_module_literal__\s*;?/gi)) {
|
|
17
|
-
add(match[1], match.index, match.index + match[0].length);
|
|
18
|
-
}
|
|
19
|
-
for (const match of testText.matchAll(/\bimport\s+\*\s+as\s+([a-z_$][a-z0-9_$]*)\s+from\s+__pi_node_assert_module_literal__\s*;?/gi)) {
|
|
20
|
-
add(match[1], match.index, match.index + match[0].length);
|
|
21
|
-
}
|
|
22
|
-
for (const match of testText.matchAll(/\bimport\s*\{([^}]{1,500})\}\s*from\s+__pi_node_assert_module_literal__\s*;?/gi)) {
|
|
23
|
-
for (const item of match[1].split(",")) {
|
|
24
|
-
const strict = item.trim().match(/^strict(?:\s+as\s+([a-z_$][a-z0-9_$]*))?$/i);
|
|
25
|
-
if (strict) add(strict[1] ?? "strict", match.index, match.index + match[0].length);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
for (const match of testText.matchAll(/\bconst\s+([a-z_$][a-z0-9_$]*)\s*=\s*require\s*\(\s*__pi_node_assert_module_literal__\s*\)(?:\s*\.\s*strict)?\s*;?/gi)) {
|
|
29
|
-
add(match[1], match.index, match.index + match[0].length);
|
|
30
|
-
}
|
|
31
|
-
for (const match of testText.matchAll(/\bconst\s*\{\s*strict\s*:\s*([a-z_$][a-z0-9_$]*)\s*\}\s*=\s*require\s*\(\s*__pi_node_assert_module_literal__\s*\)\s*;?/gi)) {
|
|
32
|
-
add(match[1], match.index, match.index + match[0].length);
|
|
33
|
-
}
|
|
34
|
-
return bindings.slice(0, 8);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function assertionCarrierIsStable(testText, binding) {
|
|
38
|
-
const escaped = escapeRegex(binding.name);
|
|
39
|
-
const withoutDeclaration = `${testText.slice(0, binding.start)}${" ".repeat(binding.end - binding.start)}${testText.slice(binding.end)}`;
|
|
40
|
-
if (assertionCarrierBindings(testText).filter((candidate) => candidate.name === binding.name).length !== 1) return false;
|
|
41
|
-
if (new RegExp(`\\b(?:const|let|var|function|class)\\s+${escaped}\\b|\\bfunction\\b[^({]{0,200}\\([^)]*\\b${escaped}\\b|\\bcatch\\s*\\([^)]*\\b${escaped}\\b|(?:\\([^)]*\\b${escaped}\\b[^)]*\\)|\\b${escaped})\\s*=>`, "i").test(withoutDeclaration)) return false;
|
|
42
|
-
if (new RegExp(`(?<![.$a-z0-9_])${escaped}\\b\\s*(?:(?<![=!<>])=(?!=|>)|\\+\\+|--|[+*/%&|^-]=)|(?:\\+\\+|--)\\s*\\b${escaped}\\b`, "i").test(withoutDeclaration)) return false;
|
|
43
|
-
if (new RegExp(`\\b(?:const|let|var)\\s+[a-z_$][a-z0-9_$]*\\s*=\\s*${escaped}\\b|\\b(?:const|let|var)\\s*\\{[^}\\n]{0,500}\\}\\s*=\\s*${escaped}\\b`, "i").test(withoutDeclaration)) return false;
|
|
44
|
-
if (new RegExp(`(?<![.$a-z0-9_])[a-z_$][a-z0-9_$]*\\s*(?<![=!<>])=(?!=|>)\\s*${escaped}\\b`, "i").test(withoutDeclaration)) return false;
|
|
45
|
-
const member = `${escaped}\\s*(?:\\.\\s*[a-z_$][a-z0-9_$]*|\\[[^\\]]{1,300}\\])`;
|
|
46
|
-
if (new RegExp(`\\b${member}\\s*(?:=|\\+\\+|--|[+*/%&|^-]=|(?:&&|\\|\\||\\?\\?)=)|(?:\\+\\+|--)\\s*\\b${member}|\\bdelete\\s+${escaped}\\s*(?:\\.|\\[)|\\b${escaped}\\s*\\.\\s*__(?:definegetter|definesetter)__\\s*\\(`, "i").test(withoutDeclaration)) return false;
|
|
47
|
-
if (new RegExp(`(?:\\{[^}\\n]{0,500}\\b${member}[^}\\n]{0,500}\\}|\\[[^\\]\\n]{0,500}\\b${member}[^\\]\\n]{0,500}\\])\\s*=|\\bfor(?:\\s+await)?\\s*\\(\\s*(?:${member}|\\{[^}\\n]{0,500}\\b${member}[^}\\n]{0,500}\\}|\\[[^\\]\\n]{0,500}\\b${member}[^\\]\\n]{0,500}\\])\\s+(?:of|in)\\b`, "i").test(withoutDeclaration)) return false;
|
|
48
|
-
if (new RegExp(`\\b(?:object|reflect)\\s*\\.\\s*[a-z_$][a-z0-9_$]*\\s*\\(\\s*${escaped}\\s*[,)]|\\b[a-z_$][a-z0-9_$.]*\\s*\\(\\s*${escaped}\\s*[,)]`, "i").test(withoutDeclaration)) return false;
|
|
49
|
-
for (const match of withoutDeclaration.matchAll(new RegExp(`\\b${escaped}\\b`, "gi"))) {
|
|
50
|
-
const suffix = withoutDeclaration.slice(match.index + match[0].length);
|
|
51
|
-
if (/^\s*\(/.test(suffix) || /^\s*\.\s*[a-z_$][a-z0-9_$]*\s*\(/i.test(suffix)) continue;
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
15
|
function assertionEvidenceFileSupported(testText) {
|
|
58
|
-
if (
|
|
16
|
+
if (!browserWindowReferencesAreLocal(testText)) return false;
|
|
17
|
+
if (/\\|__pi_(?:code_generation|module_loader)_module_literal__|\b(?:eval|createrequire)\b|\b(?:process|globalthis|global|self|this)\b|\bmodule\s*\.\s*(?:require|constructor|_load)\b|\.\s*constructor\b|\bfunction\s*\(|(?:=|[,([])\s*function\b(?!\s+[a-z_$][a-z0-9_$]*\s*\()/i.test(testText)) return false;
|
|
59
18
|
if (/\brequire\b(?!\s*\()/i.test(testText)) return false;
|
|
60
19
|
for (const match of testText.matchAll(/\b(?:require|import)\s*\(/gi)) {
|
|
61
20
|
const open = testText.indexOf("(", match.index);
|
|
62
21
|
const end = balancedEnd(testText, open);
|
|
63
22
|
const argument = end === -1 ? "" : testText.slice(open + 1, end - 1).trim();
|
|
64
|
-
if (!/^__pi_(?:bound_string_\d+|string|node_assert_module)_literal__$/.test(argument)) return false;
|
|
23
|
+
if (!/^__pi_(?:bound_string_\d+|string|node_assert_module|node_test_module)_literal__$/.test(argument)) return false;
|
|
65
24
|
}
|
|
66
25
|
return true;
|
|
67
26
|
}
|
|
@@ -70,6 +29,103 @@ function nodeAssertModuleReferenceCount(testText) {
|
|
|
70
29
|
return [...testText.matchAll(/__pi_node_assert_module_literal__/g)].length;
|
|
71
30
|
}
|
|
72
31
|
|
|
32
|
+
export function literalArrayIterationEnvironmentIsStable(testText) {
|
|
33
|
+
const code = String(testText ?? "");
|
|
34
|
+
if (/\barray\s*\.\s*prototype\b|\bsymbol\b|\breflect\b|__proto__|\bobject\s*\.\s*(?:get|set|define|assign)/i.test(code)) return false;
|
|
35
|
+
const intrinsic = "(?:array|symbol)";
|
|
36
|
+
if (new RegExp(`\\b(?:const|let|var|function|class)\\s+${intrinsic}\\b|\\bimport\\s+(?:\\*\\s+as\\s+)?${intrinsic}\\b|\\bimport\\s*\\{[^}\\n]{0,500}\\bas\\s+${intrinsic}\\b`, "i").test(code)) return false;
|
|
37
|
+
if (new RegExp(`\\b(?:const|let|var)\\s+(?:\\{[^}\\n]{0,500}\\b${intrinsic}\\b|\\[[^\\]\\n]{0,500}\\b${intrinsic}\\b)|\\b(?:function|catch)\\b[^({]{0,200}\\([^)]*\\b${intrinsic}\\b`, "i").test(code)) return false;
|
|
38
|
+
if (new RegExp(`(?:\\([^)]*\\b${intrinsic}\\b[^)]*\\)|\\b${intrinsic})\\s*=>|(?<![.$a-z0-9_])${intrinsic}\\s*(?:(?<![=!<>])=(?!=|>)|\\+\\+|--|[+*/%&|^-]=)`, "i").test(code)) return false;
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function moduleBackedBindings(code, moduleToken, exportedNames = []) {
|
|
43
|
+
const names = new Set(), token = escapeRegex(moduleToken);
|
|
44
|
+
const add = (name) => { if (/^[a-z_$][a-z0-9_$]*$/i.test(name ?? "")) names.add(name.toLowerCase()); };
|
|
45
|
+
for (const match of code.matchAll(new RegExp(`\\bimport\\s+([a-z_$][a-z0-9_$]*)(?:\\s*,\\s*\\{[^}]{1,500}\\})?\\s+from\\s+${token}\\b`, "gi"))) add(match[1]);
|
|
46
|
+
for (const match of code.matchAll(new RegExp(`\\bimport\\s+\\*\\s+as\\s+([a-z_$][a-z0-9_$]*)\\s+from\\s+${token}\\b`, "gi"))) add(match[1]);
|
|
47
|
+
for (const match of code.matchAll(new RegExp(`\\bimport\\s+(?:[a-z_$][a-z0-9_$]*\\s*,\\s*)?\\{([^}]{1,500})\\}\\s*from\\s+${token}\\b`, "gi"))) {
|
|
48
|
+
for (const raw of match[1].split(",")) {
|
|
49
|
+
const item = raw.trim().match(/^([a-z_$][a-z0-9_$]*)(?:\s+as\s+([a-z_$][a-z0-9_$]*))?$/i);
|
|
50
|
+
if (item && exportedNames.includes(item[1].toLowerCase())) add(item[2] ?? item[1]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const match of code.matchAll(new RegExp(`\\b(?:const|let|var)\\s+([a-z_$][a-z0-9_$]*)\\s*=\\s*require\\s*\\(\\s*${token}\\s*\\)(?:\\s*\\.\\s*(?:strict|${exportedNames.join("|")}))?\\s*;?`, "gi"))) add(match[1]);
|
|
54
|
+
for (const match of code.matchAll(new RegExp(`\\b(?:const|let|var)\\s*\\{([^}]{1,500})\\}\\s*=\\s*require\\s*\\(\\s*${token}\\s*\\)`, "gi"))) {
|
|
55
|
+
for (const raw of match[1].split(",")) {
|
|
56
|
+
const item = raw.trim().match(/^([a-z_$][a-z0-9_$]*)(?:\s*:\s*([a-z_$][a-z0-9_$]*))?$/i);
|
|
57
|
+
if (item && exportedNames.includes(item[1].toLowerCase())) add(item[2] ?? item[1]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
for (let pass = 0; pass < 4; pass += 1) {
|
|
61
|
+
const priorSize = names.size;
|
|
62
|
+
for (const name of [...names]) {
|
|
63
|
+
const backed = `${escapeRegex(name)}(?:\\s*\\.\\s*[a-z_$][a-z0-9_$]*|\\s*\\[[^\\]\\n]{1,300}\\])?`;
|
|
64
|
+
for (const match of code.matchAll(new RegExp(`\\b(?:const|let|var)\\s+([a-z_$][a-z0-9_$]*)\\s*=\\s*${backed}\\s*(?:;|\\n|$)`, "gi"))) add(match[1]);
|
|
65
|
+
for (const match of code.matchAll(new RegExp(`(?<![.$a-z0-9_])([a-z_$][a-z0-9_$]*)\\s*=\\s*${backed}\\s*(?:;|\\n|$)`, "gi"))) add(match[1]);
|
|
66
|
+
for (const match of code.matchAll(new RegExp(`\\b(?:const|let|var)\\s*\\{([^}]{1,500})\\}\\s*=\\s*${escapeRegex(name)}\\b`, "gi"))) {
|
|
67
|
+
for (const raw of match[1].split(",")) add(raw.trim().match(/^(?:[a-z_$][a-z0-9_$]*\s*:\s*)?([a-z_$][a-z0-9_$]*)$/i)?.[1]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (names.size === priorSize) break;
|
|
71
|
+
}
|
|
72
|
+
return [...names];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function withoutModuleBindingDeclarations(code, moduleToken) {
|
|
76
|
+
const token = escapeRegex(moduleToken), blank = (match) => " ".repeat(match.length);
|
|
77
|
+
return String(code ?? "")
|
|
78
|
+
.replace(new RegExp(`\\bimport\\s+[^;\\n]{1,800}?\\s+from\\s+${token}\\s*;?`, "gi"), blank)
|
|
79
|
+
.replace(new RegExp(`\\b(?:const|let|var)\\s+[^;\\n]{1,800}?=\\s*require\\s*\\(\\s*${token}\\s*\\)[^;\\n]*;?`, "gi"), blank);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function moduleBindingEscapes(code, binding) {
|
|
83
|
+
// Returning a direct module method call does not return the module binding.
|
|
84
|
+
// Bare members and bound methods remain escapes; mutation checks still apply.
|
|
85
|
+
const name = `(?<![.$a-z0-9_])${escapeRegex(binding)}\\b`;
|
|
86
|
+
if (new RegExp(`\\b(?:const|let|var)\\s+[a-z_$][a-z0-9_$]*\\s*=\\s*(?:${name}|\\{[^}\\n]{0,500}${name}|\\[[^\\]\\n]{0,500}${name})`, "i").test(code)) return true;
|
|
87
|
+
if (new RegExp(`(?<![=!<>])=(?!=|>)\\s*${name}|\\breturn\\s+${name}|=>\\s*${name}(?!\\s*\\.\\s*[a-z_$][a-z0-9_$]*\\s*\\()|\\.\\.\\.\\s*${name}`, "i").test(code)) return true;
|
|
88
|
+
if (new RegExp(`(?:\\(|\\{|\\[|,|:)\\s*(?:[a-z_$][a-z0-9_$]*\\s*:\\s*)?${name}\\s*(?:,|\\)|\\}|\\])`, "i").test(code)) return true;
|
|
89
|
+
return new RegExp(`(?:\\(|,)\\s*${name}\\s*(?:,|\\))`, "i").test(code);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function moduleTargetIsMutated(code, target) {
|
|
93
|
+
const member = "(?:\\s*\\.\\s*[a-z_$][a-z0-9_$]*|\\s*\\[[^\\]\\n]{1,300}\\])";
|
|
94
|
+
const lvalue = `(?:${target})(?:${member}){1,4}`;
|
|
95
|
+
if (new RegExp(`${lvalue}\\s*(?:=(?!=|>)|\\+\\+|--|[+*/%&|^-]=|(?:&&|\\|\\||\\?\\?)=)|(?:\\+\\+|--)\\s*${lvalue}|\\bdelete\\s+${lvalue}`, "i").test(code)) return true;
|
|
96
|
+
if (new RegExp(`\\b(?:object\\s*\\.\\s*(?:assign|defineproperties|defineproperty|setprototypeof)|reflect\\s*\\.\\s*(?:defineproperty|set|setprototypeof))\\s*\\(\\s*(?:${target})\\s*[,)]`, "i").test(code)) return true;
|
|
97
|
+
return new RegExp(`(?:${target})\\s*\\.\\s*__(?:definegetter|definesetter)__\\s*\\(`, "i").test(code);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Reject corpus-wide mutation of assertion carriers or test registration APIs. */
|
|
101
|
+
export function testProofIntrinsicsAreStable(testText) {
|
|
102
|
+
const code = String(testText ?? "");
|
|
103
|
+
if (/__pi_node_process_module_literal__|\bprocess\s*(?:\.|\[)/i.test(code)) return false;
|
|
104
|
+
if (/\bimport\s+(?:__pi_bound_string_\d+__|__pi_template_literal__)\s*(?=;|\b(?:assert|with)\b|[\r\n]|$)/i.test(code)) return false;
|
|
105
|
+
if (/__pi_template_literal__/.test(code)
|
|
106
|
+
&& /__pi_node_(?:assert|test)_module_literal__/.test(code)) return false;
|
|
107
|
+
for (const match of code.matchAll(/\b(?:import|require)\s*\(/gi)) {
|
|
108
|
+
const open = code.indexOf("(", match.index), end = balancedEnd(code, open);
|
|
109
|
+
const argument = end === -1 ? "" : code.slice(open + 1, end - 1).trim();
|
|
110
|
+
if (!/^__pi_(?:bound_string_\d+|node_assert_module|node_process_module|node_test_module)_literal__$/.test(argument)) return false;
|
|
111
|
+
if (/^__pi_node_(?:assert|test)_module_literal__$/.test(argument) && /^import/i.test(match[0])) return false;
|
|
112
|
+
}
|
|
113
|
+
const modules = [
|
|
114
|
+
{ token: "__pi_node_assert_module_literal__", exports: ["default", "strict"] },
|
|
115
|
+
{ token: "__pi_node_test_module_literal__", exports: ["default", ...TEST_RUNNER_EXPORT_KINDS.keys()] }
|
|
116
|
+
];
|
|
117
|
+
for (const module of modules) {
|
|
118
|
+
const direct = `require\\s*\\(\\s*${module.token}\\s*\\)(?:\\s*\\.\\s*strict)?`;
|
|
119
|
+
if (moduleTargetIsMutated(code, direct)) return false;
|
|
120
|
+
const declarationFree = withoutModuleBindingDeclarations(code, module.token);
|
|
121
|
+
for (const binding of moduleBackedBindings(code, module.token, module.exports)) {
|
|
122
|
+
if (moduleBindingEscapes(declarationFree, binding)) return false;
|
|
123
|
+
if (moduleTargetIsMutated(code, `(?<![.$a-z0-9_])${escapeRegex(binding)}\\b`)) return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
|
|
73
129
|
function balancedEnd(text, openIndex, opening = "(", closing = ")", ceiling = 8_000) {
|
|
74
130
|
if (text[openIndex] !== opening) return -1;
|
|
75
131
|
let depth = 0;
|
|
@@ -106,6 +162,141 @@ function topLevelArgumentRanges(text, openIndex, endIndex) {
|
|
|
106
162
|
export function evidenceTopLevelArguments(text, openIndex, endIndex) {
|
|
107
163
|
return topLevelArgumentRanges(text, openIndex, endIndex).map((argument) => argument.text);
|
|
108
164
|
}
|
|
165
|
+
function operationArguments(operation, target) {
|
|
166
|
+
const callable = String(target ?? "").replace(/^\*\./, "");
|
|
167
|
+
if (!callable) return [];
|
|
168
|
+
const text = String(operation ?? "");
|
|
169
|
+
const pattern = new RegExp(`(?:^|[^a-z0-9_$])${escapeRegex(callable)}\\s*\\(`, "gi");
|
|
170
|
+
for (const match of text.matchAll(pattern)) {
|
|
171
|
+
const open = text.indexOf("(", match.index + match[0].length - 1);
|
|
172
|
+
const end = balancedEnd(text, open);
|
|
173
|
+
if (end !== -1) return topLevelArgumentRanges(text, open, end).map((item) => item.text.trim());
|
|
174
|
+
}
|
|
175
|
+
return [];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function literalBooleanTernarySelection(raw) {
|
|
179
|
+
let value = String(raw ?? "").trim();
|
|
180
|
+
while (value.startsWith("(") && balancedEnd(value, 0) === value.length) value = value.slice(1, -1).trim();
|
|
181
|
+
let question = -1, colon = -1, parentheses = 0, brackets = 0, braces = 0, ternaries = 0;
|
|
182
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
183
|
+
if (value[index] === "(") parentheses += 1;
|
|
184
|
+
else if (value[index] === ")") parentheses -= 1;
|
|
185
|
+
else if (value[index] === "[") brackets += 1;
|
|
186
|
+
else if (value[index] === "]") brackets -= 1;
|
|
187
|
+
else if (value[index] === "{") braces += 1;
|
|
188
|
+
else if (value[index] === "}") braces -= 1;
|
|
189
|
+
else if (parentheses === 0 && brackets === 0 && braces === 0 && value[index] === "?") {
|
|
190
|
+
if (question === -1) question = index;
|
|
191
|
+
ternaries += 1;
|
|
192
|
+
} else if (parentheses === 0 && brackets === 0 && braces === 0 && value[index] === ":" && ternaries > 0) {
|
|
193
|
+
ternaries -= 1;
|
|
194
|
+
if (ternaries === 0) { colon = index; break; }
|
|
195
|
+
}
|
|
196
|
+
if (parentheses < 0 || brackets < 0 || braces < 0) return { kind: "unknown" };
|
|
197
|
+
}
|
|
198
|
+
if (question === -1) return { kind: "plain", value };
|
|
199
|
+
if (colon === -1 || ternaries !== 0) return { kind: "unknown" };
|
|
200
|
+
const condition = value.slice(0, question).trim();
|
|
201
|
+
const conditionValue = simpleConstantValue(condition);
|
|
202
|
+
if (conditionValue === undefined) return { kind: "unknown" };
|
|
203
|
+
return {
|
|
204
|
+
kind: "selected",
|
|
205
|
+
value: conditionValue ? value.slice(question + 1, colon).trim() : value.slice(colon + 1).trim()
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function annotateInvalidArgumentCoverage(assertions) {
|
|
210
|
+
const proofPartitions = new Set(["fractional", "invalid-calendar-date-string", "invalid-date-object", "invalid-date-string", "missing", "negative", "non-finite-number", "unsafe-integer"]);
|
|
211
|
+
const directInvalidPartitions = new Set(["invalid-calendar-date-string", "invalid-date-object", "invalid-date-string", "missing", "non-finite-number"]);
|
|
212
|
+
const argumentPartitions = (raw, collection = false) => {
|
|
213
|
+
let selected = literalBooleanTernarySelection(raw);
|
|
214
|
+
if (selected.kind === "unknown") return new Set();
|
|
215
|
+
while (selected.kind === "selected") {
|
|
216
|
+
selected = literalBooleanTernarySelection(selected.value);
|
|
217
|
+
if (selected.kind === "unknown") return new Set();
|
|
218
|
+
}
|
|
219
|
+
const value = selected.value;
|
|
220
|
+
const values = collection && value.startsWith("[") && balancedEnd(value, 0, "[", "]") === value.length
|
|
221
|
+
? topLevelArgumentRanges(value, 0, value.length).map((item) => item.text.trim()) : [value];
|
|
222
|
+
const partitions = new Set();
|
|
223
|
+
for (const item of values) {
|
|
224
|
+
if (/^new\s+date\b/i.test(item)) {
|
|
225
|
+
if (INVALID_DATE_CONSTRUCTION.test(item)) partitions.add("invalid-date-object");
|
|
226
|
+
continue; // Constructor arguments are not the value passed to the entrypoint.
|
|
227
|
+
}
|
|
228
|
+
if (!directPrimitiveArgument(item)) continue;
|
|
229
|
+
for (const partition of evidencePartitionSignals(item)) if (proofPartitions.has(partition)) partitions.add(partition);
|
|
230
|
+
if (/^__pi_(?:invalid_(?:calendar_)?date|unparseable_date)_string_literal__$/.test(item)) partitions.add("invalid-date-string");
|
|
231
|
+
if (item === "__pi_invalid_calendar_date_string_literal__") partitions.add("invalid-calendar-date-string");
|
|
232
|
+
if (/^(?:number\.)?(?:nan|positive_infinity|negative_infinity|infinity)$/i.test(item)) partitions.add("non-finite-number");
|
|
233
|
+
}
|
|
234
|
+
return partitions;
|
|
235
|
+
};
|
|
236
|
+
const groups = new Map();
|
|
237
|
+
for (const assertion of assertions) {
|
|
238
|
+
if (!new Set(["rejects", "throws"]).has(assertion.mode)) continue;
|
|
239
|
+
for (const target of assertion.targets) {
|
|
240
|
+
const argumentsList = operationArguments(assertion.operation, target);
|
|
241
|
+
if (argumentsList.length === 0) continue;
|
|
242
|
+
const key = `${target}\u0000${assertion.mode}\u0000${[...assertion.errorClasses].sort().join(",")}`;
|
|
243
|
+
const entries = groups.get(key) ?? [];
|
|
244
|
+
entries.push({ assertion, argumentsList });
|
|
245
|
+
groups.set(key, entries);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
for (const entries of groups.values()) {
|
|
249
|
+
const required = new Set();
|
|
250
|
+
const partitionsByIndex = new Map();
|
|
251
|
+
const addPartitions = (index, values) => {
|
|
252
|
+
const partitions = partitionsByIndex.get(index) ?? new Set();
|
|
253
|
+
for (const value of values) if (proofPartitions.has(value)) partitions.add(value);
|
|
254
|
+
partitionsByIndex.set(index, partitions);
|
|
255
|
+
};
|
|
256
|
+
for (const { assertion, argumentsList } of entries) {
|
|
257
|
+
if (argumentsList.length === 1) required.add(0);
|
|
258
|
+
for (let index = 0; index < argumentsList.length; index += 1) {
|
|
259
|
+
const directPartitions = argumentPartitions(argumentsList[index]);
|
|
260
|
+
if ([...directPartitions].some((partition) => directInvalidPartitions.has(partition))) {
|
|
261
|
+
required.add(index);
|
|
262
|
+
addPartitions(index, directPartitions);
|
|
263
|
+
}
|
|
264
|
+
for (const binding of assertion.iterationBindings ?? []) {
|
|
265
|
+
if (!new RegExp(`\\b${escapeRegex(binding.variable)}\\b`, "i").test(argumentsList[index])) continue;
|
|
266
|
+
required.add(index);
|
|
267
|
+
if (literalBooleanTernarySelection(argumentsList[index]).value === binding.variable) addPartitions(index, argumentPartitions(binding.literal, true));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const maximumArity = Math.max(0, ...entries.map((entry) => entry.argumentsList.length));
|
|
272
|
+
for (let index = 0; index < maximumArity; index += 1) {
|
|
273
|
+
const corpora = new Map();
|
|
274
|
+
for (const { argumentsList } of entries) {
|
|
275
|
+
if (argumentsList.length !== maximumArity) continue;
|
|
276
|
+
const fixed = argumentsList.map((value, argumentIndex) => argumentIndex === index ? "__varying__" : value).join("\u0000");
|
|
277
|
+
const values = corpora.get(fixed) ?? new Set();
|
|
278
|
+
values.add(argumentsList[index]);
|
|
279
|
+
corpora.set(fixed, values);
|
|
280
|
+
}
|
|
281
|
+
// Three independently asserted values with every other argument fixed
|
|
282
|
+
// form a bounded invalid-input corpus rather than incidental variation.
|
|
283
|
+
for (const values of corpora.values()) {
|
|
284
|
+
if (values.size < 3) continue;
|
|
285
|
+
required.add(index);
|
|
286
|
+
for (const value of values) addPartitions(index, argumentPartitions(value));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
for (const { assertion } of entries) {
|
|
290
|
+
assertion.invalidArgumentIndices = [...new Set([...(assertion.invalidArgumentIndices ?? []), ...required])]
|
|
291
|
+
.sort((left, right) => left - right);
|
|
292
|
+
assertion.invalidArgumentPartitions = [...required].sort((left, right) => left - right).map((index) => ({
|
|
293
|
+
index,
|
|
294
|
+
partitions: [...(partitionsByIndex.get(index) ?? [])].sort()
|
|
295
|
+
}));
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return assertions;
|
|
299
|
+
}
|
|
109
300
|
|
|
110
301
|
function evidenceErrorClasses(text) {
|
|
111
302
|
return ERROR_CONSTRUCTORS.filter((name) => (
|
|
@@ -152,8 +343,8 @@ function simpleConstantValue(raw) {
|
|
|
152
343
|
|
|
153
344
|
function operationTargets(raw, callableNames) {
|
|
154
345
|
let operation = String(raw ?? "").trim();
|
|
155
|
-
const arrow = operation.
|
|
156
|
-
if (arrow
|
|
346
|
+
const arrow = operation.match(/^(?:async\s+)?(?:\([^()]*\)|[a-z_$][a-z0-9_$]*)\s*=>/i);
|
|
347
|
+
if (arrow) operation = operation.slice(arrow[0].length).trim();
|
|
157
348
|
else if (/^function\b/.test(operation)) operation = operation.slice(operation.indexOf("{")).trim();
|
|
158
349
|
if (operation.startsWith("{") && balancedEnd(operation, 0, "{", "}") === operation.length) operation = operation.slice(1, -1).trim();
|
|
159
350
|
operation = operation.replace(/^(?:return\s+)?(?:await\s+)?/, "").replace(/;\s*$/, "").trim();
|
|
@@ -191,7 +382,7 @@ function evidencePartitionSignals(text) {
|
|
|
191
382
|
if (/\bundefined\b/.test(text)) signals.add("missing");
|
|
192
383
|
if (/__pi_empty_string_literal__/.test(text)) signals.add("empty-string");
|
|
193
384
|
if (/__pi_whitespace_string_literal__/.test(text)) signals.add("whitespace-string");
|
|
194
|
-
if (/(?:^|[^\w.])-\s*(?:\d+(?:\.\d+)
|
|
385
|
+
if (/(?:^|[^\w.])-\s*(?:\d+(?:\.\d+)?)\b/.test(text)) signals.add("negative");
|
|
195
386
|
if (/(?:^|[^\w.])(?:\d+\.\d+|\.\d+)(?:[^\w.]|$)/.test(text)) signals.add("fractional");
|
|
196
387
|
if (/(?:^|[^\w.])0n?(?:[^\w.]|$)/.test(text)) signals.add("zero");
|
|
197
388
|
if (/\b(?:nan|infinity)\b|number\.(?:positive_|negative_)?infinity/.test(text)) signals.add("non-finite");
|
|
@@ -222,6 +413,59 @@ function literalArrayPartitionSignals(literal) {
|
|
|
222
413
|
return signals;
|
|
223
414
|
}
|
|
224
415
|
|
|
416
|
+
function constantTupleRows(literal, testText) {
|
|
417
|
+
const atom = String.raw`(?:undefined|null|true|false|nan|infinity|number\.(?:nan|(?:positive_|negative_)?infinity)|-?(?:\d+(?:\.\d+)?|\.\d+)|__pi_[a-z0-9_]*string_literal__)`;
|
|
418
|
+
const cell = new RegExp(`^${atom}$`, "i");
|
|
419
|
+
const elements = (text) => {
|
|
420
|
+
const values = topLevelArgumentRanges(text, 0, text.length).map((item) => item.text);
|
|
421
|
+
if (values.at(-1) === "" && /,\s*\]$/.test(text)) values.pop();
|
|
422
|
+
return values;
|
|
423
|
+
};
|
|
424
|
+
const rows = elements(literal);
|
|
425
|
+
if (rows.length === 0 || rows.length > 24) return undefined;
|
|
426
|
+
const values = rows.map((row) => boundedNonEmptyArrayLiteral(row)
|
|
427
|
+
? elements(row) : []);
|
|
428
|
+
if (values.some((row) => row.length !== 2 || row.some((value) => !cell.test(value) && !INVALID_DATE_CONSTRUCTION.test(value)))) return undefined;
|
|
429
|
+
// A literal Date allocation is the only admitted cell call. Its constructor
|
|
430
|
+
// and the primitive intrinsic values must not be rebound or escape by alias.
|
|
431
|
+
const intrinsic = "(?:date|number|nan|infinity|undefined)";
|
|
432
|
+
if (new RegExp(`\\b(?:const|let|var|class|function)\\s+${intrinsic}\\b|\\b(?:import|function|catch)\\b[^;{}]{0,300}\\b${intrinsic}\\b`, "i").test(testText)
|
|
433
|
+
|| new RegExp(`\\b(?:const|let|var)\\s*(?:\\{[^}]{0,500}\\b${intrinsic}\\b|\\[[^\\]]{0,500}\\b${intrinsic}\\b)|(?:\\([^)]*\\b${intrinsic}\\b[^)]*\\)|\\b${intrinsic})\\s*=>`, "i").test(testText)
|
|
434
|
+
|| new RegExp(`\\b${intrinsic}\\b(?:\\s*\\.\\s*[a-z_$][a-z0-9_$]*)?\\s*(?:=(?!=|>)|\\+\\+|--|[+*/%&|^-]=)`, "i").test(testText)) return undefined;
|
|
435
|
+
for (const match of testText.matchAll(/\b(?:date|number)\b/gi)) {
|
|
436
|
+
const before = testText.slice(0, match.index), after = testText.slice(match.index + match[0].length);
|
|
437
|
+
if (match[0].toLowerCase() === "date" && /\bnew\s*$/.test(before) && /^\s*\(/.test(after)) continue;
|
|
438
|
+
if (/^\s*\.\s*(?:parse|now|utc|isfinite|isnan|isinteger|issafeinteger)\s*\(/i.test(after)) continue;
|
|
439
|
+
if (/^\s*\.\s*(?:nan|(?:positive_|negative_)?infinity)\b(?!\s*(?:\[|\.|=|\+\+|--))/i.test(after)) continue;
|
|
440
|
+
return undefined;
|
|
441
|
+
}
|
|
442
|
+
return values;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function tupleTargetImportsAreStable(testText, callableNames) {
|
|
446
|
+
const imports = [...testText.matchAll(/\bimport\s+([^;]{1,800}?)\s+from\s+__pi_[a-z0-9_]+__\s*;?/gi)];
|
|
447
|
+
return [...callableNames].every((name) => {
|
|
448
|
+
const root = name.split(".")[0];
|
|
449
|
+
if (!/^[a-z_$][a-z0-9_$]*$/i.test(root)) return false;
|
|
450
|
+
const matches = imports.filter((item) => new RegExp(`\\b${escapeRegex(root)}\\b`, "i").test(item[1]));
|
|
451
|
+
const bindings = matches.map((item) => ({ name: root, start: item.index, end: item.index + item[0].length }));
|
|
452
|
+
return bindings.length === 1 && importedCallableBindingIsStable(testText, bindings[0], bindings);
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function tupleExpectedErrorClasses(assertion) {
|
|
457
|
+
const invocation = assertion.match(/^[a-z_$][a-z0-9_$]*\.(?:throws|rejects)\s*\(/i);
|
|
458
|
+
if (!invocation) return undefined;
|
|
459
|
+
const open = invocation[0].length - 1, end = balancedEnd(assertion, open);
|
|
460
|
+
if (end !== assertion.length) return undefined;
|
|
461
|
+
const args = topLevelArgumentRanges(assertion, open, end).map((item) => item.text);
|
|
462
|
+
if (args.length !== 2 && args.length !== 3) return undefined;
|
|
463
|
+
if (args.length === 3 && !/^__pi_(?:[a-z0-9_]*string|error_name_[a-z]+)_literal__$/.test(args[2])) return undefined;
|
|
464
|
+
const expected = ERROR_CONSTRUCTORS.find((name) => args[1] === name
|
|
465
|
+
|| new RegExp(`^\\{\\s*name\\s*:\\s*__pi_error_name_${name}_literal__\\s*,?\\s*\\}$`).test(args[1]));
|
|
466
|
+
return expected ? [expected] : undefined;
|
|
467
|
+
}
|
|
468
|
+
|
|
225
469
|
function assertionHelperDeclarations(testText) {
|
|
226
470
|
const declarations = [];
|
|
227
471
|
for (const match of testText.matchAll(/\bfunction\s+([a-z_$][a-z0-9_$]*)\s*\(([^)]*)\)\s*\{/gi)) {
|
|
@@ -265,57 +509,82 @@ function rejectionAssertionHelpers(testText, assertionCarriers) {
|
|
|
265
509
|
function registrationArgumentsEnabled(argumentsList) {
|
|
266
510
|
if (argumentsList.length <= 2) return true;
|
|
267
511
|
if (argumentsList.length !== 3 || !/^\{[\s\S]{0,800}\}$/.test(argumentsList[1].text)) return false;
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
return
|
|
512
|
+
const options = argumentsList[1].text;
|
|
513
|
+
if (/\.\.\.|\[[^\]]+\]\s*:|__pi_(?:bound_string_\d+__|string_literal__)\s*:/.test(options)) return false;
|
|
514
|
+
const withoutDisabledFlags = options.replace(/\b(?:skip|todo)\s*:\s*false\b/g, "");
|
|
515
|
+
return !/\b(?:skip|todo)\b/.test(withoutDisabledFlags);
|
|
272
516
|
}
|
|
273
517
|
|
|
274
518
|
function callbackBodyRange(text, argument) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
519
|
+
let expressionStart = argument.start, expressionEnd = argument.end;
|
|
520
|
+
while (/\s/.test(text[expressionStart] ?? "")) expressionStart += 1;
|
|
521
|
+
while (/\s/.test(text[expressionEnd - 1] ?? "")) expressionEnd -= 1;
|
|
522
|
+
while (text[expressionStart] === "(" && balancedEnd(text, expressionStart) === expressionEnd) {
|
|
523
|
+
expressionStart += 1; expressionEnd -= 1;
|
|
524
|
+
while (/\s/.test(text[expressionStart] ?? "")) expressionStart += 1;
|
|
525
|
+
while (/\s/.test(text[expressionEnd - 1] ?? "")) expressionEnd -= 1;
|
|
526
|
+
}
|
|
527
|
+
const value = text.slice(expressionStart, expressionEnd);
|
|
528
|
+
const arrow = value.match(/^(?:async\s+)?(?:\([^)]*\)|[a-z_$][a-z0-9_$]*)\s*=>\s*/i);
|
|
529
|
+
const callable = arrow ?? value.match(/^(?:async\s+)?function(?:\s+[a-z_$][a-z0-9_$]*)?\s*\([^)]*\)\s*/i);
|
|
530
|
+
if (!callable) return undefined;
|
|
531
|
+
let bodyStart = expressionStart + callable[0].length;
|
|
280
532
|
while (/\s/.test(text[bodyStart] ?? "")) bodyStart += 1;
|
|
281
|
-
if (text[bodyStart] !== "{") return arrow
|
|
533
|
+
if (text[bodyStart] !== "{") return arrow ? { start: bodyStart, end: expressionEnd, braced: false } : undefined;
|
|
282
534
|
const end = balancedEnd(text, bodyStart, "{", "}");
|
|
283
|
-
return end
|
|
535
|
+
return end !== expressionEnd ? undefined : { start: bodyStart + 1, end: end - 1, braced: true };
|
|
284
536
|
}
|
|
285
537
|
|
|
286
|
-
export function executableRejectionAssertions(testText, callableNames, modeHintsOnly = false
|
|
538
|
+
export function executableRejectionAssertions(testText, callableNames, modeHintsOnly = false, includeSuccess = false,
|
|
539
|
+
literalIterationEnvironmentStable = true) {
|
|
287
540
|
const assertions = [];
|
|
288
541
|
const carrierBindings = assertionCarrierBindings(testText);
|
|
289
542
|
const assertionCarriers = new Set((assertionEvidenceFileSupported(testText)
|
|
290
543
|
&& carrierBindings.length === 1 && nodeAssertModuleReferenceCount(testText) === 1 ? carrierBindings : [])
|
|
291
544
|
.filter((binding) => assertionCarrierIsStable(testText, binding))
|
|
292
545
|
.map((binding) => binding.name));
|
|
546
|
+
const runnerBindings = testRunnerBindings(testText);
|
|
547
|
+
const liveRunnerBindings = new Map(runnerBindings
|
|
548
|
+
.filter((binding) => importedCallableBindingIsStable(testText, binding, runnerBindings))
|
|
549
|
+
.map((binding) => [binding.name, binding.kind]));
|
|
550
|
+
const literalIterationStable = literalIterationEnvironmentStable
|
|
551
|
+
&& literalArrayIterationEnvironmentIsStable(testText);
|
|
552
|
+
const registrationNames = (kind, fallbacks) => uniqueStrings([
|
|
553
|
+
...fallbacks, ...runnerBindings.filter((binding) => binding.kind === kind).map((binding) => binding.name)
|
|
554
|
+
]);
|
|
555
|
+
const registrationPattern = (names, suffix) => new RegExp(
|
|
556
|
+
`\\b(${names.map(escapeRegex).join("|")})${suffix}\\s*\\(`, "gi"
|
|
557
|
+
);
|
|
558
|
+
const suiteNames = registrationNames("suite", ["context", "describe", "suite"]);
|
|
559
|
+
const testNames = registrationNames("test", ["it", "specify", "test"]);
|
|
293
560
|
const declarationRanges = assertionHelperDeclarations(testText).map(({ start, end }) => ({ start, end }));
|
|
294
561
|
const skippedRanges = [];
|
|
295
562
|
const suiteRanges = [];
|
|
296
563
|
const registeredRanges = [];
|
|
297
|
-
for (const match of testText.matchAll(
|
|
564
|
+
for (const match of testText.matchAll(registrationPattern([...suiteNames, ...testNames], "\\.(?:skip|todo)"))) {
|
|
298
565
|
const open = testText.indexOf("(", match.index);
|
|
299
566
|
const end = balancedEnd(testText, open);
|
|
300
567
|
if (end !== -1) skippedRanges.push({ start: match.index, end });
|
|
301
568
|
}
|
|
302
|
-
for (const match of testText.matchAll(
|
|
569
|
+
for (const match of testText.matchAll(registrationPattern(suiteNames, "(?:\\.only)?"))) {
|
|
303
570
|
const open = testText.indexOf("(", match.index);
|
|
304
571
|
const end = balancedEnd(testText, open);
|
|
305
572
|
if (end === -1) continue;
|
|
306
573
|
const argumentsList = topLevelArgumentRanges(testText, open, end);
|
|
307
574
|
const callback = callbackBodyRange(testText, argumentsList.at(-1));
|
|
308
|
-
if (
|
|
309
|
-
|
|
575
|
+
if (liveRunnerBindings.get(match[1].toLowerCase()) !== "suite"
|
|
576
|
+
|| !registrationArgumentsEnabled(argumentsList) || !callback) skippedRanges.push({ start: match.index, end });
|
|
577
|
+
else suiteRanges.push({ ...callback, callStart: match.index, tupleCallbackClosed: tupleRegistrationIsClosed(argumentsList) });
|
|
310
578
|
}
|
|
311
|
-
for (const match of testText.matchAll(
|
|
579
|
+
for (const match of testText.matchAll(registrationPattern(testNames, "(?:\\.(?:concurrent|only))?"))) {
|
|
312
580
|
const open = testText.indexOf("(", match.index);
|
|
313
581
|
const end = balancedEnd(testText, open);
|
|
314
582
|
if (end === -1) continue;
|
|
315
583
|
const argumentsList = topLevelArgumentRanges(testText, open, end);
|
|
316
584
|
const callback = callbackBodyRange(testText, argumentsList.at(-1));
|
|
317
|
-
if (
|
|
318
|
-
|
|
585
|
+
if (liveRunnerBindings.get(match[1].toLowerCase()) !== "test"
|
|
586
|
+
|| !registrationArgumentsEnabled(argumentsList) || !callback) skippedRanges.push({ start: match.index, end });
|
|
587
|
+
else registeredRanges.push({ ...callback, callStart: match.index, tupleCallbackClosed: tupleRegistrationIsClosed(argumentsList) });
|
|
319
588
|
}
|
|
320
589
|
const bracedDepthAt = (offset) => {
|
|
321
590
|
let depth = 0;
|
|
@@ -335,16 +604,8 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
335
604
|
const topLevelCall = (start) => {
|
|
336
605
|
if (bracedDepthAt(start) !== 0) return false;
|
|
337
606
|
const prefix = testText.slice(Math.max(testText.lastIndexOf(";", start - 1) + 1, 0), start);
|
|
338
|
-
return !/=>|\bfunction\b
|
|
607
|
+
return !/=>|\bfunction\b|\?|&&|\|\|/.test(prefix);
|
|
339
608
|
};
|
|
340
|
-
const liveSuites = [];
|
|
341
|
-
for (const suite of suiteRanges) {
|
|
342
|
-
if (topLevelCall(suite.callStart) || liveSuites.some((range) => rangeDirectlyContains(range, suite.callStart))) liveSuites.push(suite);
|
|
343
|
-
}
|
|
344
|
-
suiteRanges.splice(0, suiteRanges.length, ...liveSuites);
|
|
345
|
-
const liveRegistrations = registeredRanges.filter((range) => topLevelCall(range.callStart)
|
|
346
|
-
|| suiteRanges.some((suite) => rangeDirectlyContains(suite, range.callStart)));
|
|
347
|
-
registeredRanges.splice(0, registeredRanges.length, ...liveRegistrations);
|
|
348
609
|
const statementRange = (start) => {
|
|
349
610
|
let bodyStart = start;
|
|
350
611
|
while (/\s/.test(testText[bodyStart] ?? "")) bodyStart += 1;
|
|
@@ -352,6 +613,53 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
352
613
|
const semicolon = testText.indexOf(";", bodyStart);
|
|
353
614
|
return { start: bodyStart, end: semicolon === -1 ? testText.length : semicolon + 1 };
|
|
354
615
|
};
|
|
616
|
+
const statementAbruptlyExits = (raw) => {
|
|
617
|
+
let body = String(raw ?? "").trim();
|
|
618
|
+
if (body.startsWith("{") && balancedEnd(body, 0, "{", "}") === body.length) body = body.slice(1, -1).trim();
|
|
619
|
+
return /^(?:(?:break|continue)\s*;?|return(?:[ \t]+[^;{}\r\n]*)?\s*;?|throw\s+[^;{}]+\s*;?|process\.exit\s*\([^;{}]*\)\s*;?)$/.test(body);
|
|
620
|
+
};
|
|
621
|
+
const directStatementAtDepth = (containerStart, offset, baseDepth) => {
|
|
622
|
+
let boundary = containerStart, braces = baseDepth, brackets = 0, parentheses = 0;
|
|
623
|
+
for (let index = containerStart; index < offset; index += 1) {
|
|
624
|
+
const character = testText[index];
|
|
625
|
+
if (character === "{") braces += 1;
|
|
626
|
+
else if (character === "}") { braces = Math.max(0, braces - 1); if (braces === baseDepth) boundary = index + 1; }
|
|
627
|
+
else if (braces === baseDepth && character === "[") brackets += 1;
|
|
628
|
+
else if (braces === baseDepth && character === "]") brackets -= 1;
|
|
629
|
+
else if (braces === baseDepth && character === "(") parentheses += 1;
|
|
630
|
+
else if (braces === baseDepth && character === ")") parentheses -= 1;
|
|
631
|
+
else if (braces === baseDepth && !brackets && !parentheses && character === ";") boundary = index + 1;
|
|
632
|
+
}
|
|
633
|
+
return !testText.slice(boundary, offset).trim();
|
|
634
|
+
};
|
|
635
|
+
const abruptBefore = (containerStart, start, baseDepth) => {
|
|
636
|
+
const prefix = testText.slice(containerStart, start);
|
|
637
|
+
for (const match of prefix.matchAll(/\b(?:break|continue|return|throw)\b|\bprocess\s*\.\s*exit\s*\(/g)) {
|
|
638
|
+
const absolute = containerStart + match.index;
|
|
639
|
+
if (bracedDepthAt(absolute) === baseDepth && directStatementAtDepth(containerStart, absolute, baseDepth)) return true;
|
|
640
|
+
}
|
|
641
|
+
for (const match of prefix.matchAll(/\bif\s*\(/g)) {
|
|
642
|
+
const absolute = containerStart + match.index;
|
|
643
|
+
if (bracedDepthAt(absolute) !== baseDepth || !directStatementAtDepth(containerStart, absolute, baseDepth)) continue;
|
|
644
|
+
const open = testText.indexOf("(", absolute), conditionEnd = balancedEnd(testText, open);
|
|
645
|
+
if (conditionEnd === -1 || conditionEnd > start
|
|
646
|
+
|| simpleConstantValue(testText.slice(open + 1, conditionEnd - 1)) === false) continue;
|
|
647
|
+
const consequent = statementRange(conditionEnd);
|
|
648
|
+
if (consequent.end !== -1 && consequent.end <= start
|
|
649
|
+
&& statementAbruptlyExits(testText.slice(consequent.start, consequent.end))) return true;
|
|
650
|
+
}
|
|
651
|
+
return false;
|
|
652
|
+
};
|
|
653
|
+
const topLevelAbruptBefore = (start) => abruptBefore(0, start, 0);
|
|
654
|
+
const liveSuites = [];
|
|
655
|
+
for (const suite of suiteRanges) {
|
|
656
|
+
if (!topLevelAbruptBefore(suite.callStart)
|
|
657
|
+
&& (topLevelCall(suite.callStart) || liveSuites.some((range) => rangeDirectlyContains(range, suite.callStart)))) liveSuites.push(suite);
|
|
658
|
+
}
|
|
659
|
+
suiteRanges.splice(0, suiteRanges.length, ...liveSuites);
|
|
660
|
+
const liveRegistrations = registeredRanges.filter((range) => !topLevelAbruptBefore(range.callStart)
|
|
661
|
+
&& (topLevelCall(range.callStart) || suiteRanges.some((suite) => rangeDirectlyContains(suite, range.callStart))));
|
|
662
|
+
registeredRanges.splice(0, registeredRanges.length, ...liveRegistrations);
|
|
355
663
|
const conditionalRanges = [];
|
|
356
664
|
for (const match of testText.matchAll(/\bif\s*\(/g)) {
|
|
357
665
|
const open = testText.indexOf("(", match.index);
|
|
@@ -369,16 +677,35 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
369
677
|
}
|
|
370
678
|
const triviallyDisabled = (start) => {
|
|
371
679
|
const prefix = testText.slice(Math.max(0, start - 600), start);
|
|
372
|
-
if (prefix.match(/(?:^|[;{])\s*(?:\(([^()]{1,160})\)|([^;{}()]{1,160}))\s
|
|
680
|
+
if (prefix.match(/(?:^|[;{])\s*(?:\(([^()]{1,160})\)|([^;{}()]{1,160}))\s*(?:&&|\|\|)[\s\S]{0,400}$/)) return true;
|
|
373
681
|
return Boolean(prefix.match(/(?:^|[;{])\s*(?:\(([^()]{1,160})\)|([^;{}()]{1,160}))\s*\?[\s\S]{0,400}$/));
|
|
374
682
|
};
|
|
375
683
|
const directlyInside = rangeDirectlyContains;
|
|
684
|
+
const transparentTryRanges = [];
|
|
376
685
|
const directBaseContext = (start) => {
|
|
377
|
-
if (registeredRanges.some((range) => directlyInside(range, start))) return true;
|
|
686
|
+
if ([...registeredRanges, ...transparentTryRanges].some((range) => directlyInside(range, start))) return true;
|
|
378
687
|
if (bracedDepthAt(start) !== 0) return false;
|
|
379
688
|
const prefix = testText.slice(Math.max(testText.lastIndexOf(";", start - 1) + 1, 0), start);
|
|
380
689
|
return !/=>|\bfunction\b/.test(prefix);
|
|
381
690
|
};
|
|
691
|
+
// A catch-free try with a restoration-only finally cannot turn a failed
|
|
692
|
+
// assertion into success. Keep the body in the same live registration;
|
|
693
|
+
// catches, abrupt finalizers and uncalled/nested conditional blocks abstain.
|
|
694
|
+
for (const match of testText.matchAll(/\btry\s*\{/g)) {
|
|
695
|
+
if (!directBaseContext(match.index) || triviallyDisabled(match.index)
|
|
696
|
+
|| [...declarationRanges, ...skippedRanges, ...conditionalRanges].some(range => match.index >= range.start && match.index < range.end)) continue;
|
|
697
|
+
const parent = [...registeredRanges, ...transparentTryRanges].filter(range => directlyInside(range, match.index)).at(-1);
|
|
698
|
+
if (abruptBefore(parent?.start ?? 0, match.index, bracedDepthAt(parent?.start ?? 0))) continue;
|
|
699
|
+
const open = testText.indexOf("{", match.index), end = balancedEnd(testText, open, "{", "}");
|
|
700
|
+
if (end === -1) continue;
|
|
701
|
+
const finalizer = testText.slice(end).match(/^\s*finally\s*\{/);
|
|
702
|
+
if (!finalizer) continue;
|
|
703
|
+
const finalOpen = end + finalizer[0].lastIndexOf("{"), finalEnd = balancedEnd(testText, finalOpen, "{", "}");
|
|
704
|
+
if (finalEnd === -1) continue;
|
|
705
|
+
const cleanup = testText.slice(finalOpen + 1, finalEnd - 1);
|
|
706
|
+
if (!/^(?:\s*[a-z_$][a-z0-9_$]*(?:\s*\.\s*[a-z_$][a-z0-9_$]*)*\s*=\s*[a-z_$][a-z0-9_$]*\s*;)*\s*$/i.test(cleanup)) continue;
|
|
707
|
+
transparentTryRanges.push({ start: open + 1, end: end - 1, braced: true });
|
|
708
|
+
}
|
|
382
709
|
const structurallyConnected = (start) => directBaseContext(start)
|
|
383
710
|
&& ![...declarationRanges, ...skippedRanges, ...conditionalRanges].some((range) => start >= range.start && start < range.end)
|
|
384
711
|
&& !triviallyDisabled(start);
|
|
@@ -408,6 +735,24 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
408
735
|
};
|
|
409
736
|
const iterationRanges = [];
|
|
410
737
|
const unsupportedControlRanges = [];
|
|
738
|
+
const tupleAncestryIsClosed = (start) => {
|
|
739
|
+
const callbacks = [...suiteRanges, ...registeredRanges];
|
|
740
|
+
const ancestry = callbacks.filter((range) => start >= range.start && start < range.end).sort((a, b) => a.start - b.start);
|
|
741
|
+
if (ancestry.some((range) => !range.tupleCallbackClosed)) return false;
|
|
742
|
+
let parentStart = 0;
|
|
743
|
+
for (const child of [...ancestry, { callStart: start }]) {
|
|
744
|
+
const masked = callbacks.filter((range) => range.start >= parentStart && range.end <= child.callStart);
|
|
745
|
+
let prefix = testText.slice(parentStart, child.callStart);
|
|
746
|
+
for (const range of masked.sort((a, b) => b.start - a.start)) {
|
|
747
|
+
prefix = `${prefix.slice(0, range.start - parentStart)}${" ".repeat(range.end - range.start)}${prefix.slice(range.end - parentStart)}`;
|
|
748
|
+
}
|
|
749
|
+
if (/\b(?:return|throw|break|continue|if|switch|try|catch|finally|while|do|yield|await|with)\b/.test(prefix)
|
|
750
|
+
|| unsupportedControlRanges.some((range) => range.start >= parentStart && range.end <= child.callStart
|
|
751
|
+
&& !masked.some((callback) => range.start >= callback.start && range.end <= callback.end))) return false;
|
|
752
|
+
parentStart = child.start;
|
|
753
|
+
}
|
|
754
|
+
return true;
|
|
755
|
+
};
|
|
411
756
|
for (const match of testText.matchAll(/\bfor\s*\(/g)) {
|
|
412
757
|
if (!structurallyConnected(match.index)) continue;
|
|
413
758
|
const open = testText.indexOf("(", match.index);
|
|
@@ -418,8 +763,23 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
418
763
|
const header = testText.slice(open + 1, headerEnd - 1);
|
|
419
764
|
const iterationBody = testText[body.start] === "{" ? { start: body.start + 1, end: body.end - 1, braced: true } : { ...body, braced: false };
|
|
420
765
|
const forOf = header.match(/^\s*(?:const|let)\s+([a-z_$][a-z0-9_$]*)\s+of\s+([\s\S]+?)\s*$/i);
|
|
421
|
-
const iterable = forOf && iterationLiteral(forOf[2], match.index);
|
|
766
|
+
const iterable = forOf && literalIterationStable && iterationLiteral(forOf[2], match.index);
|
|
767
|
+
const tuple = header.match(/^\s*const\s+\[\s*([a-z_$][a-z0-9_$]*)\s*,\s*([a-z_$][a-z0-9_$]*)\s*,?\s*\]\s+of\s+([\s\S]+?)\s*$/i);
|
|
768
|
+
const tupleIterable = tuple && literalIterationStable && iterationLiteral(tuple[3], match.index);
|
|
769
|
+
const tupleRows = tupleIterable && constantTupleRows(tupleIterable.literal, testText);
|
|
770
|
+
const tupleVariables = tuple?.slice(1, 3);
|
|
771
|
+
const protectedNames = new Set([...ERROR_CONSTRUCTORS, "date", "number", "nan", "infinity", "undefined",
|
|
772
|
+
...assertionCarriers, ...liveRunnerBindings.keys(), ...[...callableNames].flatMap((name) => name.split("."))]);
|
|
773
|
+
const tupleBindingClosed = tupleIterable && (!tupleIterable.binding
|
|
774
|
+
|| [...testText.matchAll(new RegExp(`\\b${escapeRegex(tupleIterable.binding)}\\b`, "g"))].length === 2);
|
|
775
|
+
const tupleContainerStart = registrationAt(match.index)?.start ?? 0;
|
|
776
|
+
const tupleReachable = !abruptBefore(tupleContainerStart, match.index, bracedDepthAt(tupleContainerStart));
|
|
422
777
|
if (iterable) iterationRanges.push({ ...iterationBody, ...iterable, kind: "for-of", variable: forOf[1] });
|
|
778
|
+
else if (tupleRows && tupleBindingClosed && tupleReachable && tupleAncestryIsClosed(match.index)
|
|
779
|
+
&& tupleTargetImportsAreStable(testText, callableNames) && new Set(tupleVariables).size === 2
|
|
780
|
+
&& tupleVariables.every((name) => !protectedNames.has(name))) {
|
|
781
|
+
iterationRanges.push({ ...iterationBody, ...tupleIterable, kind: "for-of", tupleRows, tupleVariables });
|
|
782
|
+
}
|
|
423
783
|
else if (modeHintsOnly && forOf) iterationRanges.push({ ...iterationBody, kind: "for-of", variable: forOf[1] });
|
|
424
784
|
else unsupportedControlRanges.push(body);
|
|
425
785
|
}
|
|
@@ -436,7 +796,7 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
436
796
|
receiverStart = receiver ? receiverStart - receiver[1].length : -1;
|
|
437
797
|
}
|
|
438
798
|
const receiverText = receiverStart < 0 ? "" : testText.slice(receiverStart, match.index).trim();
|
|
439
|
-
const iterable = receiverStart < 0 ? undefined : iterationLiteral(receiverText, receiverStart);
|
|
799
|
+
const iterable = receiverStart < 0 || !literalIterationStable ? undefined : iterationLiteral(receiverText, receiverStart);
|
|
440
800
|
const argumentsList = topLevelArgumentRanges(testText, open, end);
|
|
441
801
|
const callback = callbackBodyRange(testText, argumentsList.at(-1));
|
|
442
802
|
const callbackText = argumentsList.at(-1)?.text ?? "";
|
|
@@ -450,11 +810,11 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
450
810
|
if (headerEnd !== -1) unsupportedControlRanges.push(statementRange(headerEnd));
|
|
451
811
|
}
|
|
452
812
|
const abruptlyUnreachable = (start) => {
|
|
453
|
-
const containers = [...registeredRanges, ...iterationRanges]
|
|
813
|
+
const containers = [...registeredRanges, ...transparentTryRanges, ...iterationRanges]
|
|
454
814
|
.filter((range) => start >= range.start && start < range.end)
|
|
455
815
|
.sort((left, right) => right.start - left.start);
|
|
456
|
-
|
|
457
|
-
|
|
816
|
+
return (containers.length > 0 ? containers : [{ start: 0 }])
|
|
817
|
+
.some(container => abruptBefore(container.start, start, bracedDepthAt(container.start)));
|
|
458
818
|
};
|
|
459
819
|
const iterationVariableIsLive = (range, start) => {
|
|
460
820
|
const escaped = escapeRegex(range.variable);
|
|
@@ -488,6 +848,34 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
488
848
|
const returnedConciseCallback = registeredRanges.some((range) => !range.braced && start === range.start);
|
|
489
849
|
if (!/^(?:await|return(?:\s+await)?)$/.test(promisePrefix) && !returnedConciseCallback) return;
|
|
490
850
|
}
|
|
851
|
+
const tupleIteration = containingIterations.find((range) => range.tupleRows);
|
|
852
|
+
if (tupleIteration) {
|
|
853
|
+
const tuplePrefix = testText.slice(tupleIteration.start, start).trim();
|
|
854
|
+
if (containingIterations.length !== 1 || !["throws", "rejects"].includes(mode)
|
|
855
|
+
|| tuplePrefix !== (mode === "rejects" ? "await" : "")
|
|
856
|
+
|| testText.slice(end, tupleIteration.end).replace(/;/g, "").trim()) return;
|
|
857
|
+
const callback = String(operation ?? "").trim();
|
|
858
|
+
const expectedErrors = tupleExpectedErrorClasses(assertion);
|
|
859
|
+
if (!expectedErrors) return;
|
|
860
|
+
if (mode === "throws" && /^async\b/.test(callback)) return;
|
|
861
|
+
const invocation = callback.match(/^(?:async\s+)?\(\s*\)\s*=>\s*([a-z_$][a-z0-9_$.]*)\s*\(/i);
|
|
862
|
+
const open = invocation ? callback.indexOf("(", invocation[0].length - 1) : -1;
|
|
863
|
+
const callEnd = open < 0 ? -1 : balancedEnd(callback, open);
|
|
864
|
+
const argumentsList = callEnd === callback.length ? topLevelArgumentRanges(callback, open, callEnd).map((item) => item.text) : [];
|
|
865
|
+
if (argumentsList.length !== 2 || new Set(argumentsList).size !== 2
|
|
866
|
+
|| argumentsList.some((argument) => !tupleIteration.tupleVariables.includes(argument))) return;
|
|
867
|
+
const targets = operationTargets(operation, callableNames);
|
|
868
|
+
if (targets.length !== 1) return;
|
|
869
|
+
// Expand each closed row independently. Values never migrate between
|
|
870
|
+
// argument positions or assertions with different expected error classes.
|
|
871
|
+
for (const row of tupleIteration.tupleRows) {
|
|
872
|
+
const values = argumentsList.map((argument) => row[tupleIteration.tupleVariables.indexOf(argument)]);
|
|
873
|
+
const expanded = `${callback.slice(0, open + 1)}${values.join(", ")})`;
|
|
874
|
+
assertions.push({ targets, errorClasses: expectedErrors, partitions: evidencePartitionSignals(expanded), mode, operation: expanded,
|
|
875
|
+
iterationLiterals: [], iterationVariables: [], iterationBindings: [] });
|
|
876
|
+
}
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
491
879
|
const referencedIterations = containingIterations.filter((range) => (
|
|
492
880
|
new RegExp(`\\b${escapeRegex(range.variable)}\\b`, "i").test(assertion)
|
|
493
881
|
));
|
|
@@ -498,7 +886,13 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
498
886
|
for (const range of referencedIterations) {
|
|
499
887
|
if (range.literal) for (const signal of literalArrayPartitionSignals(range.literal)) partitions.add(signal);
|
|
500
888
|
}
|
|
501
|
-
assertions.push({
|
|
889
|
+
assertions.push({
|
|
890
|
+
targets, errorClasses, partitions, mode, operation,
|
|
891
|
+
iterationLiterals: referencedIterations.map((range) => range.literal).filter(Boolean).slice(0, 8),
|
|
892
|
+
iterationVariables: referencedIterations.map((range) => range.variable).filter(Boolean).slice(0, 8),
|
|
893
|
+
iterationBindings: referencedIterations.map((range) => ({ variable: range.variable, literal: range.literal }))
|
|
894
|
+
.filter((item) => item.variable && item.literal).slice(0, 8)
|
|
895
|
+
});
|
|
502
896
|
};
|
|
503
897
|
for (const match of testText.matchAll(/\b([a-z_$][a-z0-9_$]*)\.(?:throws|rejects)\s*\(/gi)) {
|
|
504
898
|
if (!assertionCarriers.has(match[1].toLowerCase())) continue;
|
|
@@ -508,6 +902,14 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
508
902
|
record(match.index, end, evidenceErrorClasses(end === -1 ? "" : testText.slice(match.index, end)), argumentsList[0]?.text,
|
|
509
903
|
/\.rejects\s*\(/i.test(match[0]) ? "rejects" : "throws");
|
|
510
904
|
}
|
|
905
|
+
if (includeSuccess) for (const match of testText.matchAll(/\b([a-z_$][a-z0-9_$]*)\.(doesnotthrow|deepequal|deepstrictequal|equal|strictequal|notequal|notstrictequal|ok)\s*\(/gi)) {
|
|
906
|
+
if (!assertionCarriers.has(match[1].toLowerCase())) continue;
|
|
907
|
+
const open = testText.indexOf("(", match.index);
|
|
908
|
+
const end = balancedEnd(testText, open);
|
|
909
|
+
const argumentsList = end === -1 ? [] : topLevelArgumentRanges(testText, open, end);
|
|
910
|
+
if (match[2].toLowerCase() !== "doesnotthrow" && /^(?:async\s*)?(?:function\b|(?:\([^)]*\)|[a-z_$][a-z0-9_$]*)\s*=>)/i.test(argumentsList[0]?.text ?? "")) continue;
|
|
911
|
+
record(match.index, end, [], argumentsList[0]?.text, "does-not-throw");
|
|
912
|
+
}
|
|
511
913
|
for (const helper of rejectionAssertionHelpers(testText, assertionCarriers)) {
|
|
512
914
|
for (const match of testText.matchAll(new RegExp(`\\b${escapeRegex(helper.name)}\\s*\\(`, "g"))) {
|
|
513
915
|
if (match.index >= helper.start && match.index < helper.end) continue;
|
|
@@ -530,5 +932,5 @@ export function executableRejectionAssertions(testText, callableNames, modeHints
|
|
|
530
932
|
record(match.index, end, evidenceErrorClasses(end === -1 ? "" : testText.slice(match.index, end)), argumentsList[0]?.text,
|
|
531
933
|
/\.rejects/i.test(chain[0]) ? "rejects" : "throws");
|
|
532
934
|
}
|
|
533
|
-
return assertions.slice(0, 64);
|
|
935
|
+
return annotateInvalidArgumentCoverage(assertions).slice(0, 64);
|
|
534
936
|
}
|