@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
@@ -4,6 +4,7 @@ import path from "node:path";
4
4
 
5
5
  import { redactForStorage } from "./redaction-core.js";
6
6
  import { ensurePrivateStateDirectory, resolveLocalStatePath } from "./local-state-path.js";
7
+ import { recoveryDecisionValidationErrors } from "./recovery-decision-validation.ts";
7
8
  import { isCurrentWorkingTreeDigest } from "./working-tree-digest.js";
8
9
 
9
10
  export const TASK_JOURNAL_SCHEMA_VERSION = 1;
@@ -47,6 +48,30 @@ function compactId(value, fallback = "unknown") {
47
48
  .slice(0, 160) || fallback;
48
49
  }
49
50
 
51
+ function checkpointMatchesTask(event, task) {
52
+ return typeof task?.taskId === "string" && task.taskId.length > 0
53
+ && typeof task?.taskRunId === "string" && task.taskRunId.length > 0
54
+ && typeof task?.sessionId === "string" && task.sessionId.length > 0
55
+ && event.taskRunId === compactId(task.taskRunId)
56
+ && event.taskId === compactId(task?.taskId)
57
+ && event.sessionId === String(task?.sessionId)
58
+ && event.data?.attempt === task?.attempt;
59
+ }
60
+
61
+ function terminalHandoffCheckpoint(checkpoint, task) {
62
+ const recovery = checkpoint?.evidence?.recovery;
63
+ return checkpoint?.checkpointId === "completion"
64
+ && ["failed", "blocked"].includes(String(checkpoint.status))
65
+ && recoveryDecisionValidationErrors(recovery).length === 0
66
+ && recovery.taskId === task?.taskId
67
+ && recovery.taskRunId === task?.taskRunId
68
+ && recovery.taskAttempt === task?.attempt
69
+ && recovery.action === "handoff"
70
+ && recovery.continuation === "none"
71
+ && recovery.nextPhase === null
72
+ && recovery.sourceMutationAllowed === false;
73
+ }
74
+
50
75
  function safeData(value) {
51
76
  const redacted = redactForStorage(value ?? {});
52
77
  const serialized = JSON.stringify(redacted);
@@ -411,6 +436,9 @@ export function replayTaskCheckpoints(cwd, taskRunId, task) {
411
436
  const checkpoints = new Map();
412
437
  const idempotency = new Set();
413
438
  const corruptions = [...journal.corruptions];
439
+ if (task && compactId(taskRunId) !== compactId(task.taskRunId)) {
440
+ corruptions.push("checkpoint replay taskRunId does not match the Task Contract");
441
+ }
414
442
  const migrationEvents = journal.events.filter((event) => event.eventType === "digest-migrated");
415
443
  const invalidMigration = migrationEvents.find((event) => !validDigestMigrationBarrier(event));
416
444
  if (invalidMigration) corruptions.push(`digest migration sequence ${invalidMigration.sequence}: marker is invalid`);
@@ -422,8 +450,12 @@ export function replayTaskCheckpoints(cwd, taskRunId, task) {
422
450
  ? undefined
423
451
  : [...migrationEvents].reverse().find((event) => digestMigrationBarrierMatchesTask(event, task));
424
452
  for (const event of journal.events) {
425
- if (migrationBarrier && event.sequence <= migrationBarrier.sequence) continue;
426
453
  if (event.eventType !== "checkpoint") continue;
454
+ if (task && !checkpointMatchesTask(event, task)) {
455
+ corruptions.push(`checkpoint sequence ${event.sequence}: identity does not match the Task Contract`);
456
+ continue;
457
+ }
458
+ if (migrationBarrier && event.sequence <= migrationBarrier.sequence) continue;
427
459
  const treeErrors = checkpointTreeDigestValidationErrors(event.data?.evidence);
428
460
  if (treeErrors.length > 0) {
429
461
  corruptions.push(`checkpoint sequence ${event.sequence}: ${treeErrors[0]}`);
@@ -432,14 +464,18 @@ export function replayTaskCheckpoints(cwd, taskRunId, task) {
432
464
  if (event.idempotencyKey && idempotency.has(event.idempotencyKey)) continue;
433
465
  if (event.idempotencyKey) idempotency.add(event.idempotencyKey);
434
466
  const checkpointId = event.checkpointId ?? "checkpoint";
435
- checkpoints.set(checkpointId, {
467
+ const checkpoint = {
436
468
  checkpointId,
437
469
  taskRunId: event.taskRunId,
438
470
  sessionId: event.sessionId,
439
471
  sequence: event.sequence,
440
472
  recordedAt: event.recordedAt,
441
473
  ...event.data
442
- });
474
+ };
475
+ const existing = checkpoints.get(checkpointId);
476
+ if (!terminalHandoffCheckpoint(existing, task) || terminalHandoffCheckpoint(checkpoint, task)) {
477
+ checkpoints.set(checkpointId, checkpoint);
478
+ }
443
479
  }
444
480
  return {
445
481
  taskRunId,
@@ -470,6 +506,15 @@ export function taskRecoveryDecision(task, replay = { checkpoints: [], corruptio
470
506
  };
471
507
  }
472
508
  const checkpoints = Array.isArray(replay.checkpoints) ? replay.checkpoints : [];
509
+ const terminalHandoff = checkpoints.findLast((checkpoint) => terminalHandoffCheckpoint(checkpoint, task));
510
+ if (terminalHandoff) {
511
+ return {
512
+ decision: "blocked",
513
+ retryAllowed: false,
514
+ checkpointId: terminalHandoff.checkpointId,
515
+ reason: `Checkpoint ${terminalHandoff.checkpointId} recorded a terminal recovery handoff; inspect that handoff before any retry.`
516
+ };
517
+ }
473
518
  const contractSteps = Array.isArray(task?.workPlan) ? task.workPlan : [];
474
519
  const contractOpen = contractSteps.findLast((step) => ["in-progress", "failed"].includes(String(step?.status)));
475
520
  const latestOpen = contractOpen
@@ -34,7 +34,8 @@ export function recordMutationCheckpoint(ctx, task, evidence = {}) {
34
34
  export function recordVerificationCheckpoint(ctx, task, verification = {}) {
35
35
  const observation = verification.observedAt ?? task.updatedAt;
36
36
  const preTree = verification.preWorkingTreeDigest ?? verification.evidence?.preWorkingTreeDigest;
37
- const identity = crypto.createHash("sha256").update(JSON.stringify([verification.commandHash, preTree, verification.workingTreeDigest, verification.exitCode, observation])).digest("hex");
37
+ const preRevision = verification.evidence?.preWorkspaceRevisionDigest, revision = verification.evidence?.workspaceRevisionDigest;
38
+ const identity = crypto.createHash("sha256").update(JSON.stringify([verification.commandHash, preTree, verification.workingTreeDigest, verification.exitCode, observation, preRevision, revision])).digest("hex");
38
39
  return recordRuntimeTaskCheckpoint(ctx, {
39
40
  taskRunId: task.taskRunId,
40
41
  taskId: task.taskId,
@@ -45,7 +46,12 @@ export function recordVerificationCheckpoint(ctx, task, verification = {}) {
45
46
  phase: "verify",
46
47
  status: verification.exitCode === 0 ? "done" : "failed",
47
48
  attempt: task.attempt,
48
- evidence: verification.evidence
49
+ evidence: { ...verification.evidence, verificationObservation: {
50
+ command: String(verification.evidence?.command ?? "").trim(), observedAt: observation, exitCode: verification.exitCode,
51
+ ...(preTree ? { preWorkingTreeDigest: preTree } : {}),
52
+ ...(preRevision ? { preWorkspaceRevisionDigest: preRevision } : {}), ...(revision ? { workspaceRevisionDigest: revision } : {}),
53
+ ...(verification.workingTreeDigest ? { workingTreeDigest: verification.workingTreeDigest } : {})
54
+ } }
49
55
  });
50
56
  }
51
57
 
@@ -3,8 +3,7 @@ import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { ensurePrivateStateDirectory, resolveLocalStatePath } from "./local-state-path.js";
5
5
  import { appendTaskJournalEvent, readTaskJournal } from "./task-journal.js";
6
- import {
7
- acceptanceReceiptProvenanceSummary,
6
+ import { acceptanceReceiptProvenanceSummary,
8
7
  acceptanceReceiptSummary,
9
8
  acceptanceReceiptValidationErrors,
10
9
  normalizeAcceptanceReceipt
@@ -12,6 +11,7 @@ import {
12
11
  import { LEGACY_UNTRUSTED_DIGEST_ALGORITHM } from "./task-digest-migration.js";
13
12
  import { criterionGraphValidationErrors, normalizeCriterionGraph } from "./criterion-graph.js";
14
13
  import { normalizeTaskAuthoritySnapshot, taskAuthorityContractValidationErrors } from "./task-authority-contract.js";
14
+ import { normalizeTerminalDisposition, validTerminalDisposition } from "./task-terminal-disposition.js";
15
15
  import {
16
16
  commitLegacySchemaTaskDigestState,
17
17
  migrateUnversionedTaskDigestState,
@@ -21,15 +21,14 @@ import {
21
21
  export { taskDigestMigrationArchiveStatus } from "./task-digest-state.js";
22
22
  import { acceptanceReceiptWithoutWorkingTreeProof, normalizedTaskDigestFields, taskDigestContractValidationErrors } from "./task-digest-contract.js";
23
23
  import { unicodeCodePointLength } from "./verification-intelligence.js";
24
- import {
25
- WORKING_TREE_DIGEST_ALGORITHM,
24
+ import { isWorkspaceRevisionDigest } from "./workspace-revision.js";
25
+ import { WORKING_TREE_DIGEST_ALGORITHM,
26
26
  isCurrentWorkingTreeDigest,
27
27
  isUnavailableWorkingTreeDigest,
28
28
  unavailableWorkingTreeHash,
29
29
  versionWorkingTreeHash
30
30
  } from "./working-tree-digest.js";
31
- import {
32
- directChildGitEvidenceRoots,
31
+ import { directChildGitEvidenceRoots,
33
32
  gitEvidenceRootDetails,
34
33
  gitEvidenceRoots,
35
34
  gitOutput,
@@ -41,7 +40,6 @@ import {
41
40
  prefixedGitPath
42
41
  } from "./workspace-evidence-roots.js";
43
42
  export { isGitWorkingTree } from "./workspace-evidence-roots.js";
44
-
45
43
  export const TASK_CONTRACT_SCHEMA_VERSION = 2; export const DEFAULT_MAX_TASK_ATTEMPTS = 3;
46
44
  export const OPERATOR_REQUEST_MAX_CHARS = 8_000;
47
45
  export const TASK_SUMMARY_MAX_CHARS = 2_000;
@@ -63,8 +61,8 @@ const CITATION_FIELDS = new Set(["path", "reason"]);
63
61
  const WORK_PLAN_FIELDS = new Set(["id", "title", "role", "mode", "status", "dependsOn", "note", "updatedAt"]);
64
62
  const ORCHESTRATION_FIELDS = new Set(["mode", "subagents", "reason", "fieldGuidePath", "modelRoles"]);
65
63
  const MODEL_ROLE_FIELDS = new Set(["planner", "worker", "reviewer", "watchdog"]);
66
- const VERIFY_EVIDENCE_FIELDS = new Set(["command", "exitCode", "summary", "recordedAt", "observed", "observedAt", "isError", "matchedProfileCommand", "preWorkingTreeDigest", "workingTreeDigest"]);
67
- const TRACE_FIELDS = new Set(["outcome", "friction", "notes", "recordedAt"]);
64
+ const VERIFY_EVIDENCE_FIELDS = new Set(["command", "exitCode", "summary", "recordedAt", "observed", "observedAt", "isError", "matchedProfileCommand", "preWorkingTreeDigest", "workingTreeDigest", "preWorkspaceRevisionDigest", "workspaceRevisionDigest"]);
65
+ const TRACE_FIELDS = new Set(["outcome", "terminalDisposition", "friction", "notes", "recordedAt"]);
68
66
  export function safeTaskId(value) {
69
67
  const normalized = String(value ?? "")
70
68
  .trim()
@@ -75,26 +73,21 @@ export function safeTaskId(value) {
75
73
  .replace(/-+$/g, "");
76
74
  return normalized || "task";
77
75
  }
78
-
79
76
  function stateRoot(cwd) { return path.join(cwd, ".pi", "piagent-state"); }
80
77
  function tasksRoot(cwd) { return path.join(stateRoot(cwd), "tasks"); }
81
78
  function sessionsRoot(cwd) { return path.join(stateRoot(cwd), "session-tasks"); }
82
-
83
79
  function taskRunPath(cwd, taskRunId) {
84
80
  return path.join(tasksRoot(cwd), `${safeTaskId(taskRunId)}.json`);
85
81
  }
86
-
87
82
  function sessionBindingPath(cwd, sessionId) {
88
83
  const digest = crypto.createHash("sha256").update(String(sessionId || "unknown")).digest("hex");
89
84
  return path.join(sessionsRoot(cwd), `${digest}.json`);
90
85
  }
91
-
92
86
  function readTaskRun(cwd, taskRunId) {
93
87
  const raw = readJson(cwd, taskRunPath(cwd, taskRunId));
94
88
  const task = normalizeTaskContract(raw, { sourceName: taskRunId });
95
89
  return task?.taskRunId === safeTaskId(taskRunId) ? task : undefined;
96
90
  }
97
-
98
91
  function readJson(cwd, filePath) {
99
92
  try {
100
93
  const safePath = resolveLocalStatePath(cwd, filePath, { label: "Task state", kind: "file" });
@@ -113,21 +106,34 @@ function readJson(cwd, filePath) {
113
106
  return undefined;
114
107
  }
115
108
  }
116
-
117
109
  function writeJsonAtomic(cwd, filePath, value) {
118
110
  const parent = ensurePrivateStateDirectory(cwd, path.dirname(filePath), "Task state directory");
119
111
  const safePath = resolveLocalStatePath(cwd, filePath, { label: "Task state" });
120
112
  const temporary = path.join(parent, `${path.basename(safePath)}.${process.pid}.${crypto.randomBytes(4).toString("hex")}.tmp`);
121
- fs.writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 });
122
- fs.renameSync(temporary, safePath);
123
113
  try {
114
+ const bytes = Buffer.from(`${JSON.stringify(value, null, 2)}\n`);
115
+ const descriptor = fs.openSync(temporary, fs.constants.O_WRONLY | fs.constants.O_CREAT
116
+ | fs.constants.O_EXCL | (fs.constants.O_NOFOLLOW ?? 0), 0o600);
117
+ try {
118
+ for (let offset = 0; offset < bytes.length;) {
119
+ const written = fs.writeSync(descriptor, bytes, offset, bytes.length - offset);
120
+ if (written < 1) throw new Error("Task state write was incomplete");
121
+ offset += written;
122
+ }
123
+ fs.fsyncSync(descriptor);
124
+ } finally {
125
+ fs.closeSync(descriptor);
126
+ }
127
+ fs.renameSync(temporary, safePath);
124
128
  fs.chmodSync(parent, 0o700);
125
129
  fs.chmodSync(safePath, 0o600);
130
+ const directory = fs.openSync(parent, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
131
+ try { fs.fsyncSync(directory); } finally { fs.closeSync(directory); }
126
132
  } catch {
127
- // Best effort on filesystems that do not expose POSIX modes.
133
+ try { fs.unlinkSync(temporary); } catch {}
134
+ throw new Error("Task state atomic persistence failed");
128
135
  }
129
136
  }
130
-
131
137
  function appendTaskStateJournalEvent(cwd, event) {
132
138
  try {
133
139
  return appendTaskJournalEvent(cwd, event);
@@ -137,42 +143,33 @@ function appendTaskStateJournalEvent(cwd, event) {
137
143
  return undefined;
138
144
  }
139
145
  }
140
-
141
146
  function stringArray(value) {
142
147
  return Array.isArray(value) ? [...new Set(value.filter((item) => typeof item === "string" && item.trim()).map((item) => item.trim()))] : [];
143
148
  }
144
-
145
149
  function exactCommandArray(value) {
146
150
  return Array.isArray(value) ? [...new Set(value.filter((item) => typeof item === "string" && item.trim()))] : [];
147
151
  }
148
-
149
152
  function stringRecord(value) {
150
153
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
151
154
  return Object.fromEntries(Object.entries(value)
152
155
  .filter(([key, item]) => key && typeof item === "string")
153
156
  .map(([key, item]) => [key.replaceAll("\\", "/"), item]));
154
157
  }
155
-
156
158
  function positiveInteger(value, fallback, maximum = Number.MAX_SAFE_INTEGER) {
157
159
  return Number.isInteger(value) && value > 0 ? Math.min(value, maximum) : fallback;
158
160
  }
159
-
160
161
  function validTimestamp(value) {
161
162
  return typeof value === "string" && value.trim().length > 0 && Number.isFinite(Date.parse(value));
162
163
  }
163
-
164
164
  export function operatorRequestDigest(value) {
165
165
  return `operator-request-v1:${crypto.createHash("sha256").update(String(value ?? "")).digest("hex")}`;
166
166
  }
167
-
168
167
  function normalizedTimestamp(value, fallback) {
169
168
  return validTimestamp(value) ? value : fallback;
170
169
  }
171
-
172
170
  function isRecord(value) {
173
171
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
174
172
  }
175
-
176
173
  function unsupportedObjectField(value, allowed) {
177
174
  if (!isRecord(value)) return undefined;
178
175
  return Object.keys(value).find((key) => !allowed.has(key));
@@ -226,8 +223,8 @@ export function taskContractValidationErrors(input) {
226
223
  }
227
224
  if (input.failedAt !== undefined && !["research", "plan", "execute", "verify", "review"].includes(input.failedAt)) errors.push("failedAt is invalid");
228
225
  if (!["source-change", "read-only"].includes(input.changeMode)) errors.push("changeMode is invalid");
229
- if (input.mutationPolicy !== undefined && !["required", "forbidden"].includes(input.mutationPolicy)) errors.push("mutationPolicy is invalid");
230
- if (input.changeMode === "read-only" && input.mutationPolicy === "required") errors.push("read-only tasks cannot require mutation");
226
+ if (input.mutationPolicy !== undefined && !["required", "allowed", "forbidden"].includes(input.mutationPolicy)) errors.push("mutationPolicy is invalid");
227
+ if (input.changeMode === "read-only" && input.mutationPolicy !== undefined && input.mutationPolicy !== "forbidden") errors.push("read-only tasks must forbid mutation");
231
228
  if (!["tiny", "normal", "high-risk"].includes(input.riskLane)) errors.push("riskLane is invalid");
232
229
  if (input.intakeMode !== undefined && !["model", "runtime"].includes(input.intakeMode)) errors.push("intakeMode is invalid");
233
230
  errors.push(...taskDigestContractValidationErrors(input));
@@ -329,13 +326,16 @@ export function taskContractValidationErrors(input) {
329
326
  || (item.matchedProfileCommand !== undefined && typeof item.matchedProfileCommand !== "boolean")
330
327
  || (item.preWorkingTreeDigest !== undefined && !isCurrentWorkingTreeDigest(item.preWorkingTreeDigest))
331
328
  || (item.workingTreeDigest !== undefined && !isCurrentWorkingTreeDigest(item.workingTreeDigest))
329
+ || (item.preWorkspaceRevisionDigest !== undefined && !isWorkspaceRevisionDigest(item.preWorkspaceRevisionDigest))
330
+ || (item.workspaceRevisionDigest !== undefined && !isWorkspaceRevisionDigest(item.workspaceRevisionDigest))
332
331
  ))) {
333
332
  errors.push("verifyEvidence entries are invalid");
334
333
  }
335
334
  if (!isRecord(input.trace) || unsupportedObjectField(input.trace, TRACE_FIELDS) || !TASK_OUTCOMES.includes(input.trace.outcome)) {
336
335
  errors.push("trace.outcome is invalid");
337
- } else if (input.trace.recordedAt !== undefined && !validTimestamp(input.trace.recordedAt)) {
338
- errors.push("trace.recordedAt must be a valid timestamp");
336
+ } else {
337
+ if (!validTerminalDisposition(input.trace)) errors.push("trace.terminalDisposition is invalid");
338
+ if (input.trace.recordedAt !== undefined && !validTimestamp(input.trace.recordedAt)) errors.push("trace.recordedAt must be a valid timestamp");
339
339
  }
340
340
  if (input.orchestration !== undefined) {
341
341
  const orchestration = input.orchestration;
@@ -411,7 +411,9 @@ export function normalizeTaskContract(input, options = {}) {
411
411
  isError: item.isError,
412
412
  matchedProfileCommand: item.matchedProfileCommand,
413
413
  preWorkingTreeDigest: item.preWorkingTreeDigest,
414
- workingTreeDigest: item.workingTreeDigest
414
+ workingTreeDigest: item.workingTreeDigest,
415
+ preWorkspaceRevisionDigest: item.preWorkspaceRevisionDigest,
416
+ workspaceRevisionDigest: item.workspaceRevisionDigest
415
417
  } : item)
416
418
  : [];
417
419
  const normalized = {
@@ -421,7 +423,9 @@ export function normalizeTaskContract(input, options = {}) {
421
423
  sessionId,
422
424
  sessionName: String(input.sessionName ?? options.sessionName ?? "").trim() || undefined,
423
425
  changeMode: input.changeMode === "read-only" ? "read-only" : "source-change",
424
- mutationPolicy: input.changeMode === "read-only" || input.mutationPolicy === "forbidden" ? "forbidden" : "required",
426
+ mutationPolicy: input.changeMode === "read-only" || input.mutationPolicy === "forbidden"
427
+ ? "forbidden"
428
+ : input.mutationPolicy === "allowed" ? "allowed" : "required",
425
429
  attempt: positiveInteger(input.attempt, 1, 100),
426
430
  maxAttempts: positiveInteger(input.maxAttempts, DEFAULT_MAX_TASK_ATTEMPTS, 10),
427
431
  previousAttempts: Array.isArray(input.previousAttempts) ? input.previousAttempts.slice(-10).map((item) => pickFields(item, PREVIOUS_ATTEMPT_FIELDS)) : [],
@@ -463,6 +467,7 @@ export function normalizeTaskContract(input, options = {}) {
463
467
  verifyEvidence: legacyDigestContract ? [] : verifyEvidence,
464
468
  trace: {
465
469
  outcome: legacyDigestContract && trace.outcome === "pending" ? "blocked" : TASK_OUTCOMES.includes(trace.outcome) ? trace.outcome : "pending",
470
+ terminalDisposition: normalizeTerminalDisposition(trace),
466
471
  friction: legacyDigestContract && trace.outcome === "pending" ? "Legacy working-tree evidence is not replayable; start a new attempt." : typeof trace.friction === "string" ? trace.friction : undefined,
467
472
  notes: typeof trace.notes === "string" ? trace.notes : undefined,
468
473
  recordedAt: legacyDigestContract && trace.outcome === "pending" ? updatedAt : trace.recordedAt === undefined ? undefined : normalizedTimestamp(trace.recordedAt, updatedAt)
@@ -524,6 +529,37 @@ export function writeTaskContract(cwd, task) {
524
529
  return normalized;
525
530
  }
526
531
 
532
+ /** Confirms the exact normalized task bytes through a stable, fsync-backed read. */
533
+ export function durableTaskContractMatches(cwd, expected) {
534
+ try {
535
+ const normalized = normalizeTaskContract(expected);
536
+ if (!normalized || taskContractValidationErrors(normalized).length > 0) return false;
537
+ const safePath = resolveLocalStatePath(cwd, taskRunPath(cwd, normalized.taskRunId), {
538
+ label: "Task state", kind: "file"
539
+ });
540
+ const descriptor = fs.openSync(safePath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW ?? 0));
541
+ try {
542
+ fs.fsyncSync(descriptor);
543
+ const before = fs.fstatSync(descriptor, { bigint: true });
544
+ if (!before.isFile() || before.nlink !== 1n || before.size < 1n
545
+ || before.size > BigInt(8 * 1024 * 1024)) return false;
546
+ const bytes = fs.readFileSync(descriptor);
547
+ const after = fs.fstatSync(descriptor, { bigint: true });
548
+ const atPath = fs.lstatSync(safePath, { bigint: true });
549
+ const fields = ["dev", "ino", "mode", "nlink", "size", "mtimeNs", "ctimeNs"];
550
+ if (bytes.length !== Number(before.size) || atPath.isSymbolicLink()
551
+ || fields.some((field) => before[field] !== after[field] || after[field] !== atPath[field])) return false;
552
+ const observed = normalizeTaskContract(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)));
553
+ return observed?.taskRunId === normalized.taskRunId
554
+ && JSON.stringify(observed) === JSON.stringify(normalized);
555
+ } finally {
556
+ fs.closeSync(descriptor);
557
+ }
558
+ } catch {
559
+ return false;
560
+ }
561
+ }
562
+
527
563
  export function listTaskContracts(cwd) {
528
564
  const root = resolveLocalStatePath(cwd, tasksRoot(cwd), { label: "Task state directory" });
529
565
  if (!fs.existsSync(root)) return [];
@@ -619,9 +655,9 @@ function gitHasHead(cwd) {
619
655
  }
620
656
  }
621
657
 
622
- function workingTreeFilesForGitRoot(cwd, observeRename) {
623
- if (!isGitWorkingTree(cwd)) return [];
624
- const changed = gitHasHead(cwd)
658
+ function workingTreeFilesForGitRoot(cwd, observeRename, knownHead = null) {
659
+ if (knownHead === null && !isGitWorkingTree(cwd)) return [];
660
+ const changed = (knownHead ?? gitHasHead(cwd))
625
661
  ? changedPathsFromNameStatus(gitOutput(cwd, ["diff", "--name-status", "-z", "--find-renames", "--diff-filter=ACMRD", "HEAD", "--"]), observeRename)
626
662
  : gitOutput(cwd, ["ls-files", "-z"]).split("\0").filter(Boolean);
627
663
  const untracked = gitOutput(cwd, ["ls-files", "--others", "--exclude-standard", "-z"]).split("\0").filter(Boolean);
@@ -820,7 +856,7 @@ export function workingTreeSnapshot(cwd, options = {}) {
820
856
  paths.forEach((file) => protectedAliases.add(file));
821
857
  };
822
858
  try {
823
- const hasHead = gitHasHead(root.cwd); for (const file of workingTreeFilesForGitRoot(root.cwd, observeRename)) {
859
+ const hasHead = gitHasHead(root.cwd); for (const file of workingTreeFilesForGitRoot(root.cwd, observeRename, hasHead)) {
824
860
  const projectPath = prefixedGitPath(root.prefix, file);
825
861
  snapshot[projectPath] = streamedWorkingTreeFileDigest(root.cwd, file, hasHead, isProtectedProjectPath(projectPath) || protectedAliases.has(file) ? projectPath : null);
826
862
  }
@@ -0,0 +1,10 @@
1
+ /** @param {Record<string, unknown>} trace */
2
+ export function validTerminalDisposition(trace) {
3
+ return trace.terminalDisposition === undefined
4
+ || trace.terminalDisposition === "refused" && trace.outcome === "blocked";
5
+ }
6
+
7
+ /** @param {Record<string, unknown>} trace @returns {"refused" | undefined} */
8
+ export function normalizeTerminalDisposition(trace) {
9
+ return trace.terminalDisposition === "refused" && trace.outcome === "blocked" ? "refused" : undefined;
10
+ }
@@ -0,0 +1,5 @@
1
+ export const TRAJECTORY_PHASES = Object.freeze([
2
+ "intake", "scout", "plan", "execute", "verify", "repair", "review", "handoff", "terminal"
3
+ ] as const);
4
+
5
+ export type TrajectoryPhase = typeof TRAJECTORY_PHASES[number];
@@ -11,7 +11,8 @@ import {
11
11
  validateFailureClassification,
12
12
  validateFailureEvidence
13
13
  } from "./failure-types.ts";
14
- import { isCurrentWorkingTreeDigest } from "./working-tree-digest.js";
14
+ import { isCurrentWorkingTreeDigest, WORKING_TREE_DIGEST_ALGORITHM } from "./working-tree-digest.js";
15
+ import { currentWorkspaceRevisionDigest, isWorkspaceRevisionDigest } from "./workspace-revision.js";
15
16
 
16
17
  export const MAX_VERIFY_COMMANDS = 2;
17
18
  export const MAX_VERIFY_COMMAND_CHARS = 900;
@@ -96,13 +97,18 @@ export function latestObservedVerification(evidence = []) {
96
97
  return latest;
97
98
  }
98
99
 
99
- export function verificationEvidenceProvesStableTree(entry, digest) {
100
+ export function verificationEvidenceProvesStableTree(entry, digest, workspaceRevisionDigest) {
101
+ const revisionRequired = workspaceRevisionDigest !== undefined
102
+ || entry?.preWorkspaceRevisionDigest !== undefined || entry?.workspaceRevisionDigest !== undefined;
100
103
  return isCurrentWorkingTreeDigest(digest)
101
104
  && entry?.observed === true
102
105
  && entry.matchedProfileCommand === true
103
106
  && entry.exitCode === 0
107
+ && entry.isError !== true
104
108
  && entry.preWorkingTreeDigest === digest
105
- && entry.workingTreeDigest === digest;
109
+ && entry.workingTreeDigest === digest
110
+ && (!revisionRequired || (isWorkspaceRevisionDigest(workspaceRevisionDigest)
111
+ && entry.preWorkspaceRevisionDigest === workspaceRevisionDigest && entry.workspaceRevisionDigest === workspaceRevisionDigest));
106
112
  }
107
113
 
108
114
  export function verificationRunIdentity(cwd, command, changedFiles = []) {
@@ -116,6 +122,24 @@ export function verificationRunIdentity(cwd, command, changedFiles = []) {
116
122
  .digest("hex");
117
123
  }
118
124
 
125
+ export function verificationEvidenceProvesCurrentWorkspace(entry, digest, cwd) {
126
+ return verificationEvidenceProvesStableTree(entry, digest, currentWorkspaceRevisionDigest(cwd));
127
+ }
128
+
129
+ /** Historical projections are readable; they do not grant runtime completion/reuse. */
130
+ export function verificationProjectionWorkspaceRevision(task, options = {}) {
131
+ return options.workspaceRevisionDigest !== undefined ? options.workspaceRevisionDigest
132
+ : task?.verifyEvidence?.some((entry) => entry.preWorkspaceRevisionDigest !== undefined || entry.workspaceRevisionDigest !== undefined)
133
+ ? currentWorkspaceRevisionDigest(options.cwd) : undefined;
134
+ }
135
+
136
+ export function allConfiguredVerifierEvidenceCurrent(task, digest, workspaceRevisionDigest) {
137
+ if (task?.workingTreeDigestAlgorithm !== WORKING_TREE_DIGEST_ALGORITHM || !isCurrentWorkingTreeDigest(digest)) return false;
138
+ const commands = meaningfulVerificationCommands(task?.verifyCommands ?? []);
139
+ const latest = latestObservedVerificationEvidence(task?.verifyEvidence);
140
+ return commands.length > 0 && commands.every((command) => verificationEvidenceProvesStableTree(latest.get(command.trim()), digest, workspaceRevisionDigest));
141
+ }
142
+
119
143
  const STRUCTURED_SIGNALS = {
120
144
  "scope-violation": "structured-scope",
121
145
  "protected-path": "structured-protected-path",
@@ -125,7 +149,8 @@ const STRUCTURED_SIGNALS = {
125
149
  environment: "structured-environment",
126
150
  "flaky-infrastructure": "structured-flaky-infrastructure",
127
151
  "stale-verifier": "structured-stale-verifier",
128
- "missing-verifier": "structured-missing-verifier"
152
+ "missing-verifier": "structured-missing-verifier",
153
+ "verification-gap": "structured-verification-gap"
129
154
  };
130
155
 
131
156
  function parsedSignals(text, exitCode, structuredEvents) {
@@ -189,6 +214,7 @@ function categoryForEvidence(evidence) {
189
214
  if (signals.has("structured-provider") || signals.has("provider-rate-limit") || signals.has("provider-transport")) return "provider-network";
190
215
  if (signals.has("structured-environment") || signals.has("environment-diagnostic")) return "environment";
191
216
  if (signals.has("structured-flaky-infrastructure") || signals.has("local-port-conflict") || signals.has("transient-infrastructure")) return "flaky-infrastructure";
217
+ if (signals.has("structured-verification-gap")) return "unknown";
192
218
  if (signals.has("structured-stale-verifier") || signals.has("structured-missing-verifier") || signals.has("dependency-config-diagnostic")) return "dependency-config";
193
219
  if (["typescript-diagnostic", "python-type-diagnostic", "go-compile-diagnostic", "rust-compile-diagnostic", "generic-compile-diagnostic"].some((signal) => signals.has(signal))) return "compile-typecheck";
194
220
  if (signals.has("test-assertion-diagnostic")) return "test-assertion";
@@ -250,16 +276,42 @@ export function classifyCompletionGateFailure(missing = [], summary = "", exitCo
250
276
  });
251
277
  }
252
278
  if (missingItems.some((item) => /^critical acceptance evidence\b/i.test(item))) {
253
- return classifyVerificationFailure("AssertionError: critical acceptance behavioral proof is missing", 1);
279
+ // A missing proof is not an observed assertion failure. In particular,
280
+ // analyzer abstention cannot fabricate source-repair eligibility.
281
+ return classifyVerificationFailure("Completion gate lacks required behavioral verification evidence.", 1, {
282
+ structuredEvents: ["verification-gap"]
283
+ });
254
284
  }
255
285
  return classifyRecordedVerificationFailure(summary, exitCode);
256
286
  }
257
287
 
258
288
  export function selectCompletionRecoveryClassification(recordedClassification, missing = [], summary = "", exitCode = 1) {
259
289
  const gateClassification = classifyCompletionGateFailure(missing, summary, exitCode);
260
- return gateClassification.category === "scope-protected-path"
261
- ? gateClassification
262
- : recordedClassification ?? gateClassification;
290
+ if (gateClassification.category === "scope-protected-path" || exitCode === 0) return gateClassification;
291
+ try { return recordedClassification ? validateFailureClassification(recordedClassification) : gateClassification; }
292
+ catch { return gateClassification; }
293
+ }
294
+
295
+ /** Reuse a checkpoint classification only for the exact current failed run. */
296
+ export function recordedFailureForObservation(checkpoints, observed, currentTreeDigest, workspaceRevisionDigest) {
297
+ if (observed?.observed !== true || observed.matchedProfileCommand !== true || observed.exitCode === 0
298
+ || !isCurrentWorkingTreeDigest(observed.preWorkingTreeDigest) || observed.preWorkingTreeDigest !== observed.workingTreeDigest
299
+ || (currentTreeDigest !== undefined && currentTreeDigest !== observed.workingTreeDigest)) return undefined;
300
+ const revisionRequired = workspaceRevisionDigest !== undefined || observed.preWorkspaceRevisionDigest !== undefined || observed.workspaceRevisionDigest !== undefined;
301
+ if (revisionRequired && (!isWorkspaceRevisionDigest(workspaceRevisionDigest)
302
+ || observed.preWorkspaceRevisionDigest !== workspaceRevisionDigest || observed.workspaceRevisionDigest !== workspaceRevisionDigest)) return undefined;
303
+ const observedAt = observed.observedAt ?? observed.recordedAt;
304
+ if (typeof observedAt !== "string" || !Number.isFinite(Date.parse(observedAt))) return undefined;
305
+ const checkpoint = (Array.isArray(checkpoints) ? checkpoints : []).filter((item) => {
306
+ const binding = item?.evidence?.verificationObservation;
307
+ return item?.phase === "verify" && item.status === "failed" && binding
308
+ && binding.command === observed.command?.trim() && binding.observedAt === observedAt
309
+ && binding.exitCode === observed.exitCode && binding.preWorkingTreeDigest === observed.preWorkingTreeDigest
310
+ && binding.workingTreeDigest === observed.workingTreeDigest
311
+ && (!revisionRequired || (binding.preWorkspaceRevisionDigest === workspaceRevisionDigest && binding.workspaceRevisionDigest === workspaceRevisionDigest));
312
+ }).at(-1);
313
+ try { return checkpoint ? validateFailureClassification(checkpoint.evidence.failureClassification) : undefined; }
314
+ catch { return undefined; }
263
315
  }
264
316
 
265
317
  export function chooseVerificationScope(profileVerifyCommands = {}, changedFiles = []) {
@@ -0,0 +1,98 @@
1
+ export const WORKFLOW_IDS = [
2
+ "task",
3
+ "scout",
4
+ "be-to-fe",
5
+ "discuss",
6
+ "plan",
7
+ "review",
8
+ "commit",
9
+ "pr",
10
+ "onboard",
11
+ "platform-improve"
12
+ ] as const;
13
+
14
+ export type WorkflowId = typeof WORKFLOW_IDS[number];
15
+ export type ContextWorkflow = "task" | "scout" | "discuss" | "plan" | "review" | "release" | "onboard"
16
+ | "usage" | "permission" | "context";
17
+
18
+ export type WorkflowOption = {
19
+ id: WorkflowId;
20
+ aliases: readonly string[];
21
+ label: string;
22
+ description: string;
23
+ argumentHint: string;
24
+ requestRequired: boolean;
25
+ contextWorkflow: ContextWorkflow;
26
+ changeMode: "source-change" | "read-only" | "plan-only" | "clarification" | "git" | "onboarding" | "platform";
27
+ modelUse: "required";
28
+ recommendedFreshSession: boolean;
29
+ };
30
+
31
+ /** Surface-neutral workflow truth shared by context classification and runtime ingress. */
32
+ export const WORKFLOW_OPTIONS: readonly WorkflowOption[] = [
33
+ { id: "task", aliases: ["task", "implement"], label: "Task", description: "Implement a bounded task", argumentHint: "<request>", requestRequired: true, contextWorkflow: "task", changeMode: "source-change", modelUse: "required", recommendedFreshSession: true },
34
+ { id: "scout", aliases: ["scout", "audit"], label: "Scout", description: "Read-only audit or research", argumentHint: "<area/spec/risk>", requestRequired: true, contextWorkflow: "scout", changeMode: "read-only", modelUse: "required", recommendedFreshSession: true },
35
+ { id: "be-to-fe", aliases: ["be-to-fe", "befe"], label: "BE → FE", description: "Implement frontend from a backend contract", argumentHint: "<BE spec/change + FE outcome>", requestRequired: true, contextWorkflow: "task", changeMode: "source-change", modelUse: "required", recommendedFreshSession: true },
36
+ { id: "discuss", aliases: ["discuss", "clarify"], label: "Discuss", description: "Clarify before planning or editing", argumentHint: "<rough idea>", requestRequired: true, contextWorkflow: "discuss", changeMode: "clarification", modelUse: "required", recommendedFreshSession: false },
37
+ { id: "plan", aliases: ["plan"], label: "Plan", description: "Create an implementation plan", argumentHint: "<goal>", requestRequired: true, contextWorkflow: "plan", changeMode: "plan-only", modelUse: "required", recommendedFreshSession: false },
38
+ { id: "review", aliases: ["review"], label: "Review", description: "Review a diff or source read-only", argumentHint: "<target or diff>", requestRequired: true, contextWorkflow: "review", changeMode: "read-only", modelUse: "required", recommendedFreshSession: false },
39
+ { id: "commit", aliases: ["commit"], label: "Commit", description: "Run the guarded local commit workflow", argumentHint: "[message]", requestRequired: false, contextWorkflow: "release", changeMode: "git", modelUse: "required", recommendedFreshSession: false },
40
+ { id: "pr", aliases: ["pr"], label: "PR", description: "Prepare a guarded pull request", argumentHint: "[title]", requestRequired: false, contextWorkflow: "release", changeMode: "git", modelUse: "required", recommendedFreshSession: false },
41
+ { id: "onboard", aliases: ["onboard", "onboard-project"], label: "Onboard", description: "Run first-read project onboarding", argumentHint: "[focus]", requestRequired: false, contextWorkflow: "onboard", changeMode: "onboarding", modelUse: "required", recommendedFreshSession: true },
42
+ { id: "platform-improve", aliases: ["platform-improve", "platform"], label: "Platform improve", description: "Improve Pi Agent Platform itself", argumentHint: "<goal + affected area>", requestRequired: true, contextWorkflow: "task", changeMode: "platform", modelUse: "required", recommendedFreshSession: true }
43
+ ] as const;
44
+
45
+ export const WORKFLOW_ALIASES: Readonly<Record<string, WorkflowId>> = Object.freeze(Object.fromEntries(
46
+ WORKFLOW_OPTIONS.flatMap((option) => option.aliases.map((alias) => [alias, option.id] as const))
47
+ ));
48
+
49
+ export function resolveWorkflowId(value: unknown): WorkflowId | null {
50
+ if (typeof value !== "string") return null;
51
+ return WORKFLOW_ALIASES[value.trim().toLowerCase()] ?? null;
52
+ }
53
+
54
+ export function workflowOption(value: unknown): WorkflowOption | null {
55
+ const id = resolveWorkflowId(value);
56
+ return id ? WORKFLOW_OPTIONS.find((option) => option.id === id) ?? null : null;
57
+ }
58
+
59
+ export function workflowCommandNames(options: { aliases?: boolean } = {}): string[] {
60
+ return options.aliases === false ? [...WORKFLOW_IDS] : Object.keys(WORKFLOW_ALIASES);
61
+ }
62
+
63
+ function escapedPattern(value: string): string {
64
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
65
+ }
66
+
67
+ /** A regex fragment derived from the catalog, for command/projection boundaries. */
68
+ export function workflowCommandPattern(options: { aliases?: boolean } = {}): string {
69
+ return workflowCommandNames(options).sort((left, right) => right.length - left.length)
70
+ .map(escapedPattern).join("|");
71
+ }
72
+
73
+ const NAMESPACED_WORKFLOW_COMMAND = new RegExp(
74
+ `^/(?:piagent-workflow|workflow)\\s+(${workflowCommandPattern()})(?=\\s|$)\\s*`, "i"
75
+ );
76
+ const DIRECT_WORKFLOW_COMMAND = new RegExp(
77
+ `^/(${workflowCommandPattern({ aliases: false })})(?=\\s|$)\\s*`, "i"
78
+ );
79
+
80
+ export function workflowIdFromCommand(input: unknown): WorkflowId | null {
81
+ const normalized = String(input ?? "").trim();
82
+ const match = NAMESPACED_WORKFLOW_COMMAND.exec(normalized) ?? DIRECT_WORKFLOW_COMMAND.exec(normalized);
83
+ return resolveWorkflowId(match?.[1]);
84
+ }
85
+
86
+ export function stripWorkflowCommand(input: string): string {
87
+ return String(input ?? "").replace(NAMESPACED_WORKFLOW_COMMAND, "").replace(DIRECT_WORKFLOW_COMMAND, "").trim();
88
+ }
89
+
90
+ export function workflowHelpLines(): string[] {
91
+ const aliasLines = WORKFLOW_OPTIONS.flatMap((option) => option.aliases.filter((alias) => alias !== option.id)
92
+ .map((alias) => `/workflow ${alias} → ${option.id}`));
93
+ return [
94
+ "namespace: /workflow",
95
+ ...WORKFLOW_OPTIONS.map((option) => `${option.id}: /workflow ${option.id} ${option.argumentHint} — ${option.description}`),
96
+ `aliases: ${aliasLines.join(" | ") || "none"}`
97
+ ];
98
+ }