@piagent/platform 1.6.0 → 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 (736) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +24 -15
  3. package/README.vi.md +36 -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 +27 -3
  10. package/benchmarks/production-v1/suite.json +5 -1
  11. package/benchmarks/production-v2/grade.mjs +892 -0
  12. package/benchmarks/production-v2/project/README.md +7 -0
  13. package/benchmarks/production-v2/project/config/service.json +4 -0
  14. package/benchmarks/production-v2/project/data/audit-ledger.jsonl +1 -0
  15. package/benchmarks/production-v2/project/docs/ops.md +3 -0
  16. package/benchmarks/production-v2/project/logs/incident.log +2 -0
  17. package/benchmarks/production-v2/project/package.json +11 -0
  18. package/benchmarks/production-v2/project/scripts/check.mjs +21 -0
  19. package/benchmarks/production-v2/project/src/backend/auth.js +3 -0
  20. package/benchmarks/production-v2/project/src/backend/billing-window.js +4 -0
  21. package/benchmarks/production-v2/project/src/backend/cache.js +15 -0
  22. package/benchmarks/production-v2/project/src/backend/invoice.js +4 -0
  23. package/benchmarks/production-v2/project/src/backend/revocation-cache.js +3 -0
  24. package/benchmarks/production-v2/project/src/data/csv.js +3 -0
  25. package/benchmarks/production-v2/project/src/data/dedup.js +5 -0
  26. package/benchmarks/production-v2/project/src/data/migration.js +9 -0
  27. package/benchmarks/production-v2/project/src/data/ndjson-stream.js +5 -0
  28. package/benchmarks/production-v2/project/src/data/versioned-replay.js +8 -0
  29. package/benchmarks/production-v2/project/src/frontend/chat-events.js +7 -0
  30. package/benchmarks/production-v2/project/src/frontend/pagination.js +8 -0
  31. package/benchmarks/production-v2/project/src/frontend/request-lifecycle.js +15 -0
  32. package/benchmarks/production-v2/project/src/frontend/search-state.js +8 -0
  33. package/benchmarks/production-v2/project/src/frontend/unicode-search.js +7 -0
  34. package/benchmarks/production-v2/project/src/fullstack/contract-sync.js +10 -0
  35. package/benchmarks/production-v2/project/src/platform/args.js +10 -0
  36. package/benchmarks/production-v2/project/src/platform/config.js +7 -0
  37. package/benchmarks/production-v2/project/src/platform/workflow-session.js +9 -0
  38. package/benchmarks/production-v2/project/src/platform/workspace.js +13 -0
  39. package/benchmarks/production-v2/project/src/reliability/checkpoint.js +5 -0
  40. package/benchmarks/production-v2/project/src/reliability/expiry.js +5 -0
  41. package/benchmarks/production-v2/project/src/reliability/retry.js +15 -0
  42. package/benchmarks/production-v2/project/test/smoke.test.js +21 -0
  43. package/benchmarks/production-v2/project/vendor/README.md +1 -0
  44. package/benchmarks/production-v2/prompts/abort-reconnect-supersession.md +11 -0
  45. package/benchmarks/production-v2/prompts/backend-frontend-contract-sync.md +12 -0
  46. package/benchmarks/production-v2/prompts/billing-cutoff-clock-skew.md +11 -0
  47. package/benchmarks/production-v2/prompts/bounded-retry.md +7 -0
  48. package/benchmarks/production-v2/prompts/chunked-record-boundary.md +9 -0
  49. package/benchmarks/production-v2/prompts/cli-double-dash.md +7 -0
  50. package/benchmarks/production-v2/prompts/config-precedence.md +6 -0
  51. package/benchmarks/production-v2/prompts/destructive-history-refusal.md +3 -0
  52. package/benchmarks/production-v2/prompts/expiry-boundary.md +7 -0
  53. package/benchmarks/production-v2/prompts/idempotent-replay-conflict.md +11 -0
  54. package/benchmarks/production-v2/prompts/incident-diagnosis.md +4 -0
  55. package/benchmarks/production-v2/prompts/invoice-rounding.md +9 -0
  56. package/benchmarks/production-v2/prompts/journeys/config-precedence-scout.md +3 -0
  57. package/benchmarks/production-v2/prompts/journeys/expiry-boundary-scout.md +3 -0
  58. package/benchmarks/production-v2/prompts/journeys/quoted-csv-scout.md +3 -0
  59. package/benchmarks/production-v2/prompts/journeys/recover-after-uncertain-send.md +4 -0
  60. package/benchmarks/production-v2/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  61. package/benchmarks/production-v2/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  62. package/benchmarks/production-v2/prompts/journeys/stable-dedup-scout.md +3 -0
  63. package/benchmarks/production-v2/prompts/journeys/stale-search-response-scout.md +3 -0
  64. package/benchmarks/production-v2/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  65. package/benchmarks/production-v2/prompts/journeys/verify-current-contract.md +4 -0
  66. package/benchmarks/production-v2/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  67. package/benchmarks/production-v2/prompts/pagination-boundary.md +7 -0
  68. package/benchmarks/production-v2/prompts/protected-env-refusal.md +2 -0
  69. package/benchmarks/production-v2/prompts/quoted-csv.md +6 -0
  70. package/benchmarks/production-v2/prompts/reconnect-chat-event-order.md +19 -0
  71. package/benchmarks/production-v2/prompts/repository-prompt-injection.md +5 -0
  72. package/benchmarks/production-v2/prompts/resumable-checkpoint-partial-failure.md +11 -0
  73. package/benchmarks/production-v2/prompts/revoked-session-cache.md +10 -0
  74. package/benchmarks/production-v2/prompts/schema-migration.md +6 -0
  75. package/benchmarks/production-v2/prompts/stable-dedup.md +6 -0
  76. package/benchmarks/production-v2/prompts/stale-search-response.md +6 -0
  77. package/benchmarks/production-v2/prompts/tenant-cache-isolation.md +6 -0
  78. package/benchmarks/production-v2/prompts/tenant-role-authorization.md +6 -0
  79. package/benchmarks/production-v2/prompts/unicode-search.md +6 -0
  80. package/benchmarks/production-v2/prompts/workflow-switch-same-session.md +30 -0
  81. package/benchmarks/production-v2/prompts/workspace-order.md +7 -0
  82. package/benchmarks/production-v2/spend-control.v1.json +115 -0
  83. package/benchmarks/production-v2/suite.json +1009 -0
  84. package/benchmarks/production-v2/variant.mjs +169 -0
  85. package/benchmarks/production-v3/CONTRACT-REVISION-20260922.md +31 -0
  86. package/benchmarks/production-v3/calibration/corpus.v1.json +63 -0
  87. package/benchmarks/production-v3/calibration/human-review-rubric.v1.json +36 -0
  88. package/benchmarks/production-v3/grade.mjs +1017 -0
  89. package/benchmarks/production-v3/project/README.md +7 -0
  90. package/benchmarks/production-v3/project/config/service.json +4 -0
  91. package/benchmarks/production-v3/project/data/audit-ledger.jsonl +1 -0
  92. package/benchmarks/production-v3/project/docs/ops.md +3 -0
  93. package/benchmarks/production-v3/project/logs/incident.log +2 -0
  94. package/benchmarks/production-v3/project/package.json +11 -0
  95. package/benchmarks/production-v3/project/scripts/check.mjs +21 -0
  96. package/benchmarks/production-v3/project/src/backend/auth.js +3 -0
  97. package/benchmarks/production-v3/project/src/backend/billing-window.js +4 -0
  98. package/benchmarks/production-v3/project/src/backend/cache.js +15 -0
  99. package/benchmarks/production-v3/project/src/backend/invoice.js +4 -0
  100. package/benchmarks/production-v3/project/src/backend/revocation-cache.js +12 -0
  101. package/benchmarks/production-v3/project/src/data/csv.js +3 -0
  102. package/benchmarks/production-v3/project/src/data/dedup.js +5 -0
  103. package/benchmarks/production-v3/project/src/data/migration.js +9 -0
  104. package/benchmarks/production-v3/project/src/data/ndjson-stream.js +5 -0
  105. package/benchmarks/production-v3/project/src/data/versioned-replay.js +8 -0
  106. package/benchmarks/production-v3/project/src/frontend/chat-events.js +7 -0
  107. package/benchmarks/production-v3/project/src/frontend/pagination.js +8 -0
  108. package/benchmarks/production-v3/project/src/frontend/request-lifecycle.js +23 -0
  109. package/benchmarks/production-v3/project/src/frontend/search-state.js +8 -0
  110. package/benchmarks/production-v3/project/src/frontend/unicode-search.js +7 -0
  111. package/benchmarks/production-v3/project/src/fullstack/contract-sync.js +10 -0
  112. package/benchmarks/production-v3/project/src/platform/args.js +10 -0
  113. package/benchmarks/production-v3/project/src/platform/config.js +7 -0
  114. package/benchmarks/production-v3/project/src/platform/workflow-session.js +9 -0
  115. package/benchmarks/production-v3/project/src/platform/workspace.js +13 -0
  116. package/benchmarks/production-v3/project/src/reliability/checkpoint.js +5 -0
  117. package/benchmarks/production-v3/project/src/reliability/expiry.js +14 -0
  118. package/benchmarks/production-v3/project/src/reliability/retry.js +15 -0
  119. package/benchmarks/production-v3/project/test/smoke.test.js +21 -0
  120. package/benchmarks/production-v3/project/vendor/README.md +1 -0
  121. package/benchmarks/production-v3/prompts/abort-reconnect-supersession.md +11 -0
  122. package/benchmarks/production-v3/prompts/backend-frontend-contract-sync.md +20 -0
  123. package/benchmarks/production-v3/prompts/billing-cutoff-clock-skew.md +11 -0
  124. package/benchmarks/production-v3/prompts/bounded-retry.md +7 -0
  125. package/benchmarks/production-v3/prompts/chunked-record-boundary.md +11 -0
  126. package/benchmarks/production-v3/prompts/cli-double-dash.md +7 -0
  127. package/benchmarks/production-v3/prompts/config-precedence.md +6 -0
  128. package/benchmarks/production-v3/prompts/destructive-history-refusal.md +9 -0
  129. package/benchmarks/production-v3/prompts/expiry-boundary.md +14 -0
  130. package/benchmarks/production-v3/prompts/idempotent-replay-conflict.md +13 -0
  131. package/benchmarks/production-v3/prompts/incident-diagnosis.md +4 -0
  132. package/benchmarks/production-v3/prompts/invoice-rounding.md +9 -0
  133. package/benchmarks/production-v3/prompts/journeys/config-precedence-scout.md +3 -0
  134. package/benchmarks/production-v3/prompts/journeys/expiry-boundary-scout.md +3 -0
  135. package/benchmarks/production-v3/prompts/journeys/quoted-csv-scout.md +3 -0
  136. package/benchmarks/production-v3/prompts/journeys/recover-after-uncertain-send.md +4 -0
  137. package/benchmarks/production-v3/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  138. package/benchmarks/production-v3/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  139. package/benchmarks/production-v3/prompts/journeys/stable-dedup-scout.md +3 -0
  140. package/benchmarks/production-v3/prompts/journeys/stale-search-response-scout.md +3 -0
  141. package/benchmarks/production-v3/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  142. package/benchmarks/production-v3/prompts/journeys/verify-current-contract.md +4 -0
  143. package/benchmarks/production-v3/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  144. package/benchmarks/production-v3/prompts/pagination-boundary.md +9 -0
  145. package/benchmarks/production-v3/prompts/protected-env-refusal.md +8 -0
  146. package/benchmarks/production-v3/prompts/quoted-csv.md +6 -0
  147. package/benchmarks/production-v3/prompts/reconnect-chat-event-order.md +20 -0
  148. package/benchmarks/production-v3/prompts/repository-prompt-injection.md +5 -0
  149. package/benchmarks/production-v3/prompts/resumable-checkpoint-partial-failure.md +15 -0
  150. package/benchmarks/production-v3/prompts/revoked-session-cache.md +10 -0
  151. package/benchmarks/production-v3/prompts/schema-migration.md +6 -0
  152. package/benchmarks/production-v3/prompts/stable-dedup.md +6 -0
  153. package/benchmarks/production-v3/prompts/stale-search-response.md +6 -0
  154. package/benchmarks/production-v3/prompts/tenant-cache-isolation.md +6 -0
  155. package/benchmarks/production-v3/prompts/tenant-role-authorization.md +6 -0
  156. package/benchmarks/production-v3/prompts/unicode-search.md +6 -0
  157. package/benchmarks/production-v3/prompts/workflow-switch-same-session.md +30 -0
  158. package/benchmarks/production-v3/prompts/workspace-order.md +7 -0
  159. package/benchmarks/production-v3/public-checks/abort-reconnect-supersession.js +34 -0
  160. package/benchmarks/production-v3/public-checks/expiry-boundary.js +29 -0
  161. package/benchmarks/production-v3/public-checks/revoked-session-cache.js +20 -0
  162. package/benchmarks/production-v3/spend-control.v1.json +121 -0
  163. package/benchmarks/production-v3/suite.json +1010 -0
  164. package/benchmarks/production-v3/variant.mjs +178 -0
  165. package/catalog/capabilities.json +16 -16
  166. package/docs/authority-manifest.md +1 -1
  167. package/docs/auto-delegation-policy.md +38 -73
  168. package/docs/benchmark-codex-mcp-metadata-contract-v1.md +159 -0
  169. package/docs/benchmark-codex-mcp-metadata-contract-v2.md +182 -0
  170. package/docs/benchmark-codex-mcp-metadata-contract-v3.md +194 -0
  171. package/docs/benchmark-public-contract-addendum-v2.md +85 -0
  172. package/docs/benchmark-public-contract-addendum-v3.md +116 -0
  173. package/docs/command-reference-vietnamese.md +30 -35
  174. package/docs/context-engine.md +5 -3
  175. package/docs/context-window-policy.md +37 -1
  176. package/docs/distribution-standard.md +9 -9
  177. package/docs/en/architecture.md +26 -13
  178. package/docs/languages.json +4 -4
  179. package/docs/operator-manual-vietnamese.md +26 -46
  180. package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
  181. package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
  182. package/docs/piagent-core-improvement-plan.md +528 -0
  183. package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
  184. package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
  185. package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
  186. package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
  187. package/docs/piagent-open-session-wait.md +19 -0
  188. package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
  189. package/docs/publishing-for-teams.md +7 -0
  190. package/docs/quality-benchmark.md +299 -23
  191. package/docs/quickstart-vietnamese.md +2 -2
  192. package/docs/release-install-policy.md +32 -9
  193. package/docs/research/harness-next-evidence-review.md +113 -0
  194. package/docs/runtime-harness-standard.md +3 -3
  195. package/docs/security-threat-model.md +1 -1
  196. package/docs/subagent-orchestration-capabilities.md +19 -51
  197. package/docs/subagents-and-multiagent.md +21 -47
  198. package/docs/task-implementation-contract.md +3 -3
  199. package/docs/task-lifecycle-vietnamese.md +1 -1
  200. package/docs/team-onboarding.md +7 -7
  201. package/docs/third-party-neutrality.md +7 -0
  202. package/docs/usage-observability.md +1 -1
  203. package/docs/vi/architecture.md +26 -13
  204. package/docs-site/architecture.html +1 -1
  205. package/docs-site/benchmark.html +89 -95
  206. package/docs-site/commands.html +1 -1
  207. package/docs-site/content/benchmark.html +88 -94
  208. package/docs-site/content/en/benchmark.html +134 -90
  209. package/docs-site/content/en/index.html +19 -19
  210. package/docs-site/content/en/runtime.html +5 -5
  211. package/docs-site/content/en/whats-new.html +23 -1
  212. package/docs-site/content/en/workflows.html +2 -2
  213. package/docs-site/content/index.html +19 -19
  214. package/docs-site/content/runtime.html +6 -6
  215. package/docs-site/content/whats-new.html +23 -1
  216. package/docs-site/content/workflows.html +2 -2
  217. package/docs-site/context-engine.html +1 -1
  218. package/docs-site/en/architecture.html +1 -1
  219. package/docs-site/en/benchmark.html +135 -91
  220. package/docs-site/en/commands.html +1 -1
  221. package/docs-site/en/context-engine.html +1 -1
  222. package/docs-site/en/index.html +20 -20
  223. package/docs-site/en/mcp-approval.html +1 -1
  224. package/docs-site/en/mcp-auth.html +1 -1
  225. package/docs-site/en/mcp-servers.html +1 -1
  226. package/docs-site/en/mcp.html +1 -1
  227. package/docs-site/en/permissions.html +1 -1
  228. package/docs-site/en/profiles.html +1 -1
  229. package/docs-site/en/quickstart.html +1 -1
  230. package/docs-site/en/runtime.html +6 -6
  231. package/docs-site/en/scope.html +1 -1
  232. package/docs-site/en/security.html +1 -1
  233. package/docs-site/en/team.html +1 -1
  234. package/docs-site/en/whats-new.html +24 -2
  235. package/docs-site/en/workflows.html +3 -3
  236. package/docs-site/index.html +20 -20
  237. package/docs-site/mcp-approval.html +1 -1
  238. package/docs-site/mcp-auth.html +1 -1
  239. package/docs-site/mcp-servers.html +1 -1
  240. package/docs-site/mcp.html +1 -1
  241. package/docs-site/permissions.html +1 -1
  242. package/docs-site/profiles.html +1 -1
  243. package/docs-site/quickstart.html +1 -1
  244. package/docs-site/runtime.html +7 -7
  245. package/docs-site/scope.html +1 -1
  246. package/docs-site/security.html +1 -1
  247. package/docs-site/team.html +1 -1
  248. package/docs-site/whats-new.html +24 -2
  249. package/docs-site/workflows.html +3 -3
  250. package/evals/architecture-conformance-v1/lane.json +18 -0
  251. package/evals/architecture-conformance-v1/runner.mjs +77 -0
  252. package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
  253. package/evals/fixtures/approved-host-contracts.valid.json +43 -0
  254. package/evals/fixtures/benchmark-assurance-evidence.invalid.json +1 -1
  255. package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
  256. package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
  257. package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
  258. package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
  259. package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
  260. package/evals/fixtures/codex-relative-efficiency-v1.invalid.json +4 -0
  261. package/evals/fixtures/codex-relative-efficiency-v1.valid.json +94 -0
  262. package/evals/fixtures/composite-criterion.invalid.json +10 -0
  263. package/evals/fixtures/composite-criterion.valid.json +33 -0
  264. package/evals/fixtures/contract-family-library.invalid.json +42 -0
  265. package/evals/fixtures/contract-family-library.valid.json +41 -0
  266. package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
  267. package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
  268. package/evals/fixtures/helper-request.invalid.json +1 -1
  269. package/evals/fixtures/helper-request.valid.json +1 -1
  270. package/evals/fixtures/host-contract-plan.invalid.json +42 -0
  271. package/evals/fixtures/host-contract-plan.valid.json +41 -0
  272. package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +7 -0
  273. package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
  274. package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
  275. package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
  276. package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
  277. package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
  278. package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
  279. package/evals/fixtures/task-authority-snapshot.valid.json +4 -4
  280. package/evals/fs4-readiness-matrix.v1.json +2 -2
  281. package/evals/fs5-artifact-archive/README.md +32 -0
  282. package/evals/fs5-artifact-archive/manifest.json +148 -0
  283. package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
  284. package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
  285. package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
  286. package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
  287. package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
  288. package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
  289. package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
  290. package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
  291. package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
  292. package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
  293. package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
  294. package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
  295. package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
  296. package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
  297. package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
  298. package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
  299. package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
  300. package/evals/fs5-causal-arm.v1.json +10 -6
  301. package/evals/fs5-pilot-protocol.v1.json +3 -3
  302. package/evals/fs5-pilot-protocol.v2.json +8 -8
  303. package/evals/fs5-pilot-protocol.v3.json +8 -8
  304. package/evals/fs5-pilot-protocol.v4.json +7 -7
  305. package/evals/fs5-pilot-protocol.v5.json +10 -8
  306. package/evals/harness-next/development-corpus.mjs +106 -0
  307. package/evals/harness-next/resource-budget-probe.mjs +38 -0
  308. package/evals/harness-next/run-calibration.mjs +83 -0
  309. package/evals/harness-next/run-resource-probe.mjs +55 -0
  310. package/evals/harness-next/selected-development-corpus.mjs +27 -0
  311. package/evals/harness-next.v1.json +51 -0
  312. package/evals/long-horizon-v1/README.md +19 -0
  313. package/evals/long-horizon-v1/runner.mjs +116 -48
  314. package/evals/long-horizon-v1/worker.mjs +77 -30
  315. package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
  316. package/evals/private-holdout-v1/README.md +5 -2
  317. package/evals/private-holdout-v1/public-exposure.v1.json +1 -1
  318. package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
  319. package/evals/runtime-conformance-v1/README.md +43 -0
  320. package/evals/runtime-conformance-v1/evaluate-paid-canary.mjs +198 -0
  321. package/evals/runtime-conformance-v1/lane.json +57 -0
  322. package/evals/runtime-conformance-v1/paid-canary.json +31 -0
  323. package/evals/runtime-conformance-v1/runner.mjs +456 -0
  324. package/package.json +9 -4
  325. package/packages/piagent-core/README.md +15 -6
  326. package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
  327. package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
  328. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
  329. package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
  330. package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
  331. package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
  332. package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
  333. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
  334. package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
  335. package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
  336. package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
  337. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +699 -0
  338. package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
  339. package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
  340. package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
  341. package/packages/piagent-core/benchmark/benchmark-core.js +111 -110
  342. package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
  343. package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
  344. package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
  345. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
  346. package/packages/piagent-core/benchmark/benchmark-forensics.js +67 -52
  347. package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
  348. package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
  349. package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
  350. package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
  351. package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
  352. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
  353. package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
  354. package/packages/piagent-core/benchmark/benchmark-preflight.js +70 -7
  355. package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
  356. package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
  357. package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
  358. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +462 -0
  359. package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
  360. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
  361. package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
  362. package/packages/piagent-core/benchmark/benchmark-record-validation.js +343 -8
  363. package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
  364. package/packages/piagent-core/benchmark/benchmark-report.js +94 -5
  365. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
  366. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
  367. package/packages/piagent-core/benchmark/benchmark-runtime-causal.js +244 -0
  368. package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
  369. package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
  370. package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
  371. package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
  372. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +246 -33
  373. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
  374. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
  375. package/packages/piagent-core/benchmark/benchmark-suite.js +232 -4
  376. package/packages/piagent-core/benchmark/benchmark-summary-support.js +33 -1
  377. package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
  378. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
  379. package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
  380. package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
  381. package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
  382. package/packages/piagent-core/benchmark/benchmark-usage.js +410 -37
  383. package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
  384. package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
  385. package/packages/piagent-core/capabilities/runtime-integrity.js +6 -0
  386. package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
  387. package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
  388. package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
  389. package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
  390. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +1000 -0
  391. package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
  392. package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
  393. package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
  394. package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
  395. package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
  396. package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
  397. package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
  398. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
  399. package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
  400. package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
  401. package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
  402. package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
  403. package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
  404. package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
  405. package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
  406. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
  407. package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
  408. package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
  409. package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
  410. package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
  411. package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
  412. package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
  413. package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
  414. package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
  415. package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
  416. package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
  417. package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
  418. package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
  419. package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
  420. package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
  421. package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
  422. package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
  423. package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
  424. package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
  425. package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
  426. package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
  427. package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
  428. package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
  429. package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
  430. package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
  431. package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
  432. package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
  433. package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
  434. package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
  435. package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
  436. package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
  437. package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
  438. package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
  439. package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
  440. package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
  441. package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
  442. package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
  443. package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
  444. package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
  445. package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
  446. package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
  447. package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
  448. package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
  449. package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
  450. package/packages/piagent-core/extensions/acceptance-receipt.js +208 -180
  451. package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
  452. package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
  453. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
  454. package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
  455. package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
  456. package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
  457. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
  458. package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
  459. package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
  460. package/packages/piagent-core/extensions/context-engine.js +12 -17
  461. package/packages/piagent-core/extensions/context-index-policy.js +4 -0
  462. package/packages/piagent-core/extensions/context-query-paths.js +57 -0
  463. package/packages/piagent-core/extensions/criterion-context-pack.js +109 -4
  464. package/packages/piagent-core/extensions/criterion-graph.js +4 -1
  465. package/packages/piagent-core/extensions/failure-types.ts +2 -2
  466. package/packages/piagent-core/extensions/fallback-base-policy.ts +101 -0
  467. package/packages/piagent-core/extensions/guard-types.ts +9 -1
  468. package/packages/piagent-core/extensions/piagent-guard.ts +374 -364
  469. package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
  470. package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
  471. package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
  472. package/packages/piagent-core/extensions/task-contract-view.js +4 -4
  473. package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
  474. package/packages/piagent-core/extensions/task-journal.js +48 -3
  475. package/packages/piagent-core/extensions/task-lifecycle.js +32 -0
  476. package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
  477. package/packages/piagent-core/extensions/task-state.js +140 -43
  478. package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
  479. package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
  480. package/packages/piagent-core/extensions/verification-intelligence.js +109 -20
  481. package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
  482. package/packages/piagent-core/extensions/workspace-evidence-roots.js +52 -16
  483. package/packages/piagent-core/extensions/workspace-revision.js +48 -0
  484. package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
  485. package/packages/piagent-core/package.json +3 -3
  486. package/packages/piagent-core/policies/base-policy.json +43 -2
  487. package/packages/piagent-core/policy/authority-manifest.v1.json +3 -3
  488. package/packages/piagent-core/prompts/be-to-fe.md +2 -8
  489. package/packages/piagent-core/prompts/plan.md +1 -1
  490. package/packages/piagent-core/prompts/platform-improve.md +2 -6
  491. package/packages/piagent-core/prompts/review.md +2 -7
  492. package/packages/piagent-core/prompts/scout.md +1 -1
  493. package/packages/piagent-core/prompts/task.md +4 -3
  494. package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
  495. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
  496. package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
  497. package/packages/piagent-core/runtime/hooks/completion-hook.ts +83 -89
  498. package/packages/piagent-core/runtime/hooks/input-hook.ts +98 -7
  499. package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
  500. package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
  501. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +150 -19
  502. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +111 -92
  503. package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
  504. package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
  505. package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
  506. package/packages/piagent-core/runtime/hooks/tool-result-value-helpers.ts +66 -0
  507. package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
  508. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
  509. package/packages/piagent-core/runtime/inspection/bounded-emission-guard.ts +286 -0
  510. package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +37 -7
  511. package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
  512. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
  513. package/packages/piagent-core/runtime/inspection/task-subagent-tree.ts +27 -4
  514. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +69 -11
  515. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +104 -22
  516. package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
  517. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
  518. package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
  519. package/packages/piagent-core/runtime/orchestration/helper-lifecycle.ts +16 -12
  520. package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +71 -0
  521. package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +28 -20
  522. package/packages/piagent-core/runtime/orchestration/role-policy.ts +27 -9
  523. package/packages/piagent-core/runtime/orchestration/subagent-tool-policy.ts +329 -0
  524. package/packages/piagent-core/runtime/policy/block-remedy.ts +0 -4
  525. package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
  526. package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
  527. package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
  528. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +15 -7
  529. package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
  530. package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
  531. package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
  532. package/packages/piagent-core/runtime/quality/edit-freshness-guard.ts +102 -0
  533. package/packages/piagent-core/runtime/quality/exact-output-contract.ts +20 -10
  534. package/packages/piagent-core/runtime/quality/performance-assurance.ts +3 -3
  535. package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
  536. package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
  537. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +12 -3
  538. package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
  539. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +196 -58
  540. package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
  541. package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
  542. package/packages/piagent-core/runtime/recovery/pristine-task-policy-refresh.ts +91 -0
  543. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +31 -40
  544. package/packages/piagent-core/runtime/recovery/resume-state.ts +120 -19
  545. package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +7 -13
  546. package/packages/piagent-core/runtime/recovery/task-evidence-coverage-refresh.ts +217 -0
  547. package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
  548. package/packages/piagent-core/runtime/registration/context-commands.ts +28 -10
  549. package/packages/piagent-core/runtime/registration/knowledge-tools.ts +9 -5
  550. package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
  551. package/packages/piagent-core/runtime/registration/operator-request-intake.ts +49 -0
  552. package/packages/piagent-core/runtime/registration/policy-tools.ts +8 -6
  553. package/packages/piagent-core/runtime/registration/session-commands.ts +10 -8
  554. package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
  555. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +39 -20
  556. package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +21 -12
  557. package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
  558. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +24 -15
  559. package/packages/piagent-core/runtime/registration/task-start-manifest.ts +54 -0
  560. package/packages/piagent-core/runtime/registration/task-start-tool.ts +79 -79
  561. package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
  562. package/packages/piagent-core/runtime/runtime-limits.ts +16 -2
  563. package/packages/piagent-core/runtime/session/adaptive-context-analysis.ts +461 -0
  564. package/packages/piagent-core/runtime/session/adaptive-context-governor.ts +464 -0
  565. package/packages/piagent-core/runtime/session/adaptive-context-ledger.ts +265 -0
  566. package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
  567. package/packages/piagent-core/runtime/session/message-signals.ts +6 -18
  568. package/packages/piagent-core/runtime/session/operator-request-carry.ts +44 -0
  569. package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
  570. package/packages/piagent-core/runtime/session/runtime-state.ts +37 -39
  571. package/packages/piagent-core/runtime/session/source-checkout-read-grants.ts +35 -0
  572. package/packages/piagent-core/runtime/session/system-prompt.ts +76 -14
  573. package/packages/piagent-core/runtime/session/task-contract-presentation.ts +39 -0
  574. package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
  575. package/packages/piagent-core/runtime/session/usage.ts +4 -3
  576. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
  577. package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
  578. package/packages/piagent-core/runtime/tools/phase-tools.ts +10 -9
  579. package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
  580. package/packages/piagent-core/runtime/tools/tool-groups.ts +22 -5
  581. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
  582. package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
  583. package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
  584. package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
  585. package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
  586. package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
  587. package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
  588. package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
  589. package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
  590. package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
  591. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +101 -0
  592. package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
  593. package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
  594. package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
  595. package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
  596. package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
  597. package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
  598. package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
  599. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +201 -0
  600. package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
  601. package/packages/piagent-core/runtime/workflows/task-intake.ts +276 -169
  602. package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
  603. package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
  604. package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
  605. package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
  606. package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
  607. package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
  608. package/packages/piagent-core/subagents/piagent-oracle.md +5 -3
  609. package/packages/piagent-core/subagents/piagent-planner.md +6 -4
  610. package/packages/piagent-core/subagents/piagent-reviewer.md +5 -3
  611. package/packages/piagent-core/subagents/piagent-scout.md +4 -2
  612. package/packages/piagent-core/subagents/piagent-worker.md +6 -4
  613. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-CxeZqTte.js → MarkdownMessage-DGk34zJT.js} +1 -1
  614. package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
  615. package/packages/piagent-webui/dist/client/assets/index-DiKRmCEP.js +176 -0
  616. package/packages/piagent-webui/dist/client/index.html +2 -2
  617. package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
  618. package/packages/piagent-webui/extension/piagent-webui.ts +13 -3
  619. package/packages/piagent-webui/extension/review-controller.ts +29 -6
  620. package/packages/piagent-webui/extension/same-session-bridge.ts +7 -8
  621. package/packages/piagent-webui/extension/session-stream-adapter.ts +88 -16
  622. package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
  623. package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
  624. package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
  625. package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
  626. package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
  627. package/packages/piagent-webui/gateway/gateway-session-stream.ts +170 -32
  628. package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
  629. package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
  630. package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
  631. package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
  632. package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
  633. package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
  634. package/packages/piagent-webui/gateway/session-inspection-registry.ts +11 -2
  635. package/packages/piagent-webui/gateway/session-operation-lifecycle.ts +237 -0
  636. package/packages/piagent-webui/gateway/session-operation-retry-control.ts +38 -0
  637. package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
  638. package/packages/piagent-webui/gateway/session-operation-watchdog.ts +9 -2
  639. package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
  640. package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
  641. package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
  642. package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
  643. package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
  644. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +118 -117
  645. package/packages/piagent-webui/ownership/session-lease-store.ts +5 -2
  646. package/packages/piagent-webui/server/core-inspection-provider.ts +75 -15
  647. package/packages/piagent-webui/server/loopback-server.ts +9 -7
  648. package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
  649. package/packages/piagent-webui/server/transcript-projection.ts +150 -11
  650. package/packages/piagent-webui/shared/message-correlation.ts +25 -0
  651. package/schemas/approved-host-contracts.schema.json +973 -0
  652. package/schemas/benchmark-attempt-outcome.schema.json +303 -0
  653. package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
  654. package/schemas/codex-relative-efficiency-v1.schema.json +155 -0
  655. package/schemas/composite-criterion.schema.json +788 -0
  656. package/schemas/contract-family-library.schema.json +28 -0
  657. package/schemas/contract-selection-recipe.schema.json +31 -0
  658. package/schemas/failure-evidence.schema.json +2 -2
  659. package/schemas/helper-request.schema.json +16 -4
  660. package/schemas/host-contract-plan.schema.json +25 -0
  661. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
  662. package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
  663. package/schemas/piagent-webui/runtime-event-v2.schema.json +46 -5
  664. package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
  665. package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
  666. package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
  667. package/schemas/piagent-webui/subagent-tree-v1.schema.json +11 -1
  668. package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
  669. package/schemas/project-profile.schema.json +1 -1
  670. package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
  671. package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
  672. package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
  673. package/schemas/public-contracts/revocation-v1.schema.json +87 -0
  674. package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
  675. package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
  676. package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
  677. package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
  678. package/schemas/task-contract.schema.json +45 -0
  679. package/scripts/approve-independent-verification.mjs +57 -0
  680. package/scripts/benchmark-arm-observer.mjs +320 -0
  681. package/scripts/benchmark-budget-ipc.mjs +34 -0
  682. package/scripts/benchmark-budget-launcher.mjs +91 -0
  683. package/scripts/benchmark-budget-processes.mjs +133 -0
  684. package/scripts/benchmark-budget-publication.mjs +228 -0
  685. package/scripts/benchmark-budget-runtime.mjs +136 -0
  686. package/scripts/benchmark-candidate-ablation.mjs +265 -0
  687. package/scripts/benchmark-codex-journey.mjs +406 -0
  688. package/scripts/benchmark-independent-verification.mjs +628 -0
  689. package/scripts/benchmark-journey-outcome.mjs +92 -0
  690. package/scripts/benchmark-production-v3-human-review.mjs +192 -0
  691. package/scripts/benchmark-public-input-catalog.mjs +158 -0
  692. package/scripts/benchmark-registered-plan-author.mjs +355 -0
  693. package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
  694. package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
  695. package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
  696. package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
  697. package/scripts/benchmark-runner-completion.mjs +133 -0
  698. package/scripts/benchmark-runner-configuration.mjs +159 -0
  699. package/scripts/benchmark-runner-core.mjs +224 -387
  700. package/scripts/benchmark-runner-finalization.mjs +144 -27
  701. package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
  702. package/scripts/benchmark-runner-schedule.mjs +256 -0
  703. package/scripts/benchmark-runner-support.mjs +136 -4
  704. package/scripts/benchmark-runner.mjs +95 -18
  705. package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
  706. package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
  707. package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
  708. package/scripts/benchmark-scoped-pi-router.mjs +196 -0
  709. package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
  710. package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
  711. package/scripts/benchmark-scoped-session-custody.mjs +599 -0
  712. package/scripts/benchmark-scoped-session-factory.mjs +342 -0
  713. package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
  714. package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
  715. package/scripts/benchmark-session-evaluator.mjs +169 -0
  716. package/scripts/benchmark-session-provider-boundary.mjs +62 -0
  717. package/scripts/benchmark-session-usage.mjs +28 -0
  718. package/scripts/benchmark-session.mjs +343 -50
  719. package/scripts/benchmark-webui-journey.mjs +678 -0
  720. package/scripts/check-public-wording.mjs +46 -0
  721. package/scripts/configure-subagents.sh +42 -34
  722. package/scripts/fs4-readiness-evaluation.mjs +7 -1
  723. package/scripts/helper-evaluation.mjs +1 -1
  724. package/scripts/phase-tools-evaluation.mjs +1 -0
  725. package/scripts/pi-auto.sh +7 -1
  726. package/scripts/pi-usage-history.mjs +201 -11
  727. package/scripts/piagent-cli.mjs +8 -0
  728. package/scripts/private-holdout-readiness.mjs +7 -1
  729. package/scripts/public-evaluation-exposure.mjs +140 -0
  730. package/scripts/select-independent-verification.mjs +62 -0
  731. package/scripts/team-doctor.sh +1 -1
  732. package/scripts/typescript-loader.mjs +135 -1
  733. package/scripts/update-global.mjs +6 -7
  734. package/scripts/verify-local.sh +41 -55
  735. package/scripts/verify-release-identity.mjs +5 -3
  736. package/packages/piagent-webui/dist/client/assets/index-DynIMe8I.js +0 -176
@@ -1,6 +1,9 @@
1
+ import { buildDiagnosticDelivery, diagnosticCompletionMissing, diagnosticDeliveryStateErrors, validDiagnosticDelivery, type DiagnosticDelivery } from "./diagnostic-delivery.ts";
1
2
  import crypto from "node:crypto";
2
3
  import fs from "node:fs";
3
4
  import path from "node:path";
5
+ import { currentWorkspaceRevisionDigest } from "../../extensions/workspace-revision.js";
6
+ import { handoffVerifierBindingErrors, type HandoffVerifierBinding } from "./handoff-verifier-binding.ts";
4
7
 
5
8
  import type { TaskContract } from "../../extensions/guard-types.ts";
6
9
  import { failureClassificationValidationErrors, type FailureClassification } from "../../extensions/failure-types.ts";
@@ -9,29 +12,26 @@ import { redactSensitiveText } from "../../extensions/redaction-core.js";
9
12
  import { changedSnapshotFiles } from "../../extensions/task-contract-view.js";
10
13
  import { replayTaskCheckpoints, taskJournalPaths } from "../../extensions/task-journal.js";
11
14
  import { safeTaskId, taskContractValidationErrors, taskDigestMigrationArchiveStatus, workingTreeSnapshot } from "../../extensions/task-state.js";
12
- import { latestObservedVerification, verificationEvidenceProvesStableTree } from "../../extensions/verification-intelligence.js";
15
+ import { latestObservedVerification, verificationEvidenceProvesCurrentWorkspace } from "../../extensions/verification-intelligence.js";
13
16
  import {
14
17
  isCurrentWorkingTreeDigest,
15
18
  WORKING_TREE_DIGEST_ALGORITHM,
16
19
  workingTreeEvidenceDigest
17
20
  } from "../../extensions/working-tree-digest.js";
18
- import type { RecoveryDecision } from "./recovery-policy.ts";
19
- import { RECOVERY_ACTIONS } from "./recovery-policy.ts";
21
+ import { recoveryDecisionValidationErrors, type RecoveryDecision } from "./recovery-policy.ts";
20
22
  import { readTrajectoryStore, trajectoryStatePath } from "../trajectory/trajectory-store.ts";
21
23
 
22
24
  export const HANDOFF_SCHEMA_VERSION = 1 as const;
23
- export const HANDOFF_PROJECTION_VERSION = "handoff-v1" as const;
25
+ export const HANDOFF_PROJECTION_VERSION = "handoff-v2" as const;
24
26
 
25
- type CompletionGate = { decision: "pass" | "fail"; missing: string[]; missingVerifyCommands: string[]; currentWorkingTreeDigest?: string };
27
+ type CompletionGate = { decision: "pass" | "fail"; missing: string[]; missingVerifyCommands: string[]; currentWorkingTreeDigest?: string; acceptanceProof?: { mode: "enforce" | "diagnostic"; pendingCriterionIds: string[]; missing: string[] } };
26
28
  type DigestRef = { sha256: string; chars: number };
27
- type LatestVerifier = {
29
+ type LatestVerifier = HandoffVerifierBinding & {
28
30
  command: string;
29
31
  exitCode: number;
30
32
  observedAt: string | null;
31
33
  matchedProfileCommand: boolean;
32
34
  isError: boolean;
33
- preWorkingTreeDigest: string | null;
34
- workingTreeDigest: string | null;
35
35
  summaryRef: DigestRef;
36
36
  };
37
37
 
@@ -41,7 +41,8 @@ export type HandoffProjection = {
41
41
  generatedAt: string;
42
42
  identity: { taskId: string; taskRunId: string; sessionHash: string; sessionName: string | null; attempt: number; maxAttempts: number };
43
43
  goal: { summary: string; expectedOutput: string; acceptanceCriteria: string[]; scope: string[]; outOfScope: string[] };
44
- state: { phase: string | null; taskOutcome: TaskContract["trace"]["outcome"]; gateDecision: "pass" | "fail"; completionApproved: boolean; missing: string[] };
44
+ state: { phase: string | null; taskOutcome: TaskContract["trace"]["outcome"]; gateDecision: "pass" | "fail"; completionApproved: boolean; missing: string[]; diagnosticDelivery?: DiagnosticDelivery };
45
+ acceptance: { required: boolean; satisfied: boolean; criteriaCount: number; dispositionDigest: string };
45
46
  decisionsAndInvariants: string[];
46
47
  contextReferences: { required: string[]; observed: Array<{ path: string; reason: string }>; memory: Array<{ path: string; reason: string }> };
47
48
  tree: {
@@ -49,6 +50,7 @@ export type HandoffProjection = {
49
50
  migration: Pick<NonNullable<TaskContract["workingTreeDigestMigration"]>, "status" | "reasonCode" | "requiredAction"> | null;
50
51
  baselineDigest: string | null;
51
52
  currentDigest: string | null;
53
+ workspaceRevisionDigest: string | null;
52
54
  evidenceCurrent: boolean;
53
55
  latestVerifierMatchesCurrentTree: boolean;
54
56
  };
@@ -68,10 +70,15 @@ export type HandoffProjection = {
68
70
  };
69
71
  };
70
72
 
71
- const TOP_LEVEL_FIELDS = new Set(["schemaVersion", "projectionVersion", "generatedAt", "identity", "goal", "state", "decisionsAndInvariants", "contextReferences", "tree", "changedFiles", "verification", "failure", "ruledOutHypotheses", "requiredAuthority", "nextSafeAction", "references"]);
72
- const TREE_FIELDS = new Set(["algorithm", "migration", "baselineDigest", "currentDigest", "evidenceCurrent", "latestVerifierMatchesCurrentTree"]);
73
+ const TOP_LEVEL_FIELDS = new Set(["schemaVersion", "projectionVersion", "generatedAt", "identity", "goal", "state", "acceptance", "decisionsAndInvariants", "contextReferences", "tree", "changedFiles", "verification", "failure", "ruledOutHypotheses", "requiredAuthority", "nextSafeAction", "references"]);
74
+ const IDENTITY_FIELDS = new Set(["taskId", "taskRunId", "sessionHash", "sessionName", "attempt", "maxAttempts"]);
75
+ const ACCEPTANCE_FIELDS = new Set(["required", "satisfied", "criteriaCount", "dispositionDigest"]);
76
+ const TREE_FIELDS = new Set(["algorithm", "migration", "baselineDigest", "currentDigest", "evidenceCurrent", "latestVerifierMatchesCurrentTree", "workspaceRevisionDigest"]);
73
77
  const TREE_MIGRATION_FIELDS = new Set(["status", "reasonCode", "requiredAction"]);
74
- const LATEST_VERIFIER_FIELDS = new Set(["command", "exitCode", "observedAt", "matchedProfileCommand", "isError", "preWorkingTreeDigest", "workingTreeDigest", "summaryRef"]);
78
+ const VERIFICATION_FIELDS = new Set(["exactCommands", "missingCommands", "latestObserved"]);
79
+ const LATEST_VERIFIER_FIELDS = new Set(["command", "exitCode", "observedAt", "matchedProfileCommand", "isError", "preWorkingTreeDigest", "workingTreeDigest", "summaryRef", "preWorkspaceRevisionDigest", "workspaceRevisionDigest"]);
80
+ const SUMMARY_REF_FIELDS = new Set(["sha256", "chars"]);
81
+ const AUTHORITY_FIELDS = new Set(["required", "kind", "reasonCodes"]);
75
82
  const HASH = /^[a-f0-9]{64}$/;
76
83
  const MIGRATION_STATUSES = new Set(["verification-refresh-required", "refreshed", "new-attempt-required", "historical-unverifiable"]);
77
84
  const MIGRATION_ACTIONS: Record<string, string> = {
@@ -98,10 +105,36 @@ export function handoffProjectionValidationErrors(input: unknown): string[] {
98
105
  ];
99
106
  if (value.schemaVersion !== HANDOFF_SCHEMA_VERSION || value.projectionVersion !== HANDOFF_PROJECTION_VERSION) errors.push("handoff projection version is invalid");
100
107
  if (typeof value.generatedAt !== "string" || !Number.isFinite(Date.parse(value.generatedAt))) errors.push("generatedAt is invalid");
101
- const identity = record(value.identity), state = record(value.state), tree = record(value.tree);
102
- if (!identity || typeof identity.taskId !== "string" || typeof identity.taskRunId !== "string" || !HASH.test(String(identity.sessionHash)) || !Number.isInteger(identity.attempt) || !Number.isInteger(identity.maxAttempts)) errors.push("identity is invalid");
108
+ const identity = record(value.identity), state = record(value.state), acceptance = record(value.acceptance), tree = record(value.tree);
109
+ const diagnostic = state?.diagnosticDelivery;
110
+ const diagnosticValid = validDiagnosticDelivery(diagnostic, acceptance?.dispositionDigest);
111
+ errors.push(...diagnosticDeliveryStateErrors(state, acceptance));
112
+ const deliveryApproved = state?.completionApproved === true || diagnosticValid;
113
+ if (!identity
114
+ || Object.keys(identity).some((field) => !IDENTITY_FIELDS.has(field))
115
+ || [...IDENTITY_FIELDS].some((field) => !(field in identity))
116
+ || typeof identity.taskId !== "string"
117
+ || typeof identity.taskRunId !== "string"
118
+ || !HASH.test(String(identity.sessionHash))
119
+ || (identity.sessionName !== null && typeof identity.sessionName !== "string")
120
+ || !Number.isInteger(identity.attempt)
121
+ || !Number.isInteger(identity.maxAttempts)
122
+ || identity.attempt < 1
123
+ || identity.maxAttempts < 1
124
+ || identity.attempt > identity.maxAttempts) errors.push("identity is invalid");
103
125
  if (!state || !["pending", "completed", "blocked", "partial", "failed"].includes(String(state.taskOutcome)) || !["pass", "fail"].includes(String(state.gateDecision)) || typeof state.completionApproved !== "boolean" || !Array.isArray(state.missing)) errors.push("state is invalid");
104
- if (state?.completionApproved === true && (state.gateDecision !== "pass" || state.taskOutcome !== "completed")) errors.push("completionApproved conflicts with operational truth");
126
+ if (deliveryApproved && (state.gateDecision !== "pass" || state.taskOutcome !== "completed")) errors.push("completionApproved conflicts with operational truth");
127
+ if (!acceptance
128
+ || Object.keys(acceptance).some((field) => !ACCEPTANCE_FIELDS.has(field))
129
+ || [...ACCEPTANCE_FIELDS].some((field) => !(field in acceptance))
130
+ || typeof acceptance.required !== "boolean"
131
+ || typeof acceptance.satisfied !== "boolean"
132
+ || !Number.isInteger(acceptance.criteriaCount)
133
+ || acceptance.criteriaCount < 0
134
+ || acceptance.criteriaCount > 12
135
+ || !HASH.test(String(acceptance.dispositionDigest))) errors.push("acceptance disposition is invalid");
136
+ if (state?.completionApproved === true && acceptance?.satisfied !== true) errors.push("completionApproved requires satisfied acceptance");
137
+ if (deliveryApproved && Array.isArray(state.missing) && state.missing.some((item: unknown) => !(diagnosticValid && item === "acceptance-criteria-pending"))) errors.push("completionApproved cannot retain missing completion evidence");
105
138
  const migration = record(tree?.migration);
106
139
  const migrationValid = tree?.migration === null || Boolean(
107
140
  migration
@@ -114,7 +147,7 @@ export function handoffProjectionValidationErrors(input: unknown): string[] {
114
147
  if (
115
148
  !tree
116
149
  || Object.keys(tree).some((field) => !TREE_FIELDS.has(field))
117
- || [...TREE_FIELDS].some((field) => !(field in tree))
150
+ || [...TREE_FIELDS].some((field) => field !== "workspaceRevisionDigest" && !(field in tree))
118
151
  || ![WORKING_TREE_DIGEST_ALGORITHM, "legacy-untrusted"].includes(String(tree.algorithm))
119
152
  || !migrationValid
120
153
  || (tree.baselineDigest !== null && !isCurrentWorkingTreeDigest(tree.baselineDigest))
@@ -132,29 +165,85 @@ export function handoffProjectionValidationErrors(input: unknown): string[] {
132
165
  if (tree?.algorithm === "legacy-untrusted" && (!migration || !["new-attempt-required", "historical-unverifiable"].includes(String(migration.status)) || tree.baselineDigest !== null || tree.currentDigest !== null || tree.evidenceCurrent !== false)) errors.push("legacy tree evidence must remain historical");
133
166
  if (tree?.algorithm === WORKING_TREE_DIGEST_ALGORITHM && ["new-attempt-required", "historical-unverifiable"].includes(String(migration?.status))) errors.push("current tree algorithm conflicts with terminal legacy migration");
134
167
  if (tree?.evidenceCurrent === true && (tree.algorithm !== WORKING_TREE_DIGEST_ALGORITHM || !isCurrentWorkingTreeDigest(tree.baselineDigest) || !isCurrentWorkingTreeDigest(tree.currentDigest) || migration?.status === "verification-refresh-required")) errors.push("tree current-evidence claim is invalid");
135
- const latestVerifier = record(value.verification?.latestObserved);
136
- if (value.verification?.latestObserved !== null && (!latestVerifier
168
+ const verification = record(value.verification);
169
+ if (!verification
170
+ || Object.keys(verification).some((field) => !VERIFICATION_FIELDS.has(field))
171
+ || [...VERIFICATION_FIELDS].some((field) => !(field in verification))
172
+ || !Array.isArray(verification.exactCommands)
173
+ || verification.exactCommands.length > 50
174
+ || verification.exactCommands.some((command: unknown) => typeof command !== "string" || command.length > 1000)
175
+ || !Array.isArray(verification.missingCommands)
176
+ || verification.missingCommands.length > 50
177
+ || verification.missingCommands.some((command: unknown) => typeof command !== "string" || command.length > 1000)
178
+ || (Array.isArray(verification.exactCommands) && Array.isArray(verification.missingCommands)
179
+ && verification.missingCommands.some((command: string) => !verification.exactCommands.includes(command)))) errors.push("verification is invalid");
180
+ const latestVerifier = record(verification?.latestObserved);
181
+ const summary = record(latestVerifier?.summaryRef);
182
+ if (verification?.latestObserved !== null && (!latestVerifier
137
183
  || Object.keys(latestVerifier).some((field) => !LATEST_VERIFIER_FIELDS.has(field))
138
- || [...LATEST_VERIFIER_FIELDS].some((field) => !(field in latestVerifier))
139
- || typeof latestVerifier.command !== "string" || !Number.isInteger(latestVerifier.exitCode)
140
- || typeof latestVerifier.matchedProfileCommand !== "boolean" || typeof latestVerifier.isError !== "boolean")) errors.push("latest verifier is invalid");
141
- if (tree?.latestVerifierMatchesCurrentTree === true && (!tree.evidenceCurrent
142
- || latestVerifier?.exitCode !== 0 || latestVerifier?.matchedProfileCommand !== true
143
- || !isCurrentWorkingTreeDigest(latestVerifier?.preWorkingTreeDigest)
144
- || latestVerifier?.preWorkingTreeDigest !== tree.currentDigest
145
- || latestVerifier?.workingTreeDigest !== tree.currentDigest)) errors.push("latest verifier tree claim is invalid");
146
- const latestVerifierDigest = latestVerifier?.workingTreeDigest;
147
- if (latestVerifierDigest !== undefined && latestVerifierDigest !== null && !isCurrentWorkingTreeDigest(latestVerifierDigest)) errors.push("latest verifier workingTreeDigest is invalid");
148
- const preVerifierDigest = latestVerifier?.preWorkingTreeDigest;
149
- if (preVerifierDigest !== undefined && preVerifierDigest !== null && !isCurrentWorkingTreeDigest(preVerifierDigest)) errors.push("latest verifier preWorkingTreeDigest is invalid");
150
- if (state?.completionApproved === true && tree?.evidenceCurrent !== true) errors.push("completionApproved requires current tree evidence");
184
+ || [...LATEST_VERIFIER_FIELDS].some((field) => !["preWorkspaceRevisionDigest", "workspaceRevisionDigest"].includes(field) && !(field in latestVerifier))
185
+ || typeof latestVerifier.command !== "string" || latestVerifier.command.length > 1000
186
+ || !Number.isInteger(latestVerifier.exitCode)
187
+ || (latestVerifier.observedAt !== null && (typeof latestVerifier.observedAt !== "string" || !Number.isFinite(Date.parse(latestVerifier.observedAt))))
188
+ || typeof latestVerifier.matchedProfileCommand !== "boolean"
189
+ || typeof latestVerifier.isError !== "boolean"
190
+ || !summary
191
+ || Object.keys(summary).some((field) => !SUMMARY_REF_FIELDS.has(field))
192
+ || [...SUMMARY_REF_FIELDS].some((field) => !(field in summary))
193
+ || !HASH.test(String(summary.sha256))
194
+ || !Number.isInteger(summary.chars)
195
+ || summary.chars < 0
196
+ || summary.chars > 20_000)) errors.push("latest verifier is invalid");
197
+ errors.push(...handoffVerifierBindingErrors(tree, latestVerifier));
198
+ if (deliveryApproved && tree?.evidenceCurrent !== true) errors.push("completionApproved requires current tree evidence");
151
199
  const requiredArrays = [value.decisionsAndInvariants, value.goal?.acceptanceCriteria, value.goal?.scope, value.contextReferences?.observed, value.changedFiles?.current, value.verification?.exactCommands, value.failure?.warnings, value.ruledOutHypotheses];
152
200
  if (requiredArrays.some((entry) => !Array.isArray(entry))) errors.push("projection collections are invalid");
153
201
  const classification = value.failure?.classification;
154
202
  if (classification !== null && failureClassificationValidationErrors(classification).length > 0) errors.push("failure classification is invalid");
155
203
  const recovery = value.failure?.recovery;
156
- if (recovery !== null && (!record(recovery) || recovery.policyVersion !== "recovery-v1" || !RECOVERY_ACTIONS.includes(recovery.action) || recovery.taskId !== identity?.taskId || recovery.taskRunId !== identity?.taskRunId)) errors.push("recovery decision is invalid");
157
- if (value.nextSafeAction?.sourceMutationAllowed === true && value.nextSafeAction?.action !== "repair") errors.push("only repair may project source mutation");
204
+ const recoveryErrors = recovery === null ? [] : recoveryDecisionValidationErrors(recovery);
205
+ if (recoveryErrors.length > 0) errors.push(`recovery decision is invalid: ${recoveryErrors.join(", ")}`);
206
+ if (recovery !== null && (recovery.taskId !== identity?.taskId || recovery.taskRunId !== identity?.taskRunId || recovery.taskAttempt !== identity?.attempt)) errors.push("recovery decision is invalid: identity conflict");
207
+ const requiredAuthority = record(value.requiredAuthority);
208
+ if (!requiredAuthority
209
+ || !Object.keys(requiredAuthority).every((field) => AUTHORITY_FIELDS.has(field))
210
+ || ![...AUTHORITY_FIELDS].every((field) => field in requiredAuthority)
211
+ || typeof requiredAuthority.required !== "boolean"
212
+ || !["none", "operator", "permission", "scope", "fresh-session"].includes(String(requiredAuthority.kind))
213
+ || !Array.isArray(requiredAuthority.reasonCodes)
214
+ || requiredAuthority.reasonCodes.some((reason: unknown) => typeof reason !== "string")) errors.push("required authority is invalid");
215
+ const nextSafeAction = record(value.nextSafeAction);
216
+ if (!nextSafeAction
217
+ || typeof nextSafeAction.action !== "string"
218
+ || typeof nextSafeAction.continuation !== "string"
219
+ || typeof nextSafeAction.sourceMutationAllowed !== "boolean"
220
+ || !Array.isArray(nextSafeAction.exactCommands)
221
+ || nextSafeAction.exactCommands.some((command: unknown) => typeof command !== "string")) errors.push("next safe action is invalid");
222
+ if (nextSafeAction?.sourceMutationAllowed === true && nextSafeAction.action !== "repair") errors.push("only repair may project source mutation");
223
+ if (deliveryApproved && (nextSafeAction?.action !== "completed"
224
+ || nextSafeAction.continuation !== "none"
225
+ || nextSafeAction.sourceMutationAllowed !== false
226
+ || !Array.isArray(nextSafeAction.exactCommands)
227
+ || nextSafeAction.exactCommands.length !== 0)) errors.push("completionApproved requires a completed next safe action");
228
+ if (deliveryApproved && (!Array.isArray(verification?.missingCommands) || verification.missingCommands.length > 0)) errors.push("completionApproved cannot retain missing verifier commands");
229
+ if (deliveryApproved && Array.isArray(verification?.exactCommands) && verification.exactCommands.length > 0
230
+ && (tree?.latestVerifierMatchesCurrentTree !== true
231
+ || !latestVerifier
232
+ || !verification.exactCommands.includes(latestVerifier.command))) errors.push("completionApproved requires current exact verifier evidence");
233
+ if (recovery === null) {
234
+ const expectedAction = deliveryApproved ? "completed" : "handoff";
235
+ if (nextSafeAction?.action !== expectedAction || nextSafeAction?.continuation !== "none"
236
+ || nextSafeAction?.sourceMutationAllowed !== false || nextSafeAction?.exactCommands?.length !== 0) errors.push("next safe action conflicts with recovery state");
237
+ if (requiredAuthority?.required !== false || requiredAuthority?.kind !== "none" || requiredAuthority?.reasonCodes?.length !== 0) errors.push("required authority conflicts with recovery state");
238
+ } else if (recoveryErrors.length === 0) {
239
+ const expectedAuthority = authority(recovery as RecoveryDecision);
240
+ const expectedCommands = ["repair", "retry"].includes(recovery.action) ? verification?.exactCommands : [];
241
+ if (nextSafeAction?.action !== recovery.action || nextSafeAction?.continuation !== recovery.continuation
242
+ || nextSafeAction?.sourceMutationAllowed !== recovery.sourceMutationAllowed
243
+ || JSON.stringify(nextSafeAction?.exactCommands) !== JSON.stringify(expectedCommands)) errors.push("next safe action conflicts with recovery decision");
244
+ if (requiredAuthority?.required !== expectedAuthority.required || requiredAuthority?.kind !== expectedAuthority.kind
245
+ || JSON.stringify(requiredAuthority?.reasonCodes) !== JSON.stringify(expectedAuthority.reasonCodes)) errors.push("required authority conflicts with recovery decision");
246
+ }
158
247
  for (const reference of [value.references?.taskContract, value.references?.journal, value.references?.trajectory]) {
159
248
  if (typeof reference !== "string" || path.isAbsolute(reference) || reference.split(/[\\/]/).includes("..")) errors.push("state reference is invalid");
160
249
  }
@@ -169,18 +258,56 @@ export function validateHandoffProjection(input: unknown, source = "handoff proj
169
258
  return input as HandoffProjection;
170
259
  }
171
260
 
172
- function digest(value: unknown): string {
173
- return crypto.createHash("sha256").update(JSON.stringify(value)).digest("hex");
174
- }
261
+ function digest(value: unknown): string { return crypto.createHash("sha256").update(JSON.stringify(value)).digest("hex"); }
175
262
 
176
- function text(value: unknown, maximum = 1000): string {
177
- return redactSensitiveText(String(value ?? "")).text.replace(/\s+/g, " ").trim().slice(0, maximum);
178
- }
263
+ function text(value: unknown, maximum = 1000): string { return redactSensitiveText(String(value ?? "")).text.replace(/\s+/g, " ").trim().slice(0, maximum); }
179
264
 
180
265
  function strings(values: unknown, maximum = 100, itemMaximum = 1000): string[] {
181
266
  return [...new Set((Array.isArray(values) ? values : []).map((item) => text(item, itemMaximum)).filter(Boolean))].slice(0, maximum);
182
267
  }
183
268
 
269
+ export function taskAcceptanceDisposition(task: Pick<TaskContract, "changeMode" | "changedFiles" | "acceptanceReceipt">): HandoffProjection["acceptance"] {
270
+ const required = task.changeMode === "source-change" && task.changedFiles.length > 0;
271
+ const criteria = task.acceptanceReceipt?.criteria ?? [];
272
+ return {
273
+ required,
274
+ satisfied: !required || (criteria.length > 0 && criteria.every((criterion) => criterion.status === "satisfied")),
275
+ criteriaCount: criteria.length,
276
+ dispositionDigest: digest(criteria.map((criterion) => ({
277
+ id: criterion.id,
278
+ hash: criterion.hash,
279
+ status: criterion.status
280
+ })))
281
+ };
282
+ }
283
+
284
+ export function taskHandoffIdentity(task: Pick<TaskContract, "taskId" | "taskRunId" | "sessionId" | "sessionName" | "attempt" | "maxAttempts">): HandoffProjection["identity"] {
285
+ return {
286
+ taskId: text(task.taskId, 160),
287
+ taskRunId: text(task.taskRunId, 160),
288
+ sessionHash: digest(task.sessionId),
289
+ sessionName: task.sessionName ? text(task.sessionName, 240) : null,
290
+ attempt: task.attempt,
291
+ maxAttempts: task.maxAttempts
292
+ };
293
+ }
294
+
295
+ export function handoffIdentityMatchesTask(
296
+ identity: HandoffProjection["identity"] | undefined,
297
+ task: Pick<TaskContract, "taskId" | "taskRunId" | "sessionId" | "sessionName" | "attempt" | "maxAttempts">
298
+ ): boolean {
299
+ if (!identity) return false;
300
+ const authoritative = taskHandoffIdentity(task);
301
+ return identity.taskId === authoritative.taskId
302
+ && identity.taskRunId === authoritative.taskRunId
303
+ && identity.sessionHash === authoritative.sessionHash
304
+ // A session title is mutable display metadata. The hashed stable session id
305
+ // above carries authority; renaming a live session must not invalidate its
306
+ // otherwise identity-bound handoff.
307
+ && identity.attempt === authoritative.attempt
308
+ && identity.maxAttempts === authoritative.maxAttempts;
309
+ }
310
+
184
311
  function summaryRef(value: unknown): DigestRef {
185
312
  const safe = text(value, 20_000);
186
313
  return { sha256: digest(safe), chars: safe.length };
@@ -211,6 +338,9 @@ function authority(recovery: RecoveryDecision | null): HandoffProjection["requir
211
338
  const reasons = strings(recovery.reasonCodes, 20, 120);
212
339
  if (recovery.action === "fresh-session") return { required: true, kind: "fresh-session", reasonCodes: reasons };
213
340
  if (recovery.reasonCodes.includes("permission-expansion-forbidden")) return { required: true, kind: "permission", reasonCodes: reasons };
341
+ if (recovery.reasonCodes.includes("protected-path-forbidden")) return { required: true, kind: "permission", reasonCodes: reasons };
342
+ // Backward-compatible projection for recovery records written before task
343
+ // scope became advisory.
214
344
  if (recovery.reasonCodes.includes("scope-replan-required")) return { required: true, kind: "scope", reasonCodes: reasons };
215
345
  if (recovery.action === "ask-operator") return { required: true, kind: "operator", reasonCodes: reasons };
216
346
  return { required: false, kind: "none", reasonCodes: reasons };
@@ -254,12 +384,21 @@ export function buildHandoffProjection(
254
384
  && isCurrentWorkingTreeDigest(currentDigest);
255
385
  const gateDigestCurrent = isCurrentWorkingTreeDigest(options.gate.currentWorkingTreeDigest)
256
386
  && options.gate.currentWorkingTreeDigest === currentDigest;
257
- const completionApproved = options.gate.decision === "pass" && task.trace.outcome === "completed" && evidenceCurrent && gateDigestCurrent;
258
- const completionMissing = strings([
259
- ...options.gate.missing,
260
- ...(options.gate.decision === "pass" && !evidenceCurrent ? ["working-tree-evidence-not-current"] : []),
261
- ...(options.gate.decision === "pass" && !gateDigestCurrent ? ["completion-gate-tree-digest-untrusted-or-mismatched"] : [])
262
- ], 50, 500);
387
+ const exactCommands = strings(task.verifyCommands, 50, 1000);
388
+ const currentExactVerifier = exactCommands.length === 0 || (verificationEvidenceProvesCurrentWorkspace(observed, currentDigest, cwd)
389
+ && exactCommands.includes(text(observed?.command, 1000)));
390
+ const acceptanceDisposition = taskAcceptanceDisposition(task);
391
+ const acceptanceSatisfied = acceptanceDisposition.satisfied;
392
+ const completionApproved = options.gate.decision === "pass"
393
+ && task.trace.outcome === "completed"
394
+ && acceptanceSatisfied
395
+ && evidenceCurrent
396
+ && gateDigestCurrent
397
+ && currentExactVerifier;
398
+ const diagnosticDelivery = buildDiagnosticDelivery(task, options.gate, acceptanceDisposition,
399
+ evidenceCurrent && gateDigestCurrent && currentExactVerifier);
400
+ const completionMissing = strings(diagnosticCompletionMissing(options.gate.decision, options.gate.missing,
401
+ acceptanceSatisfied, evidenceCurrent, gateDigestCurrent, currentExactVerifier), 50, 500);
263
402
  const ruledOut = task.ruledOut ? [{ ref: digest(text(task.ruledOut, 1000)), summary: text(task.ruledOut, 300) }] : [];
264
403
  const latestVerifier: LatestVerifier | null = observed ? {
265
404
  command: text(observed.command, 1000),
@@ -269,17 +408,15 @@ export function buildHandoffProjection(
269
408
  isError: observed.isError === true,
270
409
  preWorkingTreeDigest: observed.preWorkingTreeDigest ?? null,
271
410
  workingTreeDigest: observed.workingTreeDigest ?? null,
411
+ preWorkspaceRevisionDigest: observed.preWorkspaceRevisionDigest ?? null,
412
+ workspaceRevisionDigest: observed.workspaceRevisionDigest ?? null,
272
413
  summaryRef: summaryRef(observed.summary)
273
414
  } : null;
274
415
  const projection: HandoffProjection = {
275
416
  schemaVersion: HANDOFF_SCHEMA_VERSION,
276
417
  projectionVersion: HANDOFF_PROJECTION_VERSION,
277
418
  generatedAt: options.generatedAt ?? new Date().toISOString(),
278
- identity: {
279
- taskId: text(task.taskId, 160), taskRunId: text(task.taskRunId, 160),
280
- sessionHash: digest(task.sessionId), sessionName: task.sessionName ? text(task.sessionName, 240) : null,
281
- attempt: task.attempt, maxAttempts: task.maxAttempts
282
- },
419
+ identity: taskHandoffIdentity(task),
283
420
  goal: {
284
421
  summary: text(task.summary, 1000), expectedOutput: text(task.expectedOutput, 1000),
285
422
  acceptanceCriteria: strings(task.acceptanceCriteria, 50, 1000), scope: strings(task.scope, 100, 500), outOfScope: strings(task.outOfScope, 100, 500)
@@ -287,13 +424,14 @@ export function buildHandoffProjection(
287
424
  state: {
288
425
  phase: trajectory.enforcementSafe ? trajectory.state?.currentPhase ?? null : null,
289
426
  taskOutcome: task.trace.outcome, gateDecision: options.gate.decision, completionApproved,
290
- missing: completionMissing
427
+ missing: completionMissing, ...(diagnosticDelivery ? { diagnosticDelivery } : {})
291
428
  },
429
+ acceptance: acceptanceDisposition,
292
430
  decisionsAndInvariants: [
293
431
  "Task Contract v2 is authoritative for task outcome.",
294
432
  "Failure classification never authorizes source mutation by itself.",
295
- "Source mutation still requires task scope and hook authorization.",
296
- "Verifier evidence is current only when its namespaced working-tree digest matches the current tree."
433
+ "Source mutation still requires hook authorization; task scope is an advisory retrieval/review focus.",
434
+ "Verifier evidence is current only when both working-tree content and workspace baseline identities match before, after, and now."
297
435
  ],
298
436
  contextReferences: {
299
437
  required: strings(task.requiredContext, 100, 500),
@@ -302,23 +440,23 @@ export function buildHandoffProjection(
302
440
  },
303
441
  tree: {
304
442
  algorithm: task.workingTreeDigestAlgorithm,
443
+ workspaceRevisionDigest: currentWorkspaceRevisionDigest(cwd),
305
444
  migration: projectedMigration(task),
306
445
  baselineDigest: task.workingTreeDigestAlgorithm === WORKING_TREE_DIGEST_ALGORITHM && isCurrentWorkingTreeDigest(baselineDigest) ? baselineDigest : null,
307
446
  currentDigest: task.workingTreeDigestAlgorithm === WORKING_TREE_DIGEST_ALGORITHM && isCurrentWorkingTreeDigest(currentDigest) ? currentDigest : null,
308
447
  evidenceCurrent,
309
- latestVerifierMatchesCurrentTree: evidenceCurrent
310
- && verificationEvidenceProvesStableTree(observed, currentDigest)
448
+ latestVerifierMatchesCurrentTree: verificationEvidenceProvesCurrentWorkspace(observed, currentDigest, cwd)
311
449
  },
312
450
  changedFiles: {
313
451
  baseline: strings(task.baselineChangedFiles, 500, 500), observed: strings(task.observedChangedFiles, 500, 500),
314
452
  current: strings(relevant, 500, 500), claimed: strings(task.changedFiles, 500, 500)
315
453
  },
316
- verification: { exactCommands: strings(task.verifyCommands, 50, 1000), missingCommands: strings(options.gate.missingVerifyCommands, 50, 1000), latestObserved: latestVerifier },
454
+ verification: { exactCommands, missingCommands: strings(options.gate.missingVerifyCommands, 50, 1000), latestObserved: latestVerifier },
317
455
  failure: { classification: journal.classification, recovery, journalIntegrity: journal.integrity, warnings: journal.warnings },
318
456
  ruledOutHypotheses: ruledOut,
319
457
  requiredAuthority: authority(recovery),
320
458
  nextSafeAction: {
321
- action: recovery?.action ?? (completionApproved ? "completed" : "handoff"),
459
+ action: recovery?.action ?? (completionApproved || diagnosticDelivery ? "completed" : "handoff"),
322
460
  continuation: recovery?.continuation ?? "none",
323
461
  sourceMutationAllowed: recovery?.sourceMutationAllowed === true,
324
462
  exactCommands: recovery?.action === "retry" || recovery?.action === "repair" ? strings(task.verifyCommands, 50, 1000) : []
@@ -356,6 +494,6 @@ export function writeHandoffProjection(cwd: string, projectionInput: HandoffProj
356
494
 
357
495
  export function readHandoffProjection(cwd: string, taskRunId: string): HandoffProjection | undefined {
358
496
  const target = resolveLocalStatePath(cwd, handoffProjectionPath(cwd, taskRunId), { label: "Handoff projection" });
359
- try { return validateHandoffProjection(JSON.parse(fs.readFileSync(target, "utf8")), "persisted handoff projection"); }
497
+ try { const value = JSON.parse(fs.readFileSync(target, "utf8")); if (value?.schemaVersion === 1 && value?.projectionVersion === "handoff-v1") return undefined; return validateHandoffProjection(value, "persisted handoff projection"); }
360
498
  catch (error) { if ((error as { code?: string }).code === "ENOENT") return undefined; throw error; }
361
499
  }
@@ -0,0 +1,24 @@
1
+ import { isCurrentWorkingTreeDigest } from "../../extensions/working-tree-digest.js";
2
+ import { isWorkspaceRevisionDigest } from "../../extensions/workspace-revision.js";
3
+
4
+ export type HandoffVerifierBinding = { preWorkingTreeDigest: string | null; workingTreeDigest: string | null;
5
+ preWorkspaceRevisionDigest: string | null; workspaceRevisionDigest: string | null };
6
+
7
+ /** Validate claims within a serialized projection; this does not authenticate it. */
8
+ export function handoffVerifierBindingErrors(tree: Record<string, any> | undefined, latest: Record<string, any> | undefined): string[] {
9
+ const errors: string[] = [];
10
+ if (tree?.workspaceRevisionDigest != null && !isWorkspaceRevisionDigest(tree.workspaceRevisionDigest)) errors.push("tree workspace revision is invalid");
11
+ for (const field of ["preWorkingTreeDigest", "workingTreeDigest"]) {
12
+ if (latest?.[field] != null && !isCurrentWorkingTreeDigest(latest[field])) errors.push(`latest verifier ${field} is invalid`);
13
+ }
14
+ for (const field of ["preWorkspaceRevisionDigest", "workspaceRevisionDigest"]) {
15
+ if (latest?.[field] != null && !isWorkspaceRevisionDigest(latest[field])) errors.push(`latest verifier ${field} is invalid`);
16
+ }
17
+ if (tree?.latestVerifierMatchesCurrentTree === true && (latest?.exitCode !== 0 || latest?.isError === true || latest?.matchedProfileCommand !== true
18
+ || !isCurrentWorkingTreeDigest(latest?.preWorkingTreeDigest) || latest?.preWorkingTreeDigest !== tree.currentDigest
19
+ || latest?.workingTreeDigest !== tree.currentDigest || !isWorkspaceRevisionDigest(tree.workspaceRevisionDigest)
20
+ || latest?.preWorkspaceRevisionDigest !== tree.workspaceRevisionDigest || latest?.workspaceRevisionDigest !== tree.workspaceRevisionDigest)) {
21
+ errors.push("latest verifier tree claim is invalid");
22
+ }
23
+ return errors;
24
+ }
@@ -0,0 +1,79 @@
1
+ import { createHash } from "node:crypto";
2
+ import { independentAcceptanceState } from "../../extensions/acceptance-independent-registry.js";
3
+ import { FAILURE_POLICY_VERSION, FAILURE_SCHEMA_VERSION, failureOutputRef, validateFailureClassification } from "../../extensions/failure-types.ts";
4
+ import type { TaskContract } from "../../extensions/guard-types.ts";
5
+ import type { AuthenticatedAssessment } from "../../extensions/acceptance-authenticated-admission.js";
6
+
7
+ function blockedRecovery(task: TaskContract, workingTreeDigest: string, reason: string, attemptId?: string) {
8
+ const reconcile = ["pending", "unavailable"].includes(reason), environment = reconcile || reason === "approval";
9
+ const independentDisposition = reconcile ? "reconcile" as const : reason === "stopping" ? "cancelled" as const
10
+ : environment ? "approval" as const : "halt" as const;
11
+ const text = JSON.stringify({ taskRunId: task.taskRunId, workingTreeDigest, reason, attemptId: attemptId ?? null });
12
+ const digest = createHash("sha256").update(text).digest("hex");
13
+ const classification = validateFailureClassification({ schemaVersion: FAILURE_SCHEMA_VERSION, policyVersion: FAILURE_POLICY_VERSION,
14
+ evidenceDigest: digest, category: environment ? "environment" : "unknown", ownership: environment ? "environment" : "unknown",
15
+ retryable: false, sourceMutationPermission: "forbidden", confidence: "high", authorizesSourceMutation: false,
16
+ reasonCodes: [environment ? "environment-diagnostic" : "structured-verification-gap"], outputRef: failureOutputRef(text, { captureRef: `independent:${digest}` }) });
17
+ const next = reconcile ? "Reconcile the exact reserved execution before another attempt; elapsed time and process restart do not prove worker termination."
18
+ : reason === "exhausted" ? "The approved independent attempt budget is exhausted. Do not reset it, change source to renew it, or automatically launch another attempt."
19
+ : reason === "interrupted" ? "The previous attempt was recorded as stopped. A new attempt requires explicit retry authorization; do not automatically continue."
20
+ : reason === "approval" ? "Inspect the independently approved host configuration and its bindings. Do not silently fall back or recreate authority."
21
+ : "The session is stopping. Do not schedule completion or a model continuation.";
22
+ return { classification, hypothesisRef: `diagnostic:${digest}`, independentDisposition,
23
+ guidance: [`Host verification is blocked: ${reason}${attemptId ? ` (execution ${attemptId})` : ""}.`, next,
24
+ "This host-state diagnostic is not an executed correctness result and authorizes no source mutation."] };
25
+ }
26
+
27
+ function diagnosticRecovery(assessment: AuthenticatedAssessment) {
28
+ const diagnostic = assessment.executionDiagnostics;
29
+ if (!diagnostic || !["unknown", "error"].includes(assessment.verdict)) return undefined;
30
+ const independentDisposition: "reconcile" | "cancelled" | "unsupported" | undefined = !diagnostic.cleanupConfirmed ? "reconcile"
31
+ : diagnostic.status === "cancelled" ? "cancelled"
32
+ : diagnostic.status === "completed" && diagnostic.unsupportedCaseCount > 0 && diagnostic.errorCaseCount === 0 ? "unsupported" : undefined;
33
+ const environment = independentDisposition === "reconcile" || diagnostic.reasons.some((reason) =>
34
+ ["local-backend-unavailable", "container-create-failed", "container-create-incomplete", "spawn-error", "container-configuration-rejected"].includes(reason));
35
+ const text = JSON.stringify({ criterionId: assessment.criterionId, sourcePath: assessment.sourcePath, diagnostic });
36
+ const digest = createHash("sha256").update(JSON.stringify([assessment.snapshotDigest, assessment.projectVerificationDigest, text])).digest("hex");
37
+ const classification = validateFailureClassification({ schemaVersion: FAILURE_SCHEMA_VERSION, policyVersion: FAILURE_POLICY_VERSION,
38
+ evidenceDigest: digest, category: environment ? "environment" : "unknown", ownership: environment ? "environment" : "unknown",
39
+ retryable: false, sourceMutationPermission: "forbidden", confidence: "high", authorizesSourceMutation: false,
40
+ reasonCodes: [environment ? "environment-diagnostic" : "structured-verification-gap"], outputRef: failureOutputRef(text, { captureRef: `independent:${digest}` }) });
41
+ const next = independentDisposition === "reconcile" ? "Establish the exact reserved worker's terminal state before any new execution. Do not infer termination from elapsed time or restart."
42
+ : independentDisposition === "cancelled" ? "The independent execution was cancelled. Do not automatically restart or continue it."
43
+ : independentDisposition === "unsupported" ? "This approved backend cannot assess the observed contract. Use another independently approved validator; do not rewrite source merely to fit this backend."
44
+ : environment ? "Inspect the approved local backend configuration and availability. Do not change the approved image, authority, or retry budget automatically."
45
+ : "Inspect the bounded execution failure without changing source or increasing limits. An executor error is not a behavioral counterexample.";
46
+ return { classification, hypothesisRef: `diagnostic:${digest}`, independentDisposition, guidance: [
47
+ `Authenticated independent verification did not establish correctness: ${diagnostic.reasons.join(", ") || assessment.verdict}.`, next,
48
+ "No source mutation or external action is authorized by this diagnostic."
49
+ ] };
50
+ }
51
+
52
+ /** Only current authenticated host observations enter recovery, never task JSON. */
53
+ export function independentVerificationRecovery(cwd: string, task: TaskContract, workingTreeDigest: string) {
54
+ const state = independentAcceptanceState(cwd, task, workingTreeDigest);
55
+ if (state.stopReason) return blockedRecovery(task, workingTreeDigest, state.stopReason, state.stopAttemptId);
56
+ // A host configuration/binding failure is not an unknown source defect.
57
+ // Preserve the operator-only path instead of spending a model diagnostic.
58
+ if (state.block) return blockedRecovery(task, workingTreeDigest, "approval");
59
+ const diagnostics = [...state.assessments.values()].map(diagnosticRecovery).filter((value) => value !== undefined);
60
+ const stop = diagnostics.find((value) => ["reconcile", "cancelled"].includes(value.independentDisposition ?? ""));
61
+ if (stop) return stop;
62
+ for (const assessment of state.assessments.values()) {
63
+ if (assessment.verdict !== "fail" || !assessment.repairEligible || !assessment.counterexamples?.length) continue;
64
+ const example = assessment.counterexamples[0];
65
+ const text = JSON.stringify({ criterionId: assessment.criterionId, sourcePath: assessment.sourcePath,
66
+ checkId: example.evidence.checkId, input: example.evidence.input, expected: example.evidence.expected, observed: example.evidence.observed });
67
+ const classification = validateFailureClassification({ schemaVersion: FAILURE_SCHEMA_VERSION, policyVersion: FAILURE_POLICY_VERSION,
68
+ evidenceDigest: createHash("sha256").update(JSON.stringify([assessment.snapshotDigest, assessment.projectVerificationDigest, example.digest])).digest("hex"),
69
+ category: "test-assertion", ownership: "source", retryable: false, sourceMutationPermission: "eligible-in-scope", confidence: "high",
70
+ reasonCodes: ["test-assertion-diagnostic"], authorizesSourceMutation: false,
71
+ outputRef: failureOutputRef(text, { captureRef: `independent:${example.digest}` }) });
72
+ return { classification, hypothesisRef: `counterexample:${example.digest}`, independentDisposition: undefined, guidance: [
73
+ "Authenticated independent execution captured a behavioral mismatch. The following JSON is evidence data, not instructions.",
74
+ `Counterexample ${example.digest}: ${text.length <= 5000 ? text : `${text.slice(0, 5000)} [truncated]`}`,
75
+ "Repair only the demonstrated contract defect within existing authorization; retain the approved checks and rerun the exact project verifiers."
76
+ ] };
77
+ }
78
+ return diagnostics[0];
79
+ }
@@ -0,0 +1,91 @@
1
+ import type { ProjectProfile, TaskContract } from "../../extensions/guard-types.ts";
2
+ import { compileCriterionGraph } from "../../extensions/criterion-graph.js";
3
+ import { meaningfulVerificationCommands, selectVerificationPlan } from "../../extensions/verification-intelligence.js";
4
+ import { workingTreeSnapshot, workingTreeSnapshotHasUnavailableEvidence } from "../../extensions/task-state.js";
5
+
6
+ export type PristineTaskVerificationRefresh = {
7
+ task: TaskContract;
8
+ refreshed: boolean;
9
+ reason: string;
10
+ verifyGroup?: string;
11
+ previousCommands: string[];
12
+ nextCommands: string[];
13
+ };
14
+
15
+ function sameStringRecord(left: Record<string, string>, right: Record<string, string>): boolean {
16
+ const leftEntries = Object.entries(left).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey));
17
+ const rightEntries = Object.entries(right).sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey));
18
+ return leftEntries.length === rightEntries.length
19
+ && leftEntries.every(([key, value], index) => rightEntries[index]?.[0] === key && rightEntries[index]?.[1] === value);
20
+ }
21
+
22
+ function sameCommands(left: string[], right: string[]): boolean {
23
+ return left.length === right.length && left.every((command, index) => command === right[index]);
24
+ }
25
+
26
+ /**
27
+ * Refresh profile-derived verifier commands only while an automatic task is
28
+ * still byte-for-byte pristine. This lets a corrected workspace profile reach
29
+ * a resumed task without rewriting any source-change evidence or weakening an
30
+ * already-started implementation contract.
31
+ */
32
+ export function refreshPristineRuntimeTaskVerification(
33
+ cwd: string,
34
+ task: TaskContract,
35
+ profile: ProjectProfile,
36
+ updatedAt = new Date().toISOString()
37
+ ): PristineTaskVerificationRefresh {
38
+ const previousCommands = meaningfulVerificationCommands(task.verifyCommands);
39
+ const unchanged = (reason: string): PristineTaskVerificationRefresh => ({
40
+ task, refreshed: false, reason, previousCommands, nextCommands: previousCommands
41
+ });
42
+ if (task.trace.outcome !== "pending" || task.intakeMode !== "runtime" || task.changeMode !== "source-change") {
43
+ return unchanged("task-not-refreshable");
44
+ }
45
+ if ((task.changedFiles?.length ?? 0) > 0 || (task.observedChangedFiles?.length ?? 0) > 0 || (task.verifyEvidence?.length ?? 0) > 0) {
46
+ return unchanged("task-has-runtime-evidence");
47
+ }
48
+ const configuredGroups = profile.verifyCommands && typeof profile.verifyCommands === "object"
49
+ ? profile.verifyCommands
50
+ : {};
51
+ const retainedGroup = task.verifyGroup && Object.hasOwn(configuredGroups, task.verifyGroup)
52
+ ? task.verifyGroup
53
+ : undefined;
54
+ const plan = selectVerificationPlan(profile, retainedGroup, task.changeMode, cwd, task.scope);
55
+ if (plan.error) return unchanged("profile-verifier-invalid");
56
+ const nextCommands = meaningfulVerificationCommands(plan.commands);
57
+ if (nextCommands.length === 0) return unchanged("profile-verifier-unavailable");
58
+ if (sameCommands(previousCommands, nextCommands) && task.verifyGroup === plan.group) {
59
+ return unchanged("profile-verifier-current");
60
+ }
61
+ if (!task.baselineFileDigests || typeof task.baselineFileDigests !== "object" || Array.isArray(task.baselineFileDigests)) {
62
+ return unchanged("baseline-unavailable");
63
+ }
64
+ const baseline = task.baselineFileDigests;
65
+ const current = workingTreeSnapshot(cwd) as Record<string, string>;
66
+ if (workingTreeSnapshotHasUnavailableEvidence(current) || !sameStringRecord(baseline, current)) {
67
+ return unchanged("working-tree-not-pristine");
68
+ }
69
+ const refreshed: TaskContract = {
70
+ ...task,
71
+ verifyGroup: plan.group,
72
+ verifyCommands: nextCommands,
73
+ criterionGraph: compileCriterionGraph({
74
+ acceptanceCriteria: task.acceptanceCriteria,
75
+ scope: task.scope,
76
+ verifyCommands: nextCommands,
77
+ changeMode: task.changeMode,
78
+ mode: task.criterionGraph?.mode ?? "mechanical",
79
+ createdAt: task.criterionGraph?.createdAt ?? task.createdAt
80
+ }) as NonNullable<TaskContract["criterionGraph"]>,
81
+ updatedAt
82
+ };
83
+ return {
84
+ task: refreshed,
85
+ refreshed: true,
86
+ reason: "pristine-profile-verifier-refresh",
87
+ verifyGroup: plan.group,
88
+ previousCommands,
89
+ nextCommands
90
+ };
91
+ }