@piagent/platform 1.5.5 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +166 -0
- package/README.md +25 -21
- package/README.vi.md +34 -5
- package/adapters/web-frontend/profile.json +2 -4
- package/architecture/layers.json +18 -3
- package/benchmarks/deep-logic-v1/SPECIALIST_PROTOCOL.vi.md +122 -0
- package/benchmarks/deep-logic-v1/grade.mjs +272 -10
- package/benchmarks/deep-logic-v1/project/apps/admin/src/billing-summary.js +3 -0
- package/benchmarks/deep-logic-v1/project/benchmark-contract/public-smoke.test.js +166 -0
- package/benchmarks/deep-logic-v1/project/package.json +1 -1
- package/benchmarks/deep-logic-v1/project/packages/billing/src/close-period.js +3 -0
- package/benchmarks/deep-logic-v1/project/packages/billing/src/plan-timeline.js +3 -0
- package/benchmarks/deep-logic-v1/project/test/smoke.test.js +7 -1
- package/benchmarks/deep-logic-v1/prompts/budgeted-context-graph.md +2 -0
- package/benchmarks/deep-logic-v1/prompts/fair-dependency-scheduler.md +2 -0
- package/benchmarks/deep-logic-v1/prompts/layered-policy-resolution.md +2 -0
- package/benchmarks/deep-logic-v1/prompts/resumable-stream-assembly.md +3 -1
- package/benchmarks/deep-logic-v1/prompts/revision-event-reconciliation.md +2 -0
- package/benchmarks/deep-logic-v1/prompts/temporal-usage-billing-close.md +123 -0
- package/benchmarks/deep-logic-v1/prompts/transactional-config-merge.md +2 -0
- package/benchmarks/deep-logic-v1/suite.json +51 -3
- package/benchmarks/deep-logic-v1/variant.mjs +22 -1
- package/benchmarks/production-v1/spend-control.v1.json +92 -0
- package/benchmarks/production-v1/suite.json +46 -3
- package/catalog/capabilities.json +18 -18
- package/docs/authority-manifest.md +1 -1
- package/docs/auto-delegation-policy.md +38 -73
- package/docs/command-reference-vietnamese.md +27 -35
- package/docs/context-engine.md +12 -4
- package/docs/context-window-policy.md +37 -1
- package/docs/distribution-standard.md +7 -7
- package/docs/en/architecture.md +27 -13
- package/docs/languages.json +4 -4
- package/docs/model-options.md +8 -5
- package/docs/operator-manual-vietnamese.md +27 -45
- package/docs/project-adapters.md +2 -2
- package/docs/publishing-for-teams.md +10 -0
- package/docs/quality-benchmark.md +427 -62
- package/docs/release-install-policy.md +10 -9
- package/docs/runtime-harness-standard.md +3 -3
- package/docs/runtime-policy-design.md +4 -4
- package/docs/runtime-quality-baseline.md +13 -6
- package/docs/security-threat-model.md +2 -2
- package/docs/subagent-orchestration-capabilities.md +19 -51
- package/docs/subagents-and-multiagent.md +21 -47
- package/docs/task-implementation-contract.md +3 -3
- package/docs/task-lifecycle-vietnamese.md +3 -3
- package/docs/team-onboarding.md +2 -2
- package/docs/usage-observability.md +7 -2
- package/docs/vi/architecture.md +27 -13
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +89 -95
- package/docs-site/commands.html +1 -1
- package/docs-site/content/benchmark.html +88 -94
- package/docs-site/content/en/benchmark.html +134 -90
- package/docs-site/content/en/index.html +19 -19
- package/docs-site/content/en/runtime.html +4 -4
- package/docs-site/content/en/whats-new.html +12 -1
- package/docs-site/content/en/workflows.html +2 -2
- package/docs-site/content/index.html +19 -19
- package/docs-site/content/runtime.html +4 -4
- package/docs-site/content/whats-new.html +12 -1
- package/docs-site/content/workflows.html +2 -2
- package/docs-site/context-engine.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +135 -91
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/index.html +20 -20
- 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 +5 -5
- 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 +13 -2
- package/docs-site/en/workflows.html +3 -3
- package/docs-site/index.html +20 -20
- 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 +5 -5
- 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 +13 -2
- package/docs-site/workflows.html +3 -3
- package/evals/fixtures/benchmark-assurance-evidence.invalid.json +1 -1
- package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
- package/evals/fixtures/codex-relative-efficiency-v1.invalid.json +4 -0
- package/evals/fixtures/codex-relative-efficiency-v1.valid.json +94 -0
- package/evals/fixtures/helper-request.invalid.json +1 -1
- package/evals/fixtures/helper-request.valid.json +1 -1
- package/evals/fixtures/piagent-webui/session-live-state-v1.invalid.json +18 -0
- package/evals/fixtures/piagent-webui/session-live-state-v1.valid.json +27 -0
- package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +7 -0
- package/evals/fixtures/task-authority-snapshot.valid.json +4 -4
- package/evals/fs4-readiness-matrix.v1.json +2 -2
- package/evals/fs5-causal-arm.v1.json +3 -3
- package/evals/fs5-pilot-protocol.v1.json +3 -3
- package/evals/fs5-pilot-protocol.v2.json +8 -8
- package/evals/fs5-pilot-protocol.v3.json +8 -8
- package/evals/fs5-pilot-protocol.v4.json +7 -6
- package/evals/fs5-pilot-protocol.v5.json +9 -7
- package/evals/private-holdout-v1/public-exposure.v1.json +1 -1
- package/evals/runtime-conformance-v1/README.md +43 -0
- package/evals/runtime-conformance-v1/evaluate-paid-canary.mjs +198 -0
- package/evals/runtime-conformance-v1/lane.json +57 -0
- package/evals/runtime-conformance-v1/paid-canary.json +31 -0
- package/evals/runtime-conformance-v1/runner.mjs +456 -0
- package/package.json +3 -1
- package/packages/piagent-core/README.md +13 -4
- package/packages/piagent-core/benchmark/benchmark-assurance.js +4 -1
- package/packages/piagent-core/benchmark/benchmark-bootstrap.js +91 -9
- package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +38 -7
- package/packages/piagent-core/benchmark/benchmark-cli.js +7 -7
- package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +698 -0
- package/packages/piagent-core/benchmark/benchmark-codex.js +3 -1
- package/packages/piagent-core/benchmark/benchmark-comparison.js +271 -2
- package/packages/piagent-core/benchmark/benchmark-core.js +736 -664
- package/packages/piagent-core/benchmark/benchmark-execution-guard.js +7 -5
- package/packages/piagent-core/benchmark/benchmark-forensics.js +441 -4
- package/packages/piagent-core/benchmark/benchmark-host-readiness.js +639 -0
- package/packages/piagent-core/benchmark/benchmark-matrix.js +22 -4
- package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +317 -0
- package/packages/piagent-core/benchmark/benchmark-preflight.js +5 -1
- package/packages/piagent-core/benchmark/benchmark-process.js +6 -5
- package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +345 -0
- package/packages/piagent-core/benchmark/benchmark-provider-wire.js +126 -0
- package/packages/piagent-core/benchmark/benchmark-record-validation.js +252 -0
- package/packages/piagent-core/benchmark/benchmark-report.js +130 -12
- package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +14 -0
- package/packages/piagent-core/benchmark/benchmark-runner-policy.js +26 -0
- package/packages/piagent-core/benchmark/benchmark-runtime-causal.js +244 -0
- package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +979 -0
- package/packages/piagent-core/benchmark/benchmark-statistics.js +64 -0
- package/packages/piagent-core/benchmark/benchmark-stop-policy.js +8 -5
- package/packages/piagent-core/benchmark/benchmark-suite-identity.js +31 -0
- package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +13 -9
- package/packages/piagent-core/benchmark/benchmark-suite.js +149 -2
- package/packages/piagent-core/benchmark/benchmark-summary-support.js +380 -0
- package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +971 -0
- package/packages/piagent-core/benchmark/benchmark-usage.js +322 -0
- package/packages/piagent-core/benchmark/benchmark-workflow.js +166 -0
- package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
- package/packages/piagent-core/docs/context-efficiency-improvement-plan.md +1080 -0
- package/packages/piagent-core/extensions/acceptance-behavior-proof.js +806 -0
- package/packages/piagent-core/extensions/acceptance-contract-semantics.js +83 -69
- package/packages/piagent-core/extensions/acceptance-error-classes.js +160 -0
- package/packages/piagent-core/extensions/acceptance-executable-evidence.js +12 -9
- package/packages/piagent-core/extensions/acceptance-receipt.js +123 -59
- package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +518 -0
- package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +60 -0
- package/packages/piagent-core/extensions/context-efficiency-metrics.js +302 -0
- package/packages/piagent-core/extensions/context-efficiency-report.js +167 -0
- package/packages/piagent-core/extensions/context-engine.js +149 -156
- package/packages/piagent-core/extensions/context-evidence.js +48 -0
- package/packages/piagent-core/extensions/context-import-links.js +296 -0
- package/packages/piagent-core/extensions/context-index-policy.js +4 -0
- package/packages/piagent-core/extensions/context-query-paths.js +57 -0
- package/packages/piagent-core/extensions/context-telemetry-integrity.js +65 -0
- package/packages/piagent-core/extensions/criterion-context-pack.js +435 -7
- package/packages/piagent-core/extensions/criterion-graph.js +82 -9
- package/packages/piagent-core/extensions/fallback-base-policy.ts +101 -0
- package/packages/piagent-core/extensions/guard-types.ts +6 -0
- package/packages/piagent-core/extensions/javascript-regex-evidence.js +32 -0
- package/packages/piagent-core/extensions/piagent-guard.ts +420 -260
- package/packages/piagent-core/extensions/task-contract-view.js +17 -3
- package/packages/piagent-core/extensions/task-lifecycle.js +39 -2
- package/packages/piagent-core/extensions/task-state.js +109 -142
- package/packages/piagent-core/extensions/verification-intelligence.js +52 -13
- package/packages/piagent-core/extensions/workspace-evidence-roots.js +193 -0
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/policies/base-policy.json +44 -2
- package/packages/piagent-core/policy/authority-manifest.v1.json +3 -3
- package/packages/piagent-core/prompts/be-to-fe.md +2 -8
- package/packages/piagent-core/prompts/plan.md +1 -1
- package/packages/piagent-core/prompts/platform-improve.md +2 -6
- package/packages/piagent-core/prompts/review.md +2 -7
- package/packages/piagent-core/prompts/scout.md +1 -1
- package/packages/piagent-core/prompts/task.md +4 -3
- package/packages/piagent-core/runtime/context/context-delivery.ts +103 -0
- package/packages/piagent-core/runtime/context/context-delta-shadow.ts +53 -0
- package/packages/piagent-core/runtime/context/context-efficiency-format.ts +47 -0
- package/packages/piagent-core/runtime/context/context-evidence-qualification.ts +32 -0
- package/packages/piagent-core/runtime/context/prefix-telemetry.ts +47 -0
- package/packages/piagent-core/runtime/context/repository-memory-hints.ts +27 -0
- package/packages/piagent-core/runtime/hooks/agent-prompt-telemetry.ts +56 -0
- package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +162 -102
- package/packages/piagent-core/runtime/hooks/completion-hook.ts +12 -12
- package/packages/piagent-core/runtime/hooks/input-hook.ts +17 -1
- package/packages/piagent-core/runtime/hooks/session-hooks.ts +22 -2
- package/packages/piagent-core/runtime/hooks/session-start-hook.ts +107 -3
- package/packages/piagent-core/runtime/hooks/tool-result-content-guards.ts +95 -0
- package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +134 -166
- package/packages/piagent-core/runtime/hooks/tool-result-value-helpers.ts +66 -0
- package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +4 -2
- package/packages/piagent-core/runtime/inspection/activity-recovery.ts +104 -0
- package/packages/piagent-core/runtime/inspection/bounded-emission-guard.ts +286 -0
- package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +37 -7
- package/packages/piagent-core/runtime/inspection/task-compaction-history.ts +1 -1
- package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +1 -1
- package/packages/piagent-core/runtime/inspection/task-subagent-tree.ts +27 -4
- package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +70 -0
- package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +73 -9
- package/packages/piagent-core/runtime/model/authenticated-catalog.ts +17 -9
- package/packages/piagent-core/runtime/model/openai-codex-reasoning.ts +83 -0
- package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +238 -0
- package/packages/piagent-core/runtime/orchestration/helper-lifecycle.ts +16 -12
- package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +71 -0
- package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +28 -20
- package/packages/piagent-core/runtime/orchestration/role-policy.ts +27 -9
- package/packages/piagent-core/runtime/orchestration/subagent-tool-policy.ts +329 -0
- package/packages/piagent-core/runtime/policy/block-remedy.ts +0 -4
- package/packages/piagent-core/runtime/product/activity-inspector.ts +7 -2
- package/packages/piagent-core/runtime/product/efficiency-metrics.ts +7 -2
- package/packages/piagent-core/runtime/quality/edit-freshness-guard.ts +102 -0
- package/packages/piagent-core/runtime/quality/exact-output-contract.ts +22 -11
- package/packages/piagent-core/runtime/quality/performance-assurance-signals.ts +23 -0
- package/packages/piagent-core/runtime/quality/performance-assurance.ts +9 -5
- package/packages/piagent-core/runtime/recovery/continuation-budget.ts +1 -1
- package/packages/piagent-core/runtime/recovery/edit-recovery-context.ts +113 -0
- package/packages/piagent-core/runtime/recovery/edit-recovery-delivery.ts +42 -0
- package/packages/piagent-core/runtime/recovery/handoff-projection.ts +4 -1
- package/packages/piagent-core/runtime/recovery/pristine-task-policy-refresh.ts +91 -0
- package/packages/piagent-core/runtime/recovery/recovery-policy.ts +7 -4
- package/packages/piagent-core/runtime/recovery/resume-state.ts +112 -14
- package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +60 -13
- package/packages/piagent-core/runtime/recovery/semantic-repair-runtime.ts +55 -2
- package/packages/piagent-core/runtime/recovery/task-evidence-coverage-refresh.ts +217 -0
- package/packages/piagent-core/runtime/registration/context-commands.ts +82 -7
- package/packages/piagent-core/runtime/registration/knowledge-tools.ts +9 -5
- package/packages/piagent-core/runtime/registration/operator-request-intake.ts +49 -0
- package/packages/piagent-core/runtime/registration/policy-tools.ts +50 -15
- package/packages/piagent-core/runtime/registration/session-commands.ts +1 -1
- package/packages/piagent-core/runtime/registration/task-completion-tools.ts +61 -25
- package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +21 -12
- package/packages/piagent-core/runtime/registration/task-start-guidance.ts +169 -0
- package/packages/piagent-core/runtime/registration/task-start-manifest.ts +54 -0
- package/packages/piagent-core/runtime/registration/task-start-retry-helpers.ts +37 -0
- package/packages/piagent-core/runtime/registration/task-start-tool.ts +108 -103
- package/packages/piagent-core/runtime/runtime-limits.ts +16 -2
- package/packages/piagent-core/runtime/session/adaptive-context-analysis.ts +461 -0
- package/packages/piagent-core/runtime/session/adaptive-context-governor.ts +464 -0
- package/packages/piagent-core/runtime/session/adaptive-context-ledger.ts +265 -0
- package/packages/piagent-core/runtime/session/message-signals.ts +7 -3
- package/packages/piagent-core/runtime/session/operator-request-carry.ts +44 -0
- package/packages/piagent-core/runtime/session/runtime-state.ts +161 -5
- package/packages/piagent-core/runtime/session/source-checkout-read-grants.ts +35 -0
- package/packages/piagent-core/runtime/session/system-prompt.ts +76 -14
- package/packages/piagent-core/runtime/session/task-contract-presentation.ts +39 -0
- package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +500 -0
- package/packages/piagent-core/runtime/tools/phase-tools.ts +8 -8
- package/packages/piagent-core/runtime/tools/tool-groups.ts +12 -2
- package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +2 -1
- package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +101 -0
- package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +164 -0
- package/packages/piagent-core/runtime/workflows/task-intake.ts +207 -38
- package/packages/piagent-core/security/sensitive-data.js +13 -218
- package/packages/piagent-core/security/sensitive-project-file.js +42 -0
- package/packages/piagent-core/security/sensitive-source-expression.js +330 -0
- package/packages/piagent-core/security/sensitive-source-formats.js +394 -0
- package/packages/piagent-core/security/sensitive-text.js +234 -0
- package/packages/piagent-core/subagents/piagent-oracle.md +5 -3
- package/packages/piagent-core/subagents/piagent-planner.md +6 -4
- package/packages/piagent-core/subagents/piagent-reviewer.md +5 -3
- package/packages/piagent-core/subagents/piagent-scout.md +4 -2
- package/packages/piagent-core/subagents/piagent-worker.md +7 -5
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-rD9WJKxs.js → MarkdownMessage-B4XehTCU.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +176 -0
- package/packages/piagent-webui/dist/client/index.html +1 -1
- package/packages/piagent-webui/extension/piagent-webui.ts +3 -1
- package/packages/piagent-webui/extension/same-session-bridge.ts +1 -1
- package/packages/piagent-webui/extension/session-stream-adapter.ts +33 -10
- package/packages/piagent-webui/gateway/gateway-events.ts +109 -5
- package/packages/piagent-webui/gateway/gateway-service.ts +3 -0
- package/packages/piagent-webui/gateway/gateway-session-stream.ts +122 -20
- package/packages/piagent-webui/gateway/session-command-controller.ts +18 -3
- package/packages/piagent-webui/gateway/session-effective-options.ts +47 -0
- package/packages/piagent-webui/gateway/session-live-state.ts +21 -0
- package/packages/piagent-webui/gateway/session-operation-lifecycle.ts +237 -0
- package/packages/piagent-webui/gateway/session-operation-retry-control.ts +38 -0
- package/packages/piagent-webui/gateway/session-operation-start.ts +5 -1
- package/packages/piagent-webui/gateway/session-operation-watchdog.ts +165 -0
- package/packages/piagent-webui/gateway/session-runtime-factory.ts +45 -0
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +141 -125
- package/packages/piagent-webui/ownership/session-lease-store.ts +5 -2
- package/packages/piagent-webui/server/core-inspection-provider.ts +2 -1
- package/packages/piagent-webui/server/loopback-server.ts +8 -0
- package/packages/piagent-webui/server/transcript-projection.ts +113 -9
- package/packages/piagent-webui/shared/text-visibility.ts +10 -0
- package/schemas/codex-relative-efficiency-v1.schema.json +155 -0
- package/schemas/piagent-webui/catalog-v1.json +9 -0
- package/schemas/piagent-webui/gateway-protocol-v1.schema.json +53 -3
- package/schemas/piagent-webui/runtime-event-v2.schema.json +15 -5
- package/schemas/piagent-webui/session-live-state-v1.schema.json +76 -0
- package/schemas/piagent-webui/subagent-tree-v1.schema.json +11 -1
- package/schemas/project-profile.schema.json +1 -1
- package/schemas/task-contract.schema.json +27 -1
- package/scripts/benchmark-runner-core.mjs +367 -363
- package/scripts/benchmark-runner-finalization.mjs +313 -0
- package/scripts/benchmark-runner-host-readiness.mjs +94 -0
- package/scripts/benchmark-runner-support.mjs +200 -0
- package/scripts/benchmark-session.mjs +95 -41
- package/scripts/configure-model-scope.sh +4 -3
- package/scripts/configure-subagents.sh +42 -34
- package/scripts/helper-evaluation.mjs +2 -2
- package/scripts/install-global.sh +2 -2
- package/scripts/pi-usage-history.mjs +37 -10
- package/scripts/setup.sh +2 -2
- package/scripts/team-doctor.sh +1 -1
- package/scripts/verify-local.sh +10 -1
- package/templates/global/settings.json +2 -1
- package/packages/piagent-webui/dist/client/assets/index-BZRFw1u6.js +0 -174
|
@@ -0,0 +1,979 @@
|
|
|
1
|
+
import { benchmarkProviderWireEvidenceMatchesRequest } from "./benchmark-provider-wire.js";
|
|
2
|
+
import { productionProviderFreeEvidenceContextValidationErrors } from "./benchmark-provider-free-evidence.js";
|
|
3
|
+
import { summarizeBenchmarkSubagentBudget } from "./benchmark-codex-relative-efficiency.js";
|
|
4
|
+
import {
|
|
5
|
+
benchmarkPricingSnapshotValidationErrors,
|
|
6
|
+
normalizeBenchmarkUsageCost
|
|
7
|
+
} from "./benchmark-normalized-cost.js";
|
|
8
|
+
import { summarizeBenchmarkCausalContextEvidence } from "./benchmark-record-validation.js";
|
|
9
|
+
import {
|
|
10
|
+
benchmarkHostReadinessPolicyDigest,
|
|
11
|
+
benchmarkHostReadinessPolicyValidationErrors,
|
|
12
|
+
summarizeBenchmarkHostReadinessHistory
|
|
13
|
+
} from "./benchmark-host-readiness.js";
|
|
14
|
+
import { atMostWithinFloatingPrecision, geometricMean } from "./benchmark-statistics.js";
|
|
15
|
+
import { pairedOutcomeFloorStop } from "./benchmark-stop-policy.js";
|
|
16
|
+
import { workflowContinuityEvidenceComplete } from "./benchmark-summary-support.js";
|
|
17
|
+
import { summarizeBenchmarkTimingDiagnostics } from "./benchmark-timing-diagnostics.js";
|
|
18
|
+
import { exactBenchmarkAttemptUsage } from "./benchmark-usage.js";
|
|
19
|
+
|
|
20
|
+
const TOKEN_FIELDS = Object.freeze(["input", "output", "cacheRead", "cacheWrite", "reasoning", "fresh", "total"]);
|
|
21
|
+
const PRODUCTION_STAGE_CONTROL_POLICY = "production-v1-provider-spend-v1";
|
|
22
|
+
|
|
23
|
+
function nonEmptyString(value) {
|
|
24
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function validStageBoundaries(stageBoundaries) {
|
|
28
|
+
return Array.isArray(stageBoundaries)
|
|
29
|
+
&& stageBoundaries.length >= 2
|
|
30
|
+
&& stageBoundaries[0] === 0
|
|
31
|
+
&& stageBoundaries.every((value, index) => Number.isSafeInteger(value)
|
|
32
|
+
&& value >= 0
|
|
33
|
+
&& (index === 0 || value > stageBoundaries[index - 1]));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function productionGuardBindingMatches(manifest, spendControl) {
|
|
37
|
+
return JSON.stringify(manifest?.productionGuards ?? null)
|
|
38
|
+
=== JSON.stringify(spendControl?.productionGuards ?? null);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function productionSpendControlValidationErrors(control, {
|
|
42
|
+
suiteId,
|
|
43
|
+
expectedSessions,
|
|
44
|
+
requireHostReadiness = control?.hostReadiness?.required === true
|
|
45
|
+
} = {}) {
|
|
46
|
+
const errors = [];
|
|
47
|
+
if (!control || typeof control !== "object" || Array.isArray(control)) return ["contract-must-be-an-object"];
|
|
48
|
+
if (control.schemaVersion !== 1) errors.push("unsupported-schema-version");
|
|
49
|
+
if (!nonEmptyString(control.suiteId) || (suiteId !== undefined && control.suiteId !== suiteId)) errors.push("suite-id-mismatch");
|
|
50
|
+
if (!nonEmptyString(control.rootSeed) || control.rootSeed.length > 200) errors.push("invalid-root-seed");
|
|
51
|
+
|
|
52
|
+
const execution = control.execution;
|
|
53
|
+
if (!execution || typeof execution !== "object" || Array.isArray(execution)) errors.push("missing-execution-contract");
|
|
54
|
+
else {
|
|
55
|
+
if (!Array.isArray(execution.surfaces)
|
|
56
|
+
|| execution.surfaces.length !== 2
|
|
57
|
+
|| new Set(execution.surfaces).size !== 2
|
|
58
|
+
|| execution.surfaces.some((surface) => !nonEmptyString(surface))) errors.push("invalid-execution-surfaces");
|
|
59
|
+
if (execution.model !== null && !nonEmptyString(execution.model)) errors.push("invalid-execution-model");
|
|
60
|
+
if (execution.thinking !== null && !nonEmptyString(execution.thinking)) errors.push("invalid-execution-thinking");
|
|
61
|
+
if (!Number.isSafeInteger(execution.repeats) || execution.repeats <= 0) errors.push("invalid-execution-repeats");
|
|
62
|
+
if (execution.infrastructureRetries !== 0) errors.push("infrastructure-retries-must-be-zero");
|
|
63
|
+
if (execution.stopAfterFailedPair !== true) errors.push("stop-after-failed-pair-must-be-enabled");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (requireHostReadiness) {
|
|
67
|
+
errors.push(...benchmarkHostReadinessPolicyValidationErrors(control.hostReadiness)
|
|
68
|
+
.map((error) => `host-readiness:${error}`));
|
|
69
|
+
} else if (control.hostReadiness !== undefined) {
|
|
70
|
+
errors.push(...benchmarkHostReadinessPolicyValidationErrors(control.hostReadiness)
|
|
71
|
+
.map((error) => `host-readiness:${error}`));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (!Array.isArray(control.stages) || control.stages.length < 2) errors.push("missing-stage-boundaries");
|
|
75
|
+
else {
|
|
76
|
+
const ids = new Set();
|
|
77
|
+
let previous = 0;
|
|
78
|
+
for (const [index, stage] of control.stages.entries()) {
|
|
79
|
+
if (!stage || typeof stage !== "object" || Array.isArray(stage)) {
|
|
80
|
+
errors.push(`invalid-stage:${index}`);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (!nonEmptyString(stage.id) || ids.has(stage.id)) errors.push(`invalid-stage-id:${index}`);
|
|
84
|
+
else ids.add(stage.id);
|
|
85
|
+
if (!Number.isSafeInteger(stage.cumulativeSessions) || stage.cumulativeSessions < 0
|
|
86
|
+
|| (index > 0 && stage.cumulativeSessions <= previous)) errors.push(`invalid-stage-cumulative-sessions:${index}`);
|
|
87
|
+
const expectedNewSessions = index === 0 ? 0 : stage.cumulativeSessions - previous;
|
|
88
|
+
if (stage.newSessions !== expectedNewSessions) errors.push(`invalid-stage-new-sessions:${index}`);
|
|
89
|
+
if (index === 0) {
|
|
90
|
+
if (stage.cumulativeSessions !== 0) errors.push("initial-stage-must-start-at-zero");
|
|
91
|
+
if (stage.claimEligible !== false) errors.push("initial-stage-cannot-be-claim-eligible");
|
|
92
|
+
} else if (index === control.stages.length - 1) {
|
|
93
|
+
if (stage.claimEligible !== true) errors.push("final-stage-must-be-claim-eligible");
|
|
94
|
+
} else if (stage.claimEligible !== false) errors.push(`intermediate-stage-cannot-be-claim-eligible:${index}`);
|
|
95
|
+
if (Number.isSafeInteger(stage.cumulativeSessions)) previous = stage.cumulativeSessions;
|
|
96
|
+
}
|
|
97
|
+
const finalSessions = control.stages.at(-1)?.cumulativeSessions;
|
|
98
|
+
if (Number.isSafeInteger(expectedSessions) && finalSessions !== expectedSessions) errors.push("final-stage-session-count-mismatch");
|
|
99
|
+
}
|
|
100
|
+
const guards = control.productionGuards;
|
|
101
|
+
if (suiteId === "production-v1" && (!guards || typeof guards !== "object" || Array.isArray(guards))) errors.push("missing-production-guards");
|
|
102
|
+
else if (guards !== undefined) {
|
|
103
|
+
const subagents = guards.subagents;
|
|
104
|
+
if (subagents?.required !== true
|
|
105
|
+
|| subagents.maximumSessionsPerAttempt !== 1
|
|
106
|
+
|| subagents.maximumTrafficShare !== 0.05
|
|
107
|
+
|| subagents.requireExactAllAttemptEvidence !== true
|
|
108
|
+
|| subagents.requireExplainedSessionCount !== true) errors.push("invalid-production-subagent-guard");
|
|
109
|
+
const partial = guards.partialFreshSpend;
|
|
110
|
+
if (partial?.requiredFromCumulativeSessions !== 12
|
|
111
|
+
|| partial.maximumPooledFreshRatio !== 1.1
|
|
112
|
+
|| partial.maximumObservedFamilyFreshRatio !== 1.25
|
|
113
|
+
|| partial.includeExactFailedAttempts !== true) errors.push("invalid-production-partial-fresh-spend-guard");
|
|
114
|
+
const providerFree = guards.providerFreeEvidence;
|
|
115
|
+
if (providerFree?.requiredBeforeFirstPaidSession !== true
|
|
116
|
+
|| JSON.stringify(providerFree.requiredLaneIds) !== JSON.stringify(["runtime-conformance-v1", "long-horizon-v1", "webui-parity-v1"])
|
|
117
|
+
|| providerFree.requireCleanCommitAndTreeBinding !== true
|
|
118
|
+
|| providerFree.requireProductionConfigurationBinding !== true
|
|
119
|
+
|| providerFree.requireRunnerAndLaneConfigurationDigests !== true) errors.push("invalid-production-provider-free-evidence-guard");
|
|
120
|
+
}
|
|
121
|
+
return errors;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function sameLedgerBinding(left, right) {
|
|
125
|
+
return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function createProductionStageControl({ authorizedThroughRuns, generatedAt = new Date().toISOString() }) {
|
|
129
|
+
return {
|
|
130
|
+
schemaVersion: 1,
|
|
131
|
+
policy: PRODUCTION_STAGE_CONTROL_POLICY,
|
|
132
|
+
state: "window-authorized",
|
|
133
|
+
approvedBoundaryRuns: 0,
|
|
134
|
+
authorizedThroughRuns,
|
|
135
|
+
pendingBoundary: null,
|
|
136
|
+
updatedAt: generatedAt
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function pendProductionStageControl(control, { reason, completedRuns, ledger, generatedAt = new Date().toISOString() }) {
|
|
141
|
+
return {
|
|
142
|
+
schemaVersion: 1,
|
|
143
|
+
policy: PRODUCTION_STAGE_CONTROL_POLICY,
|
|
144
|
+
state: "review-pending",
|
|
145
|
+
approvedBoundaryRuns: Number.isSafeInteger(control?.approvedBoundaryRuns) ? control.approvedBoundaryRuns : 0,
|
|
146
|
+
authorizedThroughRuns: control?.authorizedThroughRuns,
|
|
147
|
+
pendingBoundary: {
|
|
148
|
+
reason,
|
|
149
|
+
completedRuns,
|
|
150
|
+
ledger
|
|
151
|
+
},
|
|
152
|
+
updatedAt: generatedAt
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function approveProductionStageControl(control, { completedRuns, authorizedThroughRuns, generatedAt = new Date().toISOString() }) {
|
|
157
|
+
return {
|
|
158
|
+
schemaVersion: 1,
|
|
159
|
+
policy: PRODUCTION_STAGE_CONTROL_POLICY,
|
|
160
|
+
state: "window-authorized",
|
|
161
|
+
approvedBoundaryRuns: completedRuns,
|
|
162
|
+
authorizedThroughRuns,
|
|
163
|
+
pendingBoundary: null,
|
|
164
|
+
updatedAt: generatedAt
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function productionStageResumeDisposition(control, { completedRuns, ledger, stageBoundaries }) {
|
|
169
|
+
const errors = [];
|
|
170
|
+
if (control?.schemaVersion !== 1 || control?.policy !== PRODUCTION_STAGE_CONTROL_POLICY) errors.push("missing-or-unsupported-stage-control");
|
|
171
|
+
if (!Number.isSafeInteger(completedRuns) || completedRuns < 0) errors.push("invalid-completed-run-count");
|
|
172
|
+
if (!validStageBoundaries(stageBoundaries)) errors.push("invalid-frozen-stage-boundaries");
|
|
173
|
+
const approvedBoundaryRuns = control?.approvedBoundaryRuns;
|
|
174
|
+
const authorizedThroughRuns = control?.authorizedThroughRuns;
|
|
175
|
+
const expectedAuthorizedThroughRuns = validStageBoundaries(stageBoundaries) && Number.isSafeInteger(approvedBoundaryRuns)
|
|
176
|
+
? stageBoundaries.find((boundary) => boundary > approvedBoundaryRuns)
|
|
177
|
+
: undefined;
|
|
178
|
+
if (!Number.isSafeInteger(approvedBoundaryRuns) || approvedBoundaryRuns < 0
|
|
179
|
+
|| approvedBoundaryRuns > completedRuns
|
|
180
|
+
|| (validStageBoundaries(stageBoundaries) && approvedBoundaryRuns >= stageBoundaries.at(-1))) errors.push("invalid-approved-boundary");
|
|
181
|
+
if (!Number.isSafeInteger(authorizedThroughRuns) || authorizedThroughRuns <= 0
|
|
182
|
+
|| authorizedThroughRuns < completedRuns
|
|
183
|
+
|| authorizedThroughRuns !== expectedAuthorizedThroughRuns) errors.push("invalid-authorized-window");
|
|
184
|
+
if (control?.state === "window-authorized") {
|
|
185
|
+
if (control.pendingBoundary !== null) errors.push("authorized-window-has-pending-boundary");
|
|
186
|
+
const atAuthorizedBoundary = completedRuns === authorizedThroughRuns;
|
|
187
|
+
return {
|
|
188
|
+
passed: errors.length === 0,
|
|
189
|
+
requiresStageGate: errors.length === 0 && atAuthorizedBoundary,
|
|
190
|
+
recoveryAllowed: errors.length === 0 && !atAuthorizedBoundary,
|
|
191
|
+
errors
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (control?.state === "review-pending") {
|
|
195
|
+
const pending = control.pendingBoundary;
|
|
196
|
+
if (!pending || typeof pending.reason !== "string") errors.push("missing-pending-boundary");
|
|
197
|
+
if (pending?.completedRuns !== completedRuns) errors.push("pending-boundary-run-count-mismatch");
|
|
198
|
+
if (Number.isSafeInteger(completedRuns) && Number.isSafeInteger(approvedBoundaryRuns)
|
|
199
|
+
&& completedRuns <= approvedBoundaryRuns) errors.push("pending-boundary-has-no-progress");
|
|
200
|
+
if (!sameLedgerBinding(pending?.ledger, ledger)) errors.push("pending-boundary-ledger-mismatch");
|
|
201
|
+
return { passed: errors.length === 0, requiresStageGate: true, recoveryAllowed: false, errors };
|
|
202
|
+
}
|
|
203
|
+
errors.push("invalid-stage-control-state");
|
|
204
|
+
return { passed: false, requiresStageGate: false, recoveryAllowed: false, errors };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function productionStageResumeWindow(control, { completedRuns, stageBoundaries }) {
|
|
208
|
+
if (!validStageBoundaries(stageBoundaries)
|
|
209
|
+
|| !Number.isSafeInteger(completedRuns)
|
|
210
|
+
|| completedRuns < 0
|
|
211
|
+
|| !Number.isSafeInteger(control?.authorizedThroughRuns)) return null;
|
|
212
|
+
const authorizedThroughRuns = completedRuns < control.authorizedThroughRuns
|
|
213
|
+
? control.authorizedThroughRuns
|
|
214
|
+
: stageBoundaries.find((boundary) => boundary > completedRuns);
|
|
215
|
+
if (!Number.isSafeInteger(authorizedThroughRuns)) {
|
|
216
|
+
return completedRuns === stageBoundaries.at(-1)
|
|
217
|
+
? { authorizedThroughRuns: completedRuns, remainingSessions: 0 }
|
|
218
|
+
: null;
|
|
219
|
+
}
|
|
220
|
+
const remainingSessions = authorizedThroughRuns - completedRuns;
|
|
221
|
+
if (!Number.isSafeInteger(remainingSessions) || remainingSessions <= 0) return null;
|
|
222
|
+
return { authorizedThroughRuns, remainingSessions };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Replays the terminal paired-outcome rule over an accepted ledger prefix.
|
|
227
|
+
*
|
|
228
|
+
* The live runner normally evaluates this rule immediately after appending the
|
|
229
|
+
* second record of a pair. A process can still die after the durable append but
|
|
230
|
+
* before that in-memory check. Resume must therefore derive the same terminal
|
|
231
|
+
* result from accepted records before it performs auth, tool preflight, or any
|
|
232
|
+
* additional provider work.
|
|
233
|
+
*/
|
|
234
|
+
export function durablePairedOutcomeFloorStop({ enabled, suite, runs, fullOrder }) {
|
|
235
|
+
const acceptedRuns = Array.isArray(runs) ? runs : [];
|
|
236
|
+
const expectedRuns = Array.isArray(fullOrder) ? fullOrder : [];
|
|
237
|
+
for (let index = 0; index < expectedRuns.length; index += 1) {
|
|
238
|
+
const terminal = pairedOutcomeFloorStop({
|
|
239
|
+
enabled,
|
|
240
|
+
suite,
|
|
241
|
+
runs: acceptedRuns,
|
|
242
|
+
current: expectedRuns[index],
|
|
243
|
+
next: expectedRuns[index + 1]
|
|
244
|
+
});
|
|
245
|
+
if (terminal) return terminal;
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function runKey(run) {
|
|
251
|
+
return `${run?.scenarioId ?? run?.scenario?.id}\0${run?.surface}\0${run?.repeat}`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function pairKey(value) {
|
|
255
|
+
return `${value?.scenarioId ?? value?.scenario?.id}\0${value?.repeat}`;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function publicPairId(value) {
|
|
259
|
+
return `${value?.scenarioId ?? value?.scenario?.id}:r${value?.repeat}`;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function expectedPairMap(fullOrder) {
|
|
263
|
+
const pairs = new Map();
|
|
264
|
+
for (const item of fullOrder) {
|
|
265
|
+
const key = pairKey(item);
|
|
266
|
+
const pair = pairs.get(key) ?? {
|
|
267
|
+
scenarioId: item?.scenarioId ?? item?.scenario?.id,
|
|
268
|
+
repeat: item?.repeat,
|
|
269
|
+
expectedSurfaces: new Set(),
|
|
270
|
+
expectedRunKeys: new Set()
|
|
271
|
+
};
|
|
272
|
+
pair.expectedSurfaces.add(item?.surface);
|
|
273
|
+
pair.expectedRunKeys.add(runKey(item));
|
|
274
|
+
pairs.set(key, pair);
|
|
275
|
+
}
|
|
276
|
+
return pairs;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function exactUsageIssues(run) {
|
|
280
|
+
const usage = run?.usage;
|
|
281
|
+
const issues = [];
|
|
282
|
+
if (usage?.usageCompleteness !== "exact") issues.push("usage-completeness-not-exact");
|
|
283
|
+
if (!Number.isSafeInteger(usage?.sessions) || usage.sessions <= 0) issues.push("invalid-session-count");
|
|
284
|
+
for (const field of TOKEN_FIELDS) {
|
|
285
|
+
if (!Number.isSafeInteger(usage?.[field]) || usage[field] < 0) issues.push(`invalid-${field}`);
|
|
286
|
+
}
|
|
287
|
+
if (Number.isSafeInteger(usage?.fresh) && Number.isSafeInteger(usage?.input) && Number.isSafeInteger(usage?.output)
|
|
288
|
+
&& usage.fresh !== usage.input + usage.output) issues.push("fresh-token-equation-mismatch");
|
|
289
|
+
if ([usage?.total, usage?.input, usage?.cacheRead, usage?.cacheWrite, usage?.output].every(Number.isSafeInteger)
|
|
290
|
+
&& usage.total !== usage.input + usage.cacheRead + usage.cacheWrite + usage.output) issues.push("total-token-equation-mismatch");
|
|
291
|
+
if (Number.isSafeInteger(usage?.reasoning) && Number.isSafeInteger(usage?.output) && usage.reasoning > usage.output) {
|
|
292
|
+
issues.push("reasoning-exceeds-output");
|
|
293
|
+
}
|
|
294
|
+
return issues;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function providerWireGroups(piRuns) {
|
|
298
|
+
const groups = new Map();
|
|
299
|
+
for (const run of piRuns) {
|
|
300
|
+
const key = `${run.scenarioId}\0${run.profile ?? "unspecified"}\0${run.lifecycle ?? "unspecified"}`;
|
|
301
|
+
const group = groups.get(key) ?? {
|
|
302
|
+
scenarioId: run.scenarioId,
|
|
303
|
+
profile: run.profile ?? "unspecified",
|
|
304
|
+
lifecycle: run.lifecycle ?? "unspecified",
|
|
305
|
+
runs: 0,
|
|
306
|
+
baseInstructionHashes: new Set(),
|
|
307
|
+
orderedToolSurfaceHashes: new Set()
|
|
308
|
+
};
|
|
309
|
+
group.runs += 1;
|
|
310
|
+
for (const hash of run.providerWireEvidence?.baseInstructionHashes ?? []) group.baseInstructionHashes.add(hash);
|
|
311
|
+
for (const hash of run.providerWireEvidence?.orderedToolSurfaceHashes ?? []) group.orderedToolSurfaceHashes.add(hash);
|
|
312
|
+
groups.set(key, group);
|
|
313
|
+
}
|
|
314
|
+
return [...groups.values()].map((group) => ({
|
|
315
|
+
scenarioId: group.scenarioId,
|
|
316
|
+
profile: group.profile,
|
|
317
|
+
lifecycle: group.lifecycle,
|
|
318
|
+
runs: group.runs,
|
|
319
|
+
baseInstructionHashCount: group.baseInstructionHashes.size,
|
|
320
|
+
orderedToolSurfaceHashCount: group.orderedToolSurfaceHashes.size,
|
|
321
|
+
passed: group.baseInstructionHashes.size === 1 && group.orderedToolSurfaceHashes.size === 1
|
|
322
|
+
})).sort((left, right) => left.scenarioId.localeCompare(right.scenarioId));
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
function diagnosticCheck(id, passed, details = {}, decisionRole = "blocking") {
|
|
326
|
+
return { id, passed: passed === true, decisionRole, ...details };
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function pairRatioEvidence(pairRecords, valueFor) {
|
|
330
|
+
const records = pairRecords.map(({ pair, candidate, baseline }) => {
|
|
331
|
+
const values = valueFor({ candidate, baseline });
|
|
332
|
+
const baselineValue = values?.baseline;
|
|
333
|
+
const candidateValue = values?.candidate;
|
|
334
|
+
const comparable = Number.isFinite(baselineValue) && baselineValue > 0
|
|
335
|
+
&& Number.isFinite(candidateValue) && candidateValue > 0
|
|
336
|
+
&& (!Array.isArray(values?.issues) || values.issues.length === 0);
|
|
337
|
+
return {
|
|
338
|
+
pairId: pair.id,
|
|
339
|
+
scenarioId: pair.scenarioId,
|
|
340
|
+
repeat: pair.repeat,
|
|
341
|
+
comparable,
|
|
342
|
+
issues: comparable ? [] : values?.issues?.length ? values.issues : ["non-positive-or-unavailable-value"],
|
|
343
|
+
baseline: Number.isFinite(baselineValue) ? baselineValue : null,
|
|
344
|
+
candidate: Number.isFinite(candidateValue) ? candidateValue : null,
|
|
345
|
+
ratio: comparable ? candidateValue / baselineValue : null
|
|
346
|
+
};
|
|
347
|
+
});
|
|
348
|
+
const familyMap = new Map();
|
|
349
|
+
for (const record of records) {
|
|
350
|
+
const values = familyMap.get(record.scenarioId) ?? [];
|
|
351
|
+
values.push(record);
|
|
352
|
+
familyMap.set(record.scenarioId, values);
|
|
353
|
+
}
|
|
354
|
+
const families = [...familyMap.entries()].map(([scenarioId, values]) => {
|
|
355
|
+
const comparable = values.length > 0 && values.every((value) => value.comparable);
|
|
356
|
+
return {
|
|
357
|
+
scenarioId,
|
|
358
|
+
observedPairs: values.length,
|
|
359
|
+
comparable,
|
|
360
|
+
ratio: comparable ? geometricMean(values.map((value) => value.ratio)) : null,
|
|
361
|
+
issues: comparable ? [] : ["one-or-more-observed-pairs-incomparable"]
|
|
362
|
+
};
|
|
363
|
+
}).sort((left, right) => left.scenarioId.localeCompare(right.scenarioId));
|
|
364
|
+
return {
|
|
365
|
+
records,
|
|
366
|
+
families,
|
|
367
|
+
incomparablePairs: records.filter((record) => !record.comparable),
|
|
368
|
+
pairRegressions: records.filter((record) => Number.isFinite(record.ratio) && !atMostWithinFloatingPrecision(record.ratio, 1)),
|
|
369
|
+
familyRegressions: families.filter((family) => Number.isFinite(family.ratio) && !atMostWithinFloatingPrecision(family.ratio, 1))
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function allAttemptFreshTokens(run) {
|
|
374
|
+
const failures = Array.isArray(run?.infrastructureFailures) ? run.infrastructureFailures : [];
|
|
375
|
+
const ledgerExact = Number.isSafeInteger(run?.infrastructureRetries)
|
|
376
|
+
&& Number.isSafeInteger(run?.infrastructureAttempts)
|
|
377
|
+
&& failures.length === run.infrastructureRetries
|
|
378
|
+
&& run.infrastructureAttempts === run.infrastructureRetries + 1;
|
|
379
|
+
const attempts = [
|
|
380
|
+
{ usage: run?.usage, status: run?.usageStatus ?? "measured" },
|
|
381
|
+
...failures.map((failure) => ({
|
|
382
|
+
usage: failure?.usage,
|
|
383
|
+
status: failure?.usageStatus ?? "unknown-after-provider-start"
|
|
384
|
+
}))
|
|
385
|
+
];
|
|
386
|
+
const exact = ledgerExact && attempts.every((attempt) => exactBenchmarkAttemptUsage(attempt.usage, attempt.status));
|
|
387
|
+
return {
|
|
388
|
+
exact,
|
|
389
|
+
attempts: attempts.length,
|
|
390
|
+
fresh: exact ? attempts.reduce((sum, attempt) => sum + Number(attempt.usage?.fresh ?? 0), 0) : null
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function partialCatastrophicSpendEvidence(pairRecords, {
|
|
395
|
+
maximumPooledFreshRatio,
|
|
396
|
+
maximumObservedFamilyFreshRatio
|
|
397
|
+
}) {
|
|
398
|
+
const records = pairRecords.map(({ pair, candidate, baseline }) => {
|
|
399
|
+
const candidateUsage = allAttemptFreshTokens(candidate);
|
|
400
|
+
const baselineUsage = allAttemptFreshTokens(baseline);
|
|
401
|
+
const exact = candidateUsage.exact && baselineUsage.exact
|
|
402
|
+
&& baselineUsage.fresh > 0 && candidateUsage.fresh >= 0;
|
|
403
|
+
return {
|
|
404
|
+
pairId: pair.id,
|
|
405
|
+
scenarioId: pair.scenarioId,
|
|
406
|
+
repeat: pair.repeat,
|
|
407
|
+
exact,
|
|
408
|
+
baselineFresh: exact ? baselineUsage.fresh : null,
|
|
409
|
+
candidateFresh: exact ? candidateUsage.fresh : null,
|
|
410
|
+
baselineAttempts: baselineUsage.attempts,
|
|
411
|
+
candidateAttempts: candidateUsage.attempts
|
|
412
|
+
};
|
|
413
|
+
});
|
|
414
|
+
const exact = records.length > 0 && records.every((record) => record.exact);
|
|
415
|
+
const baselineFresh = exact ? records.reduce((sum, record) => sum + record.baselineFresh, 0) : null;
|
|
416
|
+
const candidateFresh = exact ? records.reduce((sum, record) => sum + record.candidateFresh, 0) : null;
|
|
417
|
+
const pooledRatio = exact && baselineFresh > 0 ? candidateFresh / baselineFresh : null;
|
|
418
|
+
const byFamily = new Map();
|
|
419
|
+
for (const record of records) {
|
|
420
|
+
const family = byFamily.get(record.scenarioId) ?? { scenarioId: record.scenarioId, records: [] };
|
|
421
|
+
family.records.push(record);
|
|
422
|
+
byFamily.set(record.scenarioId, family);
|
|
423
|
+
}
|
|
424
|
+
const families = [...byFamily.values()].map((family) => {
|
|
425
|
+
const familyExact = family.records.length > 0 && family.records.every((record) => record.exact);
|
|
426
|
+
const baseline = familyExact ? family.records.reduce((sum, record) => sum + record.baselineFresh, 0) : null;
|
|
427
|
+
const candidate = familyExact ? family.records.reduce((sum, record) => sum + record.candidateFresh, 0) : null;
|
|
428
|
+
return {
|
|
429
|
+
scenarioId: family.scenarioId,
|
|
430
|
+
observedPairs: family.records.length,
|
|
431
|
+
exact: familyExact,
|
|
432
|
+
ratio: familyExact && baseline > 0 ? candidate / baseline : null
|
|
433
|
+
};
|
|
434
|
+
}).sort((left, right) => left.scenarioId.localeCompare(right.scenarioId));
|
|
435
|
+
const familyFailures = families.filter((family) => !family.exact
|
|
436
|
+
|| !Number.isFinite(family.ratio)
|
|
437
|
+
|| !atMostWithinFloatingPrecision(family.ratio, maximumObservedFamilyFreshRatio));
|
|
438
|
+
const passed = exact
|
|
439
|
+
&& Number.isFinite(pooledRatio)
|
|
440
|
+
&& atMostWithinFloatingPrecision(pooledRatio, maximumPooledFreshRatio)
|
|
441
|
+
&& familyFailures.length === 0;
|
|
442
|
+
return {
|
|
443
|
+
schemaVersion: 1,
|
|
444
|
+
exactUsageIncludingFailedAttempts: exact,
|
|
445
|
+
maximumPooledFreshRatio,
|
|
446
|
+
maximumObservedFamilyFreshRatio,
|
|
447
|
+
pooledRatio,
|
|
448
|
+
baselineFresh,
|
|
449
|
+
candidateFresh,
|
|
450
|
+
familyFailures,
|
|
451
|
+
families,
|
|
452
|
+
records,
|
|
453
|
+
passed
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function candidateOutcomeFailures(pairRecords, floor) {
|
|
458
|
+
return pairRecords.map(({ pair, candidate }) => {
|
|
459
|
+
const failures = [];
|
|
460
|
+
if (candidate?.resolved !== true) failures.push("unresolved-outcome");
|
|
461
|
+
if (candidate?.scope?.passed !== true) failures.push("scope-safety-evidence-failed");
|
|
462
|
+
if (candidate?.outputSafety?.passed !== true) failures.push("output-safety-evidence-failed");
|
|
463
|
+
if (candidate?.scenarioKind === "safety-refusal") {
|
|
464
|
+
if (candidate?.grade?.passed !== true) failures.push("safety-refusal-grade-failed");
|
|
465
|
+
} else {
|
|
466
|
+
if (candidate?.grade?.passed !== true) failures.push("quality-grade-failed");
|
|
467
|
+
if (candidate?.graderIntegrity?.passed !== true) failures.push("grader-integrity-failed");
|
|
468
|
+
if (candidate?.outputEvidence?.passed === false) failures.push("output-evidence-failed");
|
|
469
|
+
if (!Number.isFinite(candidate?.grade?.score) || candidate.grade.score <= floor) failures.push("quality-outcome-floor");
|
|
470
|
+
if (!Number.isFinite(candidate?.workflow?.score) || candidate.workflow.score <= floor) failures.push("workflow-outcome-floor");
|
|
471
|
+
if (!workflowContinuityEvidenceComplete(candidate?.workflow)) {
|
|
472
|
+
failures.push("workflow-evidence-incomplete-or-failed");
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return {
|
|
476
|
+
pairId: pair.id,
|
|
477
|
+
failures,
|
|
478
|
+
resolved: candidate?.resolved === true,
|
|
479
|
+
gradeScore: Number.isFinite(candidate?.grade?.score) ? candidate.grade.score : null,
|
|
480
|
+
workflowScore: Number.isFinite(candidate?.workflow?.score) ? candidate.workflow.score : null
|
|
481
|
+
};
|
|
482
|
+
}).filter((item) => item.failures.length > 0);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Builds a provider-free, claim-ineligible decision aid for a paused benchmark.
|
|
487
|
+
* Future, entirely unstarted pairs are intentionally not blockers. A partially
|
|
488
|
+
* observed pair is a blocker because stage decisions must be made at pair
|
|
489
|
+
* boundaries.
|
|
490
|
+
*/
|
|
491
|
+
export function buildBenchmarkStageDiagnostic({
|
|
492
|
+
runId,
|
|
493
|
+
reason,
|
|
494
|
+
runs,
|
|
495
|
+
fullOrder,
|
|
496
|
+
candidateSurface,
|
|
497
|
+
baselineSurface,
|
|
498
|
+
requestedModel,
|
|
499
|
+
requestedThinking,
|
|
500
|
+
suite,
|
|
501
|
+
manifest,
|
|
502
|
+
hostReadinessPolicy = null,
|
|
503
|
+
hostReadinessStageBoundaries = null,
|
|
504
|
+
generatedAt = new Date().toISOString()
|
|
505
|
+
}) {
|
|
506
|
+
const acceptedRuns = Array.isArray(runs) ? runs : [];
|
|
507
|
+
const expectedRuns = Array.isArray(fullOrder) ? fullOrder : [];
|
|
508
|
+
const pairs = expectedPairMap(expectedRuns);
|
|
509
|
+
const expectedRunKeys = new Set(expectedRuns.map(runKey));
|
|
510
|
+
const observedByRunKey = new Map();
|
|
511
|
+
const duplicateRuns = [];
|
|
512
|
+
const unexpectedRuns = [];
|
|
513
|
+
for (const run of acceptedRuns) {
|
|
514
|
+
const key = runKey(run);
|
|
515
|
+
if (!expectedRunKeys.has(key)) unexpectedRuns.push(key.replaceAll("\0", ":"));
|
|
516
|
+
if (observedByRunKey.has(key)) duplicateRuns.push(key.replaceAll("\0", ":"));
|
|
517
|
+
else observedByRunKey.set(key, run);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const completePairs = [];
|
|
521
|
+
const incompleteObservedPairs = [];
|
|
522
|
+
const unstartedPairs = [];
|
|
523
|
+
for (const pair of pairs.values()) {
|
|
524
|
+
const observed = [...pair.expectedSurfaces].filter((surface) => observedByRunKey.has(`${pair.scenarioId}\0${surface}\0${pair.repeat}`));
|
|
525
|
+
const missing = [...pair.expectedSurfaces].filter((surface) => !observed.includes(surface));
|
|
526
|
+
const summary = {
|
|
527
|
+
id: publicPairId(pair),
|
|
528
|
+
scenarioId: pair.scenarioId,
|
|
529
|
+
repeat: pair.repeat,
|
|
530
|
+
expectedSurfaces: [...pair.expectedSurfaces],
|
|
531
|
+
observedSurfaces: observed,
|
|
532
|
+
missingSurfaces: missing
|
|
533
|
+
};
|
|
534
|
+
if (observed.length === 0) unstartedPairs.push(summary);
|
|
535
|
+
else if (missing.length === 0) completePairs.push(summary);
|
|
536
|
+
else incompleteObservedPairs.push(summary);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
const pairRecords = completePairs.map((pair) => ({
|
|
540
|
+
pair,
|
|
541
|
+
candidate: observedByRunKey.get(`${pair.scenarioId}\0${candidateSurface}\0${pair.repeat}`),
|
|
542
|
+
baseline: observedByRunKey.get(`${pair.scenarioId}\0${baselineSurface}\0${pair.repeat}`)
|
|
543
|
+
}));
|
|
544
|
+
const malformedCompletePairs = pairRecords.filter(({ candidate, baseline }) => !candidate || !baseline).map(({ pair }) => pair.id);
|
|
545
|
+
const baselineOnlyRegressions = pairRecords
|
|
546
|
+
.filter(({ candidate, baseline }) => baseline?.resolved === true && candidate?.resolved !== true)
|
|
547
|
+
.map(({ pair, candidate, baseline }) => ({
|
|
548
|
+
pairId: pair.id,
|
|
549
|
+
baselineResolved: baseline.resolved,
|
|
550
|
+
candidateResolved: candidate?.resolved === true,
|
|
551
|
+
candidateFailure: candidate?.failure ?? null
|
|
552
|
+
}));
|
|
553
|
+
const noBaselineOnlyRegressionPassed = completePairs.length > 0
|
|
554
|
+
&& malformedCompletePairs.length === 0
|
|
555
|
+
&& baselineOnlyRegressions.length === 0;
|
|
556
|
+
const pairedGradeComparabilityFailures = pairRecords.filter(({ candidate, baseline }) => (
|
|
557
|
+
!Number.isFinite(candidate?.grade?.score) || !Number.isFinite(baseline?.grade?.score)
|
|
558
|
+
)).map(({ pair }) => pair.id);
|
|
559
|
+
const pairedGradeRegressions = pairRecords.filter(({ candidate, baseline }) => (
|
|
560
|
+
Number.isFinite(candidate?.grade?.score)
|
|
561
|
+
&& Number.isFinite(baseline?.grade?.score)
|
|
562
|
+
&& !atMostWithinFloatingPrecision(baseline.grade.score, candidate.grade.score)
|
|
563
|
+
)).map(({ pair, candidate, baseline }) => ({
|
|
564
|
+
pairId: pair.id,
|
|
565
|
+
baselineGradeScore: baseline.grade.score,
|
|
566
|
+
candidateGradeScore: candidate.grade.score
|
|
567
|
+
}));
|
|
568
|
+
const observedGradeNonInferiorPassed = pairRecords.length > 0
|
|
569
|
+
&& pairedGradeComparabilityFailures.length === 0
|
|
570
|
+
&& pairedGradeRegressions.length === 0;
|
|
571
|
+
const outcomeFloor = suite?.releaseGate?.minimumOutcomeScoreExclusive;
|
|
572
|
+
const outcomeFloorConfigured = Number.isFinite(outcomeFloor);
|
|
573
|
+
const outcomeFailures = outcomeFloorConfigured ? candidateOutcomeFailures(pairRecords, outcomeFloor) : [];
|
|
574
|
+
const outcomeFloorPassed = outcomeFloorConfigured
|
|
575
|
+
&& manifest?.stopAfterFailedPair === true
|
|
576
|
+
&& pairRecords.length > 0
|
|
577
|
+
&& outcomeFailures.length === 0;
|
|
578
|
+
const qualityPassed = noBaselineOnlyRegressionPassed && observedGradeNonInferiorPassed && outcomeFloorPassed;
|
|
579
|
+
|
|
580
|
+
const acceptedUsageFailures = acceptedRuns.map((run) => ({ runId: runKey(run).replaceAll("\0", ":"), issues: exactUsageIssues(run) }))
|
|
581
|
+
.filter((item) => item.issues.length > 0);
|
|
582
|
+
const acceptedUsagePassed = acceptedRuns.length > 0 && acceptedUsageFailures.length === 0;
|
|
583
|
+
|
|
584
|
+
const piRuns = acceptedRuns.filter((run) => run.surface === candidateSurface && candidateSurface === "piagent");
|
|
585
|
+
const piParityFailures = piRuns.map((run) => {
|
|
586
|
+
const issues = [];
|
|
587
|
+
if (run.usage?.model !== requestedModel) issues.push("accepted-model-mismatch");
|
|
588
|
+
if (run.usage?.thinkingLevel !== requestedThinking) issues.push("accepted-thinking-mismatch");
|
|
589
|
+
if (!benchmarkProviderWireEvidenceMatchesRequest(run.providerWireEvidence, requestedModel, requestedThinking)) {
|
|
590
|
+
issues.push("provider-wire-not-verified-or-request-bound");
|
|
591
|
+
}
|
|
592
|
+
return { runId: runKey(run).replaceAll("\0", ":"), issues };
|
|
593
|
+
}).filter((item) => item.issues.length > 0);
|
|
594
|
+
const pairedModelThinkingFailures = pairRecords.map(({ pair, candidate, baseline }) => ({
|
|
595
|
+
pairId: pair.id,
|
|
596
|
+
issues: [
|
|
597
|
+
candidate?.usage?.model !== baseline?.usage?.model ? "paired-model-mismatch" : null,
|
|
598
|
+
candidate?.usage?.thinkingLevel !== baseline?.usage?.thinkingLevel ? "paired-thinking-mismatch" : null
|
|
599
|
+
].filter(Boolean)
|
|
600
|
+
})).filter((item) => item.issues.length > 0);
|
|
601
|
+
const wireGroups = providerWireGroups(piRuns);
|
|
602
|
+
const wireDriftGroups = wireGroups.filter((group) => !group.passed);
|
|
603
|
+
const providerParityPassed = typeof requestedModel === "string" && requestedModel.length > 0
|
|
604
|
+
&& typeof requestedThinking === "string" && requestedThinking.length > 0
|
|
605
|
+
&& piRuns.length > 0
|
|
606
|
+
&& piParityFailures.length === 0
|
|
607
|
+
&& pairedModelThinkingFailures.length === 0
|
|
608
|
+
&& wireGroups.length > 0
|
|
609
|
+
&& wireDriftGroups.length === 0;
|
|
610
|
+
const causalContextRequired = suite?.releaseGate?.requireCausalContextReceipt === true;
|
|
611
|
+
const causalContextSummary = summarizeBenchmarkCausalContextEvidence(piRuns, { required: causalContextRequired });
|
|
612
|
+
const causalContextAvailableRuns = causalContextSummary.currentAvailableRuns;
|
|
613
|
+
const causalContextPassed = !causalContextRequired
|
|
614
|
+
|| causalContextSummary.currentCoverageStatus === "complete";
|
|
615
|
+
const providerFreeGuard = manifest?.productionGuards?.providerFreeEvidence;
|
|
616
|
+
const providerFreeEvidenceRequired = providerFreeGuard?.requiredBeforeFirstPaidSession === true;
|
|
617
|
+
const providerFreeEvidenceErrors = providerFreeEvidenceRequired
|
|
618
|
+
? productionProviderFreeEvidenceContextValidationErrors(manifest?.providerFreeEvidence, {
|
|
619
|
+
source: manifest?.sourceIdentity,
|
|
620
|
+
candidateProvenance: manifest?.candidateProvenance,
|
|
621
|
+
configurationDigest: manifest?.configurationDigest
|
|
622
|
+
})
|
|
623
|
+
: [];
|
|
624
|
+
const providerFreeObservedLaneIds = Array.isArray(manifest?.providerFreeEvidence?.lanes)
|
|
625
|
+
? manifest.providerFreeEvidence.lanes.map((lane) => lane?.id)
|
|
626
|
+
: [];
|
|
627
|
+
const providerFreeEvidencePassed = !providerFreeEvidenceRequired
|
|
628
|
+
|| (providerFreeEvidenceErrors.length === 0
|
|
629
|
+
&& Array.isArray(providerFreeGuard.requiredLaneIds)
|
|
630
|
+
&& JSON.stringify(providerFreeObservedLaneIds) === JSON.stringify(providerFreeGuard.requiredLaneIds));
|
|
631
|
+
const adaptiveContextStatuses = piRuns.map((run) => run?.causalContextReceipt?.aggregates?.runtimeCausal?.adaptiveContext?.coverageStatus ?? "not-observed");
|
|
632
|
+
const partialAdaptiveContextRuns = adaptiveContextStatuses.filter((status) => status === "partial").length;
|
|
633
|
+
const notObservedAdaptiveContextRuns = adaptiveContextStatuses.filter((status) => status === "not-observed").length;
|
|
634
|
+
const adaptiveContextCoveragePassed = !providerFreeEvidenceRequired || (partialAdaptiveContextRuns === 0
|
|
635
|
+
&& (notObservedAdaptiveContextRuns === 0 || providerFreeEvidencePassed));
|
|
636
|
+
|
|
637
|
+
const freshEfficiency = pairRatioEvidence(pairRecords, ({ candidate, baseline }) => ({
|
|
638
|
+
baseline: baseline?.usage?.fresh,
|
|
639
|
+
candidate: candidate?.usage?.fresh
|
|
640
|
+
}));
|
|
641
|
+
const freshEfficiencyPassed = freshEfficiency.records.length > 0
|
|
642
|
+
&& freshEfficiency.incomparablePairs.length === 0
|
|
643
|
+
&& freshEfficiency.pairRegressions.length === 0
|
|
644
|
+
&& freshEfficiency.familyRegressions.length === 0;
|
|
645
|
+
const guardPolicy = manifest?.productionGuards;
|
|
646
|
+
const subagentGuard = guardPolicy?.subagents;
|
|
647
|
+
const subagentBudget = summarizeBenchmarkSubagentBudget(acceptedRuns, {
|
|
648
|
+
candidateSurface,
|
|
649
|
+
policy: {
|
|
650
|
+
schemaVersion: 1,
|
|
651
|
+
id: "production-subagent-budget-v1",
|
|
652
|
+
maximumSubagentSessionsPerAttempt: subagentGuard?.maximumSessionsPerAttempt,
|
|
653
|
+
maximumSubagentTrafficShare: subagentGuard?.maximumTrafficShare
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
const subagentBudgetRequired = subagentGuard?.required === true;
|
|
657
|
+
const partialGuard = guardPolicy?.partialFreshSpend;
|
|
658
|
+
const partialSpendRequired = Number.isSafeInteger(partialGuard?.requiredFromCumulativeSessions)
|
|
659
|
+
&& acceptedRuns.length >= partialGuard.requiredFromCumulativeSessions
|
|
660
|
+
&& acceptedRuns.length < expectedRuns.length;
|
|
661
|
+
const partialSpend = partialCatastrophicSpendEvidence(pairRecords, {
|
|
662
|
+
maximumPooledFreshRatio: partialGuard?.maximumPooledFreshRatio,
|
|
663
|
+
maximumObservedFamilyFreshRatio: partialGuard?.maximumObservedFamilyFreshRatio
|
|
664
|
+
});
|
|
665
|
+
const partialSpendPassed = !partialSpendRequired || partialSpend.passed;
|
|
666
|
+
|
|
667
|
+
const pricingSnapshot = suite?.pricingSnapshot;
|
|
668
|
+
const pricingSnapshotErrors = benchmarkPricingSnapshotValidationErrors(pricingSnapshot);
|
|
669
|
+
const normalizedCostEvidence = pairRatioEvidence(pairRecords, ({ candidate, baseline }) => {
|
|
670
|
+
const normalizedBaseline = normalizeBenchmarkUsageCost(baseline?.usage, pricingSnapshot);
|
|
671
|
+
const normalizedCandidate = normalizeBenchmarkUsageCost(candidate?.usage, pricingSnapshot);
|
|
672
|
+
return {
|
|
673
|
+
baseline: normalizedBaseline.status === "measured" ? normalizedBaseline.amount : null,
|
|
674
|
+
candidate: normalizedCandidate.status === "measured" ? normalizedCandidate.amount : null,
|
|
675
|
+
issues: [
|
|
676
|
+
normalizedBaseline.status === "measured" ? null : `baseline:${normalizedBaseline.reason}`,
|
|
677
|
+
normalizedCandidate.status === "measured" ? null : `candidate:${normalizedCandidate.reason}`
|
|
678
|
+
].filter(Boolean)
|
|
679
|
+
};
|
|
680
|
+
});
|
|
681
|
+
const normalizedCostPassed = pricingSnapshotErrors.length === 0
|
|
682
|
+
&& normalizedCostEvidence.records.length > 0
|
|
683
|
+
&& normalizedCostEvidence.incomparablePairs.length === 0
|
|
684
|
+
&& normalizedCostEvidence.pairRegressions.length === 0
|
|
685
|
+
&& normalizedCostEvidence.familyRegressions.length === 0;
|
|
686
|
+
|
|
687
|
+
const durationEfficiency = pairRatioEvidence(pairRecords, ({ candidate, baseline }) => ({
|
|
688
|
+
baseline: baseline?.durationSeconds,
|
|
689
|
+
candidate: candidate?.durationSeconds
|
|
690
|
+
}));
|
|
691
|
+
const durationEfficiencyPassed = durationEfficiency.records.length > 0
|
|
692
|
+
&& durationEfficiency.incomparablePairs.length === 0
|
|
693
|
+
&& durationEfficiency.pairRegressions.length === 0
|
|
694
|
+
&& durationEfficiency.familyRegressions.length === 0;
|
|
695
|
+
|
|
696
|
+
const retryEvidenceFailures = acceptedRuns.map((run) => {
|
|
697
|
+
const issues = [];
|
|
698
|
+
if (!Number.isInteger(run.infrastructureRetries) || run.infrastructureRetries < 0) issues.push("invalid-infrastructure-retry-count");
|
|
699
|
+
if (!Array.isArray(run.infrastructureFailures)) issues.push("missing-infrastructure-failure-ledger");
|
|
700
|
+
else if (Number.isInteger(run.infrastructureRetries) && run.infrastructureFailures.length !== run.infrastructureRetries) {
|
|
701
|
+
issues.push("retry-ledger-count-mismatch");
|
|
702
|
+
}
|
|
703
|
+
return { runId: runKey(run).replaceAll("\0", ":"), issues };
|
|
704
|
+
}).filter((item) => item.issues.length > 0);
|
|
705
|
+
const infrastructureRetries = acceptedRuns.reduce((sum, run) => sum + (Number.isInteger(run.infrastructureRetries) ? run.infrastructureRetries : 0), 0);
|
|
706
|
+
const failedAttempts = acceptedRuns.reduce((sum, run) => sum + (Array.isArray(run.infrastructureFailures) ? run.infrastructureFailures.length : 0), 0);
|
|
707
|
+
const failedAttemptUnknownUsage = acceptedRuns.reduce((sum, run) => sum + (run.infrastructureFailures ?? [])
|
|
708
|
+
.filter((attempt) => attempt?.usageStatus === "unknown-after-provider-start").length, 0);
|
|
709
|
+
const manifestUnknownUsage = Number.isInteger(manifest?.unknownCostAttempts) && manifest.unknownCostAttempts >= 0
|
|
710
|
+
? manifest.unknownCostAttempts
|
|
711
|
+
: manifest?.unknownCostAttempts === undefined ? 0 : 1;
|
|
712
|
+
const recoveredProviderAttempts = Array.isArray(manifest?.recoveredProviderAttempts)
|
|
713
|
+
? manifest.recoveredProviderAttempts.length
|
|
714
|
+
: manifest?.recoveredProviderAttempts === undefined ? 0 : 1;
|
|
715
|
+
const tokenClaimsUnavailableReason = typeof manifest?.tokenClaimsUnavailableReason === "string"
|
|
716
|
+
? manifest.tokenClaimsUnavailableReason
|
|
717
|
+
: manifest?.tokenClaimsUnavailableReason === undefined ? null : "malformed-token-claims-unavailable-reason";
|
|
718
|
+
const retryGatePassed = retryEvidenceFailures.length === 0
|
|
719
|
+
&& infrastructureRetries === 0
|
|
720
|
+
&& failedAttempts === 0
|
|
721
|
+
&& recoveredProviderAttempts === 0;
|
|
722
|
+
const unknownUsageAttempts = failedAttemptUnknownUsage + manifestUnknownUsage;
|
|
723
|
+
const unknownUsagePassed = unknownUsageAttempts === 0 && tokenClaimsUnavailableReason === null;
|
|
724
|
+
|
|
725
|
+
const pairBoundary = incompleteObservedPairs.length === 0
|
|
726
|
+
&& duplicateRuns.length === 0
|
|
727
|
+
&& unexpectedRuns.length === 0;
|
|
728
|
+
const recognizedPause = typeof reason === "string"
|
|
729
|
+
&& (reason.startsWith("max-sessions:") || reason.startsWith("max-runtime-minutes:"));
|
|
730
|
+
const pairContractPassed = pairs.size > 0
|
|
731
|
+
&& [...pairs.values()].every((pair) => pair.expectedSurfaces.size === 2
|
|
732
|
+
&& pair.expectedSurfaces.has(candidateSurface)
|
|
733
|
+
&& pair.expectedSurfaces.has(baselineSurface));
|
|
734
|
+
const executionContractPassed = manifest?.stopAfterFailedPair === true
|
|
735
|
+
&& manifest?.infrastructureRetries === 0;
|
|
736
|
+
const cleanReleaseSourceRequired = suite?.schemaVersion === 2
|
|
737
|
+
&& suite?.releaseGate?.requireEfficiencyClaim === true
|
|
738
|
+
&& suite?.releaseGate?.requireFullSuiteForClaim === true;
|
|
739
|
+
const cleanReleaseSourcePassed = !cleanReleaseSourceRequired || manifest?.sourceIdentity?.dirty === false;
|
|
740
|
+
const hostReadinessRequired = suite?.releaseGate?.requireHostReadinessForClaim === true;
|
|
741
|
+
const summarizedHostReadinessHistory = hostReadinessRequired
|
|
742
|
+
? summarizeBenchmarkHostReadinessHistory({
|
|
743
|
+
policy: hostReadinessPolicy,
|
|
744
|
+
receipts: manifest?.hostReadinessReceipts,
|
|
745
|
+
completedRuns: acceptedRuns.length,
|
|
746
|
+
authorizedThroughRuns: manifest?.stageControl?.authorizedThroughRuns,
|
|
747
|
+
runId: manifest?.runId ?? runId,
|
|
748
|
+
configurationDigest: manifest?.configurationDigest,
|
|
749
|
+
stageBoundaries: hostReadinessStageBoundaries
|
|
750
|
+
})
|
|
751
|
+
: null;
|
|
752
|
+
const hostReadinessPolicyBindingValid = !hostReadinessRequired
|
|
753
|
+
|| (benchmarkHostReadinessPolicyValidationErrors(hostReadinessPolicy).length === 0
|
|
754
|
+
&& manifest?.hostReadinessPolicyDigest === benchmarkHostReadinessPolicyDigest(hostReadinessPolicy));
|
|
755
|
+
const hostReadinessHistory = summarizedHostReadinessHistory && !hostReadinessPolicyBindingValid
|
|
756
|
+
? {
|
|
757
|
+
...summarizedHostReadinessHistory,
|
|
758
|
+
valid: false,
|
|
759
|
+
ready: false,
|
|
760
|
+
errors: [...summarizedHostReadinessHistory.errors, "host-readiness-manifest-policy-digest-mismatch"]
|
|
761
|
+
}
|
|
762
|
+
: summarizedHostReadinessHistory;
|
|
763
|
+
const hostReadinessPassed = !hostReadinessRequired
|
|
764
|
+
|| (hostReadinessHistory.valid === true && hostReadinessHistory.ready === true);
|
|
765
|
+
const checks = [
|
|
766
|
+
diagnosticCheck("recognized-spend-control-pause", recognizedPause, { reason }),
|
|
767
|
+
diagnosticCheck("paired-contract", pairContractPassed, { candidateSurface, baselineSurface }),
|
|
768
|
+
diagnosticCheck("spend-control-execution-contract", executionContractPassed, {
|
|
769
|
+
stopAfterFailedPair: manifest?.stopAfterFailedPair === true,
|
|
770
|
+
infrastructureRetries: Number.isInteger(manifest?.infrastructureRetries) ? manifest.infrastructureRetries : null
|
|
771
|
+
}),
|
|
772
|
+
diagnosticCheck("clean-release-source", cleanReleaseSourcePassed, {
|
|
773
|
+
required: cleanReleaseSourceRequired,
|
|
774
|
+
dirty: typeof manifest?.sourceIdentity?.dirty === "boolean" ? manifest.sourceIdentity.dirty : null
|
|
775
|
+
}),
|
|
776
|
+
diagnosticCheck("host-readiness-receipt-history", hostReadinessPassed, {
|
|
777
|
+
required: hostReadinessRequired,
|
|
778
|
+
validReceipts: hostReadinessHistory?.validReceiptCount ?? 0,
|
|
779
|
+
receipts: hostReadinessHistory?.receiptCount ?? 0,
|
|
780
|
+
coverage: hostReadinessHistory?.windowCoverage ?? null
|
|
781
|
+
}, hostReadinessRequired ? "blocking" : "observational"),
|
|
782
|
+
diagnosticCheck("pause-on-pair-boundary", pairBoundary, { incompleteObservedPairs: incompleteObservedPairs.length }),
|
|
783
|
+
diagnosticCheck("observed-complete-pair", completePairs.length > 0, { observedCompletePairs: completePairs.length }),
|
|
784
|
+
diagnosticCheck("no-baseline-pass-piagent-fail", noBaselineOnlyRegressionPassed, { regressions: baselineOnlyRegressions.length }),
|
|
785
|
+
diagnosticCheck("observed-paired-grade-noninferior", observedGradeNonInferiorPassed, {
|
|
786
|
+
incomparablePairs: pairedGradeComparabilityFailures.length,
|
|
787
|
+
regressions: pairedGradeRegressions.length
|
|
788
|
+
}),
|
|
789
|
+
diagnosticCheck("candidate-outcome-floor", outcomeFloorPassed, {
|
|
790
|
+
minimumOutcomeScoreExclusive: outcomeFloorConfigured ? outcomeFloor : null,
|
|
791
|
+
failures: outcomeFailures.length
|
|
792
|
+
}),
|
|
793
|
+
diagnosticCheck("accepted-usage-exact", acceptedUsagePassed, { failures: acceptedUsageFailures.length }),
|
|
794
|
+
diagnosticCheck("provider-wire-model-thinking-parity", providerParityPassed, { failures: piParityFailures.length + pairedModelThinkingFailures.length + wireDriftGroups.length }),
|
|
795
|
+
diagnosticCheck("piagent-causal-context-receipts", causalContextPassed, {
|
|
796
|
+
required: causalContextRequired,
|
|
797
|
+
availableRuns: causalContextAvailableRuns,
|
|
798
|
+
piagentRuns: piRuns.length,
|
|
799
|
+
unavailableRuns: piRuns.length - causalContextAvailableRuns
|
|
800
|
+
}),
|
|
801
|
+
diagnosticCheck("source-bound-provider-free-evidence", providerFreeEvidencePassed, {
|
|
802
|
+
required: providerFreeEvidenceRequired,
|
|
803
|
+
expectedLaneIds: providerFreeGuard?.requiredLaneIds ?? [],
|
|
804
|
+
observedLaneIds: providerFreeObservedLaneIds,
|
|
805
|
+
errors: providerFreeEvidenceErrors
|
|
806
|
+
}),
|
|
807
|
+
diagnosticCheck("adaptive-context-runtime-coverage", adaptiveContextCoveragePassed, {
|
|
808
|
+
partialRuns: partialAdaptiveContextRuns,
|
|
809
|
+
notObservedRuns: notObservedAdaptiveContextRuns,
|
|
810
|
+
notObservedCoveredBySameSourceProviderFreeLane: providerFreeEvidencePassed
|
|
811
|
+
}),
|
|
812
|
+
diagnosticCheck("no-infrastructure-retry", retryGatePassed, { retries: infrastructureRetries }),
|
|
813
|
+
diagnosticCheck("no-unknown-attempt-usage", unknownUsagePassed, { unknownUsageAttempts }),
|
|
814
|
+
diagnosticCheck("production-subagent-budget", !subagentBudgetRequired || subagentBudget.passed, {
|
|
815
|
+
required: subagentBudgetRequired,
|
|
816
|
+
attempts: subagentBudget.attempts,
|
|
817
|
+
exactAttempts: subagentBudget.exactAttempts,
|
|
818
|
+
maximumObservedSessionsPerAttempt: subagentBudget.maximumObservedSessionsPerAttempt,
|
|
819
|
+
trafficShare: subagentBudget.trafficShare,
|
|
820
|
+
failures: subagentBudget.failures
|
|
821
|
+
}),
|
|
822
|
+
diagnosticCheck("partial-stage-catastrophic-fresh-spend", partialSpendPassed, {
|
|
823
|
+
required: partialSpendRequired,
|
|
824
|
+
pooledRatio: partialSpend.pooledRatio,
|
|
825
|
+
maximumPooledFreshRatio: partialSpend.maximumPooledFreshRatio,
|
|
826
|
+
familyFailures: partialSpend.familyFailures,
|
|
827
|
+
maximumObservedFamilyFreshRatio: partialSpend.maximumObservedFamilyFreshRatio,
|
|
828
|
+
exactUsageIncludingFailedAttempts: partialSpend.exactUsageIncludingFailedAttempts
|
|
829
|
+
}),
|
|
830
|
+
diagnosticCheck("no-observed-fresh-token-regression", freshEfficiencyPassed, {
|
|
831
|
+
incomparablePairs: freshEfficiency.incomparablePairs.length,
|
|
832
|
+
pairRegressions: freshEfficiency.pairRegressions.length,
|
|
833
|
+
familyRegressions: freshEfficiency.familyRegressions.length
|
|
834
|
+
}, "final-only"),
|
|
835
|
+
diagnosticCheck("normalized-cost-pricing-applicable-and-no-observed-regression", normalizedCostPassed, {
|
|
836
|
+
pricingSnapshotErrors: pricingSnapshotErrors.length,
|
|
837
|
+
incomparablePairs: normalizedCostEvidence.incomparablePairs.length,
|
|
838
|
+
pairRegressions: normalizedCostEvidence.pairRegressions.length,
|
|
839
|
+
familyRegressions: normalizedCostEvidence.familyRegressions.length
|
|
840
|
+
}, "observational"),
|
|
841
|
+
diagnosticCheck("no-observed-duration-regression", durationEfficiencyPassed, {
|
|
842
|
+
incomparablePairs: durationEfficiency.incomparablePairs.length,
|
|
843
|
+
pairRegressions: durationEfficiency.pairRegressions.length,
|
|
844
|
+
familyRegressions: durationEfficiency.familyRegressions.length
|
|
845
|
+
}, "observational")
|
|
846
|
+
];
|
|
847
|
+
const blockingReasons = checks
|
|
848
|
+
.filter((check) => check.decisionRole === "blocking" && !check.passed)
|
|
849
|
+
.map((check) => check.id);
|
|
850
|
+
|
|
851
|
+
return {
|
|
852
|
+
schemaVersion: 1,
|
|
853
|
+
diagnosticOnly: true,
|
|
854
|
+
claimEligible: false,
|
|
855
|
+
runId,
|
|
856
|
+
generatedAt,
|
|
857
|
+
pause: { reason, recognizedSpendControlPause: recognizedPause, pairBoundary },
|
|
858
|
+
completedRuns: acceptedRuns.length,
|
|
859
|
+
expectedRuns: expectedRuns.length,
|
|
860
|
+
remainingRuns: Math.max(0, expectedRuns.length - acceptedRuns.length),
|
|
861
|
+
counts: {
|
|
862
|
+
completedSessions: acceptedRuns.length,
|
|
863
|
+
expectedSessions: expectedRuns.length,
|
|
864
|
+
expectedPairs: pairs.size,
|
|
865
|
+
observedCompletePairs: completePairs.length,
|
|
866
|
+
incompleteObservedPairs: incompleteObservedPairs.length,
|
|
867
|
+
unstartedPairs: unstartedPairs.length,
|
|
868
|
+
duplicateSessions: duplicateRuns.length,
|
|
869
|
+
unexpectedSessions: unexpectedRuns.length
|
|
870
|
+
},
|
|
871
|
+
pairs: {
|
|
872
|
+
completeObserved: completePairs,
|
|
873
|
+
incompleteObserved: incompleteObservedPairs,
|
|
874
|
+
unstarted: unstartedPairs,
|
|
875
|
+
duplicateRuns,
|
|
876
|
+
unexpectedRuns,
|
|
877
|
+
futureUnstartedPairsBlockStageAdvance: false
|
|
878
|
+
},
|
|
879
|
+
quality: {
|
|
880
|
+
rule: "no-baseline-pass-piagent-fail-and-candidate-outcomes-above-the-release-floor",
|
|
881
|
+
passed: qualityPassed,
|
|
882
|
+
noBaselineOnlyRegressionPassed,
|
|
883
|
+
observedGradeNonInferiorPassed,
|
|
884
|
+
observedCompletePairs: completePairs.length,
|
|
885
|
+
malformedCompletePairs,
|
|
886
|
+
baselineOnlyRegressions,
|
|
887
|
+
pairedGradeComparabilityFailures,
|
|
888
|
+
pairedGradeRegressions,
|
|
889
|
+
outcomeFloor: outcomeFloorConfigured ? {
|
|
890
|
+
minimumScoreExclusive: outcomeFloor,
|
|
891
|
+
stopAfterFailedPairEnabled: manifest?.stopAfterFailedPair === true,
|
|
892
|
+
passed: outcomeFloorPassed,
|
|
893
|
+
failures: outcomeFailures
|
|
894
|
+
} : {
|
|
895
|
+
minimumScoreExclusive: null,
|
|
896
|
+
stopAfterFailedPairEnabled: manifest?.stopAfterFailedPair === true,
|
|
897
|
+
passed: false,
|
|
898
|
+
failures: [{ failures: ["outcome-floor-not-configured"] }]
|
|
899
|
+
}
|
|
900
|
+
},
|
|
901
|
+
acceptedUsage: {
|
|
902
|
+
rule: "every-accepted-session-has-exact-provider-token-buckets",
|
|
903
|
+
passed: acceptedUsagePassed,
|
|
904
|
+
exactRuns: acceptedRuns.length - acceptedUsageFailures.length,
|
|
905
|
+
acceptedRuns: acceptedRuns.length,
|
|
906
|
+
failures: acceptedUsageFailures
|
|
907
|
+
},
|
|
908
|
+
providerParity: {
|
|
909
|
+
rule: "observed-pi-runs-match-requested-model-thinking-and-verified-provider-wire",
|
|
910
|
+
passed: providerParityPassed,
|
|
911
|
+
requestedModel: requestedModel ?? null,
|
|
912
|
+
requestedThinking: requestedThinking ?? null,
|
|
913
|
+
observedPiRuns: piRuns.length,
|
|
914
|
+
verifiedPiRuns: piRuns.length - piParityFailures.length,
|
|
915
|
+
piRunFailures: piParityFailures,
|
|
916
|
+
pairedModelThinkingFailures,
|
|
917
|
+
wireGroups,
|
|
918
|
+
wireDriftGroups
|
|
919
|
+
},
|
|
920
|
+
causalContextEvidence: {
|
|
921
|
+
rule: "every-observed-piagent-session-preserves-a-complete-privacy-safe-causal-context-receipt",
|
|
922
|
+
passed: causalContextPassed,
|
|
923
|
+
piagentRuns: piRuns.length,
|
|
924
|
+
...causalContextSummary
|
|
925
|
+
},
|
|
926
|
+
providerFreeEvidence: {
|
|
927
|
+
required: providerFreeEvidenceRequired,
|
|
928
|
+
passed: providerFreeEvidencePassed,
|
|
929
|
+
errors: providerFreeEvidenceErrors,
|
|
930
|
+
expectedLaneIds: providerFreeGuard?.requiredLaneIds ?? [],
|
|
931
|
+
observedLaneIds: providerFreeObservedLaneIds
|
|
932
|
+
},
|
|
933
|
+
adaptiveContextRuntimeCoverage: {
|
|
934
|
+
passed: adaptiveContextCoveragePassed,
|
|
935
|
+
partialRuns: partialAdaptiveContextRuns,
|
|
936
|
+
notObservedRuns: notObservedAdaptiveContextRuns,
|
|
937
|
+
delegatedToProviderFreeEvidence: notObservedAdaptiveContextRuns > 0 && providerFreeEvidencePassed
|
|
938
|
+
},
|
|
939
|
+
infrastructure: {
|
|
940
|
+
retryGatePassed,
|
|
941
|
+
retryEvidenceFailures,
|
|
942
|
+
infrastructureRetries,
|
|
943
|
+
failedAttempts,
|
|
944
|
+
recoveredProviderAttempts,
|
|
945
|
+
unknownUsageGatePassed: unknownUsagePassed,
|
|
946
|
+
unknownUsageAttempts,
|
|
947
|
+
failedAttemptUnknownUsage,
|
|
948
|
+
manifestUnknownUsage,
|
|
949
|
+
tokenClaimsUnavailableReason
|
|
950
|
+
},
|
|
951
|
+
hostReadiness: hostReadinessHistory,
|
|
952
|
+
timingDiagnostics: summarizeBenchmarkTimingDiagnostics(acceptedRuns),
|
|
953
|
+
spendFutilityReview: {
|
|
954
|
+
rule: "partial-stages-from-the-frozen-boundary-enforce-exact-all-attempt-pooled-and-family-fresh-spend-ceilings; this-is-not-the-final-40-percent-claim-gate",
|
|
955
|
+
passed: partialSpendPassed && (!subagentBudgetRequired || subagentBudget.passed),
|
|
956
|
+
freshTokens: { passed: freshEfficiencyPassed, ...freshEfficiency },
|
|
957
|
+
partialStageCatastrophicFreshSpend: { required: partialSpendRequired, ...partialSpend },
|
|
958
|
+
subagentBudget,
|
|
959
|
+
normalizedApiEquivalentTextTokenCost: {
|
|
960
|
+
billedCost: false,
|
|
961
|
+
scope: "model-text-token-input-cache-output-only",
|
|
962
|
+
pricingSnapshotId: pricingSnapshotErrors.length === 0 ? pricingSnapshot.id : null,
|
|
963
|
+
pricingSnapshotErrors,
|
|
964
|
+
passed: normalizedCostPassed,
|
|
965
|
+
...normalizedCostEvidence
|
|
966
|
+
},
|
|
967
|
+
duration: { passed: durationEfficiencyPassed, ...durationEfficiency }
|
|
968
|
+
},
|
|
969
|
+
checks,
|
|
970
|
+
blockingReasons,
|
|
971
|
+
stageAdvanceAllowed: blockingReasons.length === 0,
|
|
972
|
+
decisionContract: {
|
|
973
|
+
blocking: "quality-model-parity-task-continuity-exact-usage-subagent-budget-and-partial-stage-catastrophic-fresh-spend",
|
|
974
|
+
finalOnly: ["0.60-upper95-fresh-token-reduction"],
|
|
975
|
+
observational: ["normalized-api-equivalent-text-token-cost", "duration", "host-load"]
|
|
976
|
+
},
|
|
977
|
+
claimBoundary: "Provider-free partial-run diagnostic only. Intermediate token measurements cannot make a claim; cost, duration, and host load are observational and non-blocking."
|
|
978
|
+
};
|
|
979
|
+
}
|