@piagent/platform 1.6.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (654) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +8 -2
  3. package/README.vi.md +11 -2
  4. package/adapters/common/assurance-producers.json +109 -0
  5. package/adapters/common/structured-assurance-facts.mjs +153 -0
  6. package/adapters/node-typescript/contract-families.json +2811 -0
  7. package/adapters/node-typescript/contract-families.md +90 -0
  8. package/benchmarks/production-v1/grade.mjs +20 -0
  9. package/benchmarks/production-v1/spend-control.v1.json +3 -3
  10. package/benchmarks/production-v2/grade.mjs +892 -0
  11. package/benchmarks/production-v2/project/README.md +7 -0
  12. package/benchmarks/production-v2/project/config/service.json +4 -0
  13. package/benchmarks/production-v2/project/data/audit-ledger.jsonl +1 -0
  14. package/benchmarks/production-v2/project/docs/ops.md +3 -0
  15. package/benchmarks/production-v2/project/logs/incident.log +2 -0
  16. package/benchmarks/production-v2/project/package.json +11 -0
  17. package/benchmarks/production-v2/project/scripts/check.mjs +21 -0
  18. package/benchmarks/production-v2/project/src/backend/auth.js +3 -0
  19. package/benchmarks/production-v2/project/src/backend/billing-window.js +4 -0
  20. package/benchmarks/production-v2/project/src/backend/cache.js +15 -0
  21. package/benchmarks/production-v2/project/src/backend/invoice.js +4 -0
  22. package/benchmarks/production-v2/project/src/backend/revocation-cache.js +3 -0
  23. package/benchmarks/production-v2/project/src/data/csv.js +3 -0
  24. package/benchmarks/production-v2/project/src/data/dedup.js +5 -0
  25. package/benchmarks/production-v2/project/src/data/migration.js +9 -0
  26. package/benchmarks/production-v2/project/src/data/ndjson-stream.js +5 -0
  27. package/benchmarks/production-v2/project/src/data/versioned-replay.js +8 -0
  28. package/benchmarks/production-v2/project/src/frontend/chat-events.js +7 -0
  29. package/benchmarks/production-v2/project/src/frontend/pagination.js +8 -0
  30. package/benchmarks/production-v2/project/src/frontend/request-lifecycle.js +15 -0
  31. package/benchmarks/production-v2/project/src/frontend/search-state.js +8 -0
  32. package/benchmarks/production-v2/project/src/frontend/unicode-search.js +7 -0
  33. package/benchmarks/production-v2/project/src/fullstack/contract-sync.js +10 -0
  34. package/benchmarks/production-v2/project/src/platform/args.js +10 -0
  35. package/benchmarks/production-v2/project/src/platform/config.js +7 -0
  36. package/benchmarks/production-v2/project/src/platform/workflow-session.js +9 -0
  37. package/benchmarks/production-v2/project/src/platform/workspace.js +13 -0
  38. package/benchmarks/production-v2/project/src/reliability/checkpoint.js +5 -0
  39. package/benchmarks/production-v2/project/src/reliability/expiry.js +5 -0
  40. package/benchmarks/production-v2/project/src/reliability/retry.js +15 -0
  41. package/benchmarks/production-v2/project/test/smoke.test.js +21 -0
  42. package/benchmarks/production-v2/project/vendor/README.md +1 -0
  43. package/benchmarks/production-v2/prompts/abort-reconnect-supersession.md +11 -0
  44. package/benchmarks/production-v2/prompts/backend-frontend-contract-sync.md +12 -0
  45. package/benchmarks/production-v2/prompts/billing-cutoff-clock-skew.md +11 -0
  46. package/benchmarks/production-v2/prompts/bounded-retry.md +7 -0
  47. package/benchmarks/production-v2/prompts/chunked-record-boundary.md +9 -0
  48. package/benchmarks/production-v2/prompts/cli-double-dash.md +7 -0
  49. package/benchmarks/production-v2/prompts/config-precedence.md +6 -0
  50. package/benchmarks/production-v2/prompts/destructive-history-refusal.md +3 -0
  51. package/benchmarks/production-v2/prompts/expiry-boundary.md +7 -0
  52. package/benchmarks/production-v2/prompts/idempotent-replay-conflict.md +11 -0
  53. package/benchmarks/production-v2/prompts/incident-diagnosis.md +4 -0
  54. package/benchmarks/production-v2/prompts/invoice-rounding.md +9 -0
  55. package/benchmarks/production-v2/prompts/journeys/config-precedence-scout.md +3 -0
  56. package/benchmarks/production-v2/prompts/journeys/expiry-boundary-scout.md +3 -0
  57. package/benchmarks/production-v2/prompts/journeys/quoted-csv-scout.md +3 -0
  58. package/benchmarks/production-v2/prompts/journeys/recover-after-uncertain-send.md +4 -0
  59. package/benchmarks/production-v2/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  60. package/benchmarks/production-v2/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  61. package/benchmarks/production-v2/prompts/journeys/stable-dedup-scout.md +3 -0
  62. package/benchmarks/production-v2/prompts/journeys/stale-search-response-scout.md +3 -0
  63. package/benchmarks/production-v2/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  64. package/benchmarks/production-v2/prompts/journeys/verify-current-contract.md +4 -0
  65. package/benchmarks/production-v2/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  66. package/benchmarks/production-v2/prompts/pagination-boundary.md +7 -0
  67. package/benchmarks/production-v2/prompts/protected-env-refusal.md +2 -0
  68. package/benchmarks/production-v2/prompts/quoted-csv.md +6 -0
  69. package/benchmarks/production-v2/prompts/reconnect-chat-event-order.md +19 -0
  70. package/benchmarks/production-v2/prompts/repository-prompt-injection.md +5 -0
  71. package/benchmarks/production-v2/prompts/resumable-checkpoint-partial-failure.md +11 -0
  72. package/benchmarks/production-v2/prompts/revoked-session-cache.md +10 -0
  73. package/benchmarks/production-v2/prompts/schema-migration.md +6 -0
  74. package/benchmarks/production-v2/prompts/stable-dedup.md +6 -0
  75. package/benchmarks/production-v2/prompts/stale-search-response.md +6 -0
  76. package/benchmarks/production-v2/prompts/tenant-cache-isolation.md +6 -0
  77. package/benchmarks/production-v2/prompts/tenant-role-authorization.md +6 -0
  78. package/benchmarks/production-v2/prompts/unicode-search.md +6 -0
  79. package/benchmarks/production-v2/prompts/workflow-switch-same-session.md +30 -0
  80. package/benchmarks/production-v2/prompts/workspace-order.md +7 -0
  81. package/benchmarks/production-v2/spend-control.v1.json +115 -0
  82. package/benchmarks/production-v2/suite.json +1009 -0
  83. package/benchmarks/production-v2/variant.mjs +169 -0
  84. package/benchmarks/production-v3/CONTRACT-REVISION-20260922.md +31 -0
  85. package/benchmarks/production-v3/calibration/corpus.v1.json +63 -0
  86. package/benchmarks/production-v3/calibration/human-review-rubric.v1.json +36 -0
  87. package/benchmarks/production-v3/grade.mjs +1017 -0
  88. package/benchmarks/production-v3/project/README.md +7 -0
  89. package/benchmarks/production-v3/project/config/service.json +4 -0
  90. package/benchmarks/production-v3/project/data/audit-ledger.jsonl +1 -0
  91. package/benchmarks/production-v3/project/docs/ops.md +3 -0
  92. package/benchmarks/production-v3/project/logs/incident.log +2 -0
  93. package/benchmarks/production-v3/project/package.json +11 -0
  94. package/benchmarks/production-v3/project/scripts/check.mjs +21 -0
  95. package/benchmarks/production-v3/project/src/backend/auth.js +3 -0
  96. package/benchmarks/production-v3/project/src/backend/billing-window.js +4 -0
  97. package/benchmarks/production-v3/project/src/backend/cache.js +15 -0
  98. package/benchmarks/production-v3/project/src/backend/invoice.js +4 -0
  99. package/benchmarks/production-v3/project/src/backend/revocation-cache.js +12 -0
  100. package/benchmarks/production-v3/project/src/data/csv.js +3 -0
  101. package/benchmarks/production-v3/project/src/data/dedup.js +5 -0
  102. package/benchmarks/production-v3/project/src/data/migration.js +9 -0
  103. package/benchmarks/production-v3/project/src/data/ndjson-stream.js +5 -0
  104. package/benchmarks/production-v3/project/src/data/versioned-replay.js +8 -0
  105. package/benchmarks/production-v3/project/src/frontend/chat-events.js +7 -0
  106. package/benchmarks/production-v3/project/src/frontend/pagination.js +8 -0
  107. package/benchmarks/production-v3/project/src/frontend/request-lifecycle.js +23 -0
  108. package/benchmarks/production-v3/project/src/frontend/search-state.js +8 -0
  109. package/benchmarks/production-v3/project/src/frontend/unicode-search.js +7 -0
  110. package/benchmarks/production-v3/project/src/fullstack/contract-sync.js +10 -0
  111. package/benchmarks/production-v3/project/src/platform/args.js +10 -0
  112. package/benchmarks/production-v3/project/src/platform/config.js +7 -0
  113. package/benchmarks/production-v3/project/src/platform/workflow-session.js +9 -0
  114. package/benchmarks/production-v3/project/src/platform/workspace.js +13 -0
  115. package/benchmarks/production-v3/project/src/reliability/checkpoint.js +5 -0
  116. package/benchmarks/production-v3/project/src/reliability/expiry.js +14 -0
  117. package/benchmarks/production-v3/project/src/reliability/retry.js +15 -0
  118. package/benchmarks/production-v3/project/test/smoke.test.js +21 -0
  119. package/benchmarks/production-v3/project/vendor/README.md +1 -0
  120. package/benchmarks/production-v3/prompts/abort-reconnect-supersession.md +11 -0
  121. package/benchmarks/production-v3/prompts/backend-frontend-contract-sync.md +20 -0
  122. package/benchmarks/production-v3/prompts/billing-cutoff-clock-skew.md +11 -0
  123. package/benchmarks/production-v3/prompts/bounded-retry.md +7 -0
  124. package/benchmarks/production-v3/prompts/chunked-record-boundary.md +11 -0
  125. package/benchmarks/production-v3/prompts/cli-double-dash.md +7 -0
  126. package/benchmarks/production-v3/prompts/config-precedence.md +6 -0
  127. package/benchmarks/production-v3/prompts/destructive-history-refusal.md +9 -0
  128. package/benchmarks/production-v3/prompts/expiry-boundary.md +14 -0
  129. package/benchmarks/production-v3/prompts/idempotent-replay-conflict.md +13 -0
  130. package/benchmarks/production-v3/prompts/incident-diagnosis.md +4 -0
  131. package/benchmarks/production-v3/prompts/invoice-rounding.md +9 -0
  132. package/benchmarks/production-v3/prompts/journeys/config-precedence-scout.md +3 -0
  133. package/benchmarks/production-v3/prompts/journeys/expiry-boundary-scout.md +3 -0
  134. package/benchmarks/production-v3/prompts/journeys/quoted-csv-scout.md +3 -0
  135. package/benchmarks/production-v3/prompts/journeys/recover-after-uncertain-send.md +4 -0
  136. package/benchmarks/production-v3/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  137. package/benchmarks/production-v3/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  138. package/benchmarks/production-v3/prompts/journeys/stable-dedup-scout.md +3 -0
  139. package/benchmarks/production-v3/prompts/journeys/stale-search-response-scout.md +3 -0
  140. package/benchmarks/production-v3/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  141. package/benchmarks/production-v3/prompts/journeys/verify-current-contract.md +4 -0
  142. package/benchmarks/production-v3/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  143. package/benchmarks/production-v3/prompts/pagination-boundary.md +9 -0
  144. package/benchmarks/production-v3/prompts/protected-env-refusal.md +8 -0
  145. package/benchmarks/production-v3/prompts/quoted-csv.md +6 -0
  146. package/benchmarks/production-v3/prompts/reconnect-chat-event-order.md +20 -0
  147. package/benchmarks/production-v3/prompts/repository-prompt-injection.md +5 -0
  148. package/benchmarks/production-v3/prompts/resumable-checkpoint-partial-failure.md +15 -0
  149. package/benchmarks/production-v3/prompts/revoked-session-cache.md +10 -0
  150. package/benchmarks/production-v3/prompts/schema-migration.md +6 -0
  151. package/benchmarks/production-v3/prompts/stable-dedup.md +6 -0
  152. package/benchmarks/production-v3/prompts/stale-search-response.md +6 -0
  153. package/benchmarks/production-v3/prompts/tenant-cache-isolation.md +6 -0
  154. package/benchmarks/production-v3/prompts/tenant-role-authorization.md +6 -0
  155. package/benchmarks/production-v3/prompts/unicode-search.md +6 -0
  156. package/benchmarks/production-v3/prompts/workflow-switch-same-session.md +30 -0
  157. package/benchmarks/production-v3/prompts/workspace-order.md +7 -0
  158. package/benchmarks/production-v3/public-checks/abort-reconnect-supersession.js +34 -0
  159. package/benchmarks/production-v3/public-checks/expiry-boundary.js +29 -0
  160. package/benchmarks/production-v3/public-checks/revoked-session-cache.js +20 -0
  161. package/benchmarks/production-v3/spend-control.v1.json +121 -0
  162. package/benchmarks/production-v3/suite.json +1010 -0
  163. package/benchmarks/production-v3/variant.mjs +178 -0
  164. package/catalog/capabilities.json +2 -2
  165. package/docs/benchmark-codex-mcp-metadata-contract-v1.md +159 -0
  166. package/docs/benchmark-codex-mcp-metadata-contract-v2.md +182 -0
  167. package/docs/benchmark-codex-mcp-metadata-contract-v3.md +194 -0
  168. package/docs/benchmark-public-contract-addendum-v2.md +85 -0
  169. package/docs/benchmark-public-contract-addendum-v3.md +116 -0
  170. package/docs/command-reference-vietnamese.md +10 -7
  171. package/docs/context-window-policy.md +3 -3
  172. package/docs/distribution-standard.md +9 -9
  173. package/docs/languages.json +2 -2
  174. package/docs/model-options.md +20 -15
  175. package/docs/operator-manual-vietnamese.md +12 -12
  176. package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
  177. package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
  178. package/docs/piagent-core-improvement-plan.md +528 -0
  179. package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
  180. package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
  181. package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
  182. package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
  183. package/docs/piagent-open-session-wait.md +19 -0
  184. package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
  185. package/docs/publishing-for-teams.md +3 -0
  186. package/docs/quality-benchmark.md +128 -8
  187. package/docs/quickstart-vietnamese.md +2 -2
  188. package/docs/release-install-policy.md +38 -11
  189. package/docs/research/harness-next-evidence-review.md +113 -0
  190. package/docs/team-onboarding.md +7 -7
  191. package/docs/third-party-neutrality.md +7 -0
  192. package/docs/usage-observability.md +1 -1
  193. package/docs-site/architecture.html +1 -1
  194. package/docs-site/benchmark.html +1 -1
  195. package/docs-site/commands.html +1 -1
  196. package/docs-site/content/en/runtime.html +1 -1
  197. package/docs-site/content/en/whats-new.html +23 -0
  198. package/docs-site/content/runtime.html +2 -2
  199. package/docs-site/content/whats-new.html +23 -0
  200. package/docs-site/context-engine.html +1 -1
  201. package/docs-site/en/architecture.html +1 -1
  202. package/docs-site/en/benchmark.html +1 -1
  203. package/docs-site/en/commands.html +1 -1
  204. package/docs-site/en/context-engine.html +1 -1
  205. package/docs-site/en/index.html +1 -1
  206. package/docs-site/en/mcp-approval.html +1 -1
  207. package/docs-site/en/mcp-auth.html +1 -1
  208. package/docs-site/en/mcp-servers.html +1 -1
  209. package/docs-site/en/mcp.html +1 -1
  210. package/docs-site/en/permissions.html +1 -1
  211. package/docs-site/en/profiles.html +1 -1
  212. package/docs-site/en/quickstart.html +1 -1
  213. package/docs-site/en/runtime.html +2 -2
  214. package/docs-site/en/scope.html +1 -1
  215. package/docs-site/en/security.html +1 -1
  216. package/docs-site/en/team.html +1 -1
  217. package/docs-site/en/whats-new.html +24 -1
  218. package/docs-site/en/workflows.html +1 -1
  219. package/docs-site/index.html +1 -1
  220. package/docs-site/mcp-approval.html +1 -1
  221. package/docs-site/mcp-auth.html +1 -1
  222. package/docs-site/mcp-servers.html +1 -1
  223. package/docs-site/mcp.html +1 -1
  224. package/docs-site/permissions.html +1 -1
  225. package/docs-site/profiles.html +1 -1
  226. package/docs-site/quickstart.html +1 -1
  227. package/docs-site/runtime.html +3 -3
  228. package/docs-site/scope.html +1 -1
  229. package/docs-site/security.html +1 -1
  230. package/docs-site/team.html +1 -1
  231. package/docs-site/whats-new.html +24 -1
  232. package/docs-site/workflows.html +1 -1
  233. package/evals/architecture-conformance-v1/lane.json +18 -0
  234. package/evals/architecture-conformance-v1/runner.mjs +77 -0
  235. package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
  236. package/evals/fixtures/approved-host-contracts.valid.json +43 -0
  237. package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
  238. package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
  239. package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
  240. package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
  241. package/evals/fixtures/composite-criterion.invalid.json +10 -0
  242. package/evals/fixtures/composite-criterion.valid.json +33 -0
  243. package/evals/fixtures/contract-family-library.invalid.json +42 -0
  244. package/evals/fixtures/contract-family-library.valid.json +41 -0
  245. package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
  246. package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
  247. package/evals/fixtures/host-contract-plan.invalid.json +42 -0
  248. package/evals/fixtures/host-contract-plan.valid.json +41 -0
  249. package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
  250. package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
  251. package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
  252. package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
  253. package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
  254. package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
  255. package/evals/fs5-artifact-archive/README.md +32 -0
  256. package/evals/fs5-artifact-archive/manifest.json +148 -0
  257. package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
  258. package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
  259. package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
  260. package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
  261. package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
  262. package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
  263. package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
  264. package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
  265. package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
  266. package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
  267. package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
  268. package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
  269. package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
  270. package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
  271. package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
  272. package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
  273. package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
  274. package/evals/fs5-causal-arm.v1.json +9 -5
  275. package/evals/fs5-pilot-protocol.v1.json +1 -1
  276. package/evals/fs5-pilot-protocol.v4.json +4 -4
  277. package/evals/fs5-pilot-protocol.v5.json +6 -5
  278. package/evals/harness-next/development-corpus.mjs +106 -0
  279. package/evals/harness-next/resource-budget-probe.mjs +38 -0
  280. package/evals/harness-next/run-calibration.mjs +83 -0
  281. package/evals/harness-next/run-resource-probe.mjs +55 -0
  282. package/evals/harness-next/selected-development-corpus.mjs +27 -0
  283. package/evals/harness-next.v1.json +51 -0
  284. package/evals/long-horizon-v1/README.md +19 -0
  285. package/evals/long-horizon-v1/runner.mjs +116 -48
  286. package/evals/long-horizon-v1/worker.mjs +77 -30
  287. package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
  288. package/evals/private-holdout-v1/README.md +5 -2
  289. package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
  290. package/package.json +9 -4
  291. package/packages/piagent-core/README.md +2 -2
  292. package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
  293. package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
  294. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
  295. package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
  296. package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
  297. package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
  298. package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
  299. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
  300. package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
  301. package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
  302. package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
  303. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +2 -1
  304. package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
  305. package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
  306. package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
  307. package/packages/piagent-core/benchmark/benchmark-core.js +107 -107
  308. package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
  309. package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
  310. package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
  311. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
  312. package/packages/piagent-core/benchmark/benchmark-forensics.js +63 -50
  313. package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
  314. package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
  315. package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
  316. package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
  317. package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
  318. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
  319. package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
  320. package/packages/piagent-core/benchmark/benchmark-preflight.js +69 -8
  321. package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
  322. package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
  323. package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
  324. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +162 -45
  325. package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
  326. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
  327. package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
  328. package/packages/piagent-core/benchmark/benchmark-record-validation.js +269 -3
  329. package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
  330. package/packages/piagent-core/benchmark/benchmark-report.js +79 -4
  331. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
  332. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
  333. package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
  334. package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
  335. package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
  336. package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
  337. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +144 -128
  338. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
  339. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
  340. package/packages/piagent-core/benchmark/benchmark-suite.js +211 -4
  341. package/packages/piagent-core/benchmark/benchmark-summary-support.js +30 -2
  342. package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
  343. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
  344. package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
  345. package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
  346. package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
  347. package/packages/piagent-core/benchmark/benchmark-usage.js +395 -33
  348. package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
  349. package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
  350. package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
  351. package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
  352. package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
  353. package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
  354. package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
  355. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +264 -70
  356. package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
  357. package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
  358. package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
  359. package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
  360. package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
  361. package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
  362. package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
  363. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
  364. package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
  365. package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
  366. package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
  367. package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
  368. package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
  369. package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
  370. package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
  371. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
  372. package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
  373. package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
  374. package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
  375. package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
  376. package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
  377. package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
  378. package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
  379. package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
  380. package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
  381. package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
  382. package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
  383. package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
  384. package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
  385. package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
  386. package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
  387. package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
  388. package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
  389. package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
  390. package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
  391. package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
  392. package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
  393. package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
  394. package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
  395. package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
  396. package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
  397. package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
  398. package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
  399. package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
  400. package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
  401. package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
  402. package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
  403. package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
  404. package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
  405. package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
  406. package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
  407. package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
  408. package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
  409. package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
  410. package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
  411. package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
  412. package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
  413. package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
  414. package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
  415. package/packages/piagent-core/extensions/acceptance-receipt.js +139 -152
  416. package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
  417. package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
  418. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
  419. package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
  420. package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
  421. package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
  422. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
  423. package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
  424. package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
  425. package/packages/piagent-core/extensions/context-engine.js +11 -6
  426. package/packages/piagent-core/extensions/criterion-context-pack.js +96 -4
  427. package/packages/piagent-core/extensions/failure-types.ts +2 -2
  428. package/packages/piagent-core/extensions/guard-types.ts +5 -1
  429. package/packages/piagent-core/extensions/piagent-guard.ts +197 -155
  430. package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
  431. package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
  432. package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
  433. package/packages/piagent-core/extensions/task-contract-view.js +4 -4
  434. package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
  435. package/packages/piagent-core/extensions/task-journal.js +48 -3
  436. package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
  437. package/packages/piagent-core/extensions/task-state.js +74 -38
  438. package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
  439. package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
  440. package/packages/piagent-core/extensions/verification-intelligence.js +60 -8
  441. package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
  442. package/packages/piagent-core/extensions/workspace-revision.js +48 -0
  443. package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
  444. package/packages/piagent-core/package.json +3 -3
  445. package/packages/piagent-core/policies/base-policy.json +1 -0
  446. package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
  447. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
  448. package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
  449. package/packages/piagent-core/runtime/hooks/completion-hook.ts +76 -83
  450. package/packages/piagent-core/runtime/hooks/input-hook.ts +92 -7
  451. package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
  452. package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
  453. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +50 -18
  454. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +53 -20
  455. package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
  456. package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
  457. package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
  458. package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
  459. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
  460. package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
  461. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
  462. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +49 -8
  463. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +61 -15
  464. package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
  465. package/packages/piagent-core/runtime/model/model-route-policy.ts +33 -13
  466. package/packages/piagent-core/runtime/model/model-route-types.ts +10 -6
  467. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
  468. package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
  469. package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
  470. package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
  471. package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
  472. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +12 -7
  473. package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
  474. package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
  475. package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
  476. package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
  477. package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
  478. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +11 -2
  479. package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
  480. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +192 -57
  481. package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
  482. package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
  483. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +27 -39
  484. package/packages/piagent-core/runtime/recovery/resume-state.ts +8 -5
  485. package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
  486. package/packages/piagent-core/runtime/registration/context-commands.ts +12 -8
  487. package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
  488. package/packages/piagent-core/runtime/registration/policy-tools.ts +5 -3
  489. package/packages/piagent-core/runtime/registration/session-commands.ts +9 -7
  490. package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
  491. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +27 -11
  492. package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
  493. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +5 -2
  494. package/packages/piagent-core/runtime/registration/task-start-tool.ts +23 -23
  495. package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
  496. package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
  497. package/packages/piagent-core/runtime/session/message-signals.ts +6 -22
  498. package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
  499. package/packages/piagent-core/runtime/session/runtime-state.ts +29 -35
  500. package/packages/piagent-core/runtime/session/system-prompt.ts +3 -3
  501. package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
  502. package/packages/piagent-core/runtime/session/usage.ts +4 -3
  503. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
  504. package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
  505. package/packages/piagent-core/runtime/tools/phase-tools.ts +3 -2
  506. package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
  507. package/packages/piagent-core/runtime/tools/tool-groups.ts +10 -3
  508. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
  509. package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
  510. package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
  511. package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
  512. package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
  513. package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
  514. package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
  515. package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
  516. package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
  517. package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
  518. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +11 -11
  519. package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
  520. package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
  521. package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
  522. package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
  523. package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
  524. package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
  525. package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
  526. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +44 -7
  527. package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
  528. package/packages/piagent-core/runtime/workflows/task-intake.ts +221 -242
  529. package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
  530. package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
  531. package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
  532. package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
  533. package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
  534. package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
  535. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-B4XehTCU.js → MarkdownMessage-DMU7Xe_O.js} +1 -1
  536. package/packages/piagent-webui/dist/client/assets/index-Cui9AAV_.js +176 -0
  537. package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
  538. package/packages/piagent-webui/dist/client/index.html +2 -2
  539. package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
  540. package/packages/piagent-webui/extension/piagent-webui.ts +10 -2
  541. package/packages/piagent-webui/extension/review-controller.ts +29 -6
  542. package/packages/piagent-webui/extension/same-session-bridge.ts +6 -7
  543. package/packages/piagent-webui/extension/session-stream-adapter.ts +60 -11
  544. package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
  545. package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
  546. package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
  547. package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
  548. package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
  549. package/packages/piagent-webui/gateway/gateway-session-stream.ts +141 -19
  550. package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
  551. package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
  552. package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
  553. package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
  554. package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
  555. package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
  556. package/packages/piagent-webui/gateway/session-inspection-registry.ts +14 -6
  557. package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
  558. package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
  559. package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
  560. package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
  561. package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
  562. package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
  563. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +114 -114
  564. package/packages/piagent-webui/server/core-inspection-provider.ts +73 -14
  565. package/packages/piagent-webui/server/loopback-server.ts +9 -7
  566. package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
  567. package/packages/piagent-webui/server/transcript-projection.ts +65 -12
  568. package/packages/piagent-webui/shared/message-correlation.ts +25 -0
  569. package/schemas/approved-host-contracts.schema.json +973 -0
  570. package/schemas/benchmark-attempt-outcome.schema.json +303 -0
  571. package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
  572. package/schemas/composite-criterion.schema.json +788 -0
  573. package/schemas/contract-family-library.schema.json +28 -0
  574. package/schemas/contract-selection-recipe.schema.json +31 -0
  575. package/schemas/failure-evidence.schema.json +2 -2
  576. package/schemas/helper-request.schema.json +16 -4
  577. package/schemas/host-contract-plan.schema.json +25 -0
  578. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
  579. package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
  580. package/schemas/piagent-webui/runtime-event-v2.schema.json +32 -1
  581. package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
  582. package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
  583. package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
  584. package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
  585. package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
  586. package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
  587. package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
  588. package/schemas/public-contracts/revocation-v1.schema.json +87 -0
  589. package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
  590. package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
  591. package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
  592. package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
  593. package/schemas/task-contract.schema.json +30 -0
  594. package/scripts/approve-independent-verification.mjs +57 -0
  595. package/scripts/benchmark-arm-observer.mjs +320 -0
  596. package/scripts/benchmark-budget-ipc.mjs +34 -0
  597. package/scripts/benchmark-budget-launcher.mjs +91 -0
  598. package/scripts/benchmark-budget-processes.mjs +133 -0
  599. package/scripts/benchmark-budget-publication.mjs +228 -0
  600. package/scripts/benchmark-budget-runtime.mjs +136 -0
  601. package/scripts/benchmark-candidate-ablation.mjs +265 -0
  602. package/scripts/benchmark-codex-journey.mjs +406 -0
  603. package/scripts/benchmark-independent-verification.mjs +628 -0
  604. package/scripts/benchmark-journey-outcome.mjs +92 -0
  605. package/scripts/benchmark-production-v3-human-review.mjs +192 -0
  606. package/scripts/benchmark-public-input-catalog.mjs +158 -0
  607. package/scripts/benchmark-registered-plan-author.mjs +355 -0
  608. package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
  609. package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
  610. package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
  611. package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
  612. package/scripts/benchmark-runner-completion.mjs +133 -0
  613. package/scripts/benchmark-runner-configuration.mjs +159 -0
  614. package/scripts/benchmark-runner-core.mjs +217 -388
  615. package/scripts/benchmark-runner-finalization.mjs +140 -27
  616. package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
  617. package/scripts/benchmark-runner-schedule.mjs +256 -0
  618. package/scripts/benchmark-runner-support.mjs +136 -4
  619. package/scripts/benchmark-runner.mjs +95 -18
  620. package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
  621. package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
  622. package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
  623. package/scripts/benchmark-scoped-pi-router.mjs +196 -0
  624. package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
  625. package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
  626. package/scripts/benchmark-scoped-session-custody.mjs +599 -0
  627. package/scripts/benchmark-scoped-session-factory.mjs +342 -0
  628. package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
  629. package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
  630. package/scripts/benchmark-session-evaluator.mjs +169 -0
  631. package/scripts/benchmark-session-provider-boundary.mjs +62 -0
  632. package/scripts/benchmark-session-usage.mjs +28 -0
  633. package/scripts/benchmark-session.mjs +343 -50
  634. package/scripts/benchmark-webui-journey.mjs +678 -0
  635. package/scripts/check-public-wording.mjs +46 -0
  636. package/scripts/configure-model-scope.sh +6 -2
  637. package/scripts/fs4-readiness-evaluation.mjs +7 -1
  638. package/scripts/install-global.sh +2 -2
  639. package/scripts/model-route-evaluation-core.ts +1 -0
  640. package/scripts/phase-tools-evaluation.mjs +1 -0
  641. package/scripts/pi-auto.sh +7 -1
  642. package/scripts/pi-model-route.mjs +1 -1
  643. package/scripts/pi-usage-history.mjs +201 -11
  644. package/scripts/piagent-cli.mjs +8 -0
  645. package/scripts/private-holdout-readiness.mjs +7 -1
  646. package/scripts/public-evaluation-exposure.mjs +140 -0
  647. package/scripts/select-independent-verification.mjs +62 -0
  648. package/scripts/setup.sh +2 -2
  649. package/scripts/typescript-loader.mjs +135 -1
  650. package/scripts/update-global.mjs +6 -7
  651. package/scripts/verify-local.sh +37 -56
  652. package/scripts/verify-release-identity.mjs +5 -3
  653. package/templates/global/settings.json +5 -1
  654. package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +0 -176
@@ -1,43 +1,34 @@
1
+ import { criticalAcceptanceRecoveryGuidance, type CriticalRecoveryProjection } from "../recovery/acceptance-recovery-guidance.ts";
1
2
  import crypto from "node:crypto";
2
3
  import path from "node:path";
4
+ import { completionPreparationCurrent, completionPreparationDeferred, type CompletionPreparation } from "../verification/completion-preparation.ts";
5
+ import { apiBaselineCriterionEvidence as apiBaselineEvidence } from "../verification/acceptance-api-baseline.js";
6
+ import { createCompositeCompletionFinalizer } from "../verification/composite-completion-finalizer.ts";
3
7
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
4
-
5
- import {
6
- acceptanceCriticalRecoveryProjection,
7
- applyAcceptanceRecoveryProvenance
8
- } from "../../extensions/acceptance-receipt.js";
8
+ import { acceptanceCriticalRecoveryProjection, applyAcceptanceRecoveryProvenance } from "../../extensions/acceptance-receipt.js";
9
9
  import { hasDurableContextEvidence } from "../../extensions/context-evidence.js";
10
10
  import type { TaskContract } from "../../extensions/guard-types.js";
11
11
  import { applyAssistedReadOnlyFinalHandoff, runtimeLifecycleMode, workingTreeEvidenceDigest } from "../../extensions/task-lifecycle.js";
12
12
  import { recordCompletionAudit } from "../../extensions/task-runtime-audit.js";
13
13
  import { workingTreeSnapshot } from "../../extensions/task-state.js";
14
+ import { currentWorkspaceRevisionDigest } from "../../extensions/workspace-revision.js";
14
15
  import { taskDeltaFilesFromSnapshot } from "../../extensions/task-contract-view.js";
15
16
  import { latestObservedVerification, verificationEvidenceProvesStableTree } from "../../extensions/verification-intelligence.js";
16
- import {
17
- assistantMessageHasToolCall,
18
- assistantMessageText,
19
- looksLikeCompletionClaim,
20
- looksLikeIncompleteHandoff
21
- } from "../session/message-signals.ts";
17
+ import { assistantMessageHasToolCall, assistantMessageText, prependAssistantNotice, looksLikeCompletionClaim, looksLikeIncompleteHandoff } from "../session/message-signals.ts";
22
18
  import { RuntimeSessionState, type ObservedTaskContext } from "../session/runtime-state.ts";
23
19
  import type { RecoveryDecision } from "../recovery/recovery-policy.ts";
20
+ import { independentVerificationRecovery } from "../recovery/independent-verification-recovery.ts";
24
21
  import { buildHandoffProjection, handoffProjectionPath, writeHandoffProjection } from "../recovery/handoff-projection.ts";
25
22
  import { evaluateExactFinalOutputContract } from "../quality/exact-output-contract.ts";
26
23
  import { performanceReviewGuidance, taskPerformanceAssurance } from "../quality/performance-assurance.ts";
27
- import { planRecoveryContinuation, reserveSemanticReviewContinuation } from "../recovery/continuation-budget.ts";
24
+ import { protectedRefusalHandoffMatches, settleNativeProtectedRefusal } from "./protected-refusal-completion.ts";
25
+ import { planRecoveryContinuation, reserveSemanticReviewContinuation, terminalRecoveryForContinuationDenial } from "../recovery/continuation-budget.ts";
28
26
  import { semanticRepairProvenance } from "../recovery/semantic-repair-handshake.ts";
29
27
  import { observeTrajectorySync } from "../trajectory/trajectory-observability.ts";
30
28
  import type { TrajectorySyncOptions, TrajectorySyncResult } from "../trajectory/trajectory-runtime.ts";
31
29
  import { readTrajectoryStore } from "../trajectory/trajectory-store.ts";
32
-
33
- type CompletionGate = { decision: "pass" | "fail"; missing: string[]; missingVerifyCommands: string[] };
34
-
35
- type CriticalRecoveryProjection = {
36
- criterionText: string;
37
- targets: string[];
38
- missingDimensions: string[];
39
- proofHints: string[];
40
- };
30
+ type CompletionGate = { decision: "pass" | "fail"; missing: string[]; missingVerifyCommands: string[];
31
+ acceptanceProof?: { mode: "enforce" | "diagnostic"; pendingCriterionIds: string[]; missing: string[] } };
41
32
  function exactPathCoverage(expectedPaths: string[], reviewedPaths: string[] | undefined): boolean {
42
33
  const expected = [...new Set(expectedPaths)].sort();
43
34
  const reviewed = [...new Set(reviewedPaths ?? [])].sort();
@@ -45,30 +36,13 @@ function exactPathCoverage(expectedPaths: string[], reviewedPaths: string[] | un
45
36
  && expected.length === reviewed.length
46
37
  && expected.every((file, index) => file === reviewed[index]);
47
38
  }
48
-
49
- function compactRecoveryField(value: unknown, maximum: number): string {
50
- const text = String(value ?? "").replace(/\s+/g, " ").trim();
51
- return text.length > maximum ? `${text.slice(0, Math.max(0, maximum - 1)).trimEnd()}…` : text;
52
- }
53
-
54
- function criticalAcceptanceRecoveryGuidance(projections: CriticalRecoveryProjection[]): string[] {
55
- if (projections.length === 0) return [];
56
- const lines = ["Critical proof targets (derived only from the current task contract and working tree):"];
57
- for (const projection of projections.slice(0, 8)) {
58
- const targets = projection.targets.map((item) => compactRecoveryField(item, 80)).filter(Boolean).slice(0, 8);
59
- const dimensions = projection.missingDimensions.map((item) => compactRecoveryField(item, 80)).filter(Boolean).slice(0, 8);
60
- const criterion = compactRecoveryField(projection.criterionText, 700);
61
- lines.push(`- Target: ${targets.join(", ") || "task-scoped behavior"}; missing proof: ${dimensions.join(", ") || "focused-evidence"}; criterion: ${criterion}`);
62
- }
63
- const hints = [...new Set(projections.flatMap((projection) => projection.proofHints)
64
- .map((hint) => compactRecoveryField(hint, 300))
65
- .filter(Boolean))].slice(0, 8);
66
- if (hints.length > 0) lines.push("Proof requirements:", ...hints.map((hint) => `- ${hint}`));
67
- return lines;
68
- }
69
-
70
39
  type CompletionHookDependencies = {
71
40
  state: RuntimeSessionState;
41
+ prepareIndependentAcceptance?: (ctx: ExtensionContext, task: TaskContract, response?: { origin: "assistant"; bytes: string }) => Promise<CompletionPreparation | boolean | void>;
42
+ deferIndependentCompletion?: (ctx: ExtensionContext, task: TaskContract, response: { origin: "assistant"; bytes: string }, finalizer: {
43
+ preflight: () => object | false; publication: (capability: object) => object | false; finalize: (capability: object) => boolean }) => boolean;
44
+ projectIndependentLifecycle?: (ctx: ExtensionContext, task: TaskContract, candidate: TaskContract) => TaskContract | false;
45
+ nativeRefusalFallbackAllowed?: (ctx: ExtensionContext, task: TaskContract) => boolean;
72
46
  maxManifestFiles: number; semanticReviewAllowed: (task: TaskContract) => boolean;
73
47
  activeTask: (ctx: ExtensionContext) => TaskContract | undefined;
74
48
  flushObservedTaskContext: (
@@ -89,6 +63,7 @@ type CompletionHookDependencies = {
89
63
  currentDigests: Record<string, string>,
90
64
  currentDigest: string
91
65
  ) => CompletionGate;
66
+ acceptanceEvidenceFiles: (cwd: string, task: TaskContract, currentDigests: Record<string, string>, taskLocalDelta?: string[]) => string[];
92
67
  writeTask: (cwd: string, task: TaskContract) => TaskContract;
93
68
  activateBaseTools: (ctx: ExtensionContext) => unknown;
94
69
  appendTrace: (cwd: string, payload: Record<string, unknown>) => void;
@@ -99,15 +74,13 @@ type CompletionHookDependencies = {
99
74
  recoveryDecision: (ctx: ExtensionContext, task: TaskContract, gate: CompletionGate, currentDigest: string) => RecoveryDecision;
100
75
  syncTrajectory?: (ctx: ExtensionContext, task: TaskContract, options: TrajectorySyncOptions) => TrajectorySyncResult;
101
76
  };
102
-
103
77
  export function registerCompletionHook(pi: ExtensionAPI, dependencies: CompletionHookDependencies): void {
104
78
  const {
105
79
  state,
106
80
  maxManifestFiles,
107
81
  activeTask,
108
82
  flushObservedTaskContext,
109
- completionProjection,
110
- evaluateGate,
83
+ completionProjection, evaluateGate, acceptanceEvidenceFiles,
111
84
  writeTask,
112
85
  activateBaseTools,
113
86
  appendTrace,
@@ -119,7 +92,6 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
119
92
  semanticReviewAllowed,
120
93
  syncTrajectory
121
94
  } = dependencies;
122
-
123
95
  function persistHandoff(
124
96
  ctx: ExtensionContext,
125
97
  task: TaskContract,
@@ -174,6 +146,7 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
174
146
 
175
147
  pi.on("message_end", async (event, ctx) => {
176
148
  if (!event.message || event.message.role !== "assistant" || assistantMessageHasToolCall(event.message)) return;
149
+ if (state.currentTurn(ctx)?.lightweightNonAuthorizingChange) return;
177
150
  let task = flushObservedTaskContext(
178
151
  pi,
179
152
  ctx,
@@ -184,7 +157,7 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
184
157
  if (!task) return;
185
158
  observeTrajectorySync(ctx, syncTrajectory?.(ctx, task, { sourceHook: "completion" }), telemetry);
186
159
  const text = assistantMessageText(event.message);
187
- const completionClaim = looksLikeCompletionClaim(text);
160
+ const protectedRefusalHandoff = protectedRefusalHandoffMatches(task.operatorRequest, text), completionClaim = looksLikeCompletionClaim(text) || protectedRefusalHandoff;
188
161
  const incompleteHandoff = looksLikeIncompleteHandoff(text);
189
162
  if (task.trace.outcome !== "pending") return;
190
163
  const readOnlyEvidenceObserved = (task.changeMode === "read-only" || task.mutationPolicy === "forbidden") && hasDurableContextEvidence(task);
@@ -194,9 +167,23 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
194
167
  || readOnlyEvidenceObserved;
195
168
  if (!completionClaim && (incompleteHandoff || !potentiallyFinalEvidence)) return;
196
169
 
197
- const currentDigests = workingTreeSnapshot(ctx.cwd) as Record<string, string>;
198
- const currentDigest = workingTreeEvidenceDigest(currentDigests);
199
- const currentPassingVerifierObserved = verificationEvidenceProvesStableTree(latestExactVerifier, currentDigest);
170
+ const preparation = await dependencies.prepareIndependentAcceptance?.(ctx, task, { origin: "assistant", bytes: text });
171
+ // Preserve content-observed bytes until native persistence/settlement exists.
172
+ if (completionPreparationDeferred(preparation)) {
173
+ const finalizer = createCompositeCompletionFinalizer({ ctx, pi, state, task, responseText: text, activeTask,
174
+ completionProjection, evaluateGate, semanticReviewAllowed, syncTrajectory,
175
+ projectCompositeLifecycle: (candidate) => dependencies.projectIndependentLifecycle?.(ctx, task, candidate) ?? false,
176
+ withRecoveryProvenance: (candidate, gate, digests) => withRecoveryProvenance(ctx, candidate, gate, digests, null),
177
+ writeTask, activateBaseTools, appendTrace, appendSessionTrace, telemetry,
178
+ persistHandoff: (completed, gate, digests) => persistHandoff(ctx, completed, gate, digests, null) });
179
+ dependencies.deferIndependentCompletion?.(ctx, task, { origin: "assistant", bytes: text }, finalizer);
180
+ return;
181
+ }
182
+ if (!completionPreparationCurrent(preparation)) return { message: prependAssistantNotice(event.message,
183
+ "[Piagent completion gate: NOT APPROVED]\nIndependent verification stopped with the session; no completion or follow-up was scheduled.\n\n") };
184
+ const currentDigests = workingTreeSnapshot(ctx.cwd) as Record<string, string>, currentDigest = workingTreeEvidenceDigest(currentDigests);
185
+ if (settleNativeProtectedRefusal({ pi, ctx, task, response: text, currentDigests, enabled: protectedRefusalHandoff && dependencies.nativeRefusalFallbackAllowed?.(ctx, task) === true, dependencies, persistHandoff })) return;
186
+ const currentPassingVerifierObserved = verificationEvidenceProvesStableTree(latestExactVerifier, currentDigest, currentWorkspaceRevisionDigest(ctx.cwd));
200
187
  const handoffAttempt = completionClaim || (
201
188
  !incompleteHandoff
202
189
  && (task.observedChangedFiles.length > 0 || currentPassingVerifierObserved || readOnlyEvidenceObserved)
@@ -247,7 +234,8 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
247
234
  telemetry(ctx, trace);
248
235
  }
249
236
  if (semanticReviewAllowed(task) && assurance.requiresReview && !reviewReady) {
250
- task = writeTask(ctx.cwd, { ...task, changedFiles: projected.changedFiles, acceptanceReceipt: projected.acceptanceReceipt });
237
+ task = writeTask(ctx.cwd, { ...task, changedFiles: projected.changedFiles, finalWorkingTreeFiles: projected.finalWorkingTreeFiles,
238
+ finalFileDigests: projected.finalFileDigests, acceptanceReceipt: projected.acceptanceReceipt });
251
239
  const reservation = reserveSemanticReviewContinuation(ctx.cwd, task, {
252
240
  currentWorkingTreeDigest: currentDigest, expectedPaths: expectedReviewPaths, reasonCodes: assurance.reasonCodes
253
241
  });
@@ -275,15 +263,16 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
275
263
  return { message: { ...event.message, content } };
276
264
  }
277
265
  const reviewGate: CompletionGate = { decision: "fail", missing: [`semantic review handoff: ${reservation.reason}`], missingVerifyCommands: [] };
266
+ const reviewRecovery = terminalRecoveryForContinuationDenial(recoveryDecision(ctx, task, reviewGate, currentDigest), reservation.reason);
278
267
  observeTrajectorySync(ctx, syncTrajectory?.(ctx, task, { sourceHook: "completion", handoffObserved: true }), telemetry);
279
- persistHandoff(ctx, task, reviewGate, currentDigests, null);
268
+ persistHandoff(ctx, task, reviewGate, currentDigests, reviewRecovery);
280
269
  const handoffTrace = {
281
270
  event: "performance_review_handed_off", taskId: task.taskId, taskRunId: task.taskRunId, sessionId: task.sessionId,
282
271
  reason: reservation.reason, progressSignature: reservation.progressSignature,
283
272
  globalContinuationConsumed: reservation.consumed, globalContinuationMaximum: reservation.maximum
284
273
  };
285
274
  appendTrace(ctx.cwd, handoffTrace); appendSessionTrace(pi, handoffTrace); telemetry(ctx, handoffTrace);
286
- recordCompletionAudit(ctx, task, { outcome: "blocked", evidence: handoffTrace });
275
+ recordCompletionAudit(ctx, task, { outcome: "blocked", evidence: { ...handoffTrace, recovery: reviewRecovery } });
287
276
  const notice = [
288
277
  "[Piagent completion gate: NOT APPROVED]",
289
278
  `Task ${task.taskId} cannot schedule another semantic review: ${reservation.reason}; ${review?.activityObserved ? "current-tree review activity was observed but did not produce complete credit" : "no current-tree review activity was observed"}.`,
@@ -296,6 +285,10 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
296
285
  return { message: { ...event.message, content } };
297
286
  }
298
287
  observeTrajectorySync(ctx, syncTrajectory?.(ctx, task, { sourceHook: "completion", handoffObserved: true }), telemetry);
288
+ const diagnosticProof = projectedGate.acceptanceProof?.mode === "diagnostic" ? projectedGate.acceptanceProof : undefined;
289
+ const diagnosticNotice = diagnosticProof?.pendingCriterionIds.length
290
+ ? `Diagnostic acceptance: ${diagnosticProof.pendingCriterionIds.length} criteria remain unproved; no quality claim.` : undefined;
291
+ if (diagnosticNotice) projected.trace.notes = [projected.trace.notes, diagnosticNotice].filter(Boolean).join("\n");
299
292
  projected = withRecoveryProvenance(ctx, projected, projectedGate, currentDigests, null);
300
293
  task = writeTask(ctx.cwd, projected);
301
294
  observeTrajectorySync(ctx, syncTrajectory?.(ctx, task, { sourceHook: "completion" }), telemetry);
@@ -305,6 +298,7 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
305
298
  recordCompletionAudit(ctx, task, {
306
299
  outcome: "completed",
307
300
  evidence: {
301
+ ...(diagnosticProof ? { acceptanceProof: diagnosticProof } : {}),
308
302
  changedFiles: task.changedFiles,
309
303
  lifecycleMode: runtimeLifecycleMode(task)
310
304
  }
@@ -312,6 +306,7 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
312
306
  persistHandoff(ctx, task, projectedGate, currentDigests, null);
313
307
  const trace = {
314
308
  event: "task_auto_completed",
309
+ ...(diagnosticProof ? { acceptanceProof: diagnosticProof } : {}),
315
310
  taskId: task.taskId,
316
311
  taskRunId: task.taskRunId,
317
312
  sessionId: task.sessionId,
@@ -321,21 +316,30 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
321
316
  appendTrace(ctx.cwd, trace);
322
317
  appendSessionTrace(pi, trace);
323
318
  telemetry(ctx, trace);
319
+ if (diagnosticNotice) return { message: prependAssistantNotice(event.message, `[Piagent diagnostic] ${diagnosticNotice}\n`) };
324
320
  return;
325
321
  }
326
- task = writeTask(ctx.cwd, {
327
- ...task,
328
- changedFiles: projected.changedFiles,
329
- acceptanceReceipt: projected.acceptanceReceipt
330
- });
322
+ task = writeTask(ctx.cwd, { ...task, changedFiles: projected.changedFiles, finalWorkingTreeFiles: projected.finalWorkingTreeFiles,
323
+ finalFileDigests: projected.finalFileDigests, acceptanceReceipt: projected.acceptanceReceipt });
331
324
  state.cacheTaskIdentity(ctx, task);
332
325
  }
333
326
  if (!handoffAttempt || finalGateMode(ctx) !== "enforce") return;
334
327
  const gate = completionGate ?? evaluateGate(ctx.cwd, task, currentDigests, currentDigest);
335
328
  if (gate.decision === "pass") return;
336
-
337
329
  const selectedRecovery = recoveryDecision(ctx, task, gate, currentDigest);
338
330
  const missingAcceptanceProof = gate.missing.some((item) => /^critical acceptance evidence\b/i.test(item));
331
+ let criticalRecovery: CriticalRecoveryProjection[] = [];
332
+ if (missingAcceptanceProof) {
333
+ try {
334
+ criticalRecovery = acceptanceCriticalRecoveryProjection(task, {
335
+ cwd: ctx.cwd, apiBaselineEvidence,
336
+ changedFiles: acceptanceEvidenceFiles(ctx.cwd, task, currentDigests, taskDeltaFilesFromSnapshot(task, currentDigests)),
337
+ currentWorkingTreeDigest: currentDigest
338
+ }) as CriticalRecoveryProjection[];
339
+ } catch {
340
+ // The exact gate remains authoritative if advisory projection is unavailable.
341
+ }
342
+ }
339
343
  const lifecycleMode = runtimeLifecycleMode(task);
340
344
  const continuation = planRecoveryContinuation(ctx.cwd, task, selectedRecovery, {
341
345
  lifecycleMode, currentWorkingTreeDigest: currentDigest, missing: gate.missing, missingVerifyCommands: gate.missingVerifyCommands
@@ -360,24 +364,11 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
360
364
  recoveryRequested: true
361
365
  }), telemetry);
362
366
  }
363
- let criticalRecovery: CriticalRecoveryProjection[] = [];
364
- if (missingAcceptanceProof) {
365
- try {
366
- criticalRecovery = acceptanceCriticalRecoveryProjection(task, {
367
- cwd: ctx.cwd,
368
- changedFiles: taskDeltaFilesFromSnapshot(task, currentDigests),
369
- currentWorkingTreeDigest: currentDigest
370
- }) as CriticalRecoveryProjection[];
371
- } catch {
372
- // Exact gate evidence remains the fail-closed fallback when advisory projection is unavailable.
373
- }
374
- }
375
- const criticalRecoveryGuidance = criticalAcceptanceRecoveryGuidance(criticalRecovery);
376
367
  const recoveryGuidance = selectedRecovery.action === "repair" && selectedRecovery.sourceMutationAllowed
377
368
  ? missingAcceptanceProof
378
369
  ? [
379
370
  "Continue the same bounded task with one acceptance-proof repair pass.",
380
- ...criticalRecoveryGuidance,
371
+ ...criticalAcceptanceRecoveryGuidance(criticalRecovery),
381
372
  "Add or correct focused tests for every missing critical obligation. Assert exact boundary partitions and requested error classes; if a focused test exposes a defect, repair the evidence-backed source before rerunning verification.",
382
373
  ...verifierInstructions(gate.missingVerifyCommands),
383
374
  "Do not repeat a failed hypothesis, expand permission, or perform an external action."
@@ -389,6 +380,7 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
389
380
  ]
390
381
  : selectedRecovery.reasonCodes.includes("unknown-diagnostic-pass") || task.changeMode === "read-only" || task.mutationPolicy === "forbidden"
391
382
  ? [
383
+ ...criticalAcceptanceRecoveryGuidance(criticalRecovery, false),
392
384
  ...(gate.missingVerifyCommands.length > 0
393
385
  ? ["Run only the missing exact verifier commands against the current working tree.", ...verifierInstructions(gate.missingVerifyCommands)]
394
386
  : [(task.changeMode === "read-only" || task.mutationPolicy === "forbidden") && gate.missing.length > 0 && gate.missing.every((item) => /^completed work plan\b/i.test(item)) ? "Complete only the pending read-only review checkpoint, then re-emit the complete substantive assessment from the immediately preceding response; do not repeat repository reads or replace it with checkpoint evidence." : "Run one bounded diagnostic pass using targeted reads and report the concrete evidence or unknown."]),
@@ -400,6 +392,9 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
400
392
  "Do not mutate project source, expand permission, or perform an external action during this retry."
401
393
  ];
402
394
  const otherMissing = gate.missing.filter((item) => !/^critical acceptance evidence\b/i.test(item));
395
+ const contextReadGuidance = gate.missing.includes("context manifest")
396
+ ? ["Record the missing context evidence with the native read tool on one relevant source or test region in the task scope (use offset/limit for a large file). Shell inspection and test results do not satisfy this gate. Reuse current-tree passing verification; run only missing or stale verifiers."]
397
+ : [];
403
398
  const missingSummary = criticalRecovery.length > 0
404
399
  ? [
405
400
  `${criticalRecovery.length} critical acceptance proof target(s)`,
@@ -410,6 +405,8 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
410
405
  "[Piagent continuation required]",
411
406
  `Task ${task.taskId} cannot finish yet. Missing: ${missingSummary}.`,
412
407
  `Recovery: ${selectedRecovery.action}; class: ${selectedRecovery.failureCategory}; reasons: ${selectedRecovery.reasonCodes.join(", ")}.`,
408
+ ...(independentVerificationRecovery(ctx.cwd, task, currentDigest)?.guidance ?? []),
409
+ ...contextReadGuidance,
413
410
  ...recoveryGuidance
414
411
  ].join("\n");
415
412
  pi.sendMessage(
@@ -452,10 +449,7 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
452
449
  `Task ${task.taskId} needs one bounded ${selectedRecovery.action} pass before handoff.`,
453
450
  ""
454
451
  ].join("\n");
455
- const content = Array.isArray(event.message.content)
456
- ? [{ type: "text" as const, text: continuingNotice }, ...event.message.content]
457
- : [{ type: "text" as const, text: `${continuingNotice}${text}` }];
458
- return { message: { ...event.message, content } };
452
+ return { message: prependAssistantNotice(event.message, continuingNotice) };
459
453
  }
460
454
 
461
455
  const finalRecovery = continuation.recovery;
@@ -464,13 +458,13 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
464
458
  `Task ${task.taskId} (${task.taskRunId}) is still open.`,
465
459
  `Missing: ${gate.missing.join(", ") || "a completed task trace"}.`,
466
460
  `Recovery disposition: ${finalRecovery.action} (${finalRecovery.reasonCodes.join(", ")}).`,
461
+ ...criticalAcceptanceRecoveryGuidance(criticalRecovery, false),
462
+ ...(independentVerificationRecovery(ctx.cwd, task, currentDigest)?.guidance ?? []),
467
463
  ...verifierInstructions(gate.missingVerifyCommands),
468
464
  "The response below is preserved as work in progress and must not be treated as a completion report.",
469
465
  ""
470
466
  ].join("\n");
471
- const content = Array.isArray(event.message.content)
472
- ? [{ type: "text" as const, text: notice }, ...event.message.content]
473
- : [{ type: "text" as const, text: `${notice}${text}` }];
467
+ const blockedMessage = prependAssistantNotice(event.message, notice);
474
468
  const trace = {
475
469
  event: "completion_claim_blocked",
476
470
  taskId: task.taskId,
@@ -494,7 +488,6 @@ export function registerCompletionHook(pi: ExtensionAPI, dependencies: Completio
494
488
  recovery: finalRecovery
495
489
  }
496
490
  });
497
- persistHandoff(ctx, task, gate, currentDigests, finalRecovery);
498
- return { message: { ...event.message, content } };
491
+ persistHandoff(ctx, task, gate, currentDigests, finalRecovery); return { message: blockedMessage };
499
492
  });
500
493
  }
@@ -3,18 +3,24 @@ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-a
3
3
  import { classifyContextTask } from "../../extensions/context-engine.js";
4
4
  import { matchesProtectedPath } from "../../extensions/policy-core.js";
5
5
  import type { TaskContract } from "../../extensions/guard-types.js";
6
- import { attachLocalImagesFromText } from "../input/chat-images.ts";
6
+ import { attachLocalImagesFromText, extractLocalImagePathCandidates } from "../input/chat-images.ts";
7
7
  import type { ChatImageAccessPolicy } from "../input/chat-images.ts";
8
8
  import { LONG_INPUT_CHARS } from "../runtime-limits.ts";
9
9
  import type { AuthorityResumeDecision } from "../policy/authority-resume-policy.ts";
10
10
  import { buildHandoffProjection, writeHandoffProjection } from "../recovery/handoff-projection.ts";
11
+ import {
12
+ isUncertainSendContinuation,
13
+ terminalUncertainSendReceipt
14
+ } from "../session/uncertain-send-continuation.ts";
11
15
  import { buildContextPreflight, buildUsageSnapshot } from "../session/usage.ts";
12
16
  import { registerAdaptiveContextGovernor } from "../session/adaptive-context-governor.ts";
13
- import { activeTaskToolGroups, toolGroupsForPrompt } from "../tools/tool-groups.ts";
17
+ import { activeTaskToolGroups, toolGroupsForPrompt, PIAGENT_TOOL_NAMES, PIAGENT_TOOL_ORDER, PIAGENT_TOOL_GROUPS } from "../tools/tool-groups.ts";
14
18
  import type { PiagentToolGroup } from "../tools/tool-groups.ts";
15
19
  import type { RuntimeSessionState } from "../session/runtime-state.ts";
20
+ import { observeHostWireInput } from "../session/runtime-state.ts";
16
21
  import {
17
22
  buildFreshCommand,
23
+ agentStartTaskRequest,
18
24
  chooseFreshWorkflow,
19
25
  extractTaskRequest,
20
26
  isFreshOrUtilityInput,
@@ -24,6 +30,7 @@ import {
24
30
  } from "../workflows/input-routing.ts";
25
31
  import {
26
32
  automaticTaskIntakeMode,
33
+ isLightweightNonAuthorizingChangeContinuation,
27
34
  manualTaskIntakeEligible
28
35
  } from "../workflows/task-intake.ts";
29
36
 
@@ -38,6 +45,48 @@ type InputHookDependencies = {
38
45
  telemetry: (ctx: ExtensionContext, payload: Record<string, unknown>) => void;
39
46
  };
40
47
 
48
+ /** Predict configured input definitions; unknown task or replacement state cannot create an allowed wire state. */
49
+ export function projectPiagentWireInput(input: {
50
+ text: string; expandedPrompt?: string; source: string; activeTask: TaskContract | null;
51
+ readProtectedPaths: string[]; currentTools: string[]; availableToolNames: string[];
52
+ dynamicToolsEnabled: boolean; replacementIntake: boolean; hasImages: boolean; phase?: string | null;
53
+ }): Record<string, any> {
54
+ const blocked = (reason: string) => ({ disposition: "blocked", reason });
55
+ if (input.activeTask === undefined || !Array.isArray(input.readProtectedPaths)
56
+ || typeof input.replacementIntake !== "boolean" || typeof input.dynamicToolsEnabled !== "boolean") return blocked("input-state-unfrozen");
57
+ const text = input.text.trim();
58
+ if (input.hasImages !== false || extractLocalImagePathCandidates(text, "/").length > 0) return blocked("input-images-unprojected");
59
+ if (!text || isFreshOrUtilityInput(text) || /^\/piagent-workflow\b/i.test(text)) return blocked("input-transform-unprojected");
60
+ if (!["rpc", "interactive", "extension"].includes(input.source)) return blocked("input-source-unfrozen");
61
+ if (input.source !== "extension" && (looksLikeGovernedBoilerplate(text) || isPiagentWorkflowInput(text)
62
+ || text.length >= LONG_INPUT_CHARS)) return blocked("input-preflight-unfrozen");
63
+ const signal = classifyContextTask(text), activeTask = input.activeTask?.trace.outcome === "pending" ? input.activeTask : undefined;
64
+ const onlyProtected = signal.paths.length > 0 && signal.paths.every((p) => matchesProtectedPath(p, input.readProtectedPaths));
65
+ const runtimeMode = !activeTask ? automaticTaskIntakeMode(text, input.readProtectedPaths) : undefined;
66
+ const manual = !activeTask && !runtimeMode && manualTaskIntakeEligible(text, input.readProtectedPaths);
67
+ const groups = onlyProtected ? [] : toolGroupsForPrompt(text).filter((group) => !runtimeMode || group !== "intake" && group !== "task");
68
+ if (manual && !groups.includes("intake")) groups.push("intake");
69
+ const selectedGroups = activeTask ? [...groups.filter((group) => input.replacementIntake || group !== "intake"),
70
+ ...(input.replacementIntake ? ["intake" as const] : activeTaskToolGroups(activeTask))] : groups;
71
+ const builtins = input.currentTools.filter((name) => !PIAGENT_TOOL_NAMES.has(name));
72
+ if (builtins.includes("apply_patch")) {
73
+ const firstWriter = builtins.findIndex((name) => name === "edit" || name === "write");
74
+ if (firstWriter >= 0) { builtins.splice(builtins.indexOf("apply_patch"), 1); builtins.splice(builtins.findIndex((name) => name === "edit" || name === "write"), 0, "apply_patch"); }
75
+ }
76
+ const selectedTools = input.dynamicToolsEnabled ? [...builtins, ...PIAGENT_TOOL_ORDER.filter((name) =>
77
+ selectedGroups.some((group) => PIAGENT_TOOL_GROUPS[group].includes(name as never)))] : [...input.currentTools];
78
+ if (selectedTools.some((name) => !input.availableToolNames.includes(name))) return blocked("tool-definition-missing");
79
+ const query = agentStartTaskRequest(input.expandedPrompt ?? text), querySignal = classifyContextTask(query);
80
+ const protectedQuery = querySignal.paths.length > 0 && querySignal.paths.every((p) => matchesProtectedPath(p, input.readProtectedPaths));
81
+ const agentStartRuntimeMode = !activeTask ? automaticTaskIntakeMode(query, input.readProtectedPaths) : undefined;
82
+ if (runtimeMode || agentStartRuntimeMode || input.replacementIntake) return blocked("automatic-task-state-unprojected");
83
+ if (activeTask && !input.phase) return blocked("current-task-phase-unfrozen");
84
+ return { disposition: "known", reason: null, groups: selectedGroups, selectedTools,
85
+ compactMode: protectedQuery ? "protected" : activeTask?.intakeMode === "runtime" ? "automatic" : null,
86
+ taskPresence: activeTask ? "current" : "none", phase: activeTask ? input.phase : null,
87
+ inputHash: signal.promptHash, inputText: text };
88
+ }
89
+
41
90
  export function registerInputHook(pi: ExtensionAPI, dependencies: InputHookDependencies): void {
42
91
  registerAdaptiveContextGovernor(pi, {
43
92
  activeTask: dependencies.activeTask,
@@ -53,13 +102,49 @@ export function registerInputHook(pi: ExtensionAPI, dependencies: InputHookDepen
53
102
 
54
103
  const taskSignal = classifyContextTask(text);
55
104
  const sessionTask = dependencies.activeTask(ctx);
56
- if (sessionTask && sessionTask.trace.outcome !== "pending") dependencies.state.clearTaskBoundary(ctx, sessionTask.taskRunId);
57
- else if (!sessionTask) {
58
- const cachedTask = dependencies.state.taskIdentity(ctx);
59
- if (cachedTask) dependencies.state.clearTaskBoundary(ctx, cachedTask.taskRunId);
105
+ const uncertainSendContinuation = (!Array.isArray(event.images) || event.images.length === 0)
106
+ && isUncertainSendContinuation(text);
107
+ const terminalReceipt = uncertainSendContinuation
108
+ ? terminalUncertainSendReceipt(ctx.cwd, sessionTask)
109
+ : undefined;
110
+ if (terminalReceipt && event.source !== "extension") {
111
+ dependencies.telemetry(ctx, {
112
+ event: "uncertain_send_terminal_receipt_reemitted",
113
+ source: event.source,
114
+ promptHash: taskSignal.promptHash,
115
+ taskId: terminalReceipt.details.taskId,
116
+ taskRunId: terminalReceipt.details.taskRunId,
117
+ outcome: terminalReceipt.details.outcome,
118
+ completionApproved: terminalReceipt.details.completionApproved,
119
+ replacementTaskStarted: false,
120
+ replayed: false,
121
+ modelTurnStarted: false
122
+ });
123
+ pi.sendMessage(
124
+ {
125
+ customType: terminalReceipt.customType,
126
+ content: terminalReceipt.content,
127
+ display: true,
128
+ details: terminalReceipt.details
129
+ },
130
+ { triggerTurn: false }
131
+ );
132
+ return { action: "handled" };
133
+ }
134
+ if (!uncertainSendContinuation) {
135
+ if (sessionTask && sessionTask.trace.outcome !== "pending") dependencies.state.clearTaskBoundary(ctx, sessionTask.taskRunId);
136
+ else if (!sessionTask) {
137
+ const cachedTask = dependencies.state.taskIdentity(ctx);
138
+ if (cachedTask) dependencies.state.clearTaskBoundary(ctx, cachedTask.taskRunId);
139
+ }
60
140
  }
61
141
  const activeTask = sessionTask?.trace.outcome === "pending" ? sessionTask : undefined;
62
- const turn = dependencies.state.beginTurn(ctx, taskSignal.promptHash);
142
+ const turn = dependencies.state.beginTurn(ctx, taskSignal.promptHash, {
143
+ lightweightNonAuthorizingChange: isLightweightNonAuthorizingChangeContinuation(text)
144
+ });
145
+ observeHostWireInput(ctx.cwd, ctx.sessionManager.getSessionId(), { turnId: turn.turnId,
146
+ promptHash: taskSignal.promptHash, text, source: event.source,
147
+ hasImages: Boolean(event.images?.length || extractLocalImagePathCandidates(text, ctx.cwd).length) });
63
148
  const authorityPolicy = activeTask?.trace.outcome === "pending" ? dependencies.authorityPolicy(ctx, activeTask) : undefined;
64
149
  let authorityHandoffReady = false;
65
150
  if (activeTask && authorityPolicy?.disposition === "new-attempt-required") {
@@ -0,0 +1,86 @@
1
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import type { TaskContract } from "../../extensions/guard-types.js";
3
+ import { matchesProtectedPath } from "../../extensions/policy-core.js";
4
+ import { taskDeltaFilesFromSnapshot } from "../../extensions/task-contract-view.js";
5
+ import { recordCompletionAudit } from "../../extensions/task-runtime-audit.js";
6
+ import { RuntimeSessionState } from "../session/runtime-state.ts";
7
+ import { protectedRefusalHandoffMatches } from "../quality/protected-refusal-handoff.ts";
8
+ import { observeTrajectorySync } from "../trajectory/trajectory-observability.ts";
9
+ import type { TrajectorySyncOptions, TrajectorySyncResult } from "../trajectory/trajectory-runtime.ts";
10
+ export { protectedRefusalHandoffMatches } from "../quality/protected-refusal-handoff.ts";
11
+
12
+ type RefusalGate = { decision: "fail"; missing: string[]; missingVerifyCommands: string[] };
13
+ type Dependencies = {
14
+ state: RuntimeSessionState;
15
+ writeTask: (cwd: string, task: TaskContract) => TaskContract;
16
+ activateBaseTools: (ctx: ExtensionContext) => unknown;
17
+ appendTrace: (cwd: string, payload: Record<string, unknown>) => void;
18
+ appendSessionTrace: (pi: ExtensionAPI, payload: Record<string, unknown>) => void;
19
+ telemetry: (ctx: ExtensionContext, payload: Record<string, unknown>) => void;
20
+ syncTrajectory?: (ctx: ExtensionContext, task: TaskContract, options: TrajectorySyncOptions) => TrajectorySyncResult;
21
+ };
22
+
23
+ export function nativeProtectedRefusalEligible(task: TaskContract, currentDigests: Record<string, string>): boolean {
24
+ const changedFiles = taskDeltaFilesFromSnapshot(task, currentDigests);
25
+ const protectedContextObserved = [...task.contextManifest, ...task.memoryCitations].some((entry) =>
26
+ matchesProtectedPath(entry.path, task.protectedPaths));
27
+ return changedFiles.length === 0 && task.observedChangedFiles.length === 0 && !protectedContextObserved;
28
+ }
29
+
30
+ export function settleNativeProtectedRefusal(input: {
31
+ pi: ExtensionAPI;
32
+ ctx: ExtensionContext;
33
+ task: TaskContract;
34
+ response: string;
35
+ currentDigests: Record<string, string>;
36
+ enabled: boolean;
37
+ dependencies: Dependencies;
38
+ persistHandoff: (ctx: ExtensionContext, task: TaskContract, gate: RefusalGate,
39
+ currentDigests: Record<string, string>, recovery: null) => void;
40
+ }): boolean {
41
+ const { pi, ctx, response, currentDigests, enabled, dependencies, persistHandoff } = input;
42
+ if (!enabled || !protectedRefusalHandoffMatches(input.task.operatorRequest, response)
43
+ || !nativeProtectedRefusalEligible(input.task, currentDigests)) return false;
44
+ const gate: RefusalGate = {
45
+ decision: "fail",
46
+ missing: ["operator-directed protected-material request was safely refused"],
47
+ missingVerifyCommands: []
48
+ };
49
+ observeTrajectorySync(ctx, dependencies.syncTrajectory?.(ctx, input.task, {
50
+ sourceHook: "completion", handoffObserved: true
51
+ }), dependencies.telemetry);
52
+ const task = dependencies.writeTask(ctx.cwd, {
53
+ ...input.task,
54
+ changedFiles: [],
55
+ finalWorkingTreeFiles: Object.keys(currentDigests).sort(),
56
+ finalFileDigests: currentDigests,
57
+ failureReason: "protected-material-request-refused",
58
+ trace: {
59
+ outcome: "blocked",
60
+ terminalDisposition: "refused",
61
+ friction: "Protected material access and export were refused without reading or mutating project files.",
62
+ notes: "Native refusal fallback matched only the operator-declared durable refusal markers.",
63
+ recordedAt: new Date().toISOString()
64
+ }
65
+ });
66
+ observeTrajectorySync(ctx, dependencies.syncTrajectory?.(ctx, task, { sourceHook: "completion" }), dependencies.telemetry);
67
+ dependencies.state.clearObservedContext(ctx);
68
+ dependencies.activateBaseTools(ctx);
69
+ recordCompletionAudit(ctx, task, {
70
+ outcome: "blocked",
71
+ evidence: { terminalDisposition: "refused", changedFiles: [], protectedContextObserved: false }
72
+ });
73
+ persistHandoff(ctx, task, gate, currentDigests, null);
74
+ const trace = {
75
+ event: "task_policy_refused",
76
+ taskId: task.taskId,
77
+ taskRunId: task.taskRunId,
78
+ sessionId: task.sessionId,
79
+ terminalDisposition: "refused",
80
+ changedFiles: []
81
+ };
82
+ dependencies.appendTrace(ctx.cwd, trace);
83
+ dependencies.appendSessionTrace(pi, trace);
84
+ dependencies.telemetry(ctx, trace);
85
+ return true;
86
+ }
@@ -25,7 +25,7 @@ type SessionHookDependencies = {
25
25
  ) => TaskContract | undefined;
26
26
  onTurnEnd?: (ctx: ExtensionContext) => void;
27
27
  onAgentSettled?: (ctx: ExtensionContext) => void;
28
- beforeShutdown?: (ctx: ExtensionContext) => void;
28
+ beforeShutdown?: (ctx: ExtensionContext) => void | Promise<void>;
29
29
  };
30
30
 
31
31
  export function registerSessionHooks(pi: ExtensionAPI, dependencies: SessionHookDependencies): void {
@@ -59,6 +59,9 @@ export function registerSessionHooks(pi: ExtensionAPI, dependencies: SessionHook
59
59
  const task = activeTask(ctx.cwd, sessionId);
60
60
  if (!task) return;
61
61
  const sessionName = String(event.name ?? "").trim() || undefined;
62
+ // Hosts can announce the existing name again during startup. This is not
63
+ // a task change and must not rewrite its timestamp or append a journal event.
64
+ if (task.sessionName === sessionName) return;
62
65
  task.sessionName = sessionName;
63
66
  const written = writeTask(ctx.cwd, task);
64
67
  bindTask(ctx.cwd, sessionId, sessionName, written);
@@ -112,7 +115,7 @@ export function registerSessionHooks(pi: ExtensionAPI, dependencies: SessionHook
112
115
  });
113
116
 
114
117
  pi.on("session_shutdown", async (event, ctx) => {
115
- dependencies.beforeShutdown?.(ctx);
118
+ await dependencies.beforeShutdown?.(ctx);
116
119
  flushObservedTaskContext(
117
120
  pi,
118
121
  ctx,