@piagent/platform 1.6.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (645) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +8 -2
  3. package/README.vi.md +11 -2
  4. package/adapters/common/assurance-producers.json +109 -0
  5. package/adapters/common/structured-assurance-facts.mjs +153 -0
  6. package/adapters/node-typescript/contract-families.json +2811 -0
  7. package/adapters/node-typescript/contract-families.md +90 -0
  8. package/benchmarks/production-v1/grade.mjs +20 -0
  9. package/benchmarks/production-v1/spend-control.v1.json +3 -3
  10. package/benchmarks/production-v2/grade.mjs +892 -0
  11. package/benchmarks/production-v2/project/README.md +7 -0
  12. package/benchmarks/production-v2/project/config/service.json +4 -0
  13. package/benchmarks/production-v2/project/data/audit-ledger.jsonl +1 -0
  14. package/benchmarks/production-v2/project/docs/ops.md +3 -0
  15. package/benchmarks/production-v2/project/logs/incident.log +2 -0
  16. package/benchmarks/production-v2/project/package.json +11 -0
  17. package/benchmarks/production-v2/project/scripts/check.mjs +21 -0
  18. package/benchmarks/production-v2/project/src/backend/auth.js +3 -0
  19. package/benchmarks/production-v2/project/src/backend/billing-window.js +4 -0
  20. package/benchmarks/production-v2/project/src/backend/cache.js +15 -0
  21. package/benchmarks/production-v2/project/src/backend/invoice.js +4 -0
  22. package/benchmarks/production-v2/project/src/backend/revocation-cache.js +3 -0
  23. package/benchmarks/production-v2/project/src/data/csv.js +3 -0
  24. package/benchmarks/production-v2/project/src/data/dedup.js +5 -0
  25. package/benchmarks/production-v2/project/src/data/migration.js +9 -0
  26. package/benchmarks/production-v2/project/src/data/ndjson-stream.js +5 -0
  27. package/benchmarks/production-v2/project/src/data/versioned-replay.js +8 -0
  28. package/benchmarks/production-v2/project/src/frontend/chat-events.js +7 -0
  29. package/benchmarks/production-v2/project/src/frontend/pagination.js +8 -0
  30. package/benchmarks/production-v2/project/src/frontend/request-lifecycle.js +15 -0
  31. package/benchmarks/production-v2/project/src/frontend/search-state.js +8 -0
  32. package/benchmarks/production-v2/project/src/frontend/unicode-search.js +7 -0
  33. package/benchmarks/production-v2/project/src/fullstack/contract-sync.js +10 -0
  34. package/benchmarks/production-v2/project/src/platform/args.js +10 -0
  35. package/benchmarks/production-v2/project/src/platform/config.js +7 -0
  36. package/benchmarks/production-v2/project/src/platform/workflow-session.js +9 -0
  37. package/benchmarks/production-v2/project/src/platform/workspace.js +13 -0
  38. package/benchmarks/production-v2/project/src/reliability/checkpoint.js +5 -0
  39. package/benchmarks/production-v2/project/src/reliability/expiry.js +5 -0
  40. package/benchmarks/production-v2/project/src/reliability/retry.js +15 -0
  41. package/benchmarks/production-v2/project/test/smoke.test.js +21 -0
  42. package/benchmarks/production-v2/project/vendor/README.md +1 -0
  43. package/benchmarks/production-v2/prompts/abort-reconnect-supersession.md +11 -0
  44. package/benchmarks/production-v2/prompts/backend-frontend-contract-sync.md +12 -0
  45. package/benchmarks/production-v2/prompts/billing-cutoff-clock-skew.md +11 -0
  46. package/benchmarks/production-v2/prompts/bounded-retry.md +7 -0
  47. package/benchmarks/production-v2/prompts/chunked-record-boundary.md +9 -0
  48. package/benchmarks/production-v2/prompts/cli-double-dash.md +7 -0
  49. package/benchmarks/production-v2/prompts/config-precedence.md +6 -0
  50. package/benchmarks/production-v2/prompts/destructive-history-refusal.md +3 -0
  51. package/benchmarks/production-v2/prompts/expiry-boundary.md +7 -0
  52. package/benchmarks/production-v2/prompts/idempotent-replay-conflict.md +11 -0
  53. package/benchmarks/production-v2/prompts/incident-diagnosis.md +4 -0
  54. package/benchmarks/production-v2/prompts/invoice-rounding.md +9 -0
  55. package/benchmarks/production-v2/prompts/journeys/config-precedence-scout.md +3 -0
  56. package/benchmarks/production-v2/prompts/journeys/expiry-boundary-scout.md +3 -0
  57. package/benchmarks/production-v2/prompts/journeys/quoted-csv-scout.md +3 -0
  58. package/benchmarks/production-v2/prompts/journeys/recover-after-uncertain-send.md +4 -0
  59. package/benchmarks/production-v2/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  60. package/benchmarks/production-v2/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  61. package/benchmarks/production-v2/prompts/journeys/stable-dedup-scout.md +3 -0
  62. package/benchmarks/production-v2/prompts/journeys/stale-search-response-scout.md +3 -0
  63. package/benchmarks/production-v2/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  64. package/benchmarks/production-v2/prompts/journeys/verify-current-contract.md +4 -0
  65. package/benchmarks/production-v2/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  66. package/benchmarks/production-v2/prompts/pagination-boundary.md +7 -0
  67. package/benchmarks/production-v2/prompts/protected-env-refusal.md +2 -0
  68. package/benchmarks/production-v2/prompts/quoted-csv.md +6 -0
  69. package/benchmarks/production-v2/prompts/reconnect-chat-event-order.md +19 -0
  70. package/benchmarks/production-v2/prompts/repository-prompt-injection.md +5 -0
  71. package/benchmarks/production-v2/prompts/resumable-checkpoint-partial-failure.md +11 -0
  72. package/benchmarks/production-v2/prompts/revoked-session-cache.md +10 -0
  73. package/benchmarks/production-v2/prompts/schema-migration.md +6 -0
  74. package/benchmarks/production-v2/prompts/stable-dedup.md +6 -0
  75. package/benchmarks/production-v2/prompts/stale-search-response.md +6 -0
  76. package/benchmarks/production-v2/prompts/tenant-cache-isolation.md +6 -0
  77. package/benchmarks/production-v2/prompts/tenant-role-authorization.md +6 -0
  78. package/benchmarks/production-v2/prompts/unicode-search.md +6 -0
  79. package/benchmarks/production-v2/prompts/workflow-switch-same-session.md +30 -0
  80. package/benchmarks/production-v2/prompts/workspace-order.md +7 -0
  81. package/benchmarks/production-v2/spend-control.v1.json +115 -0
  82. package/benchmarks/production-v2/suite.json +1009 -0
  83. package/benchmarks/production-v2/variant.mjs +169 -0
  84. package/benchmarks/production-v3/CONTRACT-REVISION-20260922.md +31 -0
  85. package/benchmarks/production-v3/calibration/corpus.v1.json +63 -0
  86. package/benchmarks/production-v3/calibration/human-review-rubric.v1.json +36 -0
  87. package/benchmarks/production-v3/grade.mjs +1017 -0
  88. package/benchmarks/production-v3/project/README.md +7 -0
  89. package/benchmarks/production-v3/project/config/service.json +4 -0
  90. package/benchmarks/production-v3/project/data/audit-ledger.jsonl +1 -0
  91. package/benchmarks/production-v3/project/docs/ops.md +3 -0
  92. package/benchmarks/production-v3/project/logs/incident.log +2 -0
  93. package/benchmarks/production-v3/project/package.json +11 -0
  94. package/benchmarks/production-v3/project/scripts/check.mjs +21 -0
  95. package/benchmarks/production-v3/project/src/backend/auth.js +3 -0
  96. package/benchmarks/production-v3/project/src/backend/billing-window.js +4 -0
  97. package/benchmarks/production-v3/project/src/backend/cache.js +15 -0
  98. package/benchmarks/production-v3/project/src/backend/invoice.js +4 -0
  99. package/benchmarks/production-v3/project/src/backend/revocation-cache.js +12 -0
  100. package/benchmarks/production-v3/project/src/data/csv.js +3 -0
  101. package/benchmarks/production-v3/project/src/data/dedup.js +5 -0
  102. package/benchmarks/production-v3/project/src/data/migration.js +9 -0
  103. package/benchmarks/production-v3/project/src/data/ndjson-stream.js +5 -0
  104. package/benchmarks/production-v3/project/src/data/versioned-replay.js +8 -0
  105. package/benchmarks/production-v3/project/src/frontend/chat-events.js +7 -0
  106. package/benchmarks/production-v3/project/src/frontend/pagination.js +8 -0
  107. package/benchmarks/production-v3/project/src/frontend/request-lifecycle.js +23 -0
  108. package/benchmarks/production-v3/project/src/frontend/search-state.js +8 -0
  109. package/benchmarks/production-v3/project/src/frontend/unicode-search.js +7 -0
  110. package/benchmarks/production-v3/project/src/fullstack/contract-sync.js +10 -0
  111. package/benchmarks/production-v3/project/src/platform/args.js +10 -0
  112. package/benchmarks/production-v3/project/src/platform/config.js +7 -0
  113. package/benchmarks/production-v3/project/src/platform/workflow-session.js +9 -0
  114. package/benchmarks/production-v3/project/src/platform/workspace.js +13 -0
  115. package/benchmarks/production-v3/project/src/reliability/checkpoint.js +5 -0
  116. package/benchmarks/production-v3/project/src/reliability/expiry.js +14 -0
  117. package/benchmarks/production-v3/project/src/reliability/retry.js +15 -0
  118. package/benchmarks/production-v3/project/test/smoke.test.js +21 -0
  119. package/benchmarks/production-v3/project/vendor/README.md +1 -0
  120. package/benchmarks/production-v3/prompts/abort-reconnect-supersession.md +11 -0
  121. package/benchmarks/production-v3/prompts/backend-frontend-contract-sync.md +20 -0
  122. package/benchmarks/production-v3/prompts/billing-cutoff-clock-skew.md +11 -0
  123. package/benchmarks/production-v3/prompts/bounded-retry.md +7 -0
  124. package/benchmarks/production-v3/prompts/chunked-record-boundary.md +11 -0
  125. package/benchmarks/production-v3/prompts/cli-double-dash.md +7 -0
  126. package/benchmarks/production-v3/prompts/config-precedence.md +6 -0
  127. package/benchmarks/production-v3/prompts/destructive-history-refusal.md +9 -0
  128. package/benchmarks/production-v3/prompts/expiry-boundary.md +14 -0
  129. package/benchmarks/production-v3/prompts/idempotent-replay-conflict.md +13 -0
  130. package/benchmarks/production-v3/prompts/incident-diagnosis.md +4 -0
  131. package/benchmarks/production-v3/prompts/invoice-rounding.md +9 -0
  132. package/benchmarks/production-v3/prompts/journeys/config-precedence-scout.md +3 -0
  133. package/benchmarks/production-v3/prompts/journeys/expiry-boundary-scout.md +3 -0
  134. package/benchmarks/production-v3/prompts/journeys/quoted-csv-scout.md +3 -0
  135. package/benchmarks/production-v3/prompts/journeys/recover-after-uncertain-send.md +4 -0
  136. package/benchmarks/production-v3/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  137. package/benchmarks/production-v3/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  138. package/benchmarks/production-v3/prompts/journeys/stable-dedup-scout.md +3 -0
  139. package/benchmarks/production-v3/prompts/journeys/stale-search-response-scout.md +3 -0
  140. package/benchmarks/production-v3/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  141. package/benchmarks/production-v3/prompts/journeys/verify-current-contract.md +4 -0
  142. package/benchmarks/production-v3/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  143. package/benchmarks/production-v3/prompts/pagination-boundary.md +9 -0
  144. package/benchmarks/production-v3/prompts/protected-env-refusal.md +8 -0
  145. package/benchmarks/production-v3/prompts/quoted-csv.md +6 -0
  146. package/benchmarks/production-v3/prompts/reconnect-chat-event-order.md +20 -0
  147. package/benchmarks/production-v3/prompts/repository-prompt-injection.md +5 -0
  148. package/benchmarks/production-v3/prompts/resumable-checkpoint-partial-failure.md +15 -0
  149. package/benchmarks/production-v3/prompts/revoked-session-cache.md +10 -0
  150. package/benchmarks/production-v3/prompts/schema-migration.md +6 -0
  151. package/benchmarks/production-v3/prompts/stable-dedup.md +6 -0
  152. package/benchmarks/production-v3/prompts/stale-search-response.md +6 -0
  153. package/benchmarks/production-v3/prompts/tenant-cache-isolation.md +6 -0
  154. package/benchmarks/production-v3/prompts/tenant-role-authorization.md +6 -0
  155. package/benchmarks/production-v3/prompts/unicode-search.md +6 -0
  156. package/benchmarks/production-v3/prompts/workflow-switch-same-session.md +30 -0
  157. package/benchmarks/production-v3/prompts/workspace-order.md +7 -0
  158. package/benchmarks/production-v3/public-checks/abort-reconnect-supersession.js +34 -0
  159. package/benchmarks/production-v3/public-checks/expiry-boundary.js +29 -0
  160. package/benchmarks/production-v3/public-checks/revoked-session-cache.js +20 -0
  161. package/benchmarks/production-v3/spend-control.v1.json +121 -0
  162. package/benchmarks/production-v3/suite.json +1010 -0
  163. package/benchmarks/production-v3/variant.mjs +178 -0
  164. package/catalog/capabilities.json +2 -2
  165. package/docs/benchmark-codex-mcp-metadata-contract-v1.md +159 -0
  166. package/docs/benchmark-codex-mcp-metadata-contract-v2.md +182 -0
  167. package/docs/benchmark-codex-mcp-metadata-contract-v3.md +194 -0
  168. package/docs/benchmark-public-contract-addendum-v2.md +85 -0
  169. package/docs/benchmark-public-contract-addendum-v3.md +116 -0
  170. package/docs/command-reference-vietnamese.md +10 -7
  171. package/docs/context-window-policy.md +3 -3
  172. package/docs/distribution-standard.md +9 -9
  173. package/docs/languages.json +2 -2
  174. package/docs/operator-manual-vietnamese.md +12 -12
  175. package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
  176. package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
  177. package/docs/piagent-core-improvement-plan.md +528 -0
  178. package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
  179. package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
  180. package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
  181. package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
  182. package/docs/piagent-open-session-wait.md +19 -0
  183. package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
  184. package/docs/publishing-for-teams.md +2 -0
  185. package/docs/quality-benchmark.md +128 -8
  186. package/docs/quickstart-vietnamese.md +2 -2
  187. package/docs/release-install-policy.md +32 -9
  188. package/docs/research/harness-next-evidence-review.md +113 -0
  189. package/docs/team-onboarding.md +7 -7
  190. package/docs/third-party-neutrality.md +7 -0
  191. package/docs/usage-observability.md +1 -1
  192. package/docs-site/architecture.html +1 -1
  193. package/docs-site/benchmark.html +1 -1
  194. package/docs-site/commands.html +1 -1
  195. package/docs-site/content/en/runtime.html +1 -1
  196. package/docs-site/content/en/whats-new.html +11 -0
  197. package/docs-site/content/runtime.html +2 -2
  198. package/docs-site/content/whats-new.html +11 -0
  199. package/docs-site/context-engine.html +1 -1
  200. package/docs-site/en/architecture.html +1 -1
  201. package/docs-site/en/benchmark.html +1 -1
  202. package/docs-site/en/commands.html +1 -1
  203. package/docs-site/en/context-engine.html +1 -1
  204. package/docs-site/en/index.html +1 -1
  205. package/docs-site/en/mcp-approval.html +1 -1
  206. package/docs-site/en/mcp-auth.html +1 -1
  207. package/docs-site/en/mcp-servers.html +1 -1
  208. package/docs-site/en/mcp.html +1 -1
  209. package/docs-site/en/permissions.html +1 -1
  210. package/docs-site/en/profiles.html +1 -1
  211. package/docs-site/en/quickstart.html +1 -1
  212. package/docs-site/en/runtime.html +2 -2
  213. package/docs-site/en/scope.html +1 -1
  214. package/docs-site/en/security.html +1 -1
  215. package/docs-site/en/team.html +1 -1
  216. package/docs-site/en/whats-new.html +12 -1
  217. package/docs-site/en/workflows.html +1 -1
  218. package/docs-site/index.html +1 -1
  219. package/docs-site/mcp-approval.html +1 -1
  220. package/docs-site/mcp-auth.html +1 -1
  221. package/docs-site/mcp-servers.html +1 -1
  222. package/docs-site/mcp.html +1 -1
  223. package/docs-site/permissions.html +1 -1
  224. package/docs-site/profiles.html +1 -1
  225. package/docs-site/quickstart.html +1 -1
  226. package/docs-site/runtime.html +3 -3
  227. package/docs-site/scope.html +1 -1
  228. package/docs-site/security.html +1 -1
  229. package/docs-site/team.html +1 -1
  230. package/docs-site/whats-new.html +12 -1
  231. package/docs-site/workflows.html +1 -1
  232. package/evals/architecture-conformance-v1/lane.json +18 -0
  233. package/evals/architecture-conformance-v1/runner.mjs +77 -0
  234. package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
  235. package/evals/fixtures/approved-host-contracts.valid.json +43 -0
  236. package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
  237. package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
  238. package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
  239. package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
  240. package/evals/fixtures/composite-criterion.invalid.json +10 -0
  241. package/evals/fixtures/composite-criterion.valid.json +33 -0
  242. package/evals/fixtures/contract-family-library.invalid.json +42 -0
  243. package/evals/fixtures/contract-family-library.valid.json +41 -0
  244. package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
  245. package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
  246. package/evals/fixtures/host-contract-plan.invalid.json +42 -0
  247. package/evals/fixtures/host-contract-plan.valid.json +41 -0
  248. package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
  249. package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
  250. package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
  251. package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
  252. package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
  253. package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
  254. package/evals/fs5-artifact-archive/README.md +32 -0
  255. package/evals/fs5-artifact-archive/manifest.json +148 -0
  256. package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
  257. package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
  258. package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
  259. package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
  260. package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
  261. package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
  262. package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
  263. package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
  264. package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
  265. package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
  266. package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
  267. package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
  268. package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
  269. package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
  270. package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
  271. package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
  272. package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
  273. package/evals/fs5-causal-arm.v1.json +9 -5
  274. package/evals/fs5-pilot-protocol.v1.json +1 -1
  275. package/evals/fs5-pilot-protocol.v4.json +4 -4
  276. package/evals/fs5-pilot-protocol.v5.json +6 -5
  277. package/evals/harness-next/development-corpus.mjs +106 -0
  278. package/evals/harness-next/resource-budget-probe.mjs +38 -0
  279. package/evals/harness-next/run-calibration.mjs +83 -0
  280. package/evals/harness-next/run-resource-probe.mjs +55 -0
  281. package/evals/harness-next/selected-development-corpus.mjs +27 -0
  282. package/evals/harness-next.v1.json +51 -0
  283. package/evals/long-horizon-v1/README.md +19 -0
  284. package/evals/long-horizon-v1/runner.mjs +116 -48
  285. package/evals/long-horizon-v1/worker.mjs +77 -30
  286. package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
  287. package/evals/private-holdout-v1/README.md +5 -2
  288. package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
  289. package/package.json +9 -4
  290. package/packages/piagent-core/README.md +2 -2
  291. package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
  292. package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
  293. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
  294. package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
  295. package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
  296. package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
  297. package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
  298. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
  299. package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
  300. package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
  301. package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
  302. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +2 -1
  303. package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
  304. package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
  305. package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
  306. package/packages/piagent-core/benchmark/benchmark-core.js +107 -107
  307. package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
  308. package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
  309. package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
  310. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
  311. package/packages/piagent-core/benchmark/benchmark-forensics.js +63 -50
  312. package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
  313. package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
  314. package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
  315. package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
  316. package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
  317. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
  318. package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
  319. package/packages/piagent-core/benchmark/benchmark-preflight.js +69 -8
  320. package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
  321. package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
  322. package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
  323. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +162 -45
  324. package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
  325. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
  326. package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
  327. package/packages/piagent-core/benchmark/benchmark-record-validation.js +269 -3
  328. package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
  329. package/packages/piagent-core/benchmark/benchmark-report.js +79 -4
  330. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
  331. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
  332. package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
  333. package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
  334. package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
  335. package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
  336. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +144 -128
  337. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
  338. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
  339. package/packages/piagent-core/benchmark/benchmark-suite.js +211 -4
  340. package/packages/piagent-core/benchmark/benchmark-summary-support.js +30 -2
  341. package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
  342. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
  343. package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
  344. package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
  345. package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
  346. package/packages/piagent-core/benchmark/benchmark-usage.js +395 -33
  347. package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
  348. package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
  349. package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
  350. package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
  351. package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
  352. package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
  353. package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
  354. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +264 -70
  355. package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
  356. package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
  357. package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
  358. package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
  359. package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
  360. package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
  361. package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
  362. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
  363. package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
  364. package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
  365. package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
  366. package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
  367. package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
  368. package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
  369. package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
  370. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
  371. package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
  372. package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
  373. package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
  374. package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
  375. package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
  376. package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
  377. package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
  378. package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
  379. package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
  380. package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
  381. package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
  382. package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
  383. package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
  384. package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
  385. package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
  386. package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
  387. package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
  388. package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
  389. package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
  390. package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
  391. package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
  392. package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
  393. package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
  394. package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
  395. package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
  396. package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
  397. package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
  398. package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
  399. package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
  400. package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
  401. package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
  402. package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
  403. package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
  404. package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
  405. package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
  406. package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
  407. package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
  408. package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
  409. package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
  410. package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
  411. package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
  412. package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
  413. package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
  414. package/packages/piagent-core/extensions/acceptance-receipt.js +139 -152
  415. package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
  416. package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
  417. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
  418. package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
  419. package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
  420. package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
  421. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
  422. package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
  423. package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
  424. package/packages/piagent-core/extensions/context-engine.js +11 -6
  425. package/packages/piagent-core/extensions/criterion-context-pack.js +96 -4
  426. package/packages/piagent-core/extensions/failure-types.ts +2 -2
  427. package/packages/piagent-core/extensions/guard-types.ts +5 -1
  428. package/packages/piagent-core/extensions/piagent-guard.ts +197 -155
  429. package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
  430. package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
  431. package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
  432. package/packages/piagent-core/extensions/task-contract-view.js +4 -4
  433. package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
  434. package/packages/piagent-core/extensions/task-journal.js +48 -3
  435. package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
  436. package/packages/piagent-core/extensions/task-state.js +74 -38
  437. package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
  438. package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
  439. package/packages/piagent-core/extensions/verification-intelligence.js +60 -8
  440. package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
  441. package/packages/piagent-core/extensions/workspace-revision.js +48 -0
  442. package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
  443. package/packages/piagent-core/package.json +3 -3
  444. package/packages/piagent-core/policies/base-policy.json +1 -0
  445. package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
  446. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
  447. package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
  448. package/packages/piagent-core/runtime/hooks/completion-hook.ts +76 -83
  449. package/packages/piagent-core/runtime/hooks/input-hook.ts +92 -7
  450. package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
  451. package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
  452. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +50 -18
  453. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +53 -20
  454. package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
  455. package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
  456. package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
  457. package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
  458. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
  459. package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
  460. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
  461. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +49 -8
  462. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +61 -15
  463. package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
  464. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
  465. package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
  466. package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
  467. package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
  468. package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
  469. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +12 -7
  470. package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
  471. package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
  472. package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
  473. package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
  474. package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
  475. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +11 -2
  476. package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
  477. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +192 -57
  478. package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
  479. package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
  480. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +27 -39
  481. package/packages/piagent-core/runtime/recovery/resume-state.ts +8 -5
  482. package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
  483. package/packages/piagent-core/runtime/registration/context-commands.ts +12 -8
  484. package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
  485. package/packages/piagent-core/runtime/registration/policy-tools.ts +5 -3
  486. package/packages/piagent-core/runtime/registration/session-commands.ts +9 -7
  487. package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
  488. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +27 -11
  489. package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
  490. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +5 -2
  491. package/packages/piagent-core/runtime/registration/task-start-tool.ts +23 -23
  492. package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
  493. package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
  494. package/packages/piagent-core/runtime/session/message-signals.ts +6 -22
  495. package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
  496. package/packages/piagent-core/runtime/session/runtime-state.ts +29 -35
  497. package/packages/piagent-core/runtime/session/system-prompt.ts +3 -3
  498. package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
  499. package/packages/piagent-core/runtime/session/usage.ts +4 -3
  500. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
  501. package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
  502. package/packages/piagent-core/runtime/tools/phase-tools.ts +3 -2
  503. package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
  504. package/packages/piagent-core/runtime/tools/tool-groups.ts +10 -3
  505. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
  506. package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
  507. package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
  508. package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
  509. package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
  510. package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
  511. package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
  512. package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
  513. package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
  514. package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
  515. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +11 -11
  516. package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
  517. package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
  518. package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
  519. package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
  520. package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
  521. package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
  522. package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
  523. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +44 -7
  524. package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
  525. package/packages/piagent-core/runtime/workflows/task-intake.ts +221 -242
  526. package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
  527. package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
  528. package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
  529. package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
  530. package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
  531. package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
  532. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-B4XehTCU.js → MarkdownMessage-DGk34zJT.js} +1 -1
  533. package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
  534. package/packages/piagent-webui/dist/client/assets/index-DiKRmCEP.js +176 -0
  535. package/packages/piagent-webui/dist/client/index.html +2 -2
  536. package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
  537. package/packages/piagent-webui/extension/piagent-webui.ts +10 -2
  538. package/packages/piagent-webui/extension/review-controller.ts +29 -6
  539. package/packages/piagent-webui/extension/same-session-bridge.ts +6 -7
  540. package/packages/piagent-webui/extension/session-stream-adapter.ts +60 -11
  541. package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
  542. package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
  543. package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
  544. package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
  545. package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
  546. package/packages/piagent-webui/gateway/gateway-session-stream.ts +141 -19
  547. package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
  548. package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
  549. package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
  550. package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
  551. package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
  552. package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
  553. package/packages/piagent-webui/gateway/session-inspection-registry.ts +11 -2
  554. package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
  555. package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
  556. package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
  557. package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
  558. package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
  559. package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
  560. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +114 -114
  561. package/packages/piagent-webui/server/core-inspection-provider.ts +73 -14
  562. package/packages/piagent-webui/server/loopback-server.ts +9 -7
  563. package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
  564. package/packages/piagent-webui/server/transcript-projection.ts +65 -12
  565. package/packages/piagent-webui/shared/message-correlation.ts +25 -0
  566. package/schemas/approved-host-contracts.schema.json +973 -0
  567. package/schemas/benchmark-attempt-outcome.schema.json +303 -0
  568. package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
  569. package/schemas/composite-criterion.schema.json +788 -0
  570. package/schemas/contract-family-library.schema.json +28 -0
  571. package/schemas/contract-selection-recipe.schema.json +31 -0
  572. package/schemas/failure-evidence.schema.json +2 -2
  573. package/schemas/helper-request.schema.json +16 -4
  574. package/schemas/host-contract-plan.schema.json +25 -0
  575. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
  576. package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
  577. package/schemas/piagent-webui/runtime-event-v2.schema.json +32 -1
  578. package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
  579. package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
  580. package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
  581. package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
  582. package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
  583. package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
  584. package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
  585. package/schemas/public-contracts/revocation-v1.schema.json +87 -0
  586. package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
  587. package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
  588. package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
  589. package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
  590. package/schemas/task-contract.schema.json +30 -0
  591. package/scripts/approve-independent-verification.mjs +57 -0
  592. package/scripts/benchmark-arm-observer.mjs +320 -0
  593. package/scripts/benchmark-budget-ipc.mjs +34 -0
  594. package/scripts/benchmark-budget-launcher.mjs +91 -0
  595. package/scripts/benchmark-budget-processes.mjs +133 -0
  596. package/scripts/benchmark-budget-publication.mjs +228 -0
  597. package/scripts/benchmark-budget-runtime.mjs +136 -0
  598. package/scripts/benchmark-candidate-ablation.mjs +265 -0
  599. package/scripts/benchmark-codex-journey.mjs +406 -0
  600. package/scripts/benchmark-independent-verification.mjs +628 -0
  601. package/scripts/benchmark-journey-outcome.mjs +92 -0
  602. package/scripts/benchmark-production-v3-human-review.mjs +192 -0
  603. package/scripts/benchmark-public-input-catalog.mjs +158 -0
  604. package/scripts/benchmark-registered-plan-author.mjs +355 -0
  605. package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
  606. package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
  607. package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
  608. package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
  609. package/scripts/benchmark-runner-completion.mjs +133 -0
  610. package/scripts/benchmark-runner-configuration.mjs +159 -0
  611. package/scripts/benchmark-runner-core.mjs +217 -388
  612. package/scripts/benchmark-runner-finalization.mjs +140 -27
  613. package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
  614. package/scripts/benchmark-runner-schedule.mjs +256 -0
  615. package/scripts/benchmark-runner-support.mjs +136 -4
  616. package/scripts/benchmark-runner.mjs +95 -18
  617. package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
  618. package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
  619. package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
  620. package/scripts/benchmark-scoped-pi-router.mjs +196 -0
  621. package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
  622. package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
  623. package/scripts/benchmark-scoped-session-custody.mjs +599 -0
  624. package/scripts/benchmark-scoped-session-factory.mjs +342 -0
  625. package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
  626. package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
  627. package/scripts/benchmark-session-evaluator.mjs +169 -0
  628. package/scripts/benchmark-session-provider-boundary.mjs +62 -0
  629. package/scripts/benchmark-session-usage.mjs +28 -0
  630. package/scripts/benchmark-session.mjs +343 -50
  631. package/scripts/benchmark-webui-journey.mjs +678 -0
  632. package/scripts/check-public-wording.mjs +46 -0
  633. package/scripts/fs4-readiness-evaluation.mjs +7 -1
  634. package/scripts/phase-tools-evaluation.mjs +1 -0
  635. package/scripts/pi-auto.sh +7 -1
  636. package/scripts/pi-usage-history.mjs +201 -11
  637. package/scripts/piagent-cli.mjs +8 -0
  638. package/scripts/private-holdout-readiness.mjs +7 -1
  639. package/scripts/public-evaluation-exposure.mjs +140 -0
  640. package/scripts/select-independent-verification.mjs +62 -0
  641. package/scripts/typescript-loader.mjs +135 -1
  642. package/scripts/update-global.mjs +6 -7
  643. package/scripts/verify-local.sh +36 -55
  644. package/scripts/verify-release-identity.mjs +5 -3
  645. package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +0 -176
@@ -1,3 +1,4 @@
1
+ import crypto from "node:crypto";
1
2
  import fs from "node:fs";
2
3
  import path from "node:path";
3
4
 
@@ -6,10 +7,272 @@ export const BUILT_IN_BENCHMARK_SUITE_IDS = Object.freeze([
6
7
  "capability-v1",
7
8
  "e2-framework-v1",
8
9
  "deep-logic-v1",
9
- "production-v1"
10
+ "production-v1",
11
+ "production-v2",
12
+ "production-v3"
10
13
  ]);
11
14
 
12
15
  const reservedSuiteIds = new Set(BUILT_IN_BENCHMARK_SUITE_IDS);
16
+ const HASH = /^[a-f0-9]{64}$/;
17
+ const ID = /^[A-Za-z0-9][A-Za-z0-9:._~-]{0,159}$/;
18
+ const registrationPayloadFields = Object.freeze([
19
+ "suiteId", "baseSuiteId", "publicContractRevision", "admissionProtocol", "treatment",
20
+ "baseSuiteDigest", "caseListDigest", "unchangedSeedDigest", "evaluatorDigest",
21
+ "publicAssetsDigest", "publicContractDigest", "catalogDigest", "producerManifestDigest",
22
+ "nodeProfileDigest", "sharedEnvironmentDigest", "commonObserverDigest", "restrictedBrokerDigest",
23
+ "protocolDigest", "evaluatorCompatibilityDigest", "baselineCommit", "scenarioIds",
24
+ "promptRolesChanged", "matrix", "resources", "claims"
25
+ ]);
26
+ const registrationDigestFields = Object.freeze(registrationPayloadFields.filter(name => name.endsWith("Digest")));
27
+ export const REGISTERED_BENCHMARK_PROMPT_ROLES = Object.freeze([
28
+ "revoked-session-cache", "backend-frontend-contract-sync", "workspace-order", "expiry-boundary",
29
+ "idempotent-replay-conflict", "reconnect-chat-event-order", "quoted-csv", "invoice-rounding",
30
+ "pagination-boundary", "schema-migration", "incident-diagnosis", "protected-env-refusal",
31
+ "repository-prompt-injection", "destructive-history-refusal"
32
+ ]);
33
+ export const REGISTERED_BENCHMARK_VERIFIER_IDS = Object.freeze([
34
+ "bash-runtime", "broker-source-closure", "candidate-source", "common-runtime-closure",
35
+ "controlled-codex-feature-policy", "controlled-comparison-runtime", "custody-runner-wrapper",
36
+ "docker-runtime", "git-runtime", "node-runtime", "npm-runtime", "pi-runtime", "pi-sdk-tree", "scoped-route-proof",
37
+ "tool-definitions", "webui-asset-tree", "worker-image"
38
+ ]);
39
+ const registeredStaticAssets = Object.freeze([
40
+ "catalog.json", "measurement/node-workload-api-v1.json", "measurement/shared-tool-policy-v1.json",
41
+ "measurement/assurance-rubrics.json", "measurement/calibration/incident-public-v1.json",
42
+ "measurement/calibration/config-document-public-v1.json", "measurement/calibration/refusal-public-v1.json"
43
+ ]);
44
+
45
+ function canonicalJson(value, seen = new Set()) {
46
+ if (value === null || typeof value === "string" || typeof value === "boolean") return JSON.stringify(value);
47
+ if (typeof value === "number") {
48
+ if (!Number.isFinite(value)) throw new TypeError("registered measurement canonical JSON rejects non-finite numbers");
49
+ return JSON.stringify(value);
50
+ }
51
+ if (!value || typeof value !== "object") throw new TypeError("registered measurement canonical JSON rejects non-JSON values");
52
+ if (seen.has(value)) throw new TypeError("registered measurement canonical JSON rejects cycles");
53
+ seen.add(value);
54
+ const rendered = Array.isArray(value)
55
+ ? `[${value.map(item => canonicalJson(item, seen)).join(",")}]`
56
+ : `{${Object.keys(value).sort().map(key => `${JSON.stringify(key)}:${canonicalJson(value[key], seen)}`).join(",")}}`;
57
+ seen.delete(value);
58
+ return rendered;
59
+ }
60
+
61
+ function exactKeys(value, names) {
62
+ return Boolean(value && typeof value === "object" && !Array.isArray(value)
63
+ && Object.keys(value).length === names.length && names.every(name => Object.hasOwn(value, name)));
64
+ }
65
+
66
+ function sortedUniqueIds(values, count) {
67
+ return Array.isArray(values) && values.length === count && new Set(values).size === count
68
+ && values.every(value => typeof value === "string" && ID.test(value));
69
+ }
70
+
71
+ export function registeredBenchmarkMeasurementPayloadDigest(payload) {
72
+ return crypto.createHash("sha256").update(canonicalJson(payload)).digest("hex");
73
+ }
74
+
75
+ export function registeredBenchmarkPublicAssetPaths(scenarioIds) {
76
+ if (!sortedUniqueIds(scenarioIds, 27)) throw new Error("Registered measurement asset inventory requires 27 scenario ids");
77
+ return Object.freeze([
78
+ ...scenarioIds.map(id => `plans/${id}.json`),
79
+ ...REGISTERED_BENCHMARK_PROMPT_ROLES.map(id => `measurement/prompts/${id}.md`),
80
+ ...registeredStaticAssets
81
+ ].sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right))));
82
+ }
83
+
84
+ function stableAsset(root, relativePath) {
85
+ const target = path.resolve(root, relativePath), relative = path.relative(root, target);
86
+ if (relative !== relativePath.split("/").join(path.sep) || relative === ".."
87
+ || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
88
+ throw new Error(`Registered measurement asset path escapes its root: ${relativePath}`);
89
+ }
90
+ const before = fs.lstatSync(target, { bigint: true });
91
+ if (!before.isFile() || before.isSymbolicLink() || before.nlink !== 1n || before.size > 2n * 1024n * 1024n) {
92
+ throw new Error(`Registered measurement asset must be one bounded regular file: ${relativePath}`);
93
+ }
94
+ const fd = fs.openSync(target, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
95
+ try {
96
+ const descriptor = fs.fstatSync(fd, { bigint: true }), bytes = fs.readFileSync(fd), after = fs.fstatSync(fd,
97
+ { bigint: true }), current = fs.lstatSync(target, { bigint: true }),
98
+ fields = ["dev", "ino", "mode", "nlink", "size", "mtimeNs", "ctimeNs"];
99
+ if (bytes.length !== Number(before.size) || fields.some(name => before[name] !== descriptor[name]
100
+ || before[name] !== after[name] || before[name] !== current[name])) {
101
+ throw new Error(`Registered measurement asset changed while read: ${relativePath}`);
102
+ }
103
+ return bytes;
104
+ } finally { fs.closeSync(fd); }
105
+ }
106
+
107
+ function inventoryDigest(entries) {
108
+ return crypto.createHash("sha256").update(canonicalJson(entries)).digest("hex");
109
+ }
110
+
111
+ export function registeredBenchmarkPublicAssetInventory(root, scenarioIds) {
112
+ if (typeof root !== "string" || !path.isAbsolute(root) || fs.realpathSync(root) !== root
113
+ || !fs.lstatSync(root).isDirectory()) throw new Error("Registered measurement asset root must be canonical");
114
+ const expected = registeredBenchmarkPublicAssetPaths(scenarioIds), allowed = new Set([
115
+ ...expected, "measurement/registered-suite.json"
116
+ ]), observed = [], pending = [root];
117
+ while (pending.length > 0) {
118
+ const directory = pending.pop();
119
+ for (const name of fs.readdirSync(directory)) {
120
+ const target = path.join(directory, name), info = fs.lstatSync(target), relative =
121
+ path.relative(root, target).split(path.sep).join("/");
122
+ if (info.isSymbolicLink()) throw new Error(`Registered measurement assets reject symlink: ${relative}`);
123
+ if (info.isDirectory()) pending.push(target);
124
+ else if (info.isFile()) observed.push(relative);
125
+ else throw new Error(`Registered measurement assets reject unsupported node: ${relative}`);
126
+ }
127
+ }
128
+ observed.sort((left, right) => Buffer.compare(Buffer.from(left), Buffer.from(right)));
129
+ if (observed.length !== allowed.size || observed.some(value => !allowed.has(value))) {
130
+ throw new Error("Registered measurement asset root must contain exactly the approved inventory and manifest");
131
+ }
132
+ const entries = expected.map(relativePath => {
133
+ const bytes = stableAsset(root, relativePath);
134
+ return Object.freeze({ path: relativePath, bytes: bytes.length,
135
+ sha256: crypto.createHash("sha256").update(bytes).digest("hex") });
136
+ });
137
+ const semanticPaths = new Set(expected.filter(value => value !== "measurement/node-workload-api-v1.json"
138
+ && value !== "measurement/shared-tool-policy-v1.json"));
139
+ return deepFreeze({ version: "registered-public-asset-inventory-v1", entries,
140
+ publicAssetsDigest: inventoryDigest(entries),
141
+ publicContractDigest: inventoryDigest(entries.filter(value => semanticPaths.has(value.path))) });
142
+ }
143
+
144
+ export function assertRegisteredBenchmarkPublicAssets(registration, root, scenarioIds) {
145
+ const inventory = registeredBenchmarkPublicAssetInventory(root, scenarioIds);
146
+ if (registration?.payload?.publicAssetsDigest !== inventory.publicAssetsDigest
147
+ || registration?.payload?.publicContractDigest !== inventory.publicContractDigest) {
148
+ throw new Error("Registered measurement rejected: public asset inventory digest mismatch");
149
+ }
150
+ return inventory;
151
+ }
152
+
153
+ export function registeredBenchmarkMeasurementValidationErrors(envelope, { scenarioIds } = {}) {
154
+ const errors = [];
155
+ if (!exactKeys(envelope, ["schemaVersion", "payload", "approvalRecordDigest"])) {
156
+ return ["envelope must contain exactly schemaVersion, payload and approvalRecordDigest"];
157
+ }
158
+ if (envelope.schemaVersion !== 1) errors.push("schemaVersion must be 1");
159
+ if (!HASH.test(String(envelope.approvalRecordDigest ?? ""))) errors.push("approvalRecordDigest must be lowercase sha256");
160
+ const payload = envelope.payload;
161
+ if (!exactKeys(payload, registrationPayloadFields)) {
162
+ errors.push("payload fields must match the registered measurement contract exactly");
163
+ return errors;
164
+ }
165
+ const constants = {
166
+ suiteId: "production-v2-da2", baseSuiteId: "production-v2",
167
+ publicContractRevision: "public-contract-addendum-v2",
168
+ admissionProtocol: "configured-public-108-v1", treatment: "configured-independent-v2",
169
+ baselineCommit: "05903656958fc78638779bf0a9e9b403f18992a2"
170
+ };
171
+ for (const [name, expected] of Object.entries(constants)) if (payload[name] !== expected) {
172
+ errors.push(`${name} must equal ${expected}`);
173
+ }
174
+ for (const name of registrationDigestFields) if (!HASH.test(String(payload[name] ?? ""))) {
175
+ errors.push(`${name} must be lowercase sha256`);
176
+ }
177
+ if (!sortedUniqueIds(payload.scenarioIds, 27)) errors.push("scenarioIds must contain 27 unique registered ids");
178
+ if (Array.isArray(scenarioIds) && JSON.stringify(payload.scenarioIds) !== JSON.stringify(scenarioIds)) {
179
+ errors.push("scenarioIds must equal the frozen base suite order");
180
+ }
181
+ if (JSON.stringify(payload.promptRolesChanged) !== JSON.stringify(REGISTERED_BENCHMARK_PROMPT_ROLES)) {
182
+ errors.push("promptRolesChanged must equal the approved 14-role order");
183
+ }
184
+ if (!exactKeys(payload.matrix, ["scenarioCount", "repeats", "surfaces", "sessionCount"])
185
+ || payload.matrix.scenarioCount !== 27 || payload.matrix.repeats !== 2
186
+ || JSON.stringify(payload.matrix.surfaces) !== JSON.stringify(["piagent", "codex-cli"])
187
+ || payload.matrix.sessionCount !== 108) errors.push("matrix must equal the controlled complete108 matrix");
188
+ if (!exactKeys(payload.resources, ["model", "thinking", "requestedServiceTier", "concurrency",
189
+ "timeoutSeconds", "infrastructureRetries", "verifiers"])
190
+ || payload.resources.model !== "openai-codex/gpt-5.6-luna" || payload.resources.thinking !== "medium"
191
+ || payload.resources.requestedServiceTier !== "fast" || payload.resources.concurrency !== 1
192
+ || payload.resources.timeoutSeconds !== 900 || payload.resources.infrastructureRetries !== 0
193
+ || !Array.isArray(payload.resources.verifiers) || payload.resources.verifiers.length === 0
194
+ || payload.resources.verifiers.length > 32) errors.push("resources must equal the approved provider limits and explicit verifiers");
195
+ else {
196
+ const ids = payload.resources.verifiers.map(value => value?.id);
197
+ if (JSON.stringify(ids) !== JSON.stringify(REGISTERED_BENCHMARK_VERIFIER_IDS)
198
+ || payload.resources.verifiers.some(value => !exactKeys(value, ["id", "sha256"])
199
+ || typeof value.id !== "string" || !ID.test(value.id) || !HASH.test(String(value.sha256 ?? "")))) {
200
+ errors.push("verifiers must equal the exact registered runtime and custody identity set");
201
+ }
202
+ }
203
+ if (!exactKeys(payload.claims, ["efficiencyProtocol", "wireProtocol", "configuredTreatment",
204
+ "releaseDefaultsClaim"]) || payload.claims.efficiencyProtocol !== "net35-family-pooled-v1"
205
+ || payload.claims.wireProtocol !== "phase-valid-configuration-v1"
206
+ || payload.claims.configuredTreatment !== true || payload.claims.releaseDefaultsClaim !== false) {
207
+ errors.push("claims must equal the approved configured-treatment boundary");
208
+ }
209
+ return errors;
210
+ }
211
+
212
+ function stableJson(file, label) {
213
+ if (typeof file !== "string" || !path.isAbsolute(file) || path.normalize(file) !== file || file.includes("\0")) {
214
+ throw new Error(`${label} path must be canonical and absolute`);
215
+ }
216
+ const resolved = fs.realpathSync(file), before = fs.lstatSync(resolved, { bigint: true });
217
+ if (resolved !== file || !before.isFile() || before.isSymbolicLink() || before.nlink !== 1n
218
+ || before.size < 2n || before.size > 2n * 1024n * 1024n
219
+ || typeof process.getuid === "function" && before.uid !== BigInt(process.getuid())) {
220
+ throw new Error(`${label} must be one host-owned regular unlinked file`);
221
+ }
222
+ const fd = fs.openSync(file, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
223
+ try {
224
+ const descriptor = fs.fstatSync(fd, { bigint: true }), bytes = fs.readFileSync(fd),
225
+ after = fs.fstatSync(fd, { bigint: true }), current = fs.lstatSync(file, { bigint: true }),
226
+ fields = ["dev", "ino", "mode", "nlink", "size", "mtimeNs", "ctimeNs"];
227
+ if (bytes.length !== Number(before.size) || fields.some(name => before[name] !== descriptor[name]
228
+ || before[name] !== after[name] || before[name] !== current[name])) throw new Error(`${label} changed while read`);
229
+ let value;
230
+ try { value = JSON.parse(bytes.toString("utf8")); }
231
+ catch (error) { throw new Error(`${label} is not valid JSON: ${error.message}`); }
232
+ return { bytes, value };
233
+ } finally { fs.closeSync(fd); }
234
+ }
235
+
236
+ function deepFreeze(value) {
237
+ if (!value || typeof value !== "object" || Object.isFrozen(value)) return value;
238
+ for (const child of Object.values(value)) deepFreeze(child);
239
+ return Object.freeze(value);
240
+ }
241
+
242
+ export function loadRegisteredBenchmarkMeasurement(file, { approvalFile, approvalPublicKey, scenarioIds } = {}) {
243
+ const manifest = stableJson(file, "registered measurement manifest"), errors =
244
+ registeredBenchmarkMeasurementValidationErrors(manifest.value, { scenarioIds });
245
+ if (errors.length > 0) throw new Error(`Registered measurement rejected: ${errors.join("; ")}`);
246
+ const approval = stableJson(approvalFile, "registered measurement approval"), approvalDigest =
247
+ crypto.createHash("sha256").update(approval.bytes).digest("hex");
248
+ if (approvalDigest !== manifest.value.approvalRecordDigest) {
249
+ throw new Error("Registered measurement rejected: detached approval digest mismatch");
250
+ }
251
+ if (!exactKeys(approval.value, ["schemaVersion", "kind", "approvalId", "authorityKeyId",
252
+ "payloadDigest", "signature"]) || approval.value.schemaVersion !== 1
253
+ || approval.value.kind !== "benchmark-measurement-approval-v1" || !ID.test(String(approval.value.approvalId ?? ""))
254
+ || !HASH.test(String(approval.value.authorityKeyId ?? "")) || !HASH.test(String(approval.value.payloadDigest ?? ""))
255
+ || typeof approval.value.signature !== "string") {
256
+ throw new Error("Registered measurement rejected: detached approval record is invalid");
257
+ }
258
+ let key;
259
+ try { key = approvalPublicKey?.type === "public" ? approvalPublicKey : crypto.createPublicKey(approvalPublicKey); }
260
+ catch { throw new Error("Registered measurement rejected: trusted approval public key is invalid"); }
261
+ if (key?.asymmetricKeyType !== "ed25519") throw new Error("Registered measurement rejected: trusted approval key must be Ed25519");
262
+ const der = key.export({ type: "spki", format: "der" }), keyId = crypto.createHash("sha256").update(der).digest("hex"),
263
+ payloadDigest = registeredBenchmarkMeasurementPayloadDigest(manifest.value.payload);
264
+ let signature;
265
+ try { signature = Buffer.from(approval.value.signature, "base64"); }
266
+ catch { signature = Buffer.alloc(0); }
267
+ if (approval.value.authorityKeyId !== keyId || approval.value.payloadDigest !== payloadDigest
268
+ || signature.length !== 64 || !crypto.verify(null, Buffer.from(payloadDigest), key, signature)) {
269
+ throw new Error("Registered measurement rejected: detached approval signature or payload binding is invalid");
270
+ }
271
+ return deepFreeze({ envelope: manifest.value, payload: manifest.value.payload, identity: {
272
+ manifestSha256: crypto.createHash("sha256").update(manifest.bytes).digest("hex"), payloadSha256: payloadDigest,
273
+ approvalRecordSha256: approvalDigest, approvalId: approval.value.approvalId, authorityKeyId: keyId
274
+ }, files: { manifest: file, approval: approvalFile } });
275
+ }
13
276
 
14
277
  export function isReservedBenchmarkSuiteId(value) {
15
278
  return reservedSuiteIds.has(value);
@@ -74,9 +74,13 @@ export function validateBenchmarkSuiteFiles(suite, suiteRoot) {
74
74
  const generator = scenario.variantGenerator
75
75
  ? resolveBenchmarkSuiteEntry(suiteRoot, scenario.variantGenerator, "variant generator")
76
76
  : null;
77
+ const journeyPrompts = (scenario.userJourney?.turns ?? []).map((turn) => (
78
+ resolveBenchmarkSuiteEntry(suiteRoot, turn.prompt, `journey prompt for ${scenario.id}/${turn.id}`)
79
+ ));
77
80
  assertBenchmarkModuleGraphBound(grader, suiteRoot, `${scenario.id} grader`);
78
81
  if (generator) assertBenchmarkModuleGraphBound(generator, suiteRoot, `${scenario.id} variant generator`);
79
82
  if (inside(fixture, grader) || inside(fixture, prompt)) fail(`Suite prompt and grader must stay outside the agent fixture: ${scenario.id}`);
83
+ if (journeyPrompts.some((journeyPrompt) => inside(fixture, journeyPrompt))) fail(`Suite journey prompts must stay outside the agent fixture: ${scenario.id}`);
80
84
  if (generator && inside(fixture, generator)) fail(`Suite variant generator must stay outside the agent fixture: ${scenario.id}`);
81
85
  }
82
86
  }
@@ -3,13 +3,21 @@ import { benchmarkPricingSnapshotValidationErrors } from "./benchmark-normalized
3
3
 
4
4
  const SUITE_FIELDS = new Set([
5
5
  "schemaVersion", "id", "title", "description", "profile", "defaultRepeats", "timeoutSeconds",
6
- "assurance", "releaseGate", "executionContract", "pricingSnapshot", "scenarios"
6
+ "assurance", "releaseGate", "executionContract", "pricingSnapshot", "matrixContract", "scenarios"
7
7
  ]);
8
8
  const SCENARIO_FIELDS = new Set([
9
9
  "id", "title", "description", "kind", "fixture", "prompt", "grader", "allowedChanges",
10
10
  "setupFiles", "forbiddenOutputSubstrings", "requiredOutputSubstrings", "category", "difficulty",
11
- "profile", "lifecycle", "variantGenerator"
11
+ "profile", "lifecycle", "variantGenerator", "familyId", "variantId", "variantRole", "userJourney"
12
12
  ]);
13
+ const MATRIX_CONTRACT_FIELDS = new Set([
14
+ "schemaVersion", "familyCount", "variantsPerFamily", "variantRoles", "surfaces",
15
+ "repeatsPerVariant", "expectedPairs", "expectedSessions", "confidenceSampleUnit"
16
+ ]);
17
+ const USER_JOURNEY_FIELDS = new Set(["turns", "expectedTerminalSettlement"]);
18
+ const USER_JOURNEY_TURN_FIELDS = new Set(["id", "prompt", "workflow", "reconnectBefore", "receiptUncertain"]);
19
+ const MATRIX_VARIANT_ROLES = new Set(["boundary", "interaction", "adversarial-recovery"]);
20
+ const TERMINAL_SETTLEMENTS = new Set(["completed", "refused"]);
13
21
  const RELEASE_GATE_FIELDS = new Set([
14
22
  "minimumQualityScore", "minimumSafetyScore", "minimumReliabilityScore", "minimumWorkflowScore",
15
23
  "minimumCategoryScore", "minimumOutcomeScoreExclusive", "minimumPairedScenarios", "minimumRepeats",
@@ -20,9 +28,11 @@ const RELEASE_GATE_FIELDS = new Set([
20
28
  "maximumInfrastructureRetries", "primaryEfficiencyEstimand", "requireEfficiencyClaim", "requireFullSuiteForClaim",
21
29
  "requireStableProviderWireSurface", "requireNormalizedCostClaim", "requireHostReadinessForClaim",
22
30
  "requireCausalContextReceipt", "requireSubagentBudget", "maximumSubagentSessionsPerAttempt",
23
- "maximumSubagentTrafficShare", "requireProviderFreeEvidence"
31
+ "maximumSubagentTrafficShare", "requireProviderFreeEvidence", "requireFastServiceTier",
32
+ "maximumAllAttemptPooledFreshTokenRatio", "requireCampaignAccounting", "efficiencyProtocol"
24
33
  ]);
25
- const EXECUTION_CONTRACT_FIELDS = new Set(["surfaces", "model", "thinking", "codexMode"]);
34
+ const EXECUTION_CONTRACT_FIELDS = new Set(["surfaces", "model", "thinking", "codexMode", "codexBaseline", "serviceTier"]);
35
+ const SERVICE_TIERS = new Set(["default", "fast"]);
26
36
  const THINKING_LEVELS = new Set(["off", "minimal", "low", "medium", "high", "xhigh", "max"]);
27
37
  const SCENARIO_KINDS = new Set(["source-change", "read-only", "safety-refusal"]);
28
38
  const SCENARIO_DIFFICULTIES = new Set(["small", "medium", "large"]);
@@ -76,6 +86,27 @@ export function benchmarkSuiteValidationErrors(input) {
76
86
  for (const field of Object.keys(input.releaseGate)) {
77
87
  if (!RELEASE_GATE_FIELDS.has(field)) errors.push(`releaseGate has unsupported field ${field}`);
78
88
  }
89
+ // Opt-in measurement contract only. Approval belongs to the frozen run
90
+ // protocol; this marker neither changes legacy defaults nor grants claims.
91
+ if (input.releaseGate.efficiencyProtocol !== undefined) {
92
+ if (input.releaseGate.efficiencyProtocol !== "net35-family-pooled-v1") {
93
+ errors.push("releaseGate.efficiencyProtocol must be net35-family-pooled-v1");
94
+ }
95
+ if (input.schemaVersion !== 2) errors.push("releaseGate.efficiencyProtocol requires schemaVersion 2");
96
+ if (input.releaseGate.requireEfficiencyClaim !== true) {
97
+ errors.push("net35-family-pooled-v1 requires releaseGate.requireEfficiencyClaim true");
98
+ }
99
+ for (const field of ["maximumFreshTokenRatioUpper95", "maximumAllAttemptPooledFreshTokenRatio"]) {
100
+ if (input.releaseGate[field] !== 0.65) errors.push(`net35-family-pooled-v1 requires releaseGate.${field} exactly 0.65`);
101
+ }
102
+ if (input.releaseGate.primaryEfficiencyEstimand !== "fixed-workload-family-ratio") {
103
+ errors.push("net35-family-pooled-v1 requires releaseGate.primaryEfficiencyEstimand fixed-workload-family-ratio");
104
+ }
105
+ if (input.matrixContract?.familyCount !== 9 || input.matrixContract?.variantsPerFamily !== 3
106
+ || input.matrixContract?.repeatsPerVariant !== 2 || input.matrixContract?.confidenceSampleUnit !== "task-family") {
107
+ errors.push("net35-family-pooled-v1 requires the 9-family, 3-variant, 2-repeat task-family matrixContract");
108
+ }
109
+ }
79
110
  for (const field of [
80
111
  "minimumQualityScore", "minimumSafetyScore", "minimumReliabilityScore", "minimumWorkflowScore",
81
112
  "minimumCategoryScore"
@@ -109,6 +140,13 @@ export function benchmarkSuiteValidationErrors(input) {
109
140
  if (maximumRatio !== undefined && (!Number.isFinite(maximumRatio) || maximumRatio <= 0 || maximumRatio > 10)) {
110
141
  errors.push("releaseGate.maximumFreshTokenRatioUpper95 must be greater than 0 and at most 10");
111
142
  }
143
+ const maximumAllAttemptPooledFreshTokenRatio = input.releaseGate.maximumAllAttemptPooledFreshTokenRatio;
144
+ if (maximumAllAttemptPooledFreshTokenRatio !== undefined
145
+ && (!Number.isFinite(maximumAllAttemptPooledFreshTokenRatio)
146
+ || maximumAllAttemptPooledFreshTokenRatio <= 0
147
+ || maximumAllAttemptPooledFreshTokenRatio > 10)) {
148
+ errors.push("releaseGate.maximumAllAttemptPooledFreshTokenRatio must be greater than 0 and at most 10");
149
+ }
112
150
  const maximumBandRatio = input.releaseGate.maximumBandFreshTokenRatio;
113
151
  if (maximumBandRatio !== undefined && (!Number.isFinite(maximumBandRatio) || maximumBandRatio <= 0 || maximumBandRatio > 10)) {
114
152
  errors.push("releaseGate.maximumBandFreshTokenRatio must be greater than 0 and at most 10");
@@ -170,6 +208,12 @@ export function benchmarkSuiteValidationErrors(input) {
170
208
  if (input.releaseGate.requireProviderFreeEvidence !== undefined && typeof input.releaseGate.requireProviderFreeEvidence !== "boolean") {
171
209
  errors.push("releaseGate.requireProviderFreeEvidence must be a boolean");
172
210
  }
211
+ if (input.releaseGate.requireFastServiceTier !== undefined && typeof input.releaseGate.requireFastServiceTier !== "boolean") {
212
+ errors.push("releaseGate.requireFastServiceTier must be a boolean");
213
+ }
214
+ if (input.releaseGate.requireCampaignAccounting !== undefined && typeof input.releaseGate.requireCampaignAccounting !== "boolean") {
215
+ errors.push("releaseGate.requireCampaignAccounting must be a boolean");
216
+ }
173
217
  const maximumSubagentSessions = input.releaseGate.maximumSubagentSessionsPerAttempt;
174
218
  if (maximumSubagentSessions !== undefined
175
219
  && (!Number.isSafeInteger(maximumSubagentSessions) || maximumSubagentSessions < 0 || maximumSubagentSessions > 10)) {
@@ -211,6 +255,50 @@ export function benchmarkSuiteValidationErrors(input) {
211
255
  }
212
256
  if (!THINKING_LEVELS.has(contract.thinking)) errors.push("executionContract.thinking is invalid");
213
257
  if (contract.codexMode !== "controlled") errors.push("executionContract.codexMode must be controlled");
258
+ if (contract.codexBaseline !== undefined && !["stock", "controlled-custom"].includes(contract.codexBaseline)) {
259
+ errors.push("executionContract.codexBaseline must be stock or controlled-custom");
260
+ }
261
+ if (contract.serviceTier !== undefined && !SERVICE_TIERS.has(contract.serviceTier)) {
262
+ errors.push("executionContract.serviceTier must be default or fast");
263
+ }
264
+ if (input.releaseGate?.requireFastServiceTier === true && contract.serviceTier !== "fast") {
265
+ errors.push("executionContract.serviceTier must be fast when releaseGate.requireFastServiceTier is true");
266
+ }
267
+ }
268
+ }
269
+ if (input.matrixContract !== undefined) {
270
+ const matrix = input.matrixContract;
271
+ if (input.schemaVersion !== 2) errors.push("matrixContract requires suite schemaVersion 2");
272
+ if (!plainObject(matrix)) errors.push("matrixContract must be an object");
273
+ else {
274
+ for (const field of Object.keys(matrix)) {
275
+ if (!MATRIX_CONTRACT_FIELDS.has(field)) errors.push(`matrixContract has unsupported field ${field}`);
276
+ }
277
+ if (matrix.schemaVersion !== 1) errors.push("matrixContract.schemaVersion must be 1");
278
+ for (const [field, maximum] of [["familyCount", 50], ["variantsPerFamily", 10], ["repeatsPerVariant", 10], ["expectedPairs", 500], ["expectedSessions", 1_000]]) {
279
+ if (!Number.isSafeInteger(matrix[field]) || matrix[field] < 1 || matrix[field] > maximum) {
280
+ errors.push(`matrixContract.${field} must be between 1 and ${maximum}`);
281
+ }
282
+ }
283
+ if (!Array.isArray(matrix.variantRoles)
284
+ || matrix.variantRoles.length !== matrix.variantsPerFamily
285
+ || new Set(matrix.variantRoles).size !== matrix.variantRoles.length
286
+ || matrix.variantRoles.some((role) => !MATRIX_VARIANT_ROLES.has(role))) {
287
+ errors.push("matrixContract.variantRoles must contain one supported unique role per variant");
288
+ }
289
+ if (!Array.isArray(matrix.surfaces)
290
+ || !plainObject(input.executionContract)
291
+ || JSON.stringify(matrix.surfaces) !== JSON.stringify(input.executionContract.surfaces)) {
292
+ errors.push("matrixContract.surfaces must match executionContract.surfaces");
293
+ }
294
+ if (matrix.repeatsPerVariant !== input.defaultRepeats) {
295
+ errors.push("matrixContract.repeatsPerVariant must match defaultRepeats");
296
+ }
297
+ const expectedPairs = matrix.familyCount * matrix.variantsPerFamily * matrix.repeatsPerVariant;
298
+ const expectedSessions = expectedPairs * (Array.isArray(matrix.surfaces) ? matrix.surfaces.length : 0);
299
+ if (matrix.expectedPairs !== expectedPairs) errors.push("matrixContract.expectedPairs does not match the declared matrix");
300
+ if (matrix.expectedSessions !== expectedSessions) errors.push("matrixContract.expectedSessions does not match the declared matrix");
301
+ if (matrix.confidenceSampleUnit !== "task-family") errors.push("matrixContract.confidenceSampleUnit must be task-family");
214
302
  }
215
303
  }
216
304
  if (input.schemaVersion === 2 && (!plainObject(input.assurance) || !plainObject(input.releaseGate))) {
@@ -223,6 +311,36 @@ export function benchmarkSuiteValidationErrors(input) {
223
311
  && (!Number.isFinite(input.releaseGate?.maximumFreshTokenRatioUpper95) || input.releaseGate.maximumFreshTokenRatioUpper95 > 0.8)) {
224
312
  errors.push("schemaVersion 2 token-saving claims require releaseGate.maximumFreshTokenRatioUpper95 at or below 0.8");
225
313
  }
314
+ if (input.schemaVersion === 2 && input.releaseGate?.requireEfficiencyClaim === true
315
+ && input.releaseGate?.maximumAllAttemptPooledFreshTokenRatio !== undefined
316
+ && input.releaseGate.maximumAllAttemptPooledFreshTokenRatio > 0.65) {
317
+ errors.push("schemaVersion 2 net-35 claims require releaseGate.maximumAllAttemptPooledFreshTokenRatio at or below 0.65");
318
+ }
319
+ if (input.id === "production-v2") {
320
+ if (input.executionContract?.serviceTier !== "fast") errors.push("production-v2 requires executionContract.serviceTier fast");
321
+ if (input.releaseGate?.requireFastServiceTier !== true) errors.push("production-v2 requires releaseGate.requireFastServiceTier true");
322
+ if (input.releaseGate?.requireCampaignAccounting !== true) errors.push("production-v2 requires releaseGate.requireCampaignAccounting true");
323
+ if (!Number.isFinite(input.releaseGate?.maximumAllAttemptPooledFreshTokenRatio)
324
+ || input.releaseGate.maximumAllAttemptPooledFreshTokenRatio > 0.65) {
325
+ errors.push("production-v2 requires an all-attempt pooled fresh-token ratio at or below 0.65");
326
+ }
327
+ }
328
+ if (input.id === "production-v3") {
329
+ if (input.executionContract?.codexMode !== "controlled") {
330
+ errors.push("production-v3 requires executionContract.codexMode controlled");
331
+ }
332
+ if (input.executionContract?.codexBaseline !== "stock") {
333
+ errors.push("production-v3 requires executionContract.codexBaseline stock");
334
+ }
335
+ if (input.assurance?.claimTier !== "public-regression"
336
+ || input.assurance?.familyDisjointSplit !== false) {
337
+ errors.push("production-v3 requires the public-regression non-family-disjoint claim boundary");
338
+ }
339
+ if (input.matrixContract?.familyCount !== 9 || input.matrixContract?.variantsPerFamily !== 3
340
+ || input.matrixContract?.repeatsPerVariant !== 2 || input.matrixContract?.expectedSessions !== 108) {
341
+ errors.push("production-v3 requires the exact 9-family, 3-variant, 2-repeat, 2-surface matrix");
342
+ }
343
+ }
226
344
  if (input.schemaVersion === 2 && input.releaseGate?.requireEfficiencyClaim === true && input.releaseGate?.requireFullSuiteForClaim !== true) {
227
345
  errors.push("schemaVersion 2 token-saving claims require releaseGate.requireFullSuiteForClaim true");
228
346
  }
@@ -254,6 +372,7 @@ export function benchmarkSuiteValidationErrors(input) {
254
372
  }
255
373
 
256
374
  const ids = new Set();
375
+ const matrixFamilies = new Map();
257
376
  for (const [index, scenario] of input.scenarios.entries()) {
258
377
  const label = `scenarios[${index}]`;
259
378
  if (!plainObject(scenario)) {
@@ -310,6 +429,94 @@ export function benchmarkSuiteValidationErrors(input) {
310
429
  !Array.isArray(scenario.requiredOutputSubstrings)
311
430
  || scenario.requiredOutputSubstrings.some((item) => typeof item !== "string" || !item)
312
431
  )) errors.push(`${label}.requiredOutputSubstrings must contain non-empty strings`);
432
+ if (input.matrixContract === undefined
433
+ && [scenario.familyId, scenario.variantId, scenario.variantRole, scenario.userJourney].some((value) => value !== undefined)) {
434
+ errors.push(`${label} matrix metadata requires matrixContract`);
435
+ }
436
+ if (plainObject(input.matrixContract)) {
437
+ requiredString(scenario.familyId, `${label}.familyId`, errors);
438
+ if (typeof scenario.familyId === "string" && !ID_PATTERN.test(scenario.familyId)) errors.push(`${label}.familyId must use lowercase kebab-case`);
439
+ requiredString(scenario.variantId, `${label}.variantId`, errors);
440
+ if (typeof scenario.variantId === "string" && !ID_PATTERN.test(scenario.variantId)) errors.push(`${label}.variantId must use lowercase kebab-case`);
441
+ if (!MATRIX_VARIANT_ROLES.has(scenario.variantRole)
442
+ || !Array.isArray(input.matrixContract.variantRoles)
443
+ || !input.matrixContract.variantRoles.includes(scenario.variantRole)) errors.push(`${label}.variantRole is invalid`);
444
+ if (!plainObject(scenario.userJourney)) errors.push(`${label}.userJourney must be an object`);
445
+ else {
446
+ for (const field of Object.keys(scenario.userJourney)) {
447
+ if (!USER_JOURNEY_FIELDS.has(field)) errors.push(`${label}.userJourney has unsupported field ${field}`);
448
+ }
449
+ const turns = scenario.userJourney.turns;
450
+ if (!Array.isArray(turns) || turns.length < 1 || turns.length > 10) errors.push(`${label}.userJourney.turns must contain between 1 and 10 turns`);
451
+ else {
452
+ const turnIds = new Set();
453
+ for (const [turnIndex, turn] of turns.entries()) {
454
+ const turnLabel = `${label}.userJourney.turns[${turnIndex}]`;
455
+ if (!plainObject(turn)) {
456
+ errors.push(`${turnLabel} must be an object`);
457
+ continue;
458
+ }
459
+ for (const field of Object.keys(turn)) {
460
+ if (!USER_JOURNEY_TURN_FIELDS.has(field)) errors.push(`${turnLabel} has unsupported field ${field}`);
461
+ }
462
+ requiredString(turn.id, `${turnLabel}.id`, errors);
463
+ if (typeof turn.id === "string" && !ID_PATTERN.test(turn.id)) errors.push(`${turnLabel}.id must use lowercase kebab-case`);
464
+ if (turnIds.has(turn.id)) errors.push(`${label}.userJourney has duplicate turn id ${turn.id}`);
465
+ turnIds.add(turn.id);
466
+ if (!safeRelativePath(turn.prompt)) errors.push(`${turnLabel}.prompt must stay inside the suite directory`);
467
+ if (turn.workflow !== undefined
468
+ && (typeof turn.workflow !== "string" || !ID_PATTERN.test(turn.workflow) || turn.workflow.length > 64)) {
469
+ errors.push(`${turnLabel}.workflow must be a bounded lowercase kebab-case id`);
470
+ }
471
+ if (turn.reconnectBefore !== undefined && typeof turn.reconnectBefore !== "boolean") errors.push(`${turnLabel}.reconnectBefore must be a boolean`);
472
+ if (turn.receiptUncertain !== undefined && typeof turn.receiptUncertain !== "boolean") {
473
+ errors.push(`${turnLabel}.receiptUncertain must be a boolean`);
474
+ }
475
+ if (turn.receiptUncertain === true && (turnIndex === 0 || turn.reconnectBefore !== true)) {
476
+ errors.push(`${turnLabel}.receiptUncertain requires an existing-session turn with reconnectBefore`);
477
+ }
478
+ }
479
+ if (scenario.variantRole === "boundary" && (turns.length !== 1 || turns[0]?.id !== "request")) {
480
+ errors.push(`${label}.boundary journey must contain one request turn`);
481
+ }
482
+ if (scenario.variantRole === "interaction"
483
+ && JSON.stringify(turns.map((turn) => turn?.id)) !== JSON.stringify(["scout", "implement", "verify"])) {
484
+ errors.push(`${label}.interaction journey must contain scout, implement, verify turns`);
485
+ }
486
+ if (scenario.variantRole === "adversarial-recovery"
487
+ && (turns.length < 2 || !turns.slice(1).some((turn) => turn?.reconnectBefore === true))) {
488
+ errors.push(`${label}.adversarial-recovery journey must exercise reconnect recovery`);
489
+ }
490
+ }
491
+ if (!TERMINAL_SETTLEMENTS.has(scenario.userJourney.expectedTerminalSettlement)) {
492
+ errors.push(`${label}.userJourney.expectedTerminalSettlement is invalid`);
493
+ } else if (scenario.kind === "safety-refusal" && scenario.userJourney.expectedTerminalSettlement !== "refused") {
494
+ errors.push(`${label}.safety-refusal journey must settle as refused`);
495
+ } else if (scenario.kind !== "safety-refusal" && scenario.userJourney.expectedTerminalSettlement !== "completed") {
496
+ errors.push(`${label}.non-refusal journey must settle as completed`);
497
+ }
498
+ }
499
+ if (typeof scenario.familyId === "string" && typeof scenario.variantId === "string") {
500
+ const family = matrixFamilies.get(scenario.familyId) ?? { variants: new Set(), roles: new Set() };
501
+ if (family.variants.has(scenario.variantId)) errors.push(`duplicate matrix variant ${scenario.familyId}/${scenario.variantId}`);
502
+ family.variants.add(scenario.variantId);
503
+ if (typeof scenario.variantRole === "string") family.roles.add(scenario.variantRole);
504
+ matrixFamilies.set(scenario.familyId, family);
505
+ }
506
+ }
507
+ }
508
+ if (plainObject(input.matrixContract)) {
509
+ if (matrixFamilies.size !== input.matrixContract.familyCount) errors.push("matrixContract.familyCount does not match scenarios");
510
+ for (const [familyId, family] of matrixFamilies) {
511
+ if (family.variants.size !== input.matrixContract.variantsPerFamily) errors.push(`matrix family ${familyId} must contain ${input.matrixContract.variantsPerFamily} variants`);
512
+ const expectedRoles = new Set(Array.isArray(input.matrixContract.variantRoles) ? input.matrixContract.variantRoles : []);
513
+ if (family.roles.size !== expectedRoles.size || [...expectedRoles].some((role) => !family.roles.has(role))) {
514
+ errors.push(`matrix family ${familyId} must contain every declared variant role`);
515
+ }
516
+ }
517
+ if (input.scenarios.length !== input.matrixContract.familyCount * input.matrixContract.variantsPerFamily) {
518
+ errors.push("matrixContract scenario cardinality does not match scenarios");
519
+ }
313
520
  }
314
521
  return errors;
315
522
  }
@@ -32,7 +32,7 @@ export const RELEASE_FAILURE_MESSAGES = Object.freeze({
32
32
  "primary-efficiency": "The predeclared primary efficiency estimand lacks complete family/category evidence or its upper 95% ratio exceeds the suite limit.",
33
33
  "codex-relative-efficiency": "The fixed-workload Piagent/Codex CLI comparison lacks exact parity or quality evidence, exceeds 0.70 total token traffic or API-equivalent cost at the point/upper-95 bound, or exceeds the subagent budget.",
34
34
  "production-subagent-budget": "Production Piagent attempts lack exact child-session accounting, exceed one subagent per attempt, or spend more than 5% of candidate provider traffic on subagents.",
35
- "provider-free-evidence": "The production run lacks same-source clean-commit runtime-conformance, long-horizon, or WebUI-parity evidence bound to exact lane configuration and runner bytes.",
35
+ "provider-free-evidence": "The production run lacks same-source clean-commit architecture, runtime-conformance, long-horizon, or WebUI-parity evidence bound to exact lane configuration and runner bytes.",
36
36
  "adaptive-context-runtime-coverage": "At least one Piagent runtime receipt reports partial adaptive-context evidence, or not-observed evidence lacks a same-source provider-free coverage lane.",
37
37
  "repeat-count": "The run used fewer repeats than the suite minimum.",
38
38
  "efficiency-confidence": "The upper 95% token-ratio bound exceeds the suite limit.",
@@ -40,6 +40,8 @@ export const RELEASE_FAILURE_MESSAGES = Object.freeze({
40
40
  "efficiency-family-ratio": "At least one comparable scenario family uses more fresh tokens than the suite family guardrail permits.",
41
41
  "accepted-usage-completeness": "Every accepted benchmark attempt must have exact terminal token buckets.",
42
42
  "all-attempt-usage-completeness": "Every accepted or failed provider attempt must have exact invariant-checked token buckets.",
43
+ "all-attempt-net-efficiency": "All accepted plus exact failed/retry fresh tokens must remain at or below the predeclared pooled Piagent/Codex CLI ratio.",
44
+ "fast-execution-configuration-parity": "Fast execution configuration must be verified on every run: exact Piagent outbound telemetry plus identity-bound effective Codex CLI thread settings; missing or default evidence blocks the claim.",
43
45
  "normalized-cost-configuration": "Normalized-cost claims require a valid versioned pricing snapshot and all predeclared ratio thresholds.",
44
46
  "normalized-cost-evidence": "Normalized API-equivalent text-token cost evidence is incomplete for at least one declared scenario family.",
45
47
  "normalized-cost-pricing-applicability": "Exact usage or per-request pricing applicability is unavailable for at least one accepted run.",
@@ -54,7 +56,7 @@ export const RELEASE_FAILURE_MESSAGES = Object.freeze({
54
56
  "infrastructure-retries": "Accepted benchmark runs used more recovered infrastructure retries than the suite permits.",
55
57
  "infrastructure-failure-ledger": "Accepted benchmark runs do not contain an exact attempt/retry/failure ledger.",
56
58
  "unknown-infrastructure-usage": "At least one provider-started infrastructure attempt has unknown terminal usage.",
57
- "canonical-production-identity": "The production-v1 suite id is reserved for the canonical built-in suite identity.",
59
+ "canonical-production-identity": "Production suite ids are reserved for their canonical built-in suite identities.",
58
60
  "release-claim-configuration": "Token-saving claims require schema v2, an explicit upper-95 token ratio at or below 0.80, full-suite enforcement, and provider-wire stability evidence.",
59
61
  "codex-baseline": "Token-saving product claims require controlled Codex CLI as the paired baseline.",
60
62
  "clean-release-source": "Release claims require an exact clean Git commit; dirty or unbound source trees are diagnostic only.",
@@ -378,3 +380,29 @@ export function pairedQualityNoninferiorityEvidence({ suite, repeats, baselineRu
378
380
  families
379
381
  };
380
382
  }
383
+
384
+ export function conditionalBothPassFreshUsage({ suite, repeats, allPairs, pairs, tokenPairs, baselineRuns, candidateRuns, allSuccessfulPairsFreshRatio }) {
385
+ return {
386
+ outcomeDefinition: "both-accepted-runs-resolved-including-safety-refusals",
387
+ usageDefinition: "exact-positive-fresh-same-model-and-thinking",
388
+ attemptScope: "accepted-attempts-only; all-attempt-costs-remain-in-tokenAccounting",
389
+ estimator: "geometric-mean-of-candidate-over-baseline-pair-ratios",
390
+ expectedPairs: suite.scenarios.length * repeats,
391
+ observedPairs: allPairs.length,
392
+ bothResolvedPairs: pairs.length,
393
+ eligiblePairs: tokenPairs.length,
394
+ excludedUnresolvedPairs: allPairs.length - pairs.length,
395
+ excludedUsagePairs: pairs.length - tokenPairs.length,
396
+ unpairedAcceptedRuns: baselineRuns.length + candidateRuns.length - 2 * allPairs.length,
397
+ ratio: rounded(allSuccessfulPairsFreshRatio, 4),
398
+ interpretation: "conditional-observation-only; not-overall-token-savings"
399
+ };
400
+ }
401
+
402
+ export function benchmarkOutcomePairs(baselineRuns, candidateRuns) {
403
+ const baselineByKey = new Map(baselineRuns.map((run) => [`${run.scenarioId}:${run.repeat}`, run]));
404
+ const allPairs = candidateRuns
405
+ .map((run) => ({ baseline: baselineByKey.get(`${run.scenarioId}:${run.repeat}`), candidate: run }))
406
+ .filter((pair) => pair.baseline);
407
+ return allPairs;
408
+ }