@piagent/platform 1.6.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -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/model-options.md +20 -15
- 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 +3 -0
- package/docs/quality-benchmark.md +128 -8
- package/docs/quickstart-vietnamese.md +2 -2
- package/docs/release-install-policy.md +38 -11
- 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 +23 -0
- package/docs-site/content/runtime.html +2 -2
- package/docs-site/content/whats-new.html +23 -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 +24 -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 +24 -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/model-route-policy.ts +33 -13
- package/packages/piagent-core/runtime/model/model-route-types.ts +10 -6
- 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-DMU7Xe_O.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/index-Cui9AAV_.js +176 -0
- package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
- 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 +14 -6
- 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/configure-model-scope.sh +6 -2
- package/scripts/fs4-readiness-evaluation.mjs +7 -1
- package/scripts/install-global.sh +2 -2
- package/scripts/model-route-evaluation-core.ts +1 -0
- package/scripts/phase-tools-evaluation.mjs +1 -0
- package/scripts/pi-auto.sh +7 -1
- package/scripts/pi-model-route.mjs +1 -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/setup.sh +2 -2
- package/scripts/typescript-loader.mjs +135 -1
- package/scripts/update-global.mjs +6 -7
- package/scripts/verify-local.sh +37 -56
- package/scripts/verify-release-identity.mjs +5 -3
- package/templates/global/settings.json +5 -1
- package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +0 -176
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
1
2
|
import fs from "node:fs";
|
|
2
3
|
import path from "node:path";
|
|
3
4
|
|
|
@@ -6,10 +7,272 @@ export const BUILT_IN_BENCHMARK_SUITE_IDS = Object.freeze([
|
|
|
6
7
|
"capability-v1",
|
|
7
8
|
"e2-framework-v1",
|
|
8
9
|
"deep-logic-v1",
|
|
9
|
-
"production-v1"
|
|
10
|
+
"production-v1",
|
|
11
|
+
"production-v2",
|
|
12
|
+
"production-v3"
|
|
10
13
|
]);
|
|
11
14
|
|
|
12
15
|
const reservedSuiteIds = new Set(BUILT_IN_BENCHMARK_SUITE_IDS);
|
|
16
|
+
const HASH = /^[a-f0-9]{64}$/;
|
|
17
|
+
const ID = /^[A-Za-z0-9][A-Za-z0-9:._~-]{0,159}$/;
|
|
18
|
+
const registrationPayloadFields = Object.freeze([
|
|
19
|
+
"suiteId", "baseSuiteId", "publicContractRevision", "admissionProtocol", "treatment",
|
|
20
|
+
"baseSuiteDigest", "caseListDigest", "unchangedSeedDigest", "evaluatorDigest",
|
|
21
|
+
"publicAssetsDigest", "publicContractDigest", "catalogDigest", "producerManifestDigest",
|
|
22
|
+
"nodeProfileDigest", "sharedEnvironmentDigest", "commonObserverDigest", "restrictedBrokerDigest",
|
|
23
|
+
"protocolDigest", "evaluatorCompatibilityDigest", "baselineCommit", "scenarioIds",
|
|
24
|
+
"promptRolesChanged", "matrix", "resources", "claims"
|
|
25
|
+
]);
|
|
26
|
+
const registrationDigestFields = Object.freeze(registrationPayloadFields.filter(name => name.endsWith("Digest")));
|
|
27
|
+
export const REGISTERED_BENCHMARK_PROMPT_ROLES = Object.freeze([
|
|
28
|
+
"revoked-session-cache", "backend-frontend-contract-sync", "workspace-order", "expiry-boundary",
|
|
29
|
+
"idempotent-replay-conflict", "reconnect-chat-event-order", "quoted-csv", "invoice-rounding",
|
|
30
|
+
"pagination-boundary", "schema-migration", "incident-diagnosis", "protected-env-refusal",
|
|
31
|
+
"repository-prompt-injection", "destructive-history-refusal"
|
|
32
|
+
]);
|
|
33
|
+
export const REGISTERED_BENCHMARK_VERIFIER_IDS = Object.freeze([
|
|
34
|
+
"bash-runtime", "broker-source-closure", "candidate-source", "common-runtime-closure",
|
|
35
|
+
"controlled-codex-feature-policy", "controlled-comparison-runtime", "custody-runner-wrapper",
|
|
36
|
+
"docker-runtime", "git-runtime", "node-runtime", "npm-runtime", "pi-runtime", "pi-sdk-tree", "scoped-route-proof",
|
|
37
|
+
"tool-definitions", "webui-asset-tree", "worker-image"
|
|
38
|
+
]);
|
|
39
|
+
const registeredStaticAssets = Object.freeze([
|
|
40
|
+
"catalog.json", "measurement/node-workload-api-v1.json", "measurement/shared-tool-policy-v1.json",
|
|
41
|
+
"measurement/assurance-rubrics.json", "measurement/calibration/incident-public-v1.json",
|
|
42
|
+
"measurement/calibration/config-document-public-v1.json", "measurement/calibration/refusal-public-v1.json"
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
function canonicalJson(value, seen = new Set()) {
|
|
46
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
|
|
47
|
+
if (typeof value === "number") {
|
|
48
|
+
if (!Number.isFinite(value)) throw new TypeError("registered measurement canonical JSON rejects non-finite numbers");
|
|
49
|
+
return JSON.stringify(value);
|
|
50
|
+
}
|
|
51
|
+
if (!value || typeof value !== "object") throw new TypeError("registered measurement canonical JSON rejects non-JSON values");
|
|
52
|
+
if (seen.has(value)) throw new TypeError("registered measurement canonical JSON rejects cycles");
|
|
53
|
+
seen.add(value);
|
|
54
|
+
const rendered = Array.isArray(value)
|
|
55
|
+
? `[${value.map(item => canonicalJson(item, seen)).join(",")}]`
|
|
56
|
+
: `{${Object.keys(value).sort().map(key => `${JSON.stringify(key)}:${canonicalJson(value[key], seen)}`).join(",")}}`;
|
|
57
|
+
seen.delete(value);
|
|
58
|
+
return rendered;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function exactKeys(value, names) {
|
|
62
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value)
|
|
63
|
+
&& Object.keys(value).length === names.length && names.every(name => Object.hasOwn(value, name)));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function sortedUniqueIds(values, count) {
|
|
67
|
+
return Array.isArray(values) && values.length === count && new Set(values).size === count
|
|
68
|
+
&& values.every(value => typeof value === "string" && ID.test(value));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function registeredBenchmarkMeasurementPayloadDigest(payload) {
|
|
72
|
+
return crypto.createHash("sha256").update(canonicalJson(payload)).digest("hex");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function registeredBenchmarkPublicAssetPaths(scenarioIds) {
|
|
76
|
+
if (!sortedUniqueIds(scenarioIds, 27)) throw new Error("Registered measurement asset inventory requires 27 scenario ids");
|
|
77
|
+
return Object.freeze([
|
|
78
|
+
...scenarioIds.map(id => `plans/${id}.json`),
|
|
79
|
+
...REGISTERED_BENCHMARK_PROMPT_ROLES.map(id => `measurement/prompts/${id}.md`),
|
|
80
|
+
...registeredStaticAssets
|
|
81
|
+
].sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right))));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function stableAsset(root, relativePath) {
|
|
85
|
+
const target = path.resolve(root, relativePath), relative = path.relative(root, target);
|
|
86
|
+
if (relative !== relativePath.split("/").join(path.sep) || relative === ".."
|
|
87
|
+
|| relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
|
|
88
|
+
throw new Error(`Registered measurement asset path escapes its root: ${relativePath}`);
|
|
89
|
+
}
|
|
90
|
+
const before = fs.lstatSync(target, { bigint: true });
|
|
91
|
+
if (!before.isFile() || before.isSymbolicLink() || before.nlink !== 1n || before.size > 2n * 1024n * 1024n) {
|
|
92
|
+
throw new Error(`Registered measurement asset must be one bounded regular file: ${relativePath}`);
|
|
93
|
+
}
|
|
94
|
+
const fd = fs.openSync(target, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
95
|
+
try {
|
|
96
|
+
const descriptor = fs.fstatSync(fd, { bigint: true }), bytes = fs.readFileSync(fd), after = fs.fstatSync(fd,
|
|
97
|
+
{ bigint: true }), current = fs.lstatSync(target, { bigint: true }),
|
|
98
|
+
fields = ["dev", "ino", "mode", "nlink", "size", "mtimeNs", "ctimeNs"];
|
|
99
|
+
if (bytes.length !== Number(before.size) || fields.some(name => before[name] !== descriptor[name]
|
|
100
|
+
|| before[name] !== after[name] || before[name] !== current[name])) {
|
|
101
|
+
throw new Error(`Registered measurement asset changed while read: ${relativePath}`);
|
|
102
|
+
}
|
|
103
|
+
return bytes;
|
|
104
|
+
} finally { fs.closeSync(fd); }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function inventoryDigest(entries) {
|
|
108
|
+
return crypto.createHash("sha256").update(canonicalJson(entries)).digest("hex");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function registeredBenchmarkPublicAssetInventory(root, scenarioIds) {
|
|
112
|
+
if (typeof root !== "string" || !path.isAbsolute(root) || fs.realpathSync(root) !== root
|
|
113
|
+
|| !fs.lstatSync(root).isDirectory()) throw new Error("Registered measurement asset root must be canonical");
|
|
114
|
+
const expected = registeredBenchmarkPublicAssetPaths(scenarioIds), allowed = new Set([
|
|
115
|
+
...expected, "measurement/registered-suite.json"
|
|
116
|
+
]), observed = [], pending = [root];
|
|
117
|
+
while (pending.length > 0) {
|
|
118
|
+
const directory = pending.pop();
|
|
119
|
+
for (const name of fs.readdirSync(directory)) {
|
|
120
|
+
const target = path.join(directory, name), info = fs.lstatSync(target), relative =
|
|
121
|
+
path.relative(root, target).split(path.sep).join("/");
|
|
122
|
+
if (info.isSymbolicLink()) throw new Error(`Registered measurement assets reject symlink: ${relative}`);
|
|
123
|
+
if (info.isDirectory()) pending.push(target);
|
|
124
|
+
else if (info.isFile()) observed.push(relative);
|
|
125
|
+
else throw new Error(`Registered measurement assets reject unsupported node: ${relative}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
observed.sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
|
|
129
|
+
if (observed.length !== allowed.size || observed.some(value => !allowed.has(value))) {
|
|
130
|
+
throw new Error("Registered measurement asset root must contain exactly the approved inventory and manifest");
|
|
131
|
+
}
|
|
132
|
+
const entries = expected.map(relativePath => {
|
|
133
|
+
const bytes = stableAsset(root, relativePath);
|
|
134
|
+
return Object.freeze({ path: relativePath, bytes: bytes.length,
|
|
135
|
+
sha256: crypto.createHash("sha256").update(bytes).digest("hex") });
|
|
136
|
+
});
|
|
137
|
+
const semanticPaths = new Set(expected.filter(value => value !== "measurement/node-workload-api-v1.json"
|
|
138
|
+
&& value !== "measurement/shared-tool-policy-v1.json"));
|
|
139
|
+
return deepFreeze({ version: "registered-public-asset-inventory-v1", entries,
|
|
140
|
+
publicAssetsDigest: inventoryDigest(entries),
|
|
141
|
+
publicContractDigest: inventoryDigest(entries.filter(value => semanticPaths.has(value.path))) });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function assertRegisteredBenchmarkPublicAssets(registration, root, scenarioIds) {
|
|
145
|
+
const inventory = registeredBenchmarkPublicAssetInventory(root, scenarioIds);
|
|
146
|
+
if (registration?.payload?.publicAssetsDigest !== inventory.publicAssetsDigest
|
|
147
|
+
|| registration?.payload?.publicContractDigest !== inventory.publicContractDigest) {
|
|
148
|
+
throw new Error("Registered measurement rejected: public asset inventory digest mismatch");
|
|
149
|
+
}
|
|
150
|
+
return inventory;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function registeredBenchmarkMeasurementValidationErrors(envelope, { scenarioIds } = {}) {
|
|
154
|
+
const errors = [];
|
|
155
|
+
if (!exactKeys(envelope, ["schemaVersion", "payload", "approvalRecordDigest"])) {
|
|
156
|
+
return ["envelope must contain exactly schemaVersion, payload and approvalRecordDigest"];
|
|
157
|
+
}
|
|
158
|
+
if (envelope.schemaVersion !== 1) errors.push("schemaVersion must be 1");
|
|
159
|
+
if (!HASH.test(String(envelope.approvalRecordDigest ?? ""))) errors.push("approvalRecordDigest must be lowercase sha256");
|
|
160
|
+
const payload = envelope.payload;
|
|
161
|
+
if (!exactKeys(payload, registrationPayloadFields)) {
|
|
162
|
+
errors.push("payload fields must match the registered measurement contract exactly");
|
|
163
|
+
return errors;
|
|
164
|
+
}
|
|
165
|
+
const constants = {
|
|
166
|
+
suiteId: "production-v2-da2", baseSuiteId: "production-v2",
|
|
167
|
+
publicContractRevision: "public-contract-addendum-v2",
|
|
168
|
+
admissionProtocol: "configured-public-108-v1", treatment: "configured-independent-v2",
|
|
169
|
+
baselineCommit: "05903656958fc78638779bf0a9e9b403f18992a2"
|
|
170
|
+
};
|
|
171
|
+
for (const [name, expected] of Object.entries(constants)) if (payload[name] !== expected) {
|
|
172
|
+
errors.push(`${name} must equal ${expected}`);
|
|
173
|
+
}
|
|
174
|
+
for (const name of registrationDigestFields) if (!HASH.test(String(payload[name] ?? ""))) {
|
|
175
|
+
errors.push(`${name} must be lowercase sha256`);
|
|
176
|
+
}
|
|
177
|
+
if (!sortedUniqueIds(payload.scenarioIds, 27)) errors.push("scenarioIds must contain 27 unique registered ids");
|
|
178
|
+
if (Array.isArray(scenarioIds) && JSON.stringify(payload.scenarioIds) !== JSON.stringify(scenarioIds)) {
|
|
179
|
+
errors.push("scenarioIds must equal the frozen base suite order");
|
|
180
|
+
}
|
|
181
|
+
if (JSON.stringify(payload.promptRolesChanged) !== JSON.stringify(REGISTERED_BENCHMARK_PROMPT_ROLES)) {
|
|
182
|
+
errors.push("promptRolesChanged must equal the approved 14-role order");
|
|
183
|
+
}
|
|
184
|
+
if (!exactKeys(payload.matrix, ["scenarioCount", "repeats", "surfaces", "sessionCount"])
|
|
185
|
+
|| payload.matrix.scenarioCount !== 27 || payload.matrix.repeats !== 2
|
|
186
|
+
|| JSON.stringify(payload.matrix.surfaces) !== JSON.stringify(["piagent", "codex-cli"])
|
|
187
|
+
|| payload.matrix.sessionCount !== 108) errors.push("matrix must equal the controlled complete108 matrix");
|
|
188
|
+
if (!exactKeys(payload.resources, ["model", "thinking", "requestedServiceTier", "concurrency",
|
|
189
|
+
"timeoutSeconds", "infrastructureRetries", "verifiers"])
|
|
190
|
+
|| payload.resources.model !== "openai-codex/gpt-5.6-luna" || payload.resources.thinking !== "medium"
|
|
191
|
+
|| payload.resources.requestedServiceTier !== "fast" || payload.resources.concurrency !== 1
|
|
192
|
+
|| payload.resources.timeoutSeconds !== 900 || payload.resources.infrastructureRetries !== 0
|
|
193
|
+
|| !Array.isArray(payload.resources.verifiers) || payload.resources.verifiers.length === 0
|
|
194
|
+
|| payload.resources.verifiers.length > 32) errors.push("resources must equal the approved provider limits and explicit verifiers");
|
|
195
|
+
else {
|
|
196
|
+
const ids = payload.resources.verifiers.map(value => value?.id);
|
|
197
|
+
if (JSON.stringify(ids) !== JSON.stringify(REGISTERED_BENCHMARK_VERIFIER_IDS)
|
|
198
|
+
|| payload.resources.verifiers.some(value => !exactKeys(value, ["id", "sha256"])
|
|
199
|
+
|| typeof value.id !== "string" || !ID.test(value.id) || !HASH.test(String(value.sha256 ?? "")))) {
|
|
200
|
+
errors.push("verifiers must equal the exact registered runtime and custody identity set");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (!exactKeys(payload.claims, ["efficiencyProtocol", "wireProtocol", "configuredTreatment",
|
|
204
|
+
"releaseDefaultsClaim"]) || payload.claims.efficiencyProtocol !== "net35-family-pooled-v1"
|
|
205
|
+
|| payload.claims.wireProtocol !== "phase-valid-configuration-v1"
|
|
206
|
+
|| payload.claims.configuredTreatment !== true || payload.claims.releaseDefaultsClaim !== false) {
|
|
207
|
+
errors.push("claims must equal the approved configured-treatment boundary");
|
|
208
|
+
}
|
|
209
|
+
return errors;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function stableJson(file, label) {
|
|
213
|
+
if (typeof file !== "string" || !path.isAbsolute(file) || path.normalize(file) !== file || file.includes("\0")) {
|
|
214
|
+
throw new Error(`${label} path must be canonical and absolute`);
|
|
215
|
+
}
|
|
216
|
+
const resolved = fs.realpathSync(file), before = fs.lstatSync(resolved, { bigint: true });
|
|
217
|
+
if (resolved !== file || !before.isFile() || before.isSymbolicLink() || before.nlink !== 1n
|
|
218
|
+
|| before.size < 2n || before.size > 2n * 1024n * 1024n
|
|
219
|
+
|| typeof process.getuid === "function" && before.uid !== BigInt(process.getuid())) {
|
|
220
|
+
throw new Error(`${label} must be one host-owned regular unlinked file`);
|
|
221
|
+
}
|
|
222
|
+
const fd = fs.openSync(file, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
|
|
223
|
+
try {
|
|
224
|
+
const descriptor = fs.fstatSync(fd, { bigint: true }), bytes = fs.readFileSync(fd),
|
|
225
|
+
after = fs.fstatSync(fd, { bigint: true }), current = fs.lstatSync(file, { bigint: true }),
|
|
226
|
+
fields = ["dev", "ino", "mode", "nlink", "size", "mtimeNs", "ctimeNs"];
|
|
227
|
+
if (bytes.length !== Number(before.size) || fields.some(name => before[name] !== descriptor[name]
|
|
228
|
+
|| before[name] !== after[name] || before[name] !== current[name])) throw new Error(`${label} changed while read`);
|
|
229
|
+
let value;
|
|
230
|
+
try { value = JSON.parse(bytes.toString("utf8")); }
|
|
231
|
+
catch (error) { throw new Error(`${label} is not valid JSON: ${error.message}`); }
|
|
232
|
+
return { bytes, value };
|
|
233
|
+
} finally { fs.closeSync(fd); }
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function deepFreeze(value) {
|
|
237
|
+
if (!value || typeof value !== "object" || Object.isFrozen(value)) return value;
|
|
238
|
+
for (const child of Object.values(value)) deepFreeze(child);
|
|
239
|
+
return Object.freeze(value);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function loadRegisteredBenchmarkMeasurement(file, { approvalFile, approvalPublicKey, scenarioIds } = {}) {
|
|
243
|
+
const manifest = stableJson(file, "registered measurement manifest"), errors =
|
|
244
|
+
registeredBenchmarkMeasurementValidationErrors(manifest.value, { scenarioIds });
|
|
245
|
+
if (errors.length > 0) throw new Error(`Registered measurement rejected: ${errors.join("; ")}`);
|
|
246
|
+
const approval = stableJson(approvalFile, "registered measurement approval"), approvalDigest =
|
|
247
|
+
crypto.createHash("sha256").update(approval.bytes).digest("hex");
|
|
248
|
+
if (approvalDigest !== manifest.value.approvalRecordDigest) {
|
|
249
|
+
throw new Error("Registered measurement rejected: detached approval digest mismatch");
|
|
250
|
+
}
|
|
251
|
+
if (!exactKeys(approval.value, ["schemaVersion", "kind", "approvalId", "authorityKeyId",
|
|
252
|
+
"payloadDigest", "signature"]) || approval.value.schemaVersion !== 1
|
|
253
|
+
|| approval.value.kind !== "benchmark-measurement-approval-v1" || !ID.test(String(approval.value.approvalId ?? ""))
|
|
254
|
+
|| !HASH.test(String(approval.value.authorityKeyId ?? "")) || !HASH.test(String(approval.value.payloadDigest ?? ""))
|
|
255
|
+
|| typeof approval.value.signature !== "string") {
|
|
256
|
+
throw new Error("Registered measurement rejected: detached approval record is invalid");
|
|
257
|
+
}
|
|
258
|
+
let key;
|
|
259
|
+
try { key = approvalPublicKey?.type === "public" ? approvalPublicKey : crypto.createPublicKey(approvalPublicKey); }
|
|
260
|
+
catch { throw new Error("Registered measurement rejected: trusted approval public key is invalid"); }
|
|
261
|
+
if (key?.asymmetricKeyType !== "ed25519") throw new Error("Registered measurement rejected: trusted approval key must be Ed25519");
|
|
262
|
+
const der = key.export({ type: "spki", format: "der" }), keyId = crypto.createHash("sha256").update(der).digest("hex"),
|
|
263
|
+
payloadDigest = registeredBenchmarkMeasurementPayloadDigest(manifest.value.payload);
|
|
264
|
+
let signature;
|
|
265
|
+
try { signature = Buffer.from(approval.value.signature, "base64"); }
|
|
266
|
+
catch { signature = Buffer.alloc(0); }
|
|
267
|
+
if (approval.value.authorityKeyId !== keyId || approval.value.payloadDigest !== payloadDigest
|
|
268
|
+
|| signature.length !== 64 || !crypto.verify(null, Buffer.from(payloadDigest), key, signature)) {
|
|
269
|
+
throw new Error("Registered measurement rejected: detached approval signature or payload binding is invalid");
|
|
270
|
+
}
|
|
271
|
+
return deepFreeze({ envelope: manifest.value, payload: manifest.value.payload, identity: {
|
|
272
|
+
manifestSha256: crypto.createHash("sha256").update(manifest.bytes).digest("hex"), payloadSha256: payloadDigest,
|
|
273
|
+
approvalRecordSha256: approvalDigest, approvalId: approval.value.approvalId, authorityKeyId: keyId
|
|
274
|
+
}, files: { manifest: file, approval: approvalFile } });
|
|
275
|
+
}
|
|
13
276
|
|
|
14
277
|
export function isReservedBenchmarkSuiteId(value) {
|
|
15
278
|
return reservedSuiteIds.has(value);
|
|
@@ -74,9 +74,13 @@ export function validateBenchmarkSuiteFiles(suite, suiteRoot) {
|
|
|
74
74
|
const generator = scenario.variantGenerator
|
|
75
75
|
? resolveBenchmarkSuiteEntry(suiteRoot, scenario.variantGenerator, "variant generator")
|
|
76
76
|
: null;
|
|
77
|
+
const journeyPrompts = (scenario.userJourney?.turns ?? []).map((turn) => (
|
|
78
|
+
resolveBenchmarkSuiteEntry(suiteRoot, turn.prompt, `journey prompt for ${scenario.id}/${turn.id}`)
|
|
79
|
+
));
|
|
77
80
|
assertBenchmarkModuleGraphBound(grader, suiteRoot, `${scenario.id} grader`);
|
|
78
81
|
if (generator) assertBenchmarkModuleGraphBound(generator, suiteRoot, `${scenario.id} variant generator`);
|
|
79
82
|
if (inside(fixture, grader) || inside(fixture, prompt)) fail(`Suite prompt and grader must stay outside the agent fixture: ${scenario.id}`);
|
|
83
|
+
if (journeyPrompts.some((journeyPrompt) => inside(fixture, journeyPrompt))) fail(`Suite journey prompts must stay outside the agent fixture: ${scenario.id}`);
|
|
80
84
|
if (generator && inside(fixture, generator)) fail(`Suite variant generator must stay outside the agent fixture: ${scenario.id}`);
|
|
81
85
|
}
|
|
82
86
|
}
|
|
@@ -3,13 +3,21 @@ import { benchmarkPricingSnapshotValidationErrors } from "./benchmark-normalized
|
|
|
3
3
|
|
|
4
4
|
const SUITE_FIELDS = new Set([
|
|
5
5
|
"schemaVersion", "id", "title", "description", "profile", "defaultRepeats", "timeoutSeconds",
|
|
6
|
-
"assurance", "releaseGate", "executionContract", "pricingSnapshot", "scenarios"
|
|
6
|
+
"assurance", "releaseGate", "executionContract", "pricingSnapshot", "matrixContract", "scenarios"
|
|
7
7
|
]);
|
|
8
8
|
const SCENARIO_FIELDS = new Set([
|
|
9
9
|
"id", "title", "description", "kind", "fixture", "prompt", "grader", "allowedChanges",
|
|
10
10
|
"setupFiles", "forbiddenOutputSubstrings", "requiredOutputSubstrings", "category", "difficulty",
|
|
11
|
-
"profile", "lifecycle", "variantGenerator"
|
|
11
|
+
"profile", "lifecycle", "variantGenerator", "familyId", "variantId", "variantRole", "userJourney"
|
|
12
12
|
]);
|
|
13
|
+
const MATRIX_CONTRACT_FIELDS = new Set([
|
|
14
|
+
"schemaVersion", "familyCount", "variantsPerFamily", "variantRoles", "surfaces",
|
|
15
|
+
"repeatsPerVariant", "expectedPairs", "expectedSessions", "confidenceSampleUnit"
|
|
16
|
+
]);
|
|
17
|
+
const USER_JOURNEY_FIELDS = new Set(["turns", "expectedTerminalSettlement"]);
|
|
18
|
+
const USER_JOURNEY_TURN_FIELDS = new Set(["id", "prompt", "workflow", "reconnectBefore", "receiptUncertain"]);
|
|
19
|
+
const MATRIX_VARIANT_ROLES = new Set(["boundary", "interaction", "adversarial-recovery"]);
|
|
20
|
+
const TERMINAL_SETTLEMENTS = new Set(["completed", "refused"]);
|
|
13
21
|
const RELEASE_GATE_FIELDS = new Set([
|
|
14
22
|
"minimumQualityScore", "minimumSafetyScore", "minimumReliabilityScore", "minimumWorkflowScore",
|
|
15
23
|
"minimumCategoryScore", "minimumOutcomeScoreExclusive", "minimumPairedScenarios", "minimumRepeats",
|
|
@@ -20,9 +28,11 @@ const RELEASE_GATE_FIELDS = new Set([
|
|
|
20
28
|
"maximumInfrastructureRetries", "primaryEfficiencyEstimand", "requireEfficiencyClaim", "requireFullSuiteForClaim",
|
|
21
29
|
"requireStableProviderWireSurface", "requireNormalizedCostClaim", "requireHostReadinessForClaim",
|
|
22
30
|
"requireCausalContextReceipt", "requireSubagentBudget", "maximumSubagentSessionsPerAttempt",
|
|
23
|
-
"maximumSubagentTrafficShare", "requireProviderFreeEvidence"
|
|
31
|
+
"maximumSubagentTrafficShare", "requireProviderFreeEvidence", "requireFastServiceTier",
|
|
32
|
+
"maximumAllAttemptPooledFreshTokenRatio", "requireCampaignAccounting", "efficiencyProtocol"
|
|
24
33
|
]);
|
|
25
|
-
const EXECUTION_CONTRACT_FIELDS = new Set(["surfaces", "model", "thinking", "codexMode"]);
|
|
34
|
+
const EXECUTION_CONTRACT_FIELDS = new Set(["surfaces", "model", "thinking", "codexMode", "codexBaseline", "serviceTier"]);
|
|
35
|
+
const SERVICE_TIERS = new Set(["default", "fast"]);
|
|
26
36
|
const THINKING_LEVELS = new Set(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
27
37
|
const SCENARIO_KINDS = new Set(["source-change", "read-only", "safety-refusal"]);
|
|
28
38
|
const SCENARIO_DIFFICULTIES = new Set(["small", "medium", "large"]);
|
|
@@ -76,6 +86,27 @@ export function benchmarkSuiteValidationErrors(input) {
|
|
|
76
86
|
for (const field of Object.keys(input.releaseGate)) {
|
|
77
87
|
if (!RELEASE_GATE_FIELDS.has(field)) errors.push(`releaseGate has unsupported field ${field}`);
|
|
78
88
|
}
|
|
89
|
+
// Opt-in measurement contract only. Approval belongs to the frozen run
|
|
90
|
+
// protocol; this marker neither changes legacy defaults nor grants claims.
|
|
91
|
+
if (input.releaseGate.efficiencyProtocol !== undefined) {
|
|
92
|
+
if (input.releaseGate.efficiencyProtocol !== "net35-family-pooled-v1") {
|
|
93
|
+
errors.push("releaseGate.efficiencyProtocol must be net35-family-pooled-v1");
|
|
94
|
+
}
|
|
95
|
+
if (input.schemaVersion !== 2) errors.push("releaseGate.efficiencyProtocol requires schemaVersion 2");
|
|
96
|
+
if (input.releaseGate.requireEfficiencyClaim !== true) {
|
|
97
|
+
errors.push("net35-family-pooled-v1 requires releaseGate.requireEfficiencyClaim true");
|
|
98
|
+
}
|
|
99
|
+
for (const field of ["maximumFreshTokenRatioUpper95", "maximumAllAttemptPooledFreshTokenRatio"]) {
|
|
100
|
+
if (input.releaseGate[field] !== 0.65) errors.push(`net35-family-pooled-v1 requires releaseGate.${field} exactly 0.65`);
|
|
101
|
+
}
|
|
102
|
+
if (input.releaseGate.primaryEfficiencyEstimand !== "fixed-workload-family-ratio") {
|
|
103
|
+
errors.push("net35-family-pooled-v1 requires releaseGate.primaryEfficiencyEstimand fixed-workload-family-ratio");
|
|
104
|
+
}
|
|
105
|
+
if (input.matrixContract?.familyCount !== 9 || input.matrixContract?.variantsPerFamily !== 3
|
|
106
|
+
|| input.matrixContract?.repeatsPerVariant !== 2 || input.matrixContract?.confidenceSampleUnit !== "task-family") {
|
|
107
|
+
errors.push("net35-family-pooled-v1 requires the 9-family, 3-variant, 2-repeat task-family matrixContract");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
79
110
|
for (const field of [
|
|
80
111
|
"minimumQualityScore", "minimumSafetyScore", "minimumReliabilityScore", "minimumWorkflowScore",
|
|
81
112
|
"minimumCategoryScore"
|
|
@@ -109,6 +140,13 @@ export function benchmarkSuiteValidationErrors(input) {
|
|
|
109
140
|
if (maximumRatio !== undefined && (!Number.isFinite(maximumRatio) || maximumRatio <= 0 || maximumRatio > 10)) {
|
|
110
141
|
errors.push("releaseGate.maximumFreshTokenRatioUpper95 must be greater than 0 and at most 10");
|
|
111
142
|
}
|
|
143
|
+
const maximumAllAttemptPooledFreshTokenRatio = input.releaseGate.maximumAllAttemptPooledFreshTokenRatio;
|
|
144
|
+
if (maximumAllAttemptPooledFreshTokenRatio !== undefined
|
|
145
|
+
&& (!Number.isFinite(maximumAllAttemptPooledFreshTokenRatio)
|
|
146
|
+
|| maximumAllAttemptPooledFreshTokenRatio <= 0
|
|
147
|
+
|| maximumAllAttemptPooledFreshTokenRatio > 10)) {
|
|
148
|
+
errors.push("releaseGate.maximumAllAttemptPooledFreshTokenRatio must be greater than 0 and at most 10");
|
|
149
|
+
}
|
|
112
150
|
const maximumBandRatio = input.releaseGate.maximumBandFreshTokenRatio;
|
|
113
151
|
if (maximumBandRatio !== undefined && (!Number.isFinite(maximumBandRatio) || maximumBandRatio <= 0 || maximumBandRatio > 10)) {
|
|
114
152
|
errors.push("releaseGate.maximumBandFreshTokenRatio must be greater than 0 and at most 10");
|
|
@@ -170,6 +208,12 @@ export function benchmarkSuiteValidationErrors(input) {
|
|
|
170
208
|
if (input.releaseGate.requireProviderFreeEvidence !== undefined && typeof input.releaseGate.requireProviderFreeEvidence !== "boolean") {
|
|
171
209
|
errors.push("releaseGate.requireProviderFreeEvidence must be a boolean");
|
|
172
210
|
}
|
|
211
|
+
if (input.releaseGate.requireFastServiceTier !== undefined && typeof input.releaseGate.requireFastServiceTier !== "boolean") {
|
|
212
|
+
errors.push("releaseGate.requireFastServiceTier must be a boolean");
|
|
213
|
+
}
|
|
214
|
+
if (input.releaseGate.requireCampaignAccounting !== undefined && typeof input.releaseGate.requireCampaignAccounting !== "boolean") {
|
|
215
|
+
errors.push("releaseGate.requireCampaignAccounting must be a boolean");
|
|
216
|
+
}
|
|
173
217
|
const maximumSubagentSessions = input.releaseGate.maximumSubagentSessionsPerAttempt;
|
|
174
218
|
if (maximumSubagentSessions !== undefined
|
|
175
219
|
&& (!Number.isSafeInteger(maximumSubagentSessions) || maximumSubagentSessions < 0 || maximumSubagentSessions > 10)) {
|
|
@@ -211,6 +255,50 @@ export function benchmarkSuiteValidationErrors(input) {
|
|
|
211
255
|
}
|
|
212
256
|
if (!THINKING_LEVELS.has(contract.thinking)) errors.push("executionContract.thinking is invalid");
|
|
213
257
|
if (contract.codexMode !== "controlled") errors.push("executionContract.codexMode must be controlled");
|
|
258
|
+
if (contract.codexBaseline !== undefined && !["stock", "controlled-custom"].includes(contract.codexBaseline)) {
|
|
259
|
+
errors.push("executionContract.codexBaseline must be stock or controlled-custom");
|
|
260
|
+
}
|
|
261
|
+
if (contract.serviceTier !== undefined && !SERVICE_TIERS.has(contract.serviceTier)) {
|
|
262
|
+
errors.push("executionContract.serviceTier must be default or fast");
|
|
263
|
+
}
|
|
264
|
+
if (input.releaseGate?.requireFastServiceTier === true && contract.serviceTier !== "fast") {
|
|
265
|
+
errors.push("executionContract.serviceTier must be fast when releaseGate.requireFastServiceTier is true");
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (input.matrixContract !== undefined) {
|
|
270
|
+
const matrix = input.matrixContract;
|
|
271
|
+
if (input.schemaVersion !== 2) errors.push("matrixContract requires suite schemaVersion 2");
|
|
272
|
+
if (!plainObject(matrix)) errors.push("matrixContract must be an object");
|
|
273
|
+
else {
|
|
274
|
+
for (const field of Object.keys(matrix)) {
|
|
275
|
+
if (!MATRIX_CONTRACT_FIELDS.has(field)) errors.push(`matrixContract has unsupported field ${field}`);
|
|
276
|
+
}
|
|
277
|
+
if (matrix.schemaVersion !== 1) errors.push("matrixContract.schemaVersion must be 1");
|
|
278
|
+
for (const [field, maximum] of [["familyCount", 50], ["variantsPerFamily", 10], ["repeatsPerVariant", 10], ["expectedPairs", 500], ["expectedSessions", 1_000]]) {
|
|
279
|
+
if (!Number.isSafeInteger(matrix[field]) || matrix[field] < 1 || matrix[field] > maximum) {
|
|
280
|
+
errors.push(`matrixContract.${field} must be between 1 and ${maximum}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (!Array.isArray(matrix.variantRoles)
|
|
284
|
+
|| matrix.variantRoles.length !== matrix.variantsPerFamily
|
|
285
|
+
|| new Set(matrix.variantRoles).size !== matrix.variantRoles.length
|
|
286
|
+
|| matrix.variantRoles.some((role) => !MATRIX_VARIANT_ROLES.has(role))) {
|
|
287
|
+
errors.push("matrixContract.variantRoles must contain one supported unique role per variant");
|
|
288
|
+
}
|
|
289
|
+
if (!Array.isArray(matrix.surfaces)
|
|
290
|
+
|| !plainObject(input.executionContract)
|
|
291
|
+
|| JSON.stringify(matrix.surfaces) !== JSON.stringify(input.executionContract.surfaces)) {
|
|
292
|
+
errors.push("matrixContract.surfaces must match executionContract.surfaces");
|
|
293
|
+
}
|
|
294
|
+
if (matrix.repeatsPerVariant !== input.defaultRepeats) {
|
|
295
|
+
errors.push("matrixContract.repeatsPerVariant must match defaultRepeats");
|
|
296
|
+
}
|
|
297
|
+
const expectedPairs = matrix.familyCount * matrix.variantsPerFamily * matrix.repeatsPerVariant;
|
|
298
|
+
const expectedSessions = expectedPairs * (Array.isArray(matrix.surfaces) ? matrix.surfaces.length : 0);
|
|
299
|
+
if (matrix.expectedPairs !== expectedPairs) errors.push("matrixContract.expectedPairs does not match the declared matrix");
|
|
300
|
+
if (matrix.expectedSessions !== expectedSessions) errors.push("matrixContract.expectedSessions does not match the declared matrix");
|
|
301
|
+
if (matrix.confidenceSampleUnit !== "task-family") errors.push("matrixContract.confidenceSampleUnit must be task-family");
|
|
214
302
|
}
|
|
215
303
|
}
|
|
216
304
|
if (input.schemaVersion === 2 && (!plainObject(input.assurance) || !plainObject(input.releaseGate))) {
|
|
@@ -223,6 +311,36 @@ export function benchmarkSuiteValidationErrors(input) {
|
|
|
223
311
|
&& (!Number.isFinite(input.releaseGate?.maximumFreshTokenRatioUpper95) || input.releaseGate.maximumFreshTokenRatioUpper95 > 0.8)) {
|
|
224
312
|
errors.push("schemaVersion 2 token-saving claims require releaseGate.maximumFreshTokenRatioUpper95 at or below 0.8");
|
|
225
313
|
}
|
|
314
|
+
if (input.schemaVersion === 2 && input.releaseGate?.requireEfficiencyClaim === true
|
|
315
|
+
&& input.releaseGate?.maximumAllAttemptPooledFreshTokenRatio !== undefined
|
|
316
|
+
&& input.releaseGate.maximumAllAttemptPooledFreshTokenRatio > 0.65) {
|
|
317
|
+
errors.push("schemaVersion 2 net-35 claims require releaseGate.maximumAllAttemptPooledFreshTokenRatio at or below 0.65");
|
|
318
|
+
}
|
|
319
|
+
if (input.id === "production-v2") {
|
|
320
|
+
if (input.executionContract?.serviceTier !== "fast") errors.push("production-v2 requires executionContract.serviceTier fast");
|
|
321
|
+
if (input.releaseGate?.requireFastServiceTier !== true) errors.push("production-v2 requires releaseGate.requireFastServiceTier true");
|
|
322
|
+
if (input.releaseGate?.requireCampaignAccounting !== true) errors.push("production-v2 requires releaseGate.requireCampaignAccounting true");
|
|
323
|
+
if (!Number.isFinite(input.releaseGate?.maximumAllAttemptPooledFreshTokenRatio)
|
|
324
|
+
|| input.releaseGate.maximumAllAttemptPooledFreshTokenRatio > 0.65) {
|
|
325
|
+
errors.push("production-v2 requires an all-attempt pooled fresh-token ratio at or below 0.65");
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (input.id === "production-v3") {
|
|
329
|
+
if (input.executionContract?.codexMode !== "controlled") {
|
|
330
|
+
errors.push("production-v3 requires executionContract.codexMode controlled");
|
|
331
|
+
}
|
|
332
|
+
if (input.executionContract?.codexBaseline !== "stock") {
|
|
333
|
+
errors.push("production-v3 requires executionContract.codexBaseline stock");
|
|
334
|
+
}
|
|
335
|
+
if (input.assurance?.claimTier !== "public-regression"
|
|
336
|
+
|| input.assurance?.familyDisjointSplit !== false) {
|
|
337
|
+
errors.push("production-v3 requires the public-regression non-family-disjoint claim boundary");
|
|
338
|
+
}
|
|
339
|
+
if (input.matrixContract?.familyCount !== 9 || input.matrixContract?.variantsPerFamily !== 3
|
|
340
|
+
|| input.matrixContract?.repeatsPerVariant !== 2 || input.matrixContract?.expectedSessions !== 108) {
|
|
341
|
+
errors.push("production-v3 requires the exact 9-family, 3-variant, 2-repeat, 2-surface matrix");
|
|
342
|
+
}
|
|
343
|
+
}
|
|
226
344
|
if (input.schemaVersion === 2 && input.releaseGate?.requireEfficiencyClaim === true && input.releaseGate?.requireFullSuiteForClaim !== true) {
|
|
227
345
|
errors.push("schemaVersion 2 token-saving claims require releaseGate.requireFullSuiteForClaim true");
|
|
228
346
|
}
|
|
@@ -254,6 +372,7 @@ export function benchmarkSuiteValidationErrors(input) {
|
|
|
254
372
|
}
|
|
255
373
|
|
|
256
374
|
const ids = new Set();
|
|
375
|
+
const matrixFamilies = new Map();
|
|
257
376
|
for (const [index, scenario] of input.scenarios.entries()) {
|
|
258
377
|
const label = `scenarios[${index}]`;
|
|
259
378
|
if (!plainObject(scenario)) {
|
|
@@ -310,6 +429,94 @@ export function benchmarkSuiteValidationErrors(input) {
|
|
|
310
429
|
!Array.isArray(scenario.requiredOutputSubstrings)
|
|
311
430
|
|| scenario.requiredOutputSubstrings.some((item) => typeof item !== "string" || !item)
|
|
312
431
|
)) errors.push(`${label}.requiredOutputSubstrings must contain non-empty strings`);
|
|
432
|
+
if (input.matrixContract === undefined
|
|
433
|
+
&& [scenario.familyId, scenario.variantId, scenario.variantRole, scenario.userJourney].some((value) => value !== undefined)) {
|
|
434
|
+
errors.push(`${label} matrix metadata requires matrixContract`);
|
|
435
|
+
}
|
|
436
|
+
if (plainObject(input.matrixContract)) {
|
|
437
|
+
requiredString(scenario.familyId, `${label}.familyId`, errors);
|
|
438
|
+
if (typeof scenario.familyId === "string" && !ID_PATTERN.test(scenario.familyId)) errors.push(`${label}.familyId must use lowercase kebab-case`);
|
|
439
|
+
requiredString(scenario.variantId, `${label}.variantId`, errors);
|
|
440
|
+
if (typeof scenario.variantId === "string" && !ID_PATTERN.test(scenario.variantId)) errors.push(`${label}.variantId must use lowercase kebab-case`);
|
|
441
|
+
if (!MATRIX_VARIANT_ROLES.has(scenario.variantRole)
|
|
442
|
+
|| !Array.isArray(input.matrixContract.variantRoles)
|
|
443
|
+
|| !input.matrixContract.variantRoles.includes(scenario.variantRole)) errors.push(`${label}.variantRole is invalid`);
|
|
444
|
+
if (!plainObject(scenario.userJourney)) errors.push(`${label}.userJourney must be an object`);
|
|
445
|
+
else {
|
|
446
|
+
for (const field of Object.keys(scenario.userJourney)) {
|
|
447
|
+
if (!USER_JOURNEY_FIELDS.has(field)) errors.push(`${label}.userJourney has unsupported field ${field}`);
|
|
448
|
+
}
|
|
449
|
+
const turns = scenario.userJourney.turns;
|
|
450
|
+
if (!Array.isArray(turns) || turns.length < 1 || turns.length > 10) errors.push(`${label}.userJourney.turns must contain between 1 and 10 turns`);
|
|
451
|
+
else {
|
|
452
|
+
const turnIds = new Set();
|
|
453
|
+
for (const [turnIndex, turn] of turns.entries()) {
|
|
454
|
+
const turnLabel = `${label}.userJourney.turns[${turnIndex}]`;
|
|
455
|
+
if (!plainObject(turn)) {
|
|
456
|
+
errors.push(`${turnLabel} must be an object`);
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
for (const field of Object.keys(turn)) {
|
|
460
|
+
if (!USER_JOURNEY_TURN_FIELDS.has(field)) errors.push(`${turnLabel} has unsupported field ${field}`);
|
|
461
|
+
}
|
|
462
|
+
requiredString(turn.id, `${turnLabel}.id`, errors);
|
|
463
|
+
if (typeof turn.id === "string" && !ID_PATTERN.test(turn.id)) errors.push(`${turnLabel}.id must use lowercase kebab-case`);
|
|
464
|
+
if (turnIds.has(turn.id)) errors.push(`${label}.userJourney has duplicate turn id ${turn.id}`);
|
|
465
|
+
turnIds.add(turn.id);
|
|
466
|
+
if (!safeRelativePath(turn.prompt)) errors.push(`${turnLabel}.prompt must stay inside the suite directory`);
|
|
467
|
+
if (turn.workflow !== undefined
|
|
468
|
+
&& (typeof turn.workflow !== "string" || !ID_PATTERN.test(turn.workflow) || turn.workflow.length > 64)) {
|
|
469
|
+
errors.push(`${turnLabel}.workflow must be a bounded lowercase kebab-case id`);
|
|
470
|
+
}
|
|
471
|
+
if (turn.reconnectBefore !== undefined && typeof turn.reconnectBefore !== "boolean") errors.push(`${turnLabel}.reconnectBefore must be a boolean`);
|
|
472
|
+
if (turn.receiptUncertain !== undefined && typeof turn.receiptUncertain !== "boolean") {
|
|
473
|
+
errors.push(`${turnLabel}.receiptUncertain must be a boolean`);
|
|
474
|
+
}
|
|
475
|
+
if (turn.receiptUncertain === true && (turnIndex === 0 || turn.reconnectBefore !== true)) {
|
|
476
|
+
errors.push(`${turnLabel}.receiptUncertain requires an existing-session turn with reconnectBefore`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (scenario.variantRole === "boundary" && (turns.length !== 1 || turns[0]?.id !== "request")) {
|
|
480
|
+
errors.push(`${label}.boundary journey must contain one request turn`);
|
|
481
|
+
}
|
|
482
|
+
if (scenario.variantRole === "interaction"
|
|
483
|
+
&& JSON.stringify(turns.map((turn) => turn?.id)) !== JSON.stringify(["scout", "implement", "verify"])) {
|
|
484
|
+
errors.push(`${label}.interaction journey must contain scout, implement, verify turns`);
|
|
485
|
+
}
|
|
486
|
+
if (scenario.variantRole === "adversarial-recovery"
|
|
487
|
+
&& (turns.length < 2 || !turns.slice(1).some((turn) => turn?.reconnectBefore === true))) {
|
|
488
|
+
errors.push(`${label}.adversarial-recovery journey must exercise reconnect recovery`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
if (!TERMINAL_SETTLEMENTS.has(scenario.userJourney.expectedTerminalSettlement)) {
|
|
492
|
+
errors.push(`${label}.userJourney.expectedTerminalSettlement is invalid`);
|
|
493
|
+
} else if (scenario.kind === "safety-refusal" && scenario.userJourney.expectedTerminalSettlement !== "refused") {
|
|
494
|
+
errors.push(`${label}.safety-refusal journey must settle as refused`);
|
|
495
|
+
} else if (scenario.kind !== "safety-refusal" && scenario.userJourney.expectedTerminalSettlement !== "completed") {
|
|
496
|
+
errors.push(`${label}.non-refusal journey must settle as completed`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
if (typeof scenario.familyId === "string" && typeof scenario.variantId === "string") {
|
|
500
|
+
const family = matrixFamilies.get(scenario.familyId) ?? { variants: new Set(), roles: new Set() };
|
|
501
|
+
if (family.variants.has(scenario.variantId)) errors.push(`duplicate matrix variant ${scenario.familyId}/${scenario.variantId}`);
|
|
502
|
+
family.variants.add(scenario.variantId);
|
|
503
|
+
if (typeof scenario.variantRole === "string") family.roles.add(scenario.variantRole);
|
|
504
|
+
matrixFamilies.set(scenario.familyId, family);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (plainObject(input.matrixContract)) {
|
|
509
|
+
if (matrixFamilies.size !== input.matrixContract.familyCount) errors.push("matrixContract.familyCount does not match scenarios");
|
|
510
|
+
for (const [familyId, family] of matrixFamilies) {
|
|
511
|
+
if (family.variants.size !== input.matrixContract.variantsPerFamily) errors.push(`matrix family ${familyId} must contain ${input.matrixContract.variantsPerFamily} variants`);
|
|
512
|
+
const expectedRoles = new Set(Array.isArray(input.matrixContract.variantRoles) ? input.matrixContract.variantRoles : []);
|
|
513
|
+
if (family.roles.size !== expectedRoles.size || [...expectedRoles].some((role) => !family.roles.has(role))) {
|
|
514
|
+
errors.push(`matrix family ${familyId} must contain every declared variant role`);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (input.scenarios.length !== input.matrixContract.familyCount * input.matrixContract.variantsPerFamily) {
|
|
518
|
+
errors.push("matrixContract scenario cardinality does not match scenarios");
|
|
519
|
+
}
|
|
313
520
|
}
|
|
314
521
|
return errors;
|
|
315
522
|
}
|
|
@@ -32,7 +32,7 @@ export const RELEASE_FAILURE_MESSAGES = Object.freeze({
|
|
|
32
32
|
"primary-efficiency": "The predeclared primary efficiency estimand lacks complete family/category evidence or its upper 95% ratio exceeds the suite limit.",
|
|
33
33
|
"codex-relative-efficiency": "The fixed-workload Piagent/Codex CLI comparison lacks exact parity or quality evidence, exceeds 0.70 total token traffic or API-equivalent cost at the point/upper-95 bound, or exceeds the subagent budget.",
|
|
34
34
|
"production-subagent-budget": "Production Piagent attempts lack exact child-session accounting, exceed one subagent per attempt, or spend more than 5% of candidate provider traffic on subagents.",
|
|
35
|
-
"provider-free-evidence": "The production run lacks same-source clean-commit runtime-conformance, long-horizon, or WebUI-parity evidence bound to exact lane configuration and runner bytes.",
|
|
35
|
+
"provider-free-evidence": "The production run lacks same-source clean-commit architecture, runtime-conformance, long-horizon, or WebUI-parity evidence bound to exact lane configuration and runner bytes.",
|
|
36
36
|
"adaptive-context-runtime-coverage": "At least one Piagent runtime receipt reports partial adaptive-context evidence, or not-observed evidence lacks a same-source provider-free coverage lane.",
|
|
37
37
|
"repeat-count": "The run used fewer repeats than the suite minimum.",
|
|
38
38
|
"efficiency-confidence": "The upper 95% token-ratio bound exceeds the suite limit.",
|
|
@@ -40,6 +40,8 @@ export const RELEASE_FAILURE_MESSAGES = Object.freeze({
|
|
|
40
40
|
"efficiency-family-ratio": "At least one comparable scenario family uses more fresh tokens than the suite family guardrail permits.",
|
|
41
41
|
"accepted-usage-completeness": "Every accepted benchmark attempt must have exact terminal token buckets.",
|
|
42
42
|
"all-attempt-usage-completeness": "Every accepted or failed provider attempt must have exact invariant-checked token buckets.",
|
|
43
|
+
"all-attempt-net-efficiency": "All accepted plus exact failed/retry fresh tokens must remain at or below the predeclared pooled Piagent/Codex CLI ratio.",
|
|
44
|
+
"fast-execution-configuration-parity": "Fast execution configuration must be verified on every run: exact Piagent outbound telemetry plus identity-bound effective Codex CLI thread settings; missing or default evidence blocks the claim.",
|
|
43
45
|
"normalized-cost-configuration": "Normalized-cost claims require a valid versioned pricing snapshot and all predeclared ratio thresholds.",
|
|
44
46
|
"normalized-cost-evidence": "Normalized API-equivalent text-token cost evidence is incomplete for at least one declared scenario family.",
|
|
45
47
|
"normalized-cost-pricing-applicability": "Exact usage or per-request pricing applicability is unavailable for at least one accepted run.",
|
|
@@ -54,7 +56,7 @@ export const RELEASE_FAILURE_MESSAGES = Object.freeze({
|
|
|
54
56
|
"infrastructure-retries": "Accepted benchmark runs used more recovered infrastructure retries than the suite permits.",
|
|
55
57
|
"infrastructure-failure-ledger": "Accepted benchmark runs do not contain an exact attempt/retry/failure ledger.",
|
|
56
58
|
"unknown-infrastructure-usage": "At least one provider-started infrastructure attempt has unknown terminal usage.",
|
|
57
|
-
"canonical-production-identity": "
|
|
59
|
+
"canonical-production-identity": "Production suite ids are reserved for their canonical built-in suite identities.",
|
|
58
60
|
"release-claim-configuration": "Token-saving claims require schema v2, an explicit upper-95 token ratio at or below 0.80, full-suite enforcement, and provider-wire stability evidence.",
|
|
59
61
|
"codex-baseline": "Token-saving product claims require controlled Codex CLI as the paired baseline.",
|
|
60
62
|
"clean-release-source": "Release claims require an exact clean Git commit; dirty or unbound source trees are diagnostic only.",
|
|
@@ -378,3 +380,29 @@ export function pairedQualityNoninferiorityEvidence({ suite, repeats, baselineRu
|
|
|
378
380
|
families
|
|
379
381
|
};
|
|
380
382
|
}
|
|
383
|
+
|
|
384
|
+
export function conditionalBothPassFreshUsage({ suite, repeats, allPairs, pairs, tokenPairs, baselineRuns, candidateRuns, allSuccessfulPairsFreshRatio }) {
|
|
385
|
+
return {
|
|
386
|
+
outcomeDefinition: "both-accepted-runs-resolved-including-safety-refusals",
|
|
387
|
+
usageDefinition: "exact-positive-fresh-same-model-and-thinking",
|
|
388
|
+
attemptScope: "accepted-attempts-only; all-attempt-costs-remain-in-tokenAccounting",
|
|
389
|
+
estimator: "geometric-mean-of-candidate-over-baseline-pair-ratios",
|
|
390
|
+
expectedPairs: suite.scenarios.length * repeats,
|
|
391
|
+
observedPairs: allPairs.length,
|
|
392
|
+
bothResolvedPairs: pairs.length,
|
|
393
|
+
eligiblePairs: tokenPairs.length,
|
|
394
|
+
excludedUnresolvedPairs: allPairs.length - pairs.length,
|
|
395
|
+
excludedUsagePairs: pairs.length - tokenPairs.length,
|
|
396
|
+
unpairedAcceptedRuns: baselineRuns.length + candidateRuns.length - 2 * allPairs.length,
|
|
397
|
+
ratio: rounded(allSuccessfulPairsFreshRatio, 4),
|
|
398
|
+
interpretation: "conditional-observation-only; not-overall-token-savings"
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export function benchmarkOutcomePairs(baselineRuns, candidateRuns) {
|
|
403
|
+
const baselineByKey = new Map(baselineRuns.map((run) => [`${run.scenarioId}:${run.repeat}`, run]));
|
|
404
|
+
const allPairs = candidateRuns
|
|
405
|
+
.map((run) => ({ baseline: baselineByKey.get(`${run.scenarioId}:${run.repeat}`), candidate: run }))
|
|
406
|
+
.filter((pair) => pair.baseline);
|
|
407
|
+
return allPairs;
|
|
408
|
+
}
|