@piagent/platform 1.6.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (654) hide show
  1. package/CHANGELOG.md +71 -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/model-options.md +20 -15
  175. package/docs/operator-manual-vietnamese.md +12 -12
  176. package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
  177. package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
  178. package/docs/piagent-core-improvement-plan.md +528 -0
  179. package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
  180. package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
  181. package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
  182. package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
  183. package/docs/piagent-open-session-wait.md +19 -0
  184. package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
  185. package/docs/publishing-for-teams.md +3 -0
  186. package/docs/quality-benchmark.md +128 -8
  187. package/docs/quickstart-vietnamese.md +2 -2
  188. package/docs/release-install-policy.md +38 -11
  189. package/docs/research/harness-next-evidence-review.md +113 -0
  190. package/docs/team-onboarding.md +7 -7
  191. package/docs/third-party-neutrality.md +7 -0
  192. package/docs/usage-observability.md +1 -1
  193. package/docs-site/architecture.html +1 -1
  194. package/docs-site/benchmark.html +1 -1
  195. package/docs-site/commands.html +1 -1
  196. package/docs-site/content/en/runtime.html +1 -1
  197. package/docs-site/content/en/whats-new.html +23 -0
  198. package/docs-site/content/runtime.html +2 -2
  199. package/docs-site/content/whats-new.html +23 -0
  200. package/docs-site/context-engine.html +1 -1
  201. package/docs-site/en/architecture.html +1 -1
  202. package/docs-site/en/benchmark.html +1 -1
  203. package/docs-site/en/commands.html +1 -1
  204. package/docs-site/en/context-engine.html +1 -1
  205. package/docs-site/en/index.html +1 -1
  206. package/docs-site/en/mcp-approval.html +1 -1
  207. package/docs-site/en/mcp-auth.html +1 -1
  208. package/docs-site/en/mcp-servers.html +1 -1
  209. package/docs-site/en/mcp.html +1 -1
  210. package/docs-site/en/permissions.html +1 -1
  211. package/docs-site/en/profiles.html +1 -1
  212. package/docs-site/en/quickstart.html +1 -1
  213. package/docs-site/en/runtime.html +2 -2
  214. package/docs-site/en/scope.html +1 -1
  215. package/docs-site/en/security.html +1 -1
  216. package/docs-site/en/team.html +1 -1
  217. package/docs-site/en/whats-new.html +24 -1
  218. package/docs-site/en/workflows.html +1 -1
  219. package/docs-site/index.html +1 -1
  220. package/docs-site/mcp-approval.html +1 -1
  221. package/docs-site/mcp-auth.html +1 -1
  222. package/docs-site/mcp-servers.html +1 -1
  223. package/docs-site/mcp.html +1 -1
  224. package/docs-site/permissions.html +1 -1
  225. package/docs-site/profiles.html +1 -1
  226. package/docs-site/quickstart.html +1 -1
  227. package/docs-site/runtime.html +3 -3
  228. package/docs-site/scope.html +1 -1
  229. package/docs-site/security.html +1 -1
  230. package/docs-site/team.html +1 -1
  231. package/docs-site/whats-new.html +24 -1
  232. package/docs-site/workflows.html +1 -1
  233. package/evals/architecture-conformance-v1/lane.json +18 -0
  234. package/evals/architecture-conformance-v1/runner.mjs +77 -0
  235. package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
  236. package/evals/fixtures/approved-host-contracts.valid.json +43 -0
  237. package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
  238. package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
  239. package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
  240. package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
  241. package/evals/fixtures/composite-criterion.invalid.json +10 -0
  242. package/evals/fixtures/composite-criterion.valid.json +33 -0
  243. package/evals/fixtures/contract-family-library.invalid.json +42 -0
  244. package/evals/fixtures/contract-family-library.valid.json +41 -0
  245. package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
  246. package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
  247. package/evals/fixtures/host-contract-plan.invalid.json +42 -0
  248. package/evals/fixtures/host-contract-plan.valid.json +41 -0
  249. package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
  250. package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
  251. package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
  252. package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
  253. package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
  254. package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
  255. package/evals/fs5-artifact-archive/README.md +32 -0
  256. package/evals/fs5-artifact-archive/manifest.json +148 -0
  257. package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
  258. package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
  259. package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
  260. package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
  261. package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
  262. package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
  263. package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
  264. package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
  265. package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
  266. package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
  267. package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
  268. package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
  269. package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
  270. package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
  271. package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
  272. package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
  273. package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
  274. package/evals/fs5-causal-arm.v1.json +9 -5
  275. package/evals/fs5-pilot-protocol.v1.json +1 -1
  276. package/evals/fs5-pilot-protocol.v4.json +4 -4
  277. package/evals/fs5-pilot-protocol.v5.json +6 -5
  278. package/evals/harness-next/development-corpus.mjs +106 -0
  279. package/evals/harness-next/resource-budget-probe.mjs +38 -0
  280. package/evals/harness-next/run-calibration.mjs +83 -0
  281. package/evals/harness-next/run-resource-probe.mjs +55 -0
  282. package/evals/harness-next/selected-development-corpus.mjs +27 -0
  283. package/evals/harness-next.v1.json +51 -0
  284. package/evals/long-horizon-v1/README.md +19 -0
  285. package/evals/long-horizon-v1/runner.mjs +116 -48
  286. package/evals/long-horizon-v1/worker.mjs +77 -30
  287. package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
  288. package/evals/private-holdout-v1/README.md +5 -2
  289. package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
  290. package/package.json +9 -4
  291. package/packages/piagent-core/README.md +2 -2
  292. package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
  293. package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
  294. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
  295. package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
  296. package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
  297. package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
  298. package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
  299. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
  300. package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
  301. package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
  302. package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
  303. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +2 -1
  304. package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
  305. package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
  306. package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
  307. package/packages/piagent-core/benchmark/benchmark-core.js +107 -107
  308. package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
  309. package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
  310. package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
  311. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
  312. package/packages/piagent-core/benchmark/benchmark-forensics.js +63 -50
  313. package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
  314. package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
  315. package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
  316. package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
  317. package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
  318. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
  319. package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
  320. package/packages/piagent-core/benchmark/benchmark-preflight.js +69 -8
  321. package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
  322. package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
  323. package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
  324. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +162 -45
  325. package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
  326. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
  327. package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
  328. package/packages/piagent-core/benchmark/benchmark-record-validation.js +269 -3
  329. package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
  330. package/packages/piagent-core/benchmark/benchmark-report.js +79 -4
  331. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
  332. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
  333. package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
  334. package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
  335. package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
  336. package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
  337. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +144 -128
  338. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
  339. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
  340. package/packages/piagent-core/benchmark/benchmark-suite.js +211 -4
  341. package/packages/piagent-core/benchmark/benchmark-summary-support.js +30 -2
  342. package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
  343. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
  344. package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
  345. package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
  346. package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
  347. package/packages/piagent-core/benchmark/benchmark-usage.js +395 -33
  348. package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
  349. package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
  350. package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
  351. package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
  352. package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
  353. package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
  354. package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
  355. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +264 -70
  356. package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
  357. package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
  358. package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
  359. package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
  360. package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
  361. package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
  362. package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
  363. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
  364. package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
  365. package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
  366. package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
  367. package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
  368. package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
  369. package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
  370. package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
  371. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
  372. package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
  373. package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
  374. package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
  375. package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
  376. package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
  377. package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
  378. package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
  379. package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
  380. package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
  381. package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
  382. package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
  383. package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
  384. package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
  385. package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
  386. package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
  387. package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
  388. package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
  389. package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
  390. package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
  391. package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
  392. package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
  393. package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
  394. package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
  395. package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
  396. package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
  397. package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
  398. package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
  399. package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
  400. package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
  401. package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
  402. package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
  403. package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
  404. package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
  405. package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
  406. package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
  407. package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
  408. package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
  409. package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
  410. package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
  411. package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
  412. package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
  413. package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
  414. package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
  415. package/packages/piagent-core/extensions/acceptance-receipt.js +139 -152
  416. package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
  417. package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
  418. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
  419. package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
  420. package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
  421. package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
  422. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
  423. package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
  424. package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
  425. package/packages/piagent-core/extensions/context-engine.js +11 -6
  426. package/packages/piagent-core/extensions/criterion-context-pack.js +96 -4
  427. package/packages/piagent-core/extensions/failure-types.ts +2 -2
  428. package/packages/piagent-core/extensions/guard-types.ts +5 -1
  429. package/packages/piagent-core/extensions/piagent-guard.ts +197 -155
  430. package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
  431. package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
  432. package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
  433. package/packages/piagent-core/extensions/task-contract-view.js +4 -4
  434. package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
  435. package/packages/piagent-core/extensions/task-journal.js +48 -3
  436. package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
  437. package/packages/piagent-core/extensions/task-state.js +74 -38
  438. package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
  439. package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
  440. package/packages/piagent-core/extensions/verification-intelligence.js +60 -8
  441. package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
  442. package/packages/piagent-core/extensions/workspace-revision.js +48 -0
  443. package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
  444. package/packages/piagent-core/package.json +3 -3
  445. package/packages/piagent-core/policies/base-policy.json +1 -0
  446. package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
  447. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
  448. package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
  449. package/packages/piagent-core/runtime/hooks/completion-hook.ts +76 -83
  450. package/packages/piagent-core/runtime/hooks/input-hook.ts +92 -7
  451. package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
  452. package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
  453. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +50 -18
  454. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +53 -20
  455. package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
  456. package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
  457. package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
  458. package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
  459. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
  460. package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
  461. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
  462. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +49 -8
  463. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +61 -15
  464. package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
  465. package/packages/piagent-core/runtime/model/model-route-policy.ts +33 -13
  466. package/packages/piagent-core/runtime/model/model-route-types.ts +10 -6
  467. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
  468. package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
  469. package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
  470. package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
  471. package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
  472. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +12 -7
  473. package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
  474. package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
  475. package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
  476. package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
  477. package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
  478. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +11 -2
  479. package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
  480. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +192 -57
  481. package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
  482. package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
  483. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +27 -39
  484. package/packages/piagent-core/runtime/recovery/resume-state.ts +8 -5
  485. package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
  486. package/packages/piagent-core/runtime/registration/context-commands.ts +12 -8
  487. package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
  488. package/packages/piagent-core/runtime/registration/policy-tools.ts +5 -3
  489. package/packages/piagent-core/runtime/registration/session-commands.ts +9 -7
  490. package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
  491. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +27 -11
  492. package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
  493. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +5 -2
  494. package/packages/piagent-core/runtime/registration/task-start-tool.ts +23 -23
  495. package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
  496. package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
  497. package/packages/piagent-core/runtime/session/message-signals.ts +6 -22
  498. package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
  499. package/packages/piagent-core/runtime/session/runtime-state.ts +29 -35
  500. package/packages/piagent-core/runtime/session/system-prompt.ts +3 -3
  501. package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
  502. package/packages/piagent-core/runtime/session/usage.ts +4 -3
  503. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
  504. package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
  505. package/packages/piagent-core/runtime/tools/phase-tools.ts +3 -2
  506. package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
  507. package/packages/piagent-core/runtime/tools/tool-groups.ts +10 -3
  508. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
  509. package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
  510. package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
  511. package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
  512. package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
  513. package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
  514. package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
  515. package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
  516. package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
  517. package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
  518. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +11 -11
  519. package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
  520. package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
  521. package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
  522. package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
  523. package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
  524. package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
  525. package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
  526. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +44 -7
  527. package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
  528. package/packages/piagent-core/runtime/workflows/task-intake.ts +221 -242
  529. package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
  530. package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
  531. package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
  532. package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
  533. package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
  534. package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
  535. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-B4XehTCU.js → MarkdownMessage-DMU7Xe_O.js} +1 -1
  536. package/packages/piagent-webui/dist/client/assets/index-Cui9AAV_.js +176 -0
  537. package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
  538. package/packages/piagent-webui/dist/client/index.html +2 -2
  539. package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
  540. package/packages/piagent-webui/extension/piagent-webui.ts +10 -2
  541. package/packages/piagent-webui/extension/review-controller.ts +29 -6
  542. package/packages/piagent-webui/extension/same-session-bridge.ts +6 -7
  543. package/packages/piagent-webui/extension/session-stream-adapter.ts +60 -11
  544. package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
  545. package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
  546. package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
  547. package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
  548. package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
  549. package/packages/piagent-webui/gateway/gateway-session-stream.ts +141 -19
  550. package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
  551. package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
  552. package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
  553. package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
  554. package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
  555. package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
  556. package/packages/piagent-webui/gateway/session-inspection-registry.ts +14 -6
  557. package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
  558. package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
  559. package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
  560. package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
  561. package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
  562. package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
  563. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +114 -114
  564. package/packages/piagent-webui/server/core-inspection-provider.ts +73 -14
  565. package/packages/piagent-webui/server/loopback-server.ts +9 -7
  566. package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
  567. package/packages/piagent-webui/server/transcript-projection.ts +65 -12
  568. package/packages/piagent-webui/shared/message-correlation.ts +25 -0
  569. package/schemas/approved-host-contracts.schema.json +973 -0
  570. package/schemas/benchmark-attempt-outcome.schema.json +303 -0
  571. package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
  572. package/schemas/composite-criterion.schema.json +788 -0
  573. package/schemas/contract-family-library.schema.json +28 -0
  574. package/schemas/contract-selection-recipe.schema.json +31 -0
  575. package/schemas/failure-evidence.schema.json +2 -2
  576. package/schemas/helper-request.schema.json +16 -4
  577. package/schemas/host-contract-plan.schema.json +25 -0
  578. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
  579. package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
  580. package/schemas/piagent-webui/runtime-event-v2.schema.json +32 -1
  581. package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
  582. package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
  583. package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
  584. package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
  585. package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
  586. package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
  587. package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
  588. package/schemas/public-contracts/revocation-v1.schema.json +87 -0
  589. package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
  590. package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
  591. package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
  592. package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
  593. package/schemas/task-contract.schema.json +30 -0
  594. package/scripts/approve-independent-verification.mjs +57 -0
  595. package/scripts/benchmark-arm-observer.mjs +320 -0
  596. package/scripts/benchmark-budget-ipc.mjs +34 -0
  597. package/scripts/benchmark-budget-launcher.mjs +91 -0
  598. package/scripts/benchmark-budget-processes.mjs +133 -0
  599. package/scripts/benchmark-budget-publication.mjs +228 -0
  600. package/scripts/benchmark-budget-runtime.mjs +136 -0
  601. package/scripts/benchmark-candidate-ablation.mjs +265 -0
  602. package/scripts/benchmark-codex-journey.mjs +406 -0
  603. package/scripts/benchmark-independent-verification.mjs +628 -0
  604. package/scripts/benchmark-journey-outcome.mjs +92 -0
  605. package/scripts/benchmark-production-v3-human-review.mjs +192 -0
  606. package/scripts/benchmark-public-input-catalog.mjs +158 -0
  607. package/scripts/benchmark-registered-plan-author.mjs +355 -0
  608. package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
  609. package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
  610. package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
  611. package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
  612. package/scripts/benchmark-runner-completion.mjs +133 -0
  613. package/scripts/benchmark-runner-configuration.mjs +159 -0
  614. package/scripts/benchmark-runner-core.mjs +217 -388
  615. package/scripts/benchmark-runner-finalization.mjs +140 -27
  616. package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
  617. package/scripts/benchmark-runner-schedule.mjs +256 -0
  618. package/scripts/benchmark-runner-support.mjs +136 -4
  619. package/scripts/benchmark-runner.mjs +95 -18
  620. package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
  621. package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
  622. package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
  623. package/scripts/benchmark-scoped-pi-router.mjs +196 -0
  624. package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
  625. package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
  626. package/scripts/benchmark-scoped-session-custody.mjs +599 -0
  627. package/scripts/benchmark-scoped-session-factory.mjs +342 -0
  628. package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
  629. package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
  630. package/scripts/benchmark-session-evaluator.mjs +169 -0
  631. package/scripts/benchmark-session-provider-boundary.mjs +62 -0
  632. package/scripts/benchmark-session-usage.mjs +28 -0
  633. package/scripts/benchmark-session.mjs +343 -50
  634. package/scripts/benchmark-webui-journey.mjs +678 -0
  635. package/scripts/check-public-wording.mjs +46 -0
  636. package/scripts/configure-model-scope.sh +6 -2
  637. package/scripts/fs4-readiness-evaluation.mjs +7 -1
  638. package/scripts/install-global.sh +2 -2
  639. package/scripts/model-route-evaluation-core.ts +1 -0
  640. package/scripts/phase-tools-evaluation.mjs +1 -0
  641. package/scripts/pi-auto.sh +7 -1
  642. package/scripts/pi-model-route.mjs +1 -1
  643. package/scripts/pi-usage-history.mjs +201 -11
  644. package/scripts/piagent-cli.mjs +8 -0
  645. package/scripts/private-holdout-readiness.mjs +7 -1
  646. package/scripts/public-evaluation-exposure.mjs +140 -0
  647. package/scripts/select-independent-verification.mjs +62 -0
  648. package/scripts/setup.sh +2 -2
  649. package/scripts/typescript-loader.mjs +135 -1
  650. package/scripts/update-global.mjs +6 -7
  651. package/scripts/verify-local.sh +37 -56
  652. package/scripts/verify-release-identity.mjs +5 -3
  653. package/templates/global/settings.json +5 -1
  654. package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +0 -176
@@ -6,7 +6,7 @@ import { redactSensitiveText } from "../../extensions/redaction-core.js";
6
6
  import { workingTreeSnapshot } from "../../extensions/task-state.js";
7
7
  import { workingTreeEvidenceDigest, workingTreeSnapshotUsesCurrentAlgorithm } from "../../extensions/working-tree-digest.js";
8
8
  import { inspectTaskContinuationBudget } from "../recovery/continuation-budget.ts";
9
- import { readHandoffProjection } from "../recovery/handoff-projection.ts";
9
+ import { handoffIdentityMatchesTask, readHandoffProjection } from "../recovery/handoff-projection.ts";
10
10
  import type { ActivityInspectorEvent, CurrentActivity } from "../product/activity-inspector.ts";
11
11
  import { recoveredToolCalls } from "./activity-recovery.ts";
12
12
  import { classifyToolFailure, handledToolFailure } from "./tool-failure-classification.ts";
@@ -129,7 +129,7 @@ function reconciledToolResults(events: ActivityInspectorEvent[], evidence: Retur
129
129
  const raw = evidence.results.get(call.toolCallId);
130
130
  if (!raw) continue;
131
131
  const reasonCode = classifyToolFailure(raw.toolName || call.toolName, raw.isError, raw.content, evidence.inputs.get(call.toolCallId));
132
- const effectiveError = raw.isError || Boolean(reasonCode && !handledToolFailure(reasonCode));
132
+ const effectiveError = raw.isError || Boolean(reasonCode && !handledToolFailure(reasonCode, raw.toolName || call.toolName));
133
133
  reconciled.push({ activityId: `canonical-result:${call.toolCallId}`, event: "tool_result",
134
134
  recordedAt: raw.recordedAt ?? call.recordedAt, sessionId: call.sessionId, taskRunId: call.taskRunId,
135
135
  toolCallId: call.toolCallId, toolName: raw.toolName || call.toolName, isError: effectiveError,
@@ -162,29 +162,64 @@ function sourceSummary(document: SourceChangeDocument | null, view: "task" | "wo
162
162
  };
163
163
  }
164
164
 
165
- function activityProjection(events: ActivityInspectorEvent[], current: CurrentActivity[]) {
165
+ function sourceProjectionRevision(views: CriteriaLinkProjection["sourceViews"]): string {
166
+ const content = (["task", "workingTree", "staged"] as const).map((key) => {
167
+ const document = views[key];
168
+ if (!document) return null;
169
+ const { generatedAt: _generatedAt, identity: _identity, snapshotBinding: _snapshotBinding, ...stable } = document;
170
+ const bases = Array.isArray(stable.bases) ? stable.bases.map((value) => {
171
+ if (!value || typeof value !== "object") return value;
172
+ const { taskRevision: _taskRevision, ...sourceBasis } = value as Record<string, unknown>;
173
+ return sourceBasis;
174
+ }) : stable.bases;
175
+ return { ...stable, bases };
176
+ });
177
+ return token("source-projection-rev", content);
178
+ }
179
+
180
+ function activityProjection(events: ActivityInspectorEvent[], current: CurrentActivity[], generatedAt: string,
181
+ operationLiveness?: "idle" | "running" | "unknown") {
166
182
  const results = new Map(events.filter((event) => event.event === "tool_result").map((event) => [event.toolCallId, event]));
167
183
  const decisions = new Map(events.filter((event) => event.event === "tool_decision").map((event) => [event.toolCallId, event]));
168
184
  const recoveries = recoveredToolCalls(events);
185
+ // Tool-call telemetry is deliberately written before execution. A missing
186
+ // result therefore cannot remain authoritative forever: compaction, abrupt
187
+ // host replacement, or an older runtime may have lost the matching result.
188
+ // A later host lifecycle boundary proves only that the call is no longer
189
+ // running, not that it passed or failed, so project it as terminal/unknown.
190
+ let lastLifecycleBoundary = -1;
191
+ for (let index = events.length - 1; index >= 0; index -= 1) {
192
+ if (!["turn_end", "agent_settled", "session_shutdown"].includes(String(events[index]?.event))) continue;
193
+ lastLifecycleBoundary = index;
194
+ break;
195
+ }
169
196
  const calls = events.filter((event) => event.event === "tool_call").slice(-200);
170
197
  const projected = calls.map((call) => {
171
198
  const result = results.get(call.toolCallId), decision = decisions.get(call.toolCallId);
172
199
  const blocked = decision?.decision === "blocked";
173
- const handled = Boolean(result && handledToolFailure(result.reasonCode));
200
+ const handled = Boolean(result && handledToolFailure(result.reasonCode, result.toolName ?? call.toolName));
174
201
  const failed = !blocked && !handled && Boolean(result && (result.isError === true || (typeof result.exitCode === "number" && result.exitCode !== 0)));
175
202
  const recovery = call.toolCallId ? recoveries.get(call.toolCallId) : undefined;
176
- const state = blocked ? "blocked" : !result ? "running" : failed && !recovery ? "failed" : "passed";
203
+ const lifecycleSettled = !result && !blocked && (operationLiveness === "idle"
204
+ || lastLifecycleBoundary > events.indexOf(call));
205
+ const state = blocked ? "blocked" : lifecycleSettled ? "unknown" : !result ? "running" : failed && !recovery ? "failed" : "passed";
177
206
  const toolName = display(call.toolName ?? "unknown", 80).replace(/[^A-Za-z0-9._:@~-]/g, "-") || "unknown";
178
207
  const rawId = String(call.toolCallId ?? call.activityId ?? `${call.recordedAt}:${toolName}`);
179
208
  const command = display(call.command ?? call.targetPath ?? toolName, 65_536);
209
+ const boundaryAt = lastLifecycleBoundary > events.indexOf(call)
210
+ ? timestamp(events[lastLifecycleBoundary]?.recordedAt, timestamp(call.recordedAt, generatedAt))
211
+ : timestamp(events.at(-1)?.recordedAt, timestamp(call.recordedAt, generatedAt));
180
212
  return {
181
213
  activityRef: token("activity", [rawId, call.recordedAt]), kind: ["bash", "shell", "exec"].includes(toolName) ? "command" : "tool", state,
182
- label: display(recovery ? `${toolName} recovered` : handled ? `${toolName} warning` : state === "running" ? `${toolName} running` : `${toolName} ${state}`, 500), preview: command,
214
+ label: display(recovery ? `${toolName} recovered` : handled ? `${toolName} warning`
215
+ : state === "unknown" ? `${toolName} ended · result unavailable`
216
+ : state === "running" ? `${toolName} running` : `${toolName} ${state}`, 500), preview: command,
183
217
  toolCallId: token("tool", rawId), toolName, commandDigest: call.command ? `sha256:${hash(call.command)}` : null,
184
218
  logRef: null, exitCode: recovery?.exitCode ?? (typeof result?.exitCode === "number" ? result.exitCode : null),
185
219
  exitCodeExact: recovery?.exitCodeExact ?? (result?.exitCodeExact === true),
186
220
  startedAt: timestamp(call.recordedAt), finishedAt: recovery ? timestamp(recovery.recoveredAt, timestamp(call.recordedAt))
187
- : result || blocked ? timestamp(result?.recordedAt ?? decision?.recordedAt, timestamp(call.recordedAt)) : null
221
+ : result || blocked ? timestamp(result?.recordedAt ?? decision?.recordedAt, timestamp(call.recordedAt))
222
+ : lifecycleSettled ? boundaryAt : null
188
223
  };
189
224
  });
190
225
  const callIds = new Set(calls.map((call) => String(call.toolCallId ?? "")));
@@ -213,7 +248,7 @@ function capabilities(identity: WebUiIdentity, generatedAt: string, resyncRequir
213
248
  capabilities: {
214
249
  inspect: { status: "available", version: 1, reason: null, sourceViews: ["task", "working-tree", "staged"] },
215
250
  "control.chat": unavailableCapability("chat-control-not-enabled", "The same-session bridge exists, but transcript, queue, server control and browser UX are not enabled"),
216
- "control.lifecycle": unavailableCapability("lifecycle-contract-incomplete", "Pi 0.84.1 lacks semantic Pause and an acknowledged phase-complete Stop contract"),
251
+ "control.lifecycle": unavailableCapability("lifecycle-contract-incomplete", "Pi host lacks semantic Pause and an acknowledged phase-complete Stop contract"),
217
252
  "control.resumeAndContinue": unavailableCapability("compound-control-unavailable", "Resume is unavailable until a durable acknowledged Pause contract exists"),
218
253
  "control.sessionOptions": unavailableCapability("effect-scope-not-productionized", "Model and thinking APIs exist but lifecycle and persistence scope enforcement is not enabled"),
219
254
  attachments: unavailableCapability("attachments-not-implemented", "Attachments are not implemented"),
@@ -299,7 +334,7 @@ function handoff(cwd: string, task: TaskContract | undefined, currentDigest: str
299
334
  if (!task) return null;
300
335
  let value;
301
336
  try { value = readHandoffProjection(cwd, task.taskRunId); } catch { return null; }
302
- if (!value) return null;
337
+ if (!value || !handoffIdentityMatchesTask(value.identity, task)) return null;
303
338
  const stale = Boolean(currentDigest && value.tree.currentDigest && currentDigest !== value.tree.currentDigest);
304
339
  return { handoffRef: token("handoff", task.taskRunId), state: stale ? "stale" : "ready", summary: display(value.goal.summary, 500),
305
340
  blocker: value.failure.warnings[0] ? display(value.failure.warnings[0], 500) : null,
@@ -324,6 +359,7 @@ export async function buildWebUiInspectionProjection(input: {
324
359
  eventReplay?: { eventRetentionCount: number; eventRetentionSeconds: number };
325
360
  model?: WebUiRuntimeModel;
326
361
  thinkingLevel?: unknown;
362
+ operationLiveness?: "idle" | "running" | "unknown";
327
363
  }): Promise<WebUiInspectionProjection> {
328
364
  const generatedAt = timestamp(input.generatedAt);
329
365
  const identity: WebUiIdentity = { projectRef: webUiProjectRef(input.cwd), runtimeInstanceId: input.runtimeInstanceId ?? WEBUI_RUNTIME_INSTANCE_REF,
@@ -339,14 +375,18 @@ export async function buildWebUiInspectionProjection(input: {
339
375
  const events = reconciledToolResults(scopedEvents(input.events ?? [], input.sessionId, input.task), canonicalEvidence);
340
376
  const linked = projectCriteriaFileVerifier({ cwd: input.cwd, task: input.task, sourceViews: views, currentSnapshot,
341
377
  protectedPaths: input.protectedPaths, events, at: new Date(generatedAt) });
342
- const sourceChanges = { task: sourceSummary(linked.sourceViews.task, "task"), workingTree: sourceSummary(linked.sourceViews.workingTree, "working-tree"), staged: sourceSummary(linked.sourceViews.staged, "staged") };
378
+ const sourceChanges = { projectionRevision: sourceProjectionRevision(linked.sourceViews),
379
+ task: sourceSummary(linked.sourceViews.task, "task"), workingTree: sourceSummary(linked.sourceViews.workingTree, "working-tree"),
380
+ staged: sourceSummary(linked.sourceViews.staged, "staged") };
343
381
  const currentDigest = workingTreeSnapshotUsesCurrentAlgorithm(currentSnapshot) ? workingTreeEvidenceDigest(currentSnapshot) : null;
344
- const current = (input.current ?? []).filter((item) => (item.status ?? "running") !== "running" || !canonicalEvidence.results.has(item.toolCallId));
382
+ const current = (input.current ?? []).filter((item) => ((item.status ?? "running") !== "running" || input.operationLiveness !== "idle")
383
+ && ((item.status ?? "running") !== "running" || !canonicalEvidence.results.has(item.toolCallId)));
345
384
  const runningCurrent = current.find((item) => (item.status ?? "running") === "running");
346
385
  const controlState = input.task?.trace.outcome === "pending" ? "active" as const : "terminal" as const;
347
386
  const context = contextProjection(input.contextUsage, generatedAt), usageFacts = usage(input.sessionEntries ?? []);
348
387
  const eventCursor = input.eventCursor ?? token("event-cursor", events.map((event) => event.activityId ?? [event.event, event.toolCallId, event.recordedAt]));
349
- const runtimeRevision = token("runtime-rev", [taskRevision, sourceChanges.workingTree.revision, sourceChanges.staged.revision, eventCursor, current]);
388
+ const runtimeRevision = token("runtime-rev", [taskRevision, sourceChanges.workingTree.revision, sourceChanges.staged.revision,
389
+ eventCursor, current, input.operationLiveness ?? null]);
350
390
  const approvals = { state: "unknown", pending: [], recent: [], health: { state: "unavailable", reasonCode: "approval-projection-unavailable", message: "Current host approval state is not exposed to the read-only projector" } };
351
391
  const task = input.task ? taskProjection(input.task, linked.criteria, controlState) : null;
352
392
  const issues = [
@@ -364,8 +404,8 @@ export async function buildWebUiInspectionProjection(input: {
364
404
  capabilities: capabilities(identity, generatedAt, input.resyncRequired === true, input.eventReplay),
365
405
  session: {
366
406
  connectionState: input.resyncRequired ? "resync-required" : "connected", connectionReason: input.resyncRequired ? "event-replay-gap" : null, displayName: input.task?.sessionName ?? null,
367
- operation: runningCurrent
368
- ? { liveness: "running", operationRef: null, hostPhase: { state: "known", value: "tool", evidence: "derived", reasonCode: null }, startedAt: timestamp(runningCurrent.startedAt, generatedAt), settledAt: null, reasonCode: null }
407
+ operation: input.operationLiveness === "running" || runningCurrent
408
+ ? { liveness: "running", operationRef: null, hostPhase: { state: "known", value: runningCurrent ? "tool" : "other", evidence: "derived", reasonCode: null }, startedAt: runningCurrent ? timestamp(runningCurrent.startedAt, generatedAt) : null, settledAt: null, reasonCode: null }
369
409
  : { liveness: "idle", operationRef: null, hostPhase: { state: "known", value: "idle", evidence: "derived", reasonCode: null }, startedAt: null, settledAt: null, reasonCode: null },
370
410
  controlState: input.task ? controlState : "active", taskOutcome: input.task?.trace.outcome ?? null, approvalState: approvals.state,
371
411
  verificationState: linked.verification.state, permissionProfile: { state: "unavailable", value: null, evidence: null, reasonCode: "permission-profile-not-projected" },
@@ -373,12 +413,18 @@ export async function buildWebUiInspectionProjection(input: {
373
413
  thinking: thinkingFact(input.thinkingLevel),
374
414
  queue: { state: "unavailable", hasPending: null, heldCount: null, revision: null, reasonCode: "host-queue-api-unavailable" }, context
375
415
  },
376
- task, sourceChanges, activity: activityProjection(events, current), approvals, verification: linked.verification,
416
+ task, sourceChanges, activity: activityProjection(events, current, generatedAt, input.operationLiveness), approvals, verification: linked.verification,
377
417
  usage: { context, latestTurn: usageCounter(usageFacts.latest, "no-assistant-turn"), sessionTotal: usageCounter(usageFacts.observed ? usageFacts.totals : null, "host-total-usage-unavailable"),
378
418
  taskTotal: usageCounter(null, input.task ? "task-usage-boundary-unavailable" : "no-active-task"), capturedAt: generatedAt,
379
419
  health: { state: "degraded", reasonCode: "partial-usage-only", message: "Task-attributed usage is not available" } },
380
420
  continuation: continuation(input.cwd, input.task), handoff: handoff(input.cwd, input.task, currentDigest),
381
421
  health: { state: issues.length ? "degraded" : "ok", issues, resyncRequired: input.resyncRequired === true, generatedFromRevision: runtimeRevision }
382
422
  };
423
+ const snapshotBinding = { sourceProjectionRevision: snapshot.sourceChanges.projectionRevision,
424
+ taskViewRevision: snapshot.sourceChanges.task.revision, workspaceRevision: snapshot.sourceChanges.workingTree.revision,
425
+ indexRevision: snapshot.sourceChanges.staged.revision };
426
+ for (const document of Object.values(linked.sourceViews)) {
427
+ if (document) (document as SourceChangeDocument & { snapshotBinding: typeof snapshotBinding }).snapshotBinding = snapshotBinding;
428
+ }
383
429
  return { snapshot, sourceViews: linked.sourceViews, relations: linked.relations, verifierAttempts: linked.verifierAttempts, scopedEvents: events };
384
430
  }
@@ -1,132 +1,2 @@
1
- import { createHash } from "node:crypto";
2
- import fs from "node:fs";
3
- import path from "node:path";
4
-
5
- export class WorkspaceReadError extends Error {
6
- readonly code: "outside-root" | "symlink-ancestor" | "not-file" | "oversized" | "changed-during-read";
7
-
8
- constructor(code: WorkspaceReadError["code"], message: string) {
9
- super(message);
10
- this.name = "WorkspaceReadError";
11
- this.code = code;
12
- }
13
- }
14
-
15
- type SafeCandidate = { root: string; absolute: string; parent: string };
16
-
17
- function inside(root: string, candidate: string): boolean {
18
- const relative = path.relative(root, candidate);
19
- return relative === "" || (relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
20
- }
21
-
22
- function safeCandidate(repoRoot: string, repoPath: string): SafeCandidate {
23
- const root = fs.realpathSync.native(repoRoot);
24
- const segments = repoPath.split("/");
25
- if (!repoPath || path.posix.isAbsolute(repoPath) || segments.includes("..") || segments.includes("")) {
26
- throw new WorkspaceReadError("outside-root", "Workspace path is not a safe repository-relative path");
27
- }
28
- let parent = root;
29
- for (const segment of segments.slice(0, -1)) {
30
- parent = path.join(parent, segment);
31
- const stat = fs.lstatSync(parent);
32
- if (stat.isSymbolicLink()) throw new WorkspaceReadError("symlink-ancestor", "Workspace path traverses a symbolic link");
33
- if (!stat.isDirectory()) throw new WorkspaceReadError("not-file", "Workspace path has a non-directory ancestor");
34
- }
35
- const canonicalParent = fs.realpathSync.native(parent);
36
- if (!inside(root, canonicalParent)) throw new WorkspaceReadError("outside-root", "Workspace path resolves outside its repository root");
37
- const absolute = path.join(canonicalParent, segments.at(-1) as string);
38
- if (!inside(root, absolute)) throw new WorkspaceReadError("outside-root", "Workspace path escapes its repository root");
39
- return { root, absolute, parent: canonicalParent };
40
- }
41
-
42
- function sameFile(left: fs.Stats, right: fs.Stats): boolean {
43
- return left.dev === right.dev && left.ino === right.ino && left.mode === right.mode;
44
- }
45
-
46
- function openRegularFile(repoRoot: string, repoPath: string): { descriptor: number; stat: fs.Stats; candidate: SafeCandidate } {
47
- const candidate = safeCandidate(repoRoot, repoPath);
48
- const descriptor = fs.openSync(candidate.absolute, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
49
- try {
50
- const stat = fs.fstatSync(descriptor);
51
- if (!stat.isFile()) throw new WorkspaceReadError("not-file", "Workspace entry is not a regular file");
52
- const canonical = fs.realpathSync.native(candidate.absolute);
53
- const current = fs.lstatSync(candidate.absolute);
54
- if (!inside(candidate.root, canonical) || !sameFile(stat, current)) {
55
- throw new WorkspaceReadError("changed-during-read", "Workspace path changed while it was opened");
56
- }
57
- return { descriptor, stat, candidate };
58
- } catch (error) {
59
- fs.closeSync(descriptor);
60
- throw error;
61
- }
62
- }
63
-
64
- function verifyAfterRead(descriptor: number, before: fs.Stats, candidate: SafeCandidate): void {
65
- const after = fs.fstatSync(descriptor);
66
- const current = fs.lstatSync(candidate.absolute);
67
- const canonical = fs.realpathSync.native(candidate.absolute);
68
- if (
69
- !sameFile(before, after)
70
- || !sameFile(after, current)
71
- || before.size !== after.size
72
- || before.mtimeMs !== after.mtimeMs
73
- || before.ctimeMs !== after.ctimeMs
74
- || !inside(candidate.root, canonical)
75
- ) {
76
- throw new WorkspaceReadError("changed-during-read", "Workspace file changed during inspection");
77
- }
78
- }
79
-
80
- export function inspectWorkspaceEntry(repoRoot: string, repoPath: string): fs.Stats {
81
- const candidate = safeCandidate(repoRoot, repoPath);
82
- return fs.lstatSync(candidate.absolute);
83
- }
84
-
85
- export function readWorkspaceLink(repoRoot: string, repoPath: string): string {
86
- const candidate = safeCandidate(repoRoot, repoPath);
87
- const before = fs.lstatSync(candidate.absolute);
88
- if (!before.isSymbolicLink()) throw new WorkspaceReadError("not-file", "Workspace entry is not a symbolic link");
89
- const target = fs.readlinkSync(candidate.absolute);
90
- const after = fs.lstatSync(candidate.absolute);
91
- if (!sameFile(before, after) || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs) {
92
- throw new WorkspaceReadError("changed-during-read", "Workspace link changed during inspection");
93
- }
94
- return target;
95
- }
96
-
97
- export function readWorkspaceFile(repoRoot: string, repoPath: string, maxBytes: number): Buffer {
98
- const opened = openRegularFile(repoRoot, repoPath);
99
- try {
100
- if (opened.stat.size > maxBytes) throw new WorkspaceReadError("oversized", "Workspace file exceeds its read cap");
101
- const content = Buffer.allocUnsafe(opened.stat.size);
102
- let position = 0;
103
- while (position < content.length) {
104
- const count = fs.readSync(opened.descriptor, content, position, content.length - position, position);
105
- if (count <= 0) throw new WorkspaceReadError("changed-during-read", "Workspace file ended during inspection");
106
- position += count;
107
- }
108
- verifyAfterRead(opened.descriptor, opened.stat, opened.candidate);
109
- return content;
110
- } finally {
111
- fs.closeSync(opened.descriptor);
112
- }
113
- }
114
-
115
- export function hashWorkspaceFile(repoRoot: string, repoPath: string): string {
116
- const opened = openRegularFile(repoRoot, repoPath);
117
- try {
118
- const state = createHash("sha256");
119
- const buffer = Buffer.allocUnsafe(256 * 1024);
120
- let position = 0;
121
- while (position < opened.stat.size) {
122
- const count = fs.readSync(opened.descriptor, buffer, 0, Math.min(buffer.length, opened.stat.size - position), position);
123
- if (count <= 0) throw new WorkspaceReadError("changed-during-read", "Workspace file ended during hashing");
124
- state.update(buffer.subarray(0, count));
125
- position += count;
126
- }
127
- verifyAfterRead(opened.descriptor, opened.stat, opened.candidate);
128
- return state.digest("hex");
129
- } finally {
130
- fs.closeSync(opened.descriptor);
131
- }
132
- }
1
+ // Compatibility entrypoint; core and runtime share the same bounded file reader.
2
+ export * from "../../security/workspace-file-reader.ts";
@@ -4,8 +4,11 @@ import {
4
4
  authenticatedCatalogDigest,
5
5
  CAPABILITY_BANDS,
6
6
  createModelRouteDecision,
7
+ LEGACY_OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION,
8
+ OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION,
7
9
  type CapabilityBand,
8
10
  type ModelRouteDecision,
11
+ type ModelRouteMappingVersion,
9
12
  type ModelSelectionSource,
10
13
  type ParentRoutingMode,
11
14
  type RoutingObjective
@@ -22,33 +25,47 @@ export type ModelRoutePolicyInput = {
22
25
  current: { provider: string | null; modelId: string | null; effort: string | null };
23
26
  freshTaskBoundary: boolean;
24
27
  hostBoundary: ModelRouteHostBoundary;
28
+ mappingVersion?: ModelRouteMappingVersion;
25
29
  };
26
30
 
27
31
  type Candidate = { provider: "openai-codex"; modelId: string; effort: string };
28
32
 
29
- const BAND_CANDIDATES: Record<CapabilityBand, Candidate[]> = {
33
+ const LEGACY_BAND_CANDIDATES: Record<CapabilityBand, Candidate[]> = {
30
34
  low: [{ provider: "openai-codex", modelId: "gpt-5.6-luna", effort: "medium" }],
31
35
  medium: [{ provider: "openai-codex", modelId: "gpt-5.6-terra", effort: "medium" }],
32
36
  high: [{ provider: "openai-codex", modelId: "gpt-5.6-sol", effort: "high" }],
33
37
  ultra: [{ provider: "openai-codex", modelId: "gpt-5.6-sol", effort: "xhigh" }]
34
38
  };
39
+ const BAND_CANDIDATES: Record<CapabilityBand, Candidate[]> = {
40
+ low: [{ provider: "openai-codex", modelId: "gpt-6-luna", effort: "medium" }, ...LEGACY_BAND_CANDIDATES.low],
41
+ medium: [{ provider: "openai-codex", modelId: "gpt-6-sol", effort: "medium" }, ...LEGACY_BAND_CANDIDATES.medium],
42
+ high: [{ provider: "openai-codex", modelId: "gpt-6-sol", effort: "high" }, ...LEGACY_BAND_CANDIDATES.high],
43
+ ultra: [{ provider: "openai-codex", modelId: "gpt-6-astra", effort: "xhigh" }, ...LEGACY_BAND_CANDIDATES.ultra]
44
+ };
35
45
  const BAND_INDEX = new Map(CAPABILITY_BANDS.map((band, index) => [band, index]));
36
46
 
37
- function exactCandidate(catalog: AuthenticatedModelCatalog, band: CapabilityBand): { model: AuthenticatedModelCatalogEntry; effort: string } | undefined {
38
- for (const candidate of BAND_CANDIDATES[band]) {
47
+ function exactCandidate(catalog: AuthenticatedModelCatalog, band: CapabilityBand, mappingVersion: ModelRouteMappingVersion): { model: AuthenticatedModelCatalogEntry; effort: string; legacyFallback: boolean } | undefined {
48
+ const candidates = mappingVersion === LEGACY_OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION ? LEGACY_BAND_CANDIDATES[band] : BAND_CANDIDATES[band];
49
+ for (const [index, candidate] of candidates.entries()) {
39
50
  const model = catalog.models.find((entry) => entry.provider === candidate.provider
40
51
  && entry.modelId === candidate.modelId
41
52
  && (entry.supportedThinkingLevels === null || entry.supportedThinkingLevels.includes(candidate.effort)));
42
- if (model) return { model, effort: candidate.effort };
53
+ if (model) return { model, effort: candidate.effort, legacyFallback: mappingVersion === OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION && index > 0 };
43
54
  }
44
55
  return undefined;
45
56
  }
46
57
 
47
- function currentBand(modelId: string | null): CapabilityBand | undefined {
48
- return modelId === "gpt-5.6-luna" ? "low"
49
- : modelId === "gpt-5.6-terra" ? "medium"
50
- : modelId === "gpt-5.6-sol" ? "high"
51
- : undefined;
58
+ function currentBand(modelId: string | null, effort: string | null): CapabilityBand | undefined {
59
+ if (modelId === "gpt-6-luna" || modelId === "gpt-5.6-luna") return "low";
60
+ if (modelId === "gpt-6-astra") return "ultra";
61
+ if (modelId === "gpt-6-sol") {
62
+ if (effort === "medium") return "medium";
63
+ if (effort === "xhigh" || effort === "max") return "ultra";
64
+ return "high";
65
+ }
66
+ if (modelId === "gpt-5.6-terra") return "medium";
67
+ if (modelId === "gpt-5.6-sol") return "high";
68
+ return undefined;
52
69
  }
53
70
 
54
71
  function maxBand(left: CapabilityBand, right: CapabilityBand): CapabilityBand {
@@ -102,6 +119,7 @@ function downgradeSteps(current: CapabilityBand | undefined, target: CapabilityB
102
119
  }
103
120
 
104
121
  export function routeParentModel(input: ModelRoutePolicyInput): ModelRouteDecision {
122
+ const mappingVersion = input.mappingVersion ?? OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION;
105
123
  const floor = safetyFloor(input.features);
106
124
  const desired = objectiveBand(floor.band, input.objective);
107
125
  const catalogDigest = authenticatedCatalogDigest(input.catalog);
@@ -114,7 +132,8 @@ export function routeParentModel(input: ModelRoutePolicyInput): ModelRouteDecisi
114
132
  currentModelId: input.current.modelId,
115
133
  currentEffort: input.current.effort,
116
134
  selectionSource: input.selectionSource,
117
- catalogDigest
135
+ catalogDigest,
136
+ mappingVersion
118
137
  } as const;
119
138
  if (input.mode === "off") return createModelRouteDecision({
120
139
  ...common, capabilityBand: "abstain", fallbackBand: desired, provider: input.current.provider,
@@ -136,14 +155,15 @@ export function routeParentModel(input: ModelRoutePolicyInput): ModelRouteDecisi
136
155
  confidence: "low", disposition: "unavailable", reasonCodes: ["authenticated-catalog-unavailable", ...floor.reasons],
137
156
  downgradeSteps: 0, enforced: false
138
157
  });
139
- const candidate = exactCandidate(input.catalog, desired);
158
+ const candidate = exactCandidate(input.catalog, desired, mappingVersion);
140
159
  if (!candidate) return createModelRouteDecision({
141
160
  ...common, capabilityBand: "abstain", fallbackBand: desired, provider: null, modelId: null, effort: null,
142
161
  confidence: "low", disposition: "unavailable", reasonCodes: ["preferred-model-or-effort-unavailable", "no-silent-substitution", ...floor.reasons],
143
162
  downgradeSteps: 0, enforced: false
144
163
  });
145
- const reasons = [...floor.reasons, `objective-${input.objective}`, `candidate-${desired}`, "runtime-catalog-match"];
146
- const steps = downgradeSteps(currentBand(input.current.modelId), desired);
164
+ const reasons = [...floor.reasons, `objective-${input.objective}`, `candidate-${desired}`, "runtime-catalog-match",
165
+ ...(candidate.legacyFallback ? ["legacy-model-fallback"] : [])];
166
+ const steps = downgradeSteps(currentBand(input.current.modelId, input.current.effort), desired);
147
167
  if (input.mode === "shadow") return createModelRouteDecision({
148
168
  ...common, capabilityBand: desired, fallbackBand: null, provider: candidate.model.provider, modelId: candidate.model.modelId,
149
169
  effort: candidate.effort, confidence: floor.band === "low" || floor.band === "ultra" ? "high" : "medium",
@@ -4,7 +4,9 @@ import type { AuthenticatedModelCatalog } from "./authenticated-catalog.ts";
4
4
 
5
5
  export const MODEL_ROUTE_DECISION_SCHEMA_VERSION = 1 as const;
6
6
  export const MODEL_ROUTE_POLICY_VERSION = "model-route-v1" as const;
7
- export const OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION = "openai-codex-model-route-map-v1" as const;
7
+ export const LEGACY_OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION = "openai-codex-model-route-map-v1" as const;
8
+ export const OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION = "openai-codex-model-route-map-v2" as const;
9
+ export type ModelRouteMappingVersion = typeof LEGACY_OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION | typeof OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION;
8
10
 
9
11
  export const PARENT_ROUTING_MODES = Object.freeze(["off", "shadow", "recommend", "auto"] as const);
10
12
  export const ROUTING_OBJECTIVES = Object.freeze(["intelligence", "balance", "cost"] as const);
@@ -26,7 +28,7 @@ export type ModelRouteDisposition = "preserved" | "shadowed" | "recommended" | "
26
28
  export type ModelRouteDecision = {
27
29
  schemaVersion: typeof MODEL_ROUTE_DECISION_SCHEMA_VERSION;
28
30
  policyVersion: typeof MODEL_ROUTE_POLICY_VERSION;
29
- mappingVersion: typeof OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION;
31
+ mappingVersion: ModelRouteMappingVersion;
30
32
  featureHash: string;
31
33
  mode: ParentRoutingMode;
32
34
  objective: RoutingObjective;
@@ -88,13 +90,14 @@ export function authenticatedCatalogDigest(catalog: AuthenticatedModelCatalog):
88
90
  }
89
91
 
90
92
  export function createModelRouteDecision(
91
- input: Omit<ModelRouteDecision, "schemaVersion" | "policyVersion" | "mappingVersion" | "decisionDigest">
93
+ input: Omit<ModelRouteDecision, "schemaVersion" | "policyVersion" | "mappingVersion" | "decisionDigest"> & { mappingVersion?: ModelRouteMappingVersion }
92
94
  ): ModelRouteDecision {
95
+ const { mappingVersion = OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION, ...decisionInput } = input;
93
96
  const payload = {
94
97
  schemaVersion: MODEL_ROUTE_DECISION_SCHEMA_VERSION,
95
98
  policyVersion: MODEL_ROUTE_POLICY_VERSION,
96
- mappingVersion: OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION,
97
- ...structuredClone(input)
99
+ mappingVersion,
100
+ ...structuredClone(decisionInput)
98
101
  } satisfies Omit<ModelRouteDecision, "decisionDigest">;
99
102
  return validateModelRouteDecision({ ...payload, decisionDigest: digestPayload(payload) });
100
103
  }
@@ -108,7 +111,8 @@ export function modelRouteDecisionValidationErrors(input: unknown): string[] {
108
111
  ];
109
112
  if (value.schemaVersion !== MODEL_ROUTE_DECISION_SCHEMA_VERSION
110
113
  || value.policyVersion !== MODEL_ROUTE_POLICY_VERSION
111
- || value.mappingVersion !== OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION) errors.push("model route schema/policy/mapping version is invalid");
114
+ || (value.mappingVersion !== LEGACY_OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION
115
+ && value.mappingVersion !== OPENAI_CODEX_MODEL_ROUTE_MAPPING_VERSION)) errors.push("model route schema/policy/mapping version is invalid");
112
116
  if (typeof value.featureHash !== "string" || !HASH.test(value.featureHash)) errors.push("featureHash must be sha256 hex");
113
117
  if (!PARENT_ROUTING_MODES.includes(value.mode as ParentRoutingMode)) errors.push("mode is invalid");
114
118
  if (!ROUTING_OBJECTIVES.includes(value.objective as RoutingObjective)) errors.push("objective is invalid");
@@ -236,3 +236,23 @@ export function buildOpenAiCodexWireFingerprint(input: {
236
236
  return unavailable(modelId, error instanceof SurfaceBoundError ? error.reasonCode : "surface-not-json");
237
237
  }
238
238
  }
239
+
240
+ // Measurement remains outside the signed fingerprint contract. A new telemetry
241
+ // field must not silently change an existing signed-receipt schema.
242
+ export function measureProviderPayload(payload: unknown) {
243
+ if (!record(payload)) return null;
244
+ try {
245
+ // Validate the entire payload within the existing bounds before measuring.
246
+ // This is the JSON at this hook, not HTTP bytes or proof of a cache hit.
247
+ canonicalJson(payload);
248
+ const serialized = JSON.stringify(payload);
249
+ const measured = JSON.parse(serialized);
250
+ const bytes = (value: unknown) => Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
251
+ const instructionsBytes = bytes(measured.instructions);
252
+ const toolsBytes = bytes(measured.tools);
253
+ const inputBytes = bytes(measured.input);
254
+ const totalBytes = Buffer.byteLength(serialized, "utf8");
255
+ return { basis: "hook-json-utf8" as const, instructionsBytes, toolsBytes, inputBytes,
256
+ remainingBytes: totalBytes - instructionsBytes - toolsBytes - inputBytes, totalBytes, cacheHit: null };
257
+ } catch { return null; }
258
+ }