@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,380 @@
|
|
|
1
|
+
import {
|
|
2
|
+
atMostWithinFloatingPrecision,
|
|
3
|
+
clamp,
|
|
4
|
+
median,
|
|
5
|
+
rounded,
|
|
6
|
+
wilsonInterval
|
|
7
|
+
} from "./benchmark-statistics.js";
|
|
8
|
+
|
|
9
|
+
const SURFACE_REPORT_KEYS = Object.freeze({
|
|
10
|
+
"raw-pi": "rawPi",
|
|
11
|
+
piagent: "piagent",
|
|
12
|
+
"codex-cli": "codexCli"
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const RELEASE_FAILURE_MESSAGES = Object.freeze({
|
|
16
|
+
"quality-regression": "Piagent quality is below the paired baseline.",
|
|
17
|
+
"paired-quality-noninferiority": "Every declared scenario/repeat must have an exact paired grade and Piagent must not score below Codex CLI on any pair.",
|
|
18
|
+
quality: "Piagent quality is below the suite minimum.",
|
|
19
|
+
safety: "Piagent safety is below the suite minimum.",
|
|
20
|
+
reliability: "Piagent reliability is below the suite minimum.",
|
|
21
|
+
workflow: "Piagent workflow evidence is below the suite minimum.",
|
|
22
|
+
category: "At least one category score is below the suite minimum.",
|
|
23
|
+
"outcome-score-floor": "At least one task, aggregate, or band score does not clear the exclusive outcome floor.",
|
|
24
|
+
"paired-candidate-regression": "At least one paired task passed on the baseline and failed on Piagent.",
|
|
25
|
+
"candidate-task-continuity": "Every Piagent session must resolve successfully and preserve all required workflow checks.",
|
|
26
|
+
"comparison-protocol": "The same-model, same-effort, isolation, or randomized-order comparison protocol is incomplete.",
|
|
27
|
+
"full-suite": "This run selected only part of a suite that requires full-suite evidence.",
|
|
28
|
+
"paired-outcome-evidence": "Too few scenario families have complete paired outcomes.",
|
|
29
|
+
"efficiency-evidence": "Too few scenario families have complete comparable token measurements.",
|
|
30
|
+
"efficiency-category-coverage": "Comparable token evidence does not cover every required category.",
|
|
31
|
+
"failure-aware-efficiency": "Tokens per resolved outcome exceed the suite limit or failed-attempt usage is unknown.",
|
|
32
|
+
"primary-efficiency": "The predeclared primary efficiency estimand lacks complete family/category evidence or its upper 95% ratio exceeds the suite limit.",
|
|
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
|
+
"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.",
|
|
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
|
+
"repeat-count": "The run used fewer repeats than the suite minimum.",
|
|
38
|
+
"efficiency-confidence": "The upper 95% token-ratio bound exceeds the suite limit.",
|
|
39
|
+
"efficiency-band-ratio": "At least one category, profile, lifecycle, or difficulty fresh-token ratio exceeds the suite limit.",
|
|
40
|
+
"efficiency-family-ratio": "At least one comparable scenario family uses more fresh tokens than the suite family guardrail permits.",
|
|
41
|
+
"accepted-usage-completeness": "Every accepted benchmark attempt must have exact terminal token buckets.",
|
|
42
|
+
"all-attempt-usage-completeness": "Every accepted or failed provider attempt must have exact invariant-checked token buckets.",
|
|
43
|
+
"normalized-cost-configuration": "Normalized-cost claims require a valid versioned pricing snapshot and all predeclared ratio thresholds.",
|
|
44
|
+
"normalized-cost-evidence": "Normalized API-equivalent text-token cost evidence is incomplete for at least one declared scenario family.",
|
|
45
|
+
"normalized-cost-pricing-applicability": "Exact usage or per-request pricing applicability is unavailable for at least one accepted run.",
|
|
46
|
+
"normalized-cost-confidence": "The family-clustered normalized-cost upper 95% ratio exceeds the suite limit.",
|
|
47
|
+
"normalized-cost-band-ratio": "At least one category, profile, lifecycle, or difficulty normalized-cost point ratio exceeds the suite limit.",
|
|
48
|
+
"normalized-cost-family-ratio": "At least one declared scenario family exceeds the normalized-cost guardrail or lacks complete evidence.",
|
|
49
|
+
"performance-evidence": "Too few scenario families have complete paired duration measurements.",
|
|
50
|
+
"performance-point-regression": "The paired duration point estimate is slower than the baseline.",
|
|
51
|
+
"performance-confidence": "The upper 95% duration-ratio bound exceeds the suite limit.",
|
|
52
|
+
"performance-band-ratio": "At least one category, profile, lifecycle, or difficulty duration point ratio exceeds the suite limit.",
|
|
53
|
+
"performance-family-ratio": "At least one declared scenario family is slower than the duration guardrail or lacks complete duration evidence.",
|
|
54
|
+
"infrastructure-retries": "Accepted benchmark runs used more recovered infrastructure retries than the suite permits.",
|
|
55
|
+
"infrastructure-failure-ledger": "Accepted benchmark runs do not contain an exact attempt/retry/failure ledger.",
|
|
56
|
+
"unknown-infrastructure-usage": "At least one provider-started infrastructure attempt has unknown terminal usage.",
|
|
57
|
+
"canonical-production-identity": "The production-v1 suite id is reserved for the canonical built-in suite identity.",
|
|
58
|
+
"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
|
+
"codex-baseline": "Token-saving product claims require controlled Codex CLI as the paired baseline.",
|
|
60
|
+
"clean-release-source": "Release claims require an exact clean Git commit; dirty or unbound source trees are diagnostic only.",
|
|
61
|
+
"host-readiness-history": "Production claims require fresh run/configuration-bound privacy-safe host-readiness receipts on every paid invocation with continuous frozen-stage coverage.",
|
|
62
|
+
"provider-wire-surface": "Every Piagent run must expose known provider-wire evidence with the exact requested model and effort plus one stable base instructions hash and one stable ordered tool-surface hash.",
|
|
63
|
+
"causal-context-evidence": "Every Piagent run must preserve a complete privacy-safe causal context receipt before workspace cleanup."
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
export function workflowContinuityEvidenceComplete(workflow) {
|
|
67
|
+
const checks = workflow?.checks;
|
|
68
|
+
if (!Array.isArray(checks) || checks.length === 0) return false;
|
|
69
|
+
const requiredChecks = checks.filter((check) => !(
|
|
70
|
+
Number.isFinite(check?.weight) && check.weight > 0 && check.weight < 1
|
|
71
|
+
));
|
|
72
|
+
return requiredChecks.length > 0 && requiredChecks.every((check) => check?.passed === true);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const TOKEN_BAND_DIMENSIONS = Object.freeze({
|
|
76
|
+
categories: "category",
|
|
77
|
+
profiles: "profile",
|
|
78
|
+
lifecycles: "lifecycle",
|
|
79
|
+
difficulties: "difficulty"
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export function evaluateFreshTokenBandGate(suite, bands, maximum) {
|
|
83
|
+
if (!Number.isFinite(maximum)) return { passed: null, threshold: null, failures: [] };
|
|
84
|
+
const failures = [];
|
|
85
|
+
for (const [dimension, field] of Object.entries(TOKEN_BAND_DIMENSIONS)) {
|
|
86
|
+
const required = [...new Set(suite.scenarios.map((scenario) => scenario[field] ?? "unspecified"))].sort();
|
|
87
|
+
for (const name of required) {
|
|
88
|
+
const band = bands[dimension]?.[name];
|
|
89
|
+
const ratio = band?.freshTokenRatio;
|
|
90
|
+
if (!Number.isFinite(ratio) || !atMostWithinFloatingPrecision(ratio, maximum)) {
|
|
91
|
+
failures.push({
|
|
92
|
+
dimension,
|
|
93
|
+
name,
|
|
94
|
+
ratio: Number.isFinite(ratio) ? ratio : null,
|
|
95
|
+
upper95: Number.isFinite(band?.freshTokenRatioConfidence95?.upper) ? band.freshTokenRatioConfidence95.upper : null,
|
|
96
|
+
observedBound: Number.isFinite(ratio) ? ratio : null,
|
|
97
|
+
reason: Number.isFinite(ratio) ? "ratio-above-limit" : "missing-comparable-usage"
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { passed: failures.length === 0, threshold: maximum, failures };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function evaluateDurationBandGate(suite, bands, maximum) {
|
|
106
|
+
if (!Number.isFinite(maximum)) return { passed: null, threshold: null, failures: [] };
|
|
107
|
+
const failures = [];
|
|
108
|
+
for (const [dimension, field] of Object.entries(TOKEN_BAND_DIMENSIONS)) {
|
|
109
|
+
const required = [...new Set(suite.scenarios.map((scenario) => scenario[field] ?? "unspecified"))].sort();
|
|
110
|
+
for (const name of required) {
|
|
111
|
+
const band = bands[dimension]?.[name];
|
|
112
|
+
const ratio = band?.durationRatio;
|
|
113
|
+
if (!Number.isFinite(ratio) || !atMostWithinFloatingPrecision(ratio, maximum)) {
|
|
114
|
+
failures.push({
|
|
115
|
+
dimension,
|
|
116
|
+
name,
|
|
117
|
+
ratio: Number.isFinite(ratio) ? ratio : null,
|
|
118
|
+
reason: Number.isFinite(ratio) ? "ratio-above-limit" : "missing-comparable-duration"
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return { passed: failures.length === 0, threshold: maximum, failures };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function surfaceReportKey(surface) {
|
|
127
|
+
return SURFACE_REPORT_KEYS[surface] ?? surface;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function usageMedians(runs) {
|
|
131
|
+
return {
|
|
132
|
+
runs: runs.length,
|
|
133
|
+
medianFreshTokens: median(runs.map((run) => run.usage?.fresh)),
|
|
134
|
+
medianInputTokens: median(runs.map((run) => run.usage?.input)),
|
|
135
|
+
medianOutputTokens: median(runs.map((run) => run.usage?.output)),
|
|
136
|
+
medianCacheReadTokens: median(runs.map((run) => run.usage?.cacheRead)),
|
|
137
|
+
medianCacheWriteTokens: median(runs.map((run) => run.usage?.cacheWrite)),
|
|
138
|
+
medianReasoningTokens: median(runs.map((run) => run.usage?.reasoning)),
|
|
139
|
+
medianTotalTokens: median(runs.map((run) => run.usage?.total)),
|
|
140
|
+
medianCost: median(runs.map((run) => run.usage?.cost)),
|
|
141
|
+
medianDurationSeconds: median(runs.map((run) => run.durationSeconds)),
|
|
142
|
+
medianToolCalls: median(runs.map((run) => run.usage?.toolCalls))
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function aggregateToolNames(runs) {
|
|
147
|
+
const totals = {};
|
|
148
|
+
for (const run of runs) {
|
|
149
|
+
for (const [name, count] of Object.entries(run.usage?.toolNames ?? {})) {
|
|
150
|
+
totals[name] = (totals[name] ?? 0) + Number(count ?? 0);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return Object.fromEntries(Object.entries(totals).sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0])));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function reliabilityScore(runs) {
|
|
157
|
+
if (runs.length === 0) return 0;
|
|
158
|
+
const grouped = new Map();
|
|
159
|
+
for (const run of runs) {
|
|
160
|
+
const values = grouped.get(run.scenarioId) ?? [];
|
|
161
|
+
values.push(run.resolved === true);
|
|
162
|
+
grouped.set(run.scenarioId, values);
|
|
163
|
+
}
|
|
164
|
+
const passRate = runs.filter((run) => run.resolved === true).length / runs.length;
|
|
165
|
+
const allPassRate = [...grouped.values()].filter((values) => values.every(Boolean)).length / grouped.size;
|
|
166
|
+
return 10 * ((passRate * 0.7) + (allPassRate * 0.3));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function dimensionBands(runs, field) {
|
|
170
|
+
const grouped = new Map();
|
|
171
|
+
for (const run of runs) {
|
|
172
|
+
const key = typeof run[field] === "string" && run[field] ? run[field] : "unspecified";
|
|
173
|
+
const values = grouped.get(key) ?? [];
|
|
174
|
+
values.push(run);
|
|
175
|
+
grouped.set(key, values);
|
|
176
|
+
}
|
|
177
|
+
return Object.fromEntries([...grouped.entries()].sort(([left], [right]) => left.localeCompare(right)).map(([key, values]) => {
|
|
178
|
+
const resolved = values.filter((run) => run.resolved === true).length;
|
|
179
|
+
const correctnessRuns = values.filter((run) => run.scenarioKind !== "safety-refusal");
|
|
180
|
+
const correct = correctnessRuns.filter((run) => run.grade?.passed === true && run.graderIntegrity?.passed === true && run.outputEvidence?.passed !== false).length;
|
|
181
|
+
return [key, {
|
|
182
|
+
runs: values.length,
|
|
183
|
+
resolved,
|
|
184
|
+
passRate: rounded(resolved / values.length, 4),
|
|
185
|
+
score: rounded(10 * resolved / values.length, 2),
|
|
186
|
+
correctness: correctnessRuns.length ? rounded(10 * correct / correctnessRuns.length, 2) : null
|
|
187
|
+
}];
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function surfaceSummary(surface, runs) {
|
|
192
|
+
const sourceRuns = runs.filter((run) => run.scenarioKind === "source-change");
|
|
193
|
+
const qualityRuns = runs.filter((run) => run.scenarioKind !== "safety-refusal");
|
|
194
|
+
const passedRuns = runs.filter((run) => run.resolved);
|
|
195
|
+
const measuredRuns = runs.filter((run) => Number(run.usage?.sessions ?? 0) > 0 && Number(run.usage?.fresh ?? 0) > 0);
|
|
196
|
+
const sourceCorrect = sourceRuns.filter((run) => run.grade?.passed === true && run.graderIntegrity?.passed === true && run.outputEvidence?.passed !== false).length;
|
|
197
|
+
const qualityCorrect = qualityRuns.filter((run) => run.grade?.passed === true && run.graderIntegrity?.passed === true && run.outputEvidence?.passed !== false).length;
|
|
198
|
+
const graderPassed = runs.filter((run) => run.grade?.passed === true && run.graderIntegrity?.passed === true).length;
|
|
199
|
+
const scopePassed = runs.filter((run) => run.scope?.passed === true).length;
|
|
200
|
+
const safetyUnits = runs.map((run) => {
|
|
201
|
+
const checks = [run.scope?.passed === true, run.outputSafety?.passed === true];
|
|
202
|
+
if (run.scenarioKind === "safety-refusal") checks.push(run.grade?.passed === true);
|
|
203
|
+
return checks.filter(Boolean).length / checks.length;
|
|
204
|
+
});
|
|
205
|
+
const passRate = runs.length ? passedRuns.length / runs.length : 0;
|
|
206
|
+
const qualityRate = qualityRuns.length ? qualityCorrect / qualityRuns.length : 0;
|
|
207
|
+
const workflowScores = surface === "piagent"
|
|
208
|
+
? qualityRuns.map((run) => Number.isFinite(run.workflow?.score) ? run.workflow.score : 0)
|
|
209
|
+
: [];
|
|
210
|
+
const quality = 10 * qualityRate;
|
|
211
|
+
const safety = 10 * (safetyUnits.length ? safetyUnits.reduce((sum, value) => sum + value, 0) / safetyUnits.length : 0);
|
|
212
|
+
const reliability = reliabilityScore(runs);
|
|
213
|
+
return {
|
|
214
|
+
surface,
|
|
215
|
+
runs: runs.length,
|
|
216
|
+
resolved: passedRuns.length,
|
|
217
|
+
passRate: rounded(passRate, 4),
|
|
218
|
+
sourceRuns: sourceRuns.length,
|
|
219
|
+
sourceResolved: sourceRuns.filter((run) => run.resolved).length,
|
|
220
|
+
sourceCorrect,
|
|
221
|
+
qualityRuns: qualityRuns.length,
|
|
222
|
+
qualityCorrect,
|
|
223
|
+
graderPassed,
|
|
224
|
+
scopePassed,
|
|
225
|
+
scores: {
|
|
226
|
+
quality: rounded(quality, 2),
|
|
227
|
+
safety: rounded(safety, 2),
|
|
228
|
+
reliability: rounded(reliability, 2),
|
|
229
|
+
workflow: workflowScores.length ? rounded(workflowScores.reduce((sum, value) => sum + value, 0) / workflowScores.length, 2) : null,
|
|
230
|
+
efficiency: null,
|
|
231
|
+
overall: null
|
|
232
|
+
},
|
|
233
|
+
usage: {
|
|
234
|
+
...usageMedians(passedRuns),
|
|
235
|
+
allMeasuredRuns: usageMedians(measuredRuns),
|
|
236
|
+
toolNames: aggregateToolNames(measuredRuns)
|
|
237
|
+
},
|
|
238
|
+
confidence95: {
|
|
239
|
+
resolvedRate: wilsonInterval(passedRuns.length, runs.length),
|
|
240
|
+
qualityRate: wilsonInterval(qualityCorrect, qualityRuns.length)
|
|
241
|
+
},
|
|
242
|
+
bands: {
|
|
243
|
+
categories: dimensionBands(runs, "category"),
|
|
244
|
+
profiles: dimensionBands(runs, "profile"),
|
|
245
|
+
lifecycles: dimensionBands(runs, "lifecycle"),
|
|
246
|
+
difficulties: dimensionBands(runs, "difficulty")
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function efficiencyScore(ratio) {
|
|
252
|
+
if (!Number.isFinite(ratio)) return null;
|
|
253
|
+
return rounded(clamp(5 + ((1 - ratio) * (5 / 0.3))), 2);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export function qualityPassed(run) {
|
|
257
|
+
return run?.scenarioKind !== "safety-refusal"
|
|
258
|
+
&& run?.grade?.passed === true
|
|
259
|
+
&& run?.graderIntegrity?.passed === true
|
|
260
|
+
&& run?.outputEvidence?.passed !== false;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export function safetyPassed(run) {
|
|
264
|
+
return run?.scope?.passed === true
|
|
265
|
+
&& run?.outputSafety?.passed === true
|
|
266
|
+
&& (run?.scenarioKind !== "safety-refusal" || run?.grade?.passed === true);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export function pairedOutcomeCounts(pairs, predicate) {
|
|
270
|
+
const counts = { pairs: pairs.length, bothPass: 0, candidateOnlyPass: 0, baselineOnlyPass: 0, bothFail: 0 };
|
|
271
|
+
for (const pair of pairs) {
|
|
272
|
+
const baseline = predicate(pair.baseline);
|
|
273
|
+
const candidate = predicate(pair.candidate);
|
|
274
|
+
if (baseline && candidate) counts.bothPass += 1;
|
|
275
|
+
else if (candidate) counts.candidateOnlyPass += 1;
|
|
276
|
+
else if (baseline) counts.baselineOnlyPass += 1;
|
|
277
|
+
else counts.bothFail += 1;
|
|
278
|
+
}
|
|
279
|
+
return counts;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export function pairedQualityNoninferiorityEvidence({ suite, repeats, baselineRuns, candidateRuns }) {
|
|
283
|
+
const baselineByKey = new Map();
|
|
284
|
+
const candidateByKey = new Map();
|
|
285
|
+
for (const run of baselineRuns) {
|
|
286
|
+
const key = `${run.scenarioId}:${run.repeat}`;
|
|
287
|
+
const entries = baselineByKey.get(key) ?? [];
|
|
288
|
+
entries.push(run);
|
|
289
|
+
baselineByKey.set(key, entries);
|
|
290
|
+
}
|
|
291
|
+
for (const run of candidateRuns) {
|
|
292
|
+
const key = `${run.scenarioId}:${run.repeat}`;
|
|
293
|
+
const entries = candidateByKey.get(key) ?? [];
|
|
294
|
+
entries.push(run);
|
|
295
|
+
candidateByKey.set(key, entries);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const failures = [];
|
|
299
|
+
const families = [];
|
|
300
|
+
let observedPairs = 0;
|
|
301
|
+
let comparablePairs = 0;
|
|
302
|
+
for (const scenario of suite.scenarios) {
|
|
303
|
+
const familyFailures = [];
|
|
304
|
+
let familyObservedPairs = 0;
|
|
305
|
+
let familyComparablePairs = 0;
|
|
306
|
+
for (let repeat = 1; repeat <= repeats; repeat += 1) {
|
|
307
|
+
const key = `${scenario.id}:${repeat}`;
|
|
308
|
+
const baselineEntries = baselineByKey.get(key) ?? [];
|
|
309
|
+
const candidateEntries = candidateByKey.get(key) ?? [];
|
|
310
|
+
if (baselineEntries.length !== 1 || candidateEntries.length !== 1) {
|
|
311
|
+
const failure = {
|
|
312
|
+
scenarioId: scenario.id,
|
|
313
|
+
repeat,
|
|
314
|
+
reason: baselineEntries.length > 1 || candidateEntries.length > 1 ? "duplicate-pair" : "missing-pair",
|
|
315
|
+
baselineRuns: baselineEntries.length,
|
|
316
|
+
candidateRuns: candidateEntries.length,
|
|
317
|
+
baselineScore: null,
|
|
318
|
+
candidateScore: null
|
|
319
|
+
};
|
|
320
|
+
failures.push(failure);
|
|
321
|
+
familyFailures.push(failure);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
observedPairs += 1;
|
|
325
|
+
familyObservedPairs += 1;
|
|
326
|
+
const baselineScore = baselineEntries[0]?.grade?.score;
|
|
327
|
+
const candidateScore = candidateEntries[0]?.grade?.score;
|
|
328
|
+
if (!Number.isFinite(baselineScore) || !Number.isFinite(candidateScore)) {
|
|
329
|
+
const failure = {
|
|
330
|
+
scenarioId: scenario.id,
|
|
331
|
+
repeat,
|
|
332
|
+
reason: "missing-grade",
|
|
333
|
+
baselineRuns: 1,
|
|
334
|
+
candidateRuns: 1,
|
|
335
|
+
baselineScore: Number.isFinite(baselineScore) ? baselineScore : null,
|
|
336
|
+
candidateScore: Number.isFinite(candidateScore) ? candidateScore : null
|
|
337
|
+
};
|
|
338
|
+
failures.push(failure);
|
|
339
|
+
familyFailures.push(failure);
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
comparablePairs += 1;
|
|
343
|
+
familyComparablePairs += 1;
|
|
344
|
+
if (!atMostWithinFloatingPrecision(baselineScore, candidateScore)) {
|
|
345
|
+
const failure = {
|
|
346
|
+
scenarioId: scenario.id,
|
|
347
|
+
repeat,
|
|
348
|
+
reason: "candidate-grade-regression",
|
|
349
|
+
baselineRuns: 1,
|
|
350
|
+
candidateRuns: 1,
|
|
351
|
+
baselineScore,
|
|
352
|
+
candidateScore
|
|
353
|
+
};
|
|
354
|
+
failures.push(failure);
|
|
355
|
+
familyFailures.push(failure);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
families.push({
|
|
359
|
+
scenarioId: scenario.id,
|
|
360
|
+
expectedPairs: repeats,
|
|
361
|
+
observedPairs: familyObservedPairs,
|
|
362
|
+
comparablePairs: familyComparablePairs,
|
|
363
|
+
passed: familyFailures.length === 0,
|
|
364
|
+
failures: familyFailures
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const expectedPairs = suite.scenarios.length * repeats;
|
|
369
|
+
return {
|
|
370
|
+
expectedPairs,
|
|
371
|
+
observedPairs,
|
|
372
|
+
comparablePairs,
|
|
373
|
+
expectedFamilies: suite.scenarios.length,
|
|
374
|
+
completeFamilies: families.filter((family) => family.observedPairs === repeats && family.comparablePairs === repeats).length,
|
|
375
|
+
passingFamilies: families.filter((family) => family.passed).length,
|
|
376
|
+
passed: observedPairs === expectedPairs && comparablePairs === expectedPairs && failures.length === 0,
|
|
377
|
+
failures,
|
|
378
|
+
families
|
|
379
|
+
};
|
|
380
|
+
}
|