@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.
Files changed (323) hide show
  1. package/CHANGELOG.md +166 -0
  2. package/README.md +25 -21
  3. package/README.vi.md +34 -5
  4. package/adapters/web-frontend/profile.json +2 -4
  5. package/architecture/layers.json +18 -3
  6. package/benchmarks/deep-logic-v1/SPECIALIST_PROTOCOL.vi.md +122 -0
  7. package/benchmarks/deep-logic-v1/grade.mjs +272 -10
  8. package/benchmarks/deep-logic-v1/project/apps/admin/src/billing-summary.js +3 -0
  9. package/benchmarks/deep-logic-v1/project/benchmark-contract/public-smoke.test.js +166 -0
  10. package/benchmarks/deep-logic-v1/project/package.json +1 -1
  11. package/benchmarks/deep-logic-v1/project/packages/billing/src/close-period.js +3 -0
  12. package/benchmarks/deep-logic-v1/project/packages/billing/src/plan-timeline.js +3 -0
  13. package/benchmarks/deep-logic-v1/project/test/smoke.test.js +7 -1
  14. package/benchmarks/deep-logic-v1/prompts/budgeted-context-graph.md +2 -0
  15. package/benchmarks/deep-logic-v1/prompts/fair-dependency-scheduler.md +2 -0
  16. package/benchmarks/deep-logic-v1/prompts/layered-policy-resolution.md +2 -0
  17. package/benchmarks/deep-logic-v1/prompts/resumable-stream-assembly.md +3 -1
  18. package/benchmarks/deep-logic-v1/prompts/revision-event-reconciliation.md +2 -0
  19. package/benchmarks/deep-logic-v1/prompts/temporal-usage-billing-close.md +123 -0
  20. package/benchmarks/deep-logic-v1/prompts/transactional-config-merge.md +2 -0
  21. package/benchmarks/deep-logic-v1/suite.json +51 -3
  22. package/benchmarks/deep-logic-v1/variant.mjs +22 -1
  23. package/benchmarks/production-v1/spend-control.v1.json +92 -0
  24. package/benchmarks/production-v1/suite.json +46 -3
  25. package/catalog/capabilities.json +18 -18
  26. package/docs/authority-manifest.md +1 -1
  27. package/docs/auto-delegation-policy.md +38 -73
  28. package/docs/command-reference-vietnamese.md +27 -35
  29. package/docs/context-engine.md +12 -4
  30. package/docs/context-window-policy.md +37 -1
  31. package/docs/distribution-standard.md +7 -7
  32. package/docs/en/architecture.md +27 -13
  33. package/docs/languages.json +4 -4
  34. package/docs/model-options.md +8 -5
  35. package/docs/operator-manual-vietnamese.md +27 -45
  36. package/docs/project-adapters.md +2 -2
  37. package/docs/publishing-for-teams.md +10 -0
  38. package/docs/quality-benchmark.md +427 -62
  39. package/docs/release-install-policy.md +10 -9
  40. package/docs/runtime-harness-standard.md +3 -3
  41. package/docs/runtime-policy-design.md +4 -4
  42. package/docs/runtime-quality-baseline.md +13 -6
  43. package/docs/security-threat-model.md +2 -2
  44. package/docs/subagent-orchestration-capabilities.md +19 -51
  45. package/docs/subagents-and-multiagent.md +21 -47
  46. package/docs/task-implementation-contract.md +3 -3
  47. package/docs/task-lifecycle-vietnamese.md +3 -3
  48. package/docs/team-onboarding.md +2 -2
  49. package/docs/usage-observability.md +7 -2
  50. package/docs/vi/architecture.md +27 -13
  51. package/docs-site/architecture.html +1 -1
  52. package/docs-site/benchmark.html +89 -95
  53. package/docs-site/commands.html +1 -1
  54. package/docs-site/content/benchmark.html +88 -94
  55. package/docs-site/content/en/benchmark.html +134 -90
  56. package/docs-site/content/en/index.html +19 -19
  57. package/docs-site/content/en/runtime.html +4 -4
  58. package/docs-site/content/en/whats-new.html +12 -1
  59. package/docs-site/content/en/workflows.html +2 -2
  60. package/docs-site/content/index.html +19 -19
  61. package/docs-site/content/runtime.html +4 -4
  62. package/docs-site/content/whats-new.html +12 -1
  63. package/docs-site/content/workflows.html +2 -2
  64. package/docs-site/context-engine.html +1 -1
  65. package/docs-site/en/architecture.html +1 -1
  66. package/docs-site/en/benchmark.html +135 -91
  67. package/docs-site/en/commands.html +1 -1
  68. package/docs-site/en/context-engine.html +1 -1
  69. package/docs-site/en/index.html +20 -20
  70. package/docs-site/en/mcp-approval.html +1 -1
  71. package/docs-site/en/mcp-auth.html +1 -1
  72. package/docs-site/en/mcp-servers.html +1 -1
  73. package/docs-site/en/mcp.html +1 -1
  74. package/docs-site/en/permissions.html +1 -1
  75. package/docs-site/en/profiles.html +1 -1
  76. package/docs-site/en/quickstart.html +1 -1
  77. package/docs-site/en/runtime.html +5 -5
  78. package/docs-site/en/scope.html +1 -1
  79. package/docs-site/en/security.html +1 -1
  80. package/docs-site/en/team.html +1 -1
  81. package/docs-site/en/whats-new.html +13 -2
  82. package/docs-site/en/workflows.html +3 -3
  83. package/docs-site/index.html +20 -20
  84. package/docs-site/mcp-approval.html +1 -1
  85. package/docs-site/mcp-auth.html +1 -1
  86. package/docs-site/mcp-servers.html +1 -1
  87. package/docs-site/mcp.html +1 -1
  88. package/docs-site/permissions.html +1 -1
  89. package/docs-site/profiles.html +1 -1
  90. package/docs-site/quickstart.html +1 -1
  91. package/docs-site/runtime.html +5 -5
  92. package/docs-site/scope.html +1 -1
  93. package/docs-site/security.html +1 -1
  94. package/docs-site/team.html +1 -1
  95. package/docs-site/whats-new.html +13 -2
  96. package/docs-site/workflows.html +3 -3
  97. package/evals/fixtures/benchmark-assurance-evidence.invalid.json +1 -1
  98. package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
  99. package/evals/fixtures/codex-relative-efficiency-v1.invalid.json +4 -0
  100. package/evals/fixtures/codex-relative-efficiency-v1.valid.json +94 -0
  101. package/evals/fixtures/helper-request.invalid.json +1 -1
  102. package/evals/fixtures/helper-request.valid.json +1 -1
  103. package/evals/fixtures/piagent-webui/session-live-state-v1.invalid.json +18 -0
  104. package/evals/fixtures/piagent-webui/session-live-state-v1.valid.json +27 -0
  105. package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +7 -0
  106. package/evals/fixtures/task-authority-snapshot.valid.json +4 -4
  107. package/evals/fs4-readiness-matrix.v1.json +2 -2
  108. package/evals/fs5-causal-arm.v1.json +3 -3
  109. package/evals/fs5-pilot-protocol.v1.json +3 -3
  110. package/evals/fs5-pilot-protocol.v2.json +8 -8
  111. package/evals/fs5-pilot-protocol.v3.json +8 -8
  112. package/evals/fs5-pilot-protocol.v4.json +7 -6
  113. package/evals/fs5-pilot-protocol.v5.json +9 -7
  114. package/evals/private-holdout-v1/public-exposure.v1.json +1 -1
  115. package/evals/runtime-conformance-v1/README.md +43 -0
  116. package/evals/runtime-conformance-v1/evaluate-paid-canary.mjs +198 -0
  117. package/evals/runtime-conformance-v1/lane.json +57 -0
  118. package/evals/runtime-conformance-v1/paid-canary.json +31 -0
  119. package/evals/runtime-conformance-v1/runner.mjs +456 -0
  120. package/package.json +3 -1
  121. package/packages/piagent-core/README.md +13 -4
  122. package/packages/piagent-core/benchmark/benchmark-assurance.js +4 -1
  123. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +91 -9
  124. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +38 -7
  125. package/packages/piagent-core/benchmark/benchmark-cli.js +7 -7
  126. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +698 -0
  127. package/packages/piagent-core/benchmark/benchmark-codex.js +3 -1
  128. package/packages/piagent-core/benchmark/benchmark-comparison.js +271 -2
  129. package/packages/piagent-core/benchmark/benchmark-core.js +736 -664
  130. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +7 -5
  131. package/packages/piagent-core/benchmark/benchmark-forensics.js +441 -4
  132. package/packages/piagent-core/benchmark/benchmark-host-readiness.js +639 -0
  133. package/packages/piagent-core/benchmark/benchmark-matrix.js +22 -4
  134. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +317 -0
  135. package/packages/piagent-core/benchmark/benchmark-preflight.js +5 -1
  136. package/packages/piagent-core/benchmark/benchmark-process.js +6 -5
  137. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +345 -0
  138. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +126 -0
  139. package/packages/piagent-core/benchmark/benchmark-record-validation.js +252 -0
  140. package/packages/piagent-core/benchmark/benchmark-report.js +130 -12
  141. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +14 -0
  142. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +26 -0
  143. package/packages/piagent-core/benchmark/benchmark-runtime-causal.js +244 -0
  144. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +979 -0
  145. package/packages/piagent-core/benchmark/benchmark-statistics.js +64 -0
  146. package/packages/piagent-core/benchmark/benchmark-stop-policy.js +8 -5
  147. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +31 -0
  148. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +13 -9
  149. package/packages/piagent-core/benchmark/benchmark-suite.js +149 -2
  150. package/packages/piagent-core/benchmark/benchmark-summary-support.js +380 -0
  151. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +971 -0
  152. package/packages/piagent-core/benchmark/benchmark-usage.js +322 -0
  153. package/packages/piagent-core/benchmark/benchmark-workflow.js +166 -0
  154. package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
  155. package/packages/piagent-core/docs/context-efficiency-improvement-plan.md +1080 -0
  156. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +806 -0
  157. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +83 -69
  158. package/packages/piagent-core/extensions/acceptance-error-classes.js +160 -0
  159. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +12 -9
  160. package/packages/piagent-core/extensions/acceptance-receipt.js +123 -59
  161. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +518 -0
  162. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +60 -0
  163. package/packages/piagent-core/extensions/context-efficiency-metrics.js +302 -0
  164. package/packages/piagent-core/extensions/context-efficiency-report.js +167 -0
  165. package/packages/piagent-core/extensions/context-engine.js +149 -156
  166. package/packages/piagent-core/extensions/context-evidence.js +48 -0
  167. package/packages/piagent-core/extensions/context-import-links.js +296 -0
  168. package/packages/piagent-core/extensions/context-index-policy.js +4 -0
  169. package/packages/piagent-core/extensions/context-query-paths.js +57 -0
  170. package/packages/piagent-core/extensions/context-telemetry-integrity.js +65 -0
  171. package/packages/piagent-core/extensions/criterion-context-pack.js +435 -7
  172. package/packages/piagent-core/extensions/criterion-graph.js +82 -9
  173. package/packages/piagent-core/extensions/fallback-base-policy.ts +101 -0
  174. package/packages/piagent-core/extensions/guard-types.ts +6 -0
  175. package/packages/piagent-core/extensions/javascript-regex-evidence.js +32 -0
  176. package/packages/piagent-core/extensions/piagent-guard.ts +420 -260
  177. package/packages/piagent-core/extensions/task-contract-view.js +17 -3
  178. package/packages/piagent-core/extensions/task-lifecycle.js +39 -2
  179. package/packages/piagent-core/extensions/task-state.js +109 -142
  180. package/packages/piagent-core/extensions/verification-intelligence.js +52 -13
  181. package/packages/piagent-core/extensions/workspace-evidence-roots.js +193 -0
  182. package/packages/piagent-core/package.json +1 -1
  183. package/packages/piagent-core/policies/base-policy.json +44 -2
  184. package/packages/piagent-core/policy/authority-manifest.v1.json +3 -3
  185. package/packages/piagent-core/prompts/be-to-fe.md +2 -8
  186. package/packages/piagent-core/prompts/plan.md +1 -1
  187. package/packages/piagent-core/prompts/platform-improve.md +2 -6
  188. package/packages/piagent-core/prompts/review.md +2 -7
  189. package/packages/piagent-core/prompts/scout.md +1 -1
  190. package/packages/piagent-core/prompts/task.md +4 -3
  191. package/packages/piagent-core/runtime/context/context-delivery.ts +103 -0
  192. package/packages/piagent-core/runtime/context/context-delta-shadow.ts +53 -0
  193. package/packages/piagent-core/runtime/context/context-efficiency-format.ts +47 -0
  194. package/packages/piagent-core/runtime/context/context-evidence-qualification.ts +32 -0
  195. package/packages/piagent-core/runtime/context/prefix-telemetry.ts +47 -0
  196. package/packages/piagent-core/runtime/context/repository-memory-hints.ts +27 -0
  197. package/packages/piagent-core/runtime/hooks/agent-prompt-telemetry.ts +56 -0
  198. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +162 -102
  199. package/packages/piagent-core/runtime/hooks/completion-hook.ts +12 -12
  200. package/packages/piagent-core/runtime/hooks/input-hook.ts +17 -1
  201. package/packages/piagent-core/runtime/hooks/session-hooks.ts +22 -2
  202. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +107 -3
  203. package/packages/piagent-core/runtime/hooks/tool-result-content-guards.ts +95 -0
  204. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +134 -166
  205. package/packages/piagent-core/runtime/hooks/tool-result-value-helpers.ts +66 -0
  206. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +4 -2
  207. package/packages/piagent-core/runtime/inspection/activity-recovery.ts +104 -0
  208. package/packages/piagent-core/runtime/inspection/bounded-emission-guard.ts +286 -0
  209. package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +37 -7
  210. package/packages/piagent-core/runtime/inspection/task-compaction-history.ts +1 -1
  211. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +1 -1
  212. package/packages/piagent-core/runtime/inspection/task-subagent-tree.ts +27 -4
  213. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +70 -0
  214. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +73 -9
  215. package/packages/piagent-core/runtime/model/authenticated-catalog.ts +17 -9
  216. package/packages/piagent-core/runtime/model/openai-codex-reasoning.ts +83 -0
  217. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +238 -0
  218. package/packages/piagent-core/runtime/orchestration/helper-lifecycle.ts +16 -12
  219. package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +71 -0
  220. package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +28 -20
  221. package/packages/piagent-core/runtime/orchestration/role-policy.ts +27 -9
  222. package/packages/piagent-core/runtime/orchestration/subagent-tool-policy.ts +329 -0
  223. package/packages/piagent-core/runtime/policy/block-remedy.ts +0 -4
  224. package/packages/piagent-core/runtime/product/activity-inspector.ts +7 -2
  225. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +7 -2
  226. package/packages/piagent-core/runtime/quality/edit-freshness-guard.ts +102 -0
  227. package/packages/piagent-core/runtime/quality/exact-output-contract.ts +22 -11
  228. package/packages/piagent-core/runtime/quality/performance-assurance-signals.ts +23 -0
  229. package/packages/piagent-core/runtime/quality/performance-assurance.ts +9 -5
  230. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +1 -1
  231. package/packages/piagent-core/runtime/recovery/edit-recovery-context.ts +113 -0
  232. package/packages/piagent-core/runtime/recovery/edit-recovery-delivery.ts +42 -0
  233. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +4 -1
  234. package/packages/piagent-core/runtime/recovery/pristine-task-policy-refresh.ts +91 -0
  235. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +7 -4
  236. package/packages/piagent-core/runtime/recovery/resume-state.ts +112 -14
  237. package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +60 -13
  238. package/packages/piagent-core/runtime/recovery/semantic-repair-runtime.ts +55 -2
  239. package/packages/piagent-core/runtime/recovery/task-evidence-coverage-refresh.ts +217 -0
  240. package/packages/piagent-core/runtime/registration/context-commands.ts +82 -7
  241. package/packages/piagent-core/runtime/registration/knowledge-tools.ts +9 -5
  242. package/packages/piagent-core/runtime/registration/operator-request-intake.ts +49 -0
  243. package/packages/piagent-core/runtime/registration/policy-tools.ts +50 -15
  244. package/packages/piagent-core/runtime/registration/session-commands.ts +1 -1
  245. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +61 -25
  246. package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +21 -12
  247. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +169 -0
  248. package/packages/piagent-core/runtime/registration/task-start-manifest.ts +54 -0
  249. package/packages/piagent-core/runtime/registration/task-start-retry-helpers.ts +37 -0
  250. package/packages/piagent-core/runtime/registration/task-start-tool.ts +108 -103
  251. package/packages/piagent-core/runtime/runtime-limits.ts +16 -2
  252. package/packages/piagent-core/runtime/session/adaptive-context-analysis.ts +461 -0
  253. package/packages/piagent-core/runtime/session/adaptive-context-governor.ts +464 -0
  254. package/packages/piagent-core/runtime/session/adaptive-context-ledger.ts +265 -0
  255. package/packages/piagent-core/runtime/session/message-signals.ts +7 -3
  256. package/packages/piagent-core/runtime/session/operator-request-carry.ts +44 -0
  257. package/packages/piagent-core/runtime/session/runtime-state.ts +161 -5
  258. package/packages/piagent-core/runtime/session/source-checkout-read-grants.ts +35 -0
  259. package/packages/piagent-core/runtime/session/system-prompt.ts +76 -14
  260. package/packages/piagent-core/runtime/session/task-contract-presentation.ts +39 -0
  261. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +500 -0
  262. package/packages/piagent-core/runtime/tools/phase-tools.ts +8 -8
  263. package/packages/piagent-core/runtime/tools/tool-groups.ts +12 -2
  264. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +2 -1
  265. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +101 -0
  266. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +164 -0
  267. package/packages/piagent-core/runtime/workflows/task-intake.ts +207 -38
  268. package/packages/piagent-core/security/sensitive-data.js +13 -218
  269. package/packages/piagent-core/security/sensitive-project-file.js +42 -0
  270. package/packages/piagent-core/security/sensitive-source-expression.js +330 -0
  271. package/packages/piagent-core/security/sensitive-source-formats.js +394 -0
  272. package/packages/piagent-core/security/sensitive-text.js +234 -0
  273. package/packages/piagent-core/subagents/piagent-oracle.md +5 -3
  274. package/packages/piagent-core/subagents/piagent-planner.md +6 -4
  275. package/packages/piagent-core/subagents/piagent-reviewer.md +5 -3
  276. package/packages/piagent-core/subagents/piagent-scout.md +4 -2
  277. package/packages/piagent-core/subagents/piagent-worker.md +7 -5
  278. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-rD9WJKxs.js → MarkdownMessage-B4XehTCU.js} +1 -1
  279. package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +176 -0
  280. package/packages/piagent-webui/dist/client/index.html +1 -1
  281. package/packages/piagent-webui/extension/piagent-webui.ts +3 -1
  282. package/packages/piagent-webui/extension/same-session-bridge.ts +1 -1
  283. package/packages/piagent-webui/extension/session-stream-adapter.ts +33 -10
  284. package/packages/piagent-webui/gateway/gateway-events.ts +109 -5
  285. package/packages/piagent-webui/gateway/gateway-service.ts +3 -0
  286. package/packages/piagent-webui/gateway/gateway-session-stream.ts +122 -20
  287. package/packages/piagent-webui/gateway/session-command-controller.ts +18 -3
  288. package/packages/piagent-webui/gateway/session-effective-options.ts +47 -0
  289. package/packages/piagent-webui/gateway/session-live-state.ts +21 -0
  290. package/packages/piagent-webui/gateway/session-operation-lifecycle.ts +237 -0
  291. package/packages/piagent-webui/gateway/session-operation-retry-control.ts +38 -0
  292. package/packages/piagent-webui/gateway/session-operation-start.ts +5 -1
  293. package/packages/piagent-webui/gateway/session-operation-watchdog.ts +165 -0
  294. package/packages/piagent-webui/gateway/session-runtime-factory.ts +45 -0
  295. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +141 -125
  296. package/packages/piagent-webui/ownership/session-lease-store.ts +5 -2
  297. package/packages/piagent-webui/server/core-inspection-provider.ts +2 -1
  298. package/packages/piagent-webui/server/loopback-server.ts +8 -0
  299. package/packages/piagent-webui/server/transcript-projection.ts +113 -9
  300. package/packages/piagent-webui/shared/text-visibility.ts +10 -0
  301. package/schemas/codex-relative-efficiency-v1.schema.json +155 -0
  302. package/schemas/piagent-webui/catalog-v1.json +9 -0
  303. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +53 -3
  304. package/schemas/piagent-webui/runtime-event-v2.schema.json +15 -5
  305. package/schemas/piagent-webui/session-live-state-v1.schema.json +76 -0
  306. package/schemas/piagent-webui/subagent-tree-v1.schema.json +11 -1
  307. package/schemas/project-profile.schema.json +1 -1
  308. package/schemas/task-contract.schema.json +27 -1
  309. package/scripts/benchmark-runner-core.mjs +367 -363
  310. package/scripts/benchmark-runner-finalization.mjs +313 -0
  311. package/scripts/benchmark-runner-host-readiness.mjs +94 -0
  312. package/scripts/benchmark-runner-support.mjs +200 -0
  313. package/scripts/benchmark-session.mjs +95 -41
  314. package/scripts/configure-model-scope.sh +4 -3
  315. package/scripts/configure-subagents.sh +42 -34
  316. package/scripts/helper-evaluation.mjs +2 -2
  317. package/scripts/install-global.sh +2 -2
  318. package/scripts/pi-usage-history.mjs +37 -10
  319. package/scripts/setup.sh +2 -2
  320. package/scripts/team-doctor.sh +1 -1
  321. package/scripts/verify-local.sh +10 -1
  322. package/templates/global/settings.json +2 -1
  323. package/packages/piagent-webui/dist/client/assets/index-BZRFw1u6.js +0 -174
@@ -0,0 +1,698 @@
1
+ import { benchmarkClaimEligibility } from "./benchmark-assurance.js";
2
+ import { normalizeBenchmarkUsageCost } from "./benchmark-normalized-cost.js";
3
+ import {
4
+ atMostWithinFloatingPrecision,
5
+ geometricMean,
6
+ geometricMeanConfidence95,
7
+ geometricMeanConfidence95Raw,
8
+ rounded
9
+ } from "./benchmark-statistics.js";
10
+ import { exactBenchmarkAttemptUsage } from "./benchmark-usage.js";
11
+ import { productionProviderFreeEvidenceContextValidationErrors } from "./benchmark-provider-free-evidence.js";
12
+ import { RELEASE_FAILURE_MESSAGES } from "./benchmark-summary-support.js";
13
+
14
+ const HASH = /^[a-f0-9]{64}$/;
15
+ const TOKEN_FIELDS = Object.freeze(["input", "output", "cacheRead", "cacheWrite", "reasoning", "fresh", "total"]);
16
+
17
+ /**
18
+ * The production claim is intentionally stricter than the historical fresh-token
19
+ * claim. Both provider traffic and API-equivalent text-token cost include cache
20
+ * reads/writes and every declared provider-started attempt.
21
+ */
22
+ export const CODEX_RELATIVE_EFFICIENCY_POLICY = Object.freeze({
23
+ schemaVersion: 1,
24
+ id: "codex-relative-efficiency-v1",
25
+ baselineSurface: "codex-cli",
26
+ candidateSurface: "piagent",
27
+ estimand: "fixed-workload-family-geometric-mean",
28
+ outcomeConditioning: "none",
29
+ attemptPolicy: "accepted-plus-exact-provider-started-failed-attempts",
30
+ maximumTotalTokenTrafficRatio: 0.7,
31
+ maximumTotalTokenTrafficRatioUpper95: 0.7,
32
+ maximumApiEquivalentCostRatio: 0.7,
33
+ maximumApiEquivalentCostRatioUpper95: 0.7,
34
+ maximumSubagentSessionsPerAttempt: 1,
35
+ maximumSubagentTrafficShare: 0.05
36
+ });
37
+
38
+ export const PRODUCTION_SUBAGENT_BUDGET_POLICY = Object.freeze({
39
+ schemaVersion: 1,
40
+ id: "production-subagent-budget-v1",
41
+ maximumSubagentSessionsPerAttempt: 1,
42
+ maximumSubagentTrafficShare: 0.05
43
+ });
44
+
45
+ function zeroTokens() {
46
+ return Object.fromEntries(TOKEN_FIELDS.map((field) => [field, 0]));
47
+ }
48
+
49
+ function addTokens(target, usage) {
50
+ for (const field of TOKEN_FIELDS) target[field] += Number(usage?.[field] ?? 0);
51
+ }
52
+
53
+ function isKnownPreProviderZero(usage, status) {
54
+ return status === "known-pre-provider-zero"
55
+ && Number(usage?.sessions ?? 0) === 0
56
+ && TOKEN_FIELDS.every((field) => Number(usage?.[field] ?? 0) === 0);
57
+ }
58
+
59
+ function normalizedAttemptCost(usage, status, pricingSnapshot) {
60
+ if (isKnownPreProviderZero(usage, status)) {
61
+ return { status: "measured", amount: 0, amountUsd: 0, source: "known-pre-provider-zero" };
62
+ }
63
+ return normalizeBenchmarkUsageCost(usage, pricingSnapshot);
64
+ }
65
+
66
+ function exactSubagentEvidence(usage) {
67
+ const sessions = usage?.subagentSessions;
68
+ const tokens = usage?.subagentTokens;
69
+ return Number.isSafeInteger(sessions)
70
+ && sessions >= 0
71
+ && usage.sessions === 1 + sessions
72
+ && tokens
73
+ && TOKEN_FIELDS.every((field) => Number.isSafeInteger(tokens[field]) && tokens[field] >= 0)
74
+ && tokens.fresh === tokens.input + tokens.output
75
+ && tokens.total === tokens.input + tokens.cacheRead + tokens.cacheWrite + tokens.output
76
+ && tokens.reasoning <= tokens.output
77
+ && tokens.total <= usage.total;
78
+ }
79
+
80
+ function measuredSubagentEvidence(usage, status) {
81
+ if (!exactBenchmarkAttemptUsage(usage, status)) {
82
+ return { exact: false, sessions: 0, traffic: 0 };
83
+ }
84
+ if (isKnownPreProviderZero(usage, status)) {
85
+ return { exact: true, sessions: 0, traffic: 0 };
86
+ }
87
+ return exactSubagentEvidence(usage)
88
+ ? { exact: true, sessions: usage.subagentSessions, traffic: usage.subagentTokens.total }
89
+ : { exact: false, sessions: 0, traffic: 0 };
90
+ }
91
+
92
+ /**
93
+ * Measure the candidate child-session budget independently from cost claims.
94
+ * Every accepted and failed provider attempt must explain its full session
95
+ * count as one root session plus the exact child-session count. This gate is
96
+ * deliberately usable on a partial production ledger.
97
+ */
98
+ export function summarizeBenchmarkSubagentBudget(runs, {
99
+ candidateSurface = "piagent",
100
+ policy = PRODUCTION_SUBAGENT_BUDGET_POLICY
101
+ } = {}) {
102
+ const candidateRuns = (runs ?? []).filter((run) => run?.surface === candidateSurface);
103
+ const attempts = [];
104
+ const ledgerIssues = [];
105
+ for (const run of candidateRuns) {
106
+ const failures = Array.isArray(run?.infrastructureFailures) ? run.infrastructureFailures : [];
107
+ const retryCountExact = Number.isSafeInteger(run?.infrastructureRetries) && run.infrastructureRetries >= 0;
108
+ const attemptCountExact = Number.isSafeInteger(run?.infrastructureAttempts) && run.infrastructureAttempts >= 1;
109
+ if (!retryCountExact || !attemptCountExact || !Array.isArray(run?.infrastructureFailures)
110
+ || failures.length !== run.infrastructureRetries
111
+ || run.infrastructureAttempts !== run.infrastructureRetries + 1) {
112
+ ledgerIssues.push(`${run?.scenarioId ?? "unknown"}:r${run?.repeat ?? "?"}:attempt-ledger-mismatch`);
113
+ }
114
+ const values = [
115
+ { kind: "accepted", usage: run?.usage, status: run?.usageStatus ?? "measured" },
116
+ ...failures.map((failure) => ({
117
+ kind: "failed",
118
+ usage: failure?.usage,
119
+ status: failure?.usageStatus ?? "unknown-after-provider-start"
120
+ }))
121
+ ];
122
+ for (const [index, value] of values.entries()) {
123
+ const evidence = measuredSubagentEvidence(value.usage, value.status);
124
+ attempts.push({
125
+ scenarioId: run?.scenarioId ?? null,
126
+ repeat: run?.repeat ?? null,
127
+ attempt: index + 1,
128
+ kind: value.kind,
129
+ exact: evidence.exact,
130
+ sessions: evidence.exact ? evidence.sessions : null,
131
+ subagentTraffic: evidence.exact ? evidence.traffic : null,
132
+ candidateTraffic: evidence.exact ? Number(value.usage?.total ?? 0) : null
133
+ });
134
+ }
135
+ }
136
+ const exact = candidateRuns.length > 0
137
+ && ledgerIssues.length === 0
138
+ && attempts.length > 0
139
+ && attempts.every((attempt) => attempt.exact);
140
+ const exactAttempts = attempts.filter((attempt) => attempt.exact);
141
+ const subagentSessions = exactAttempts.reduce((sum, attempt) => sum + attempt.sessions, 0);
142
+ const subagentTraffic = exactAttempts.reduce((sum, attempt) => sum + attempt.subagentTraffic, 0);
143
+ const candidateTraffic = exactAttempts.reduce((sum, attempt) => sum + attempt.candidateTraffic, 0);
144
+ const trafficShare = exact && candidateTraffic > 0
145
+ ? subagentTraffic / candidateTraffic
146
+ : exact && subagentTraffic === 0 ? 0 : null;
147
+ const maximumObservedSessionsPerAttempt = exactAttempts.reduce(
148
+ (maximum, attempt) => Math.max(maximum, attempt.sessions),
149
+ 0
150
+ );
151
+ const checks = {
152
+ "candidate-attempts-observed": candidateRuns.length > 0 && attempts.length > 0,
153
+ "subagent-usage-exact": exact,
154
+ "subagent-sessions-explained": exact,
155
+ "subagent-session-budget": exact
156
+ && maximumObservedSessionsPerAttempt <= policy.maximumSubagentSessionsPerAttempt,
157
+ "subagent-traffic-budget": exact
158
+ && Number.isFinite(trafficShare)
159
+ && atMostWithinFloatingPrecision(trafficShare, policy.maximumSubagentTrafficShare)
160
+ };
161
+ return {
162
+ schemaVersion: 1,
163
+ policy,
164
+ checks,
165
+ failures: booleanChecks(checks),
166
+ passed: booleanChecks(checks).length === 0,
167
+ candidateRuns: candidateRuns.length,
168
+ attempts: attempts.length,
169
+ exactAttempts: exactAttempts.length,
170
+ ledgerIssues,
171
+ sessions: subagentSessions,
172
+ tokenTraffic: subagentTraffic,
173
+ candidateTokenTraffic: candidateTraffic,
174
+ trafficShare,
175
+ maximumObservedSessionsPerAttempt,
176
+ attemptEvidence: attempts
177
+ };
178
+ }
179
+
180
+ function measureRun(run, pricingSnapshot, expectedModel, expectedThinking, { candidate }) {
181
+ const tokenIssues = [], costIssues = [], subagentIssues = [];
182
+ const status = run?.usageStatus ?? "measured";
183
+ if (!exactBenchmarkAttemptUsage(run?.usage, status)) tokenIssues.push("accepted-usage-not-exact");
184
+ if (run?.usage?.model !== expectedModel) tokenIssues.push("accepted-model-mismatch");
185
+ if (run?.usage?.thinkingLevel !== expectedThinking) tokenIssues.push("accepted-thinking-mismatch");
186
+ const failures = Array.isArray(run?.infrastructureFailures) ? run.infrastructureFailures : [];
187
+ const retryCountExact = Number.isSafeInteger(run?.infrastructureRetries) && run.infrastructureRetries >= 0;
188
+ const attemptCountExact = Number.isSafeInteger(run?.infrastructureAttempts) && run.infrastructureAttempts >= 1;
189
+ const ledgerExact = Array.isArray(run?.infrastructureFailures)
190
+ && retryCountExact
191
+ && attemptCountExact
192
+ && failures.length === run.infrastructureRetries
193
+ && run.infrastructureAttempts === run.infrastructureRetries + 1;
194
+ if (!ledgerExact) {
195
+ tokenIssues.push("failed-attempt-ledger-mismatch");
196
+ if (candidate) subagentIssues.push("failed-attempt-subagent-ledger-mismatch");
197
+ }
198
+
199
+ const tokens = zeroTokens();
200
+ if (exactBenchmarkAttemptUsage(run?.usage, status)) addTokens(tokens, run.usage);
201
+ let cost = normalizedAttemptCost(run?.usage, status, pricingSnapshot);
202
+ if (cost.status !== "measured") costIssues.push(`accepted-cost:${cost.reason}`);
203
+ let costAmount = cost.status === "measured" ? cost.amount : null;
204
+
205
+ let subagentSessions = 0;
206
+ let subagentTraffic = 0;
207
+ let maximumSubagentSessionsPerAttempt = 0;
208
+ let attemptCount = 1;
209
+ if (candidate) {
210
+ const evidence = measuredSubagentEvidence(run?.usage, status);
211
+ if (!evidence.exact) subagentIssues.push("subagent-usage-not-exact");
212
+ else {
213
+ subagentSessions += evidence.sessions;
214
+ subagentTraffic += evidence.traffic;
215
+ maximumSubagentSessionsPerAttempt = evidence.sessions;
216
+ }
217
+ }
218
+
219
+ for (const failure of failures) {
220
+ attemptCount += 1;
221
+ const failureStatus = failure?.usageStatus ?? "unknown-after-provider-start";
222
+ if (!exactBenchmarkAttemptUsage(failure?.usage, failureStatus)) {
223
+ tokenIssues.push("failed-attempt-usage-not-exact");
224
+ if (candidate) subagentIssues.push("failed-attempt-subagent-usage-not-exact");
225
+ continue;
226
+ }
227
+ if (!isKnownPreProviderZero(failure.usage, failureStatus)) {
228
+ if (failure.usage.model !== expectedModel) tokenIssues.push("failed-attempt-model-mismatch");
229
+ if (failure.usage.thinkingLevel !== expectedThinking) tokenIssues.push("failed-attempt-thinking-mismatch");
230
+ }
231
+ addTokens(tokens, failure.usage);
232
+ cost = normalizedAttemptCost(failure.usage, failureStatus, pricingSnapshot);
233
+ if (cost.status !== "measured") {
234
+ costIssues.push(`failed-attempt-cost:${cost.reason}`);
235
+ costAmount = null;
236
+ } else if (costAmount !== null) {
237
+ costAmount += cost.amount;
238
+ }
239
+ if (candidate) {
240
+ const evidence = measuredSubagentEvidence(failure?.usage, failureStatus);
241
+ if (!evidence.exact) subagentIssues.push("failed-attempt-subagent-usage-not-exact");
242
+ else {
243
+ subagentSessions += evidence.sessions;
244
+ subagentTraffic += evidence.traffic;
245
+ maximumSubagentSessionsPerAttempt = Math.max(maximumSubagentSessionsPerAttempt, evidence.sessions);
246
+ }
247
+ }
248
+ }
249
+
250
+ return {
251
+ tokenExact: tokenIssues.length === 0,
252
+ costExact: tokenIssues.length === 0 && costIssues.length === 0,
253
+ subagentExact: subagentIssues.length === 0,
254
+ exact: tokenIssues.length === 0 && costIssues.length === 0 && subagentIssues.length === 0,
255
+ issues: [...tokenIssues, ...costIssues, ...subagentIssues],
256
+ tokens,
257
+ costAmount,
258
+ subagentSessions,
259
+ subagentTraffic,
260
+ maximumSubagentSessionsPerAttempt,
261
+ attemptCount
262
+ };
263
+ }
264
+
265
+ function pairIdentityIssues(pair) {
266
+ const issues = [];
267
+ const baselinePrompt = pair.baseline?.promptHash;
268
+ const candidatePrompt = pair.candidate?.promptHash;
269
+ const baselineFixture = pair.baseline?.variant?.fixtureDigest;
270
+ const candidateFixture = pair.candidate?.variant?.fixtureDigest;
271
+ if (!HASH.test(baselinePrompt ?? "") || !HASH.test(candidatePrompt ?? "")) issues.push("missing-paired-prompt-identity");
272
+ else if (baselinePrompt !== candidatePrompt) issues.push("paired-prompt-mismatch");
273
+ if (!HASH.test(baselineFixture ?? "") || !HASH.test(candidateFixture ?? "")) issues.push("missing-paired-fixture-identity");
274
+ else if (baselineFixture !== candidateFixture) issues.push("paired-fixture-mismatch");
275
+ return issues;
276
+ }
277
+
278
+ function aggregateFamilies(families, field) {
279
+ const completeFamilies = families.filter((family) => Number.isFinite(family[field]) && family[field] > 0);
280
+ const complete = completeFamilies.length === families.length && families.length > 1;
281
+ const ratios = complete ? completeFamilies.map((family) => family[field]) : [];
282
+ return {
283
+ complete,
284
+ expectedScenarioFamilies: families.length,
285
+ completeScenarioFamilies: completeFamilies.length,
286
+ ratio: complete ? geometricMean(ratios) : null,
287
+ ratioConfidence95: complete ? geometricMeanConfidence95(ratios) : null,
288
+ ratioConfidence95Raw: complete ? geometricMeanConfidence95Raw(ratios) : null
289
+ };
290
+ }
291
+
292
+ function booleanChecks(value) {
293
+ return Object.entries(value).filter(([, passed]) => passed !== true).map(([id]) => id);
294
+ }
295
+
296
+ /**
297
+ * Build fixed-workload Codex-relative evidence. The caller supplies quality and
298
+ * execution-parity checks because those are evaluated by the benchmark core.
299
+ */
300
+ export function evaluateCodexRelativeEfficiency({
301
+ suite,
302
+ allPairs,
303
+ repeats,
304
+ baselineSurface,
305
+ candidateSurface,
306
+ required = false,
307
+ parityChecks = {},
308
+ qualityChecks = {},
309
+ policy = CODEX_RELATIVE_EFFICIENCY_POLICY
310
+ }) {
311
+ const expectedAttempts = Number.isSafeInteger(repeats) && repeats > 0 ? repeats : null;
312
+ const expectedModel = suite?.executionContract?.model;
313
+ const expectedThinking = suite?.executionContract?.thinking;
314
+ const byScenario = new Map();
315
+ for (const pair of allPairs ?? []) {
316
+ const scenarioId = pair?.candidate?.scenarioId ?? pair?.baseline?.scenarioId;
317
+ if (typeof scenarioId !== "string") continue;
318
+ const values = byScenario.get(scenarioId) ?? [];
319
+ values.push(pair);
320
+ byScenario.set(scenarioId, values);
321
+ }
322
+
323
+ const families = (suite?.scenarios ?? []).map((scenario) => {
324
+ const pairs = byScenario.get(scenario.id) ?? [];
325
+ const repeatCount = new Set(pairs.map((pair) => pair?.candidate?.repeat ?? pair?.baseline?.repeat)).size;
326
+ const issues = [];
327
+ const coverageComplete = expectedAttempts !== null && pairs.length === expectedAttempts && repeatCount === expectedAttempts;
328
+ if (!coverageComplete) {
329
+ issues.push("incomplete-paired-attempt-coverage");
330
+ }
331
+ const baselineTokens = zeroTokens();
332
+ const candidateTokens = zeroTokens();
333
+ let baselineCostUsd = 0;
334
+ let candidateCostUsd = 0;
335
+ let subagentSessions = 0;
336
+ let subagentTraffic = 0;
337
+ let maximumSubagentSessionsPerAttempt = 0;
338
+ let candidateAttempts = 0;
339
+ let measuredTokenPairs = 0;
340
+ let measuredCostPairs = 0;
341
+ let measuredSubagentPairs = 0;
342
+ for (const pair of pairs) {
343
+ const identityIssues = pairIdentityIssues(pair);
344
+ issues.push(...identityIssues);
345
+ const baseline = measureRun(pair.baseline, suite.pricingSnapshot, expectedModel, expectedThinking, { candidate: false });
346
+ const candidate = measureRun(pair.candidate, suite.pricingSnapshot, expectedModel, expectedThinking, { candidate: true });
347
+ candidateAttempts += candidate.attemptCount;
348
+ issues.push(...baseline.issues.map((issue) => `baseline:${issue}`));
349
+ issues.push(...candidate.issues.map((issue) => `candidate:${issue}`));
350
+ const tokenPairExact = identityIssues.length === 0 && baseline.tokenExact && candidate.tokenExact;
351
+ if (tokenPairExact) {
352
+ measuredTokenPairs += 1;
353
+ addTokens(baselineTokens, baseline.tokens);
354
+ addTokens(candidateTokens, candidate.tokens);
355
+ }
356
+ if (tokenPairExact && baseline.costExact && candidate.costExact) {
357
+ measuredCostPairs += 1;
358
+ baselineCostUsd += baseline.costAmount;
359
+ candidateCostUsd += candidate.costAmount;
360
+ }
361
+ if (candidate.subagentExact) {
362
+ measuredSubagentPairs += 1;
363
+ subagentSessions += candidate.subagentSessions;
364
+ subagentTraffic += candidate.subagentTraffic;
365
+ maximumSubagentSessionsPerAttempt = Math.max(
366
+ maximumSubagentSessionsPerAttempt,
367
+ candidate.maximumSubagentSessionsPerAttempt
368
+ );
369
+ }
370
+ }
371
+ const tokenExact = coverageComplete && measuredTokenPairs === expectedAttempts;
372
+ const costExact = tokenExact && measuredCostPairs === expectedAttempts;
373
+ const subagentExact = coverageComplete && measuredSubagentPairs === expectedAttempts;
374
+ const totalTokenTrafficRatio = tokenExact && baselineTokens.total > 0 && candidateTokens.total > 0
375
+ ? candidateTokens.total / baselineTokens.total
376
+ : null;
377
+ const apiEquivalentCostRatio = costExact && baselineCostUsd > 0 && candidateCostUsd > 0
378
+ ? candidateCostUsd / baselineCostUsd
379
+ : null;
380
+ if (tokenExact && !Number.isFinite(totalTokenTrafficRatio)) issues.push("non-positive-token-traffic");
381
+ if (costExact && !Number.isFinite(apiEquivalentCostRatio)) issues.push("non-positive-api-equivalent-cost");
382
+ return {
383
+ scenarioId: scenario.id,
384
+ expectedAttempts,
385
+ pairedAttempts: pairs.length,
386
+ exact: issues.length === 0 && tokenExact && costExact && subagentExact,
387
+ issues: [...new Set(issues)],
388
+ baselineTokenTraffic: baselineTokens.total,
389
+ candidateTokenTraffic: candidateTokens.total,
390
+ totalTokenTrafficRatio,
391
+ baselineApiEquivalentCostUsd: rounded(baselineCostUsd, 9),
392
+ candidateApiEquivalentCostUsd: rounded(candidateCostUsd, 9),
393
+ apiEquivalentCostRatio,
394
+ candidateSubagentSessions: subagentSessions,
395
+ candidateSubagentTraffic: subagentTraffic,
396
+ maximumSubagentSessionsPerAttempt,
397
+ candidateAttempts,
398
+ subagentEvidenceComplete: subagentExact
399
+ };
400
+ });
401
+
402
+ const traffic = aggregateFamilies(families, "totalTokenTrafficRatio");
403
+ const cost = aggregateFamilies(families, "apiEquivalentCostRatio");
404
+ const baselineTraffic = families.reduce((sum, family) => sum + family.baselineTokenTraffic, 0);
405
+ const candidateTraffic = families.reduce((sum, family) => sum + family.candidateTokenTraffic, 0);
406
+ const baselineCostUsd = families.reduce((sum, family) => sum + family.baselineApiEquivalentCostUsd, 0);
407
+ const candidateCostUsd = families.reduce((sum, family) => sum + family.candidateApiEquivalentCostUsd, 0);
408
+ const candidateSubagentSessions = families.reduce((sum, family) => sum + family.candidateSubagentSessions, 0);
409
+ const candidateSubagentTraffic = families.reduce((sum, family) => sum + family.candidateSubagentTraffic, 0);
410
+ const candidateAttempts = families.reduce((sum, family) => sum + family.candidateAttempts, 0);
411
+ const subagentEvidenceComplete = families.every((family) => family.subagentEvidenceComplete === true);
412
+ const subagentTrafficShare = candidateTraffic > 0 ? candidateSubagentTraffic / candidateTraffic : null;
413
+ const maxObservedSubagents = families.reduce(
414
+ (maximum, family) => Math.max(maximum, family.maximumSubagentSessionsPerAttempt),
415
+ 0
416
+ );
417
+
418
+ const surfaceChecks = {
419
+ "codex-cli-baseline": baselineSurface === policy.baselineSurface,
420
+ "piagent-candidate": candidateSurface === policy.candidateSurface,
421
+ "execution-contract-surfaces": suite?.executionContract?.surfaces?.[0] === "piagent"
422
+ && suite.executionContract.surfaces?.[1] === "codex-cli",
423
+ "execution-contract-model": typeof expectedModel === "string" && expectedModel.length > 0,
424
+ "execution-contract-thinking": typeof expectedThinking === "string" && expectedThinking.length > 0,
425
+ "pricing-snapshot-bound-to-model": suite?.pricingSnapshot?.model === expectedModel
426
+ };
427
+ const evidenceChecks = {
428
+ "fixed-workload-token-traffic-complete": traffic.complete,
429
+ "fixed-workload-api-equivalent-cost-complete": cost.complete,
430
+ "total-token-traffic-point": Number.isFinite(traffic.ratio)
431
+ && atMostWithinFloatingPrecision(traffic.ratio, policy.maximumTotalTokenTrafficRatio),
432
+ "total-token-traffic-upper95": Number.isFinite(traffic.ratioConfidence95Raw?.upper)
433
+ && atMostWithinFloatingPrecision(traffic.ratioConfidence95Raw.upper, policy.maximumTotalTokenTrafficRatioUpper95),
434
+ "api-equivalent-cost-point": Number.isFinite(cost.ratio)
435
+ && atMostWithinFloatingPrecision(cost.ratio, policy.maximumApiEquivalentCostRatio),
436
+ "api-equivalent-cost-upper95": Number.isFinite(cost.ratioConfidence95Raw?.upper)
437
+ && atMostWithinFloatingPrecision(cost.ratioConfidence95Raw.upper, policy.maximumApiEquivalentCostRatioUpper95),
438
+ "subagent-usage-complete": subagentEvidenceComplete,
439
+ "subagent-session-budget": maxObservedSubagents <= policy.maximumSubagentSessionsPerAttempt,
440
+ "subagent-traffic-budget": Number.isFinite(subagentTrafficShare)
441
+ && atMostWithinFloatingPrecision(subagentTrafficShare, policy.maximumSubagentTrafficShare)
442
+ };
443
+ const checks = { ...surfaceChecks, ...parityChecks, ...qualityChecks, ...evidenceChecks };
444
+ const failures = booleanChecks(checks);
445
+
446
+ return {
447
+ schemaVersion: 1,
448
+ policy,
449
+ required,
450
+ claim: "Piagent uses at least 30% less provider token traffic and API-equivalent text-token cost than controlled Codex CLI on the same fixed workload without quality or continuity regression.",
451
+ billedOrSubscriptionCost: false,
452
+ costBoundary: "versioned-api-equivalent-text-token-pricing; not OAuth subscription debiting",
453
+ checks,
454
+ failures,
455
+ passed: failures.length === 0,
456
+ families,
457
+ totalTokenTraffic: {
458
+ ...traffic,
459
+ aggregateBaselineTokens: baselineTraffic,
460
+ aggregateCandidateTokens: candidateTraffic,
461
+ aggregateRatio: baselineTraffic > 0 ? candidateTraffic / baselineTraffic : null,
462
+ deltaPercent: Number.isFinite(traffic.ratio) ? rounded((traffic.ratio - 1) * 100, 2) : null
463
+ },
464
+ apiEquivalentCost: {
465
+ ...cost,
466
+ aggregateBaselineUsd: rounded(baselineCostUsd, 9),
467
+ aggregateCandidateUsd: rounded(candidateCostUsd, 9),
468
+ aggregateRatio: baselineCostUsd > 0 ? candidateCostUsd / baselineCostUsd : null,
469
+ deltaPercent: Number.isFinite(cost.ratio) ? rounded((cost.ratio - 1) * 100, 2) : null
470
+ },
471
+ subagents: {
472
+ candidateAttempts,
473
+ sessions: candidateSubagentSessions,
474
+ tokenTraffic: candidateSubagentTraffic,
475
+ trafficShare: subagentTrafficShare,
476
+ maximumObservedSessionsPerAttempt: maxObservedSubagents
477
+ }
478
+ };
479
+ }
480
+
481
+ const DOWNSTREAM_VERDICTS = new Set([
482
+ "performance-evidence-gate-failed",
483
+ "performance-point-regression",
484
+ "performance-confidence-gate-failed",
485
+ "performance-band-ratio-gate-failed",
486
+ "performance-family-ratio-gate-failed",
487
+ "efficiency-band-ratio-gate-failed",
488
+ "efficiency-family-ratio-gate-failed",
489
+ "efficiency-confidence-gate-failed",
490
+ "observational-efficiency-only"
491
+ ]);
492
+
493
+ function pairedRuns(report) {
494
+ const baselineSurface = report.comparison.baselineSurface;
495
+ const candidateSurface = report.comparison.candidateSurface;
496
+ const baselineByKey = new Map(report.runs
497
+ .filter((run) => run.surface === baselineSurface)
498
+ .map((run) => [`${run.scenarioId}:${run.repeat}`, run]));
499
+ return report.runs
500
+ .filter((run) => run.surface === candidateSurface)
501
+ .map((candidate) => ({ baseline: baselineByKey.get(`${candidate.scenarioId}:${candidate.repeat}`), candidate }))
502
+ .filter((pair) => pair.baseline);
503
+ }
504
+
505
+ function insertReleaseFailure(gate, failure = "codex-relative-efficiency") {
506
+ if (!gate || gate.failures.includes(failure)) return;
507
+ const laterFailures = new Set([
508
+ "repeat-count",
509
+ "efficiency-confidence",
510
+ "performance-evidence",
511
+ "performance-point-regression",
512
+ "performance-confidence",
513
+ "performance-band-ratio",
514
+ "performance-family-ratio"
515
+ ]);
516
+ const index = gate.failures.findIndex((failure) => laterFailures.has(failure));
517
+ gate.failures.splice(index < 0 ? gate.failures.length : index, 0, failure);
518
+ gate.failureReasons = gate.failures.map((id) => ({ id, message: RELEASE_FAILURE_MESSAGES[id] ?? id }));
519
+ gate.passed = false;
520
+ }
521
+
522
+ function codexRelativeChecks(report) {
523
+ const comparison = report.comparison;
524
+ return {
525
+ parityChecks: {
526
+ "comparison-protocol": comparison.comparisonProtocolGate.passed,
527
+ "equivalent-task-access-context": report.environment.comparisonAccessContract === "paired-workspace-write-offline-surface-system",
528
+ "full-suite": comparison.fullSuiteGate !== false,
529
+ "stable-provider-wire": comparison.providerWireSurfaceGate !== false,
530
+ "exact-all-attempt-usage": comparison.allAttemptUsageCompletenessGate !== false,
531
+ "stable-attempt-ledger": comparison.stabilityGate !== false,
532
+ "causal-context-evidence": comparison.causalContextEvidenceGate !== false
533
+ },
534
+ qualityChecks: {
535
+ "quality-noninferior": comparison.qualityNonInferior,
536
+ "paired-quality-noninferior": comparison.pairedQualityNoninferiorityGate !== false,
537
+ "absolute-quality": comparison.qualityGate,
538
+ safety: comparison.safetyGate,
539
+ reliability: comparison.reliabilityGate,
540
+ workflow: comparison.workflowGate !== false,
541
+ category: comparison.categoryGate !== false,
542
+ "outcome-score-floor": comparison.outcomeScoreGate !== false,
543
+ "no-baseline-pass-candidate-fail": comparison.pairedRegressionGate,
544
+ "candidate-task-continuity": comparison.candidateTaskContinuityGate
545
+ }
546
+ };
547
+ }
548
+
549
+ function productionRuntimeCoverage(report, suite) {
550
+ const required = suite.releaseGate?.requireProviderFreeEvidence === true;
551
+ const receipt = report.environment?.providerFreeEvidence ?? null;
552
+ const providerFreeErrors = required
553
+ ? productionProviderFreeEvidenceContextValidationErrors(receipt, {
554
+ source: report.environment?.source,
555
+ candidateProvenance: report.environment?.candidateProvenance,
556
+ configurationDigest: report.environment?.configurationDigest
557
+ })
558
+ : [];
559
+ const providerFreePassed = !required || providerFreeErrors.length === 0;
560
+ const candidateRuns = report.runs.filter((run) => run.surface === report.comparison.candidateSurface);
561
+ const statuses = candidateRuns.map((run) => run?.causalContextReceipt?.aggregates?.runtimeCausal?.adaptiveContext?.coverageStatus ?? "not-observed");
562
+ const partialRuns = statuses.filter((status) => status === "partial").length;
563
+ const notObservedRuns = statuses.filter((status) => status === "not-observed").length;
564
+ const adaptiveContextPassed = !required || (partialRuns === 0 && (notObservedRuns === 0 || providerFreePassed));
565
+ return {
566
+ required,
567
+ passed: providerFreePassed && adaptiveContextPassed,
568
+ providerFree: { passed: providerFreePassed, errors: providerFreeErrors, receipt },
569
+ adaptiveContext: {
570
+ passed: adaptiveContextPassed,
571
+ partialRuns,
572
+ notObservedRuns,
573
+ notObservedCoveredBySameSourceProviderFreeLane: notObservedRuns > 0 && providerFreePassed
574
+ }
575
+ };
576
+ }
577
+
578
+ /**
579
+ * Add the Codex-relative claim gate after the generic benchmark report is built.
580
+ * Keeping this policy adapter outside benchmark-core prevents one product claim
581
+ * from expanding the generic summarizer while preserving the public report.
582
+ */
583
+ export function integrateCodexRelativeEfficiencyReport(report, suite) {
584
+ const comparison = report.comparison;
585
+ const required = suite.releaseGate?.requireNormalizedCostClaim === true;
586
+ const checks = codexRelativeChecks(report);
587
+ const evidence = comparison.baselineSurface === CODEX_RELATIVE_EFFICIENCY_POLICY.baselineSurface
588
+ ? evaluateCodexRelativeEfficiency({
589
+ suite,
590
+ allPairs: pairedRuns(report),
591
+ repeats: report.repeats,
592
+ baselineSurface: comparison.baselineSurface,
593
+ candidateSurface: comparison.candidateSurface,
594
+ required,
595
+ ...checks
596
+ })
597
+ : null;
598
+ const gate = required ? evidence?.passed === true : null;
599
+ comparison.codexRelativeEfficiency = evidence;
600
+ comparison.codexRelativeEfficiencyGate = gate;
601
+
602
+ const subagentBudgetRequired = suite.releaseGate?.requireSubagentBudget === true
603
+ && comparison.baselineSurface === CODEX_RELATIVE_EFFICIENCY_POLICY.baselineSurface
604
+ && comparison.candidateSurface === CODEX_RELATIVE_EFFICIENCY_POLICY.candidateSurface;
605
+ const subagentBudget = subagentBudgetRequired
606
+ ? summarizeBenchmarkSubagentBudget(report.runs, {
607
+ candidateSurface: comparison.candidateSurface,
608
+ policy: {
609
+ ...PRODUCTION_SUBAGENT_BUDGET_POLICY,
610
+ maximumSubagentSessionsPerAttempt: suite.releaseGate.maximumSubagentSessionsPerAttempt,
611
+ maximumSubagentTrafficShare: suite.releaseGate.maximumSubagentTrafficShare
612
+ }
613
+ })
614
+ : null;
615
+ const subagentBudgetGate = subagentBudgetRequired ? subagentBudget?.passed === true : null;
616
+ comparison.productionSubagentBudget = subagentBudget;
617
+ comparison.productionSubagentBudgetGate = subagentBudgetGate;
618
+ const runtimeCoverage = productionRuntimeCoverage(report, suite);
619
+ comparison.productionProviderFreeEvidenceGate = runtimeCoverage.required ? runtimeCoverage.providerFree.passed : null;
620
+ comparison.productionProviderFreeEvidence = runtimeCoverage.providerFree;
621
+ comparison.adaptiveContextRuntimeGate = runtimeCoverage.required ? runtimeCoverage.adaptiveContext.passed : null;
622
+ comparison.adaptiveContextRuntimeCoverage = runtimeCoverage.adaptiveContext;
623
+
624
+ if (comparison.suiteGate) {
625
+ comparison.suiteGate.observed.codexRelativeMaximumTokenTrafficRatioUpper95 = required
626
+ ? CODEX_RELATIVE_EFFICIENCY_POLICY.maximumTotalTokenTrafficRatioUpper95
627
+ : null;
628
+ comparison.suiteGate.observed.codexRelativeMaximumApiEquivalentCostRatioUpper95 = required
629
+ ? CODEX_RELATIVE_EFFICIENCY_POLICY.maximumApiEquivalentCostRatioUpper95
630
+ : null;
631
+ comparison.suiteGate.observed.productionSubagentBudget = subagentBudget;
632
+ }
633
+
634
+ if (required && gate === false) {
635
+ for (const releaseGate of new Set([comparison.suiteGate, comparison.productionGate])) {
636
+ insertReleaseFailure(releaseGate);
637
+ }
638
+ comparison.tokenClaimAllowed = false;
639
+ comparison.claimEligibility = benchmarkClaimEligibility({
640
+ suite,
641
+ environment: report.environment,
642
+ baselineSurface: comparison.baselineSurface,
643
+ protocolPassed: comparison.comparisonProtocolGate.passed,
644
+ tokenClaimAllowed: false
645
+ });
646
+ comparison.purpose = comparison.claimEligibility.comparisonPurpose;
647
+ const candidate = Object.values(report.surfaces).find((surface) => surface.surface === comparison.candidateSurface);
648
+ if (candidate?.scores) candidate.scores.overall = null;
649
+ if (DOWNSTREAM_VERDICTS.has(report.verdict.status) || report.verdict.status === `${comparison.candidateSurface}-more-efficient`) {
650
+ report.verdict.status = "codex-relative-efficiency-gate-failed";
651
+ }
652
+ }
653
+
654
+ if (subagentBudgetRequired && subagentBudgetGate === false) {
655
+ for (const releaseGate of new Set([comparison.suiteGate, comparison.productionGate])) {
656
+ insertReleaseFailure(releaseGate, "production-subagent-budget");
657
+ }
658
+ comparison.tokenClaimAllowed = false;
659
+ comparison.claimEligibility = benchmarkClaimEligibility({
660
+ suite,
661
+ environment: report.environment,
662
+ baselineSurface: comparison.baselineSurface,
663
+ protocolPassed: comparison.comparisonProtocolGate.passed,
664
+ tokenClaimAllowed: false
665
+ });
666
+ comparison.purpose = comparison.claimEligibility.comparisonPurpose;
667
+ const candidate = Object.values(report.surfaces).find((surface) => surface.surface === comparison.candidateSurface);
668
+ if (candidate?.scores) candidate.scores.overall = null;
669
+ if (DOWNSTREAM_VERDICTS.has(report.verdict.status) || report.verdict.status === `${comparison.candidateSurface}-more-efficient`) {
670
+ report.verdict.status = "production-subagent-budget-gate-failed";
671
+ }
672
+ }
673
+ if (runtimeCoverage.required && runtimeCoverage.passed === false) {
674
+ for (const releaseGate of new Set([comparison.suiteGate, comparison.productionGate])) {
675
+ if (!runtimeCoverage.providerFree.passed) insertReleaseFailure(releaseGate, "provider-free-evidence");
676
+ if (!runtimeCoverage.adaptiveContext.passed) insertReleaseFailure(releaseGate, "adaptive-context-runtime-coverage");
677
+ }
678
+ comparison.tokenClaimAllowed = false;
679
+ comparison.claimEligibility = benchmarkClaimEligibility({ suite, environment: report.environment,
680
+ baselineSurface: comparison.baselineSurface, protocolPassed: comparison.comparisonProtocolGate.passed, tokenClaimAllowed: false });
681
+ comparison.purpose = comparison.claimEligibility.comparisonPurpose;
682
+ const candidate = Object.values(report.surfaces).find((surface) => surface.surface === comparison.candidateSurface);
683
+ if (candidate?.scores) candidate.scores.overall = null;
684
+ if (DOWNSTREAM_VERDICTS.has(report.verdict.status) || report.verdict.status === `${comparison.candidateSurface}-more-efficient`) {
685
+ report.verdict.status = runtimeCoverage.providerFree.passed
686
+ ? "adaptive-context-runtime-coverage-gate-failed"
687
+ : "provider-free-evidence-gate-failed";
688
+ }
689
+ }
690
+
691
+ report.verdict.note = report.verdict.note
692
+ .replace(
693
+ "quality and continuity remain independent hard gates. ",
694
+ "quality and continuity remain independent hard gates. Production token claims always require exact child-session evidence, at most one subagent per provider attempt, and no more than 5% subagent token traffic. When a suite explicitly enables the optional Codex-relative cost claim, its separate gate requires both total provider token traffic and API-equivalent text-token cost, including cache traffic, to have point and upper-95 ratios at or below 0.70; it is not a subscription-spend claim. "
695
+ )
696
+ .replace(" Normalized cost is API-equivalent text-token input/cache/output cost from the versioned suite pricing snapshot and exact token buckets, never OAuth/provider-billed or tool-specific total cost.", "");
697
+ return report;
698
+ }