@piagent/platform 1.6.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (645) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +8 -2
  3. package/README.vi.md +11 -2
  4. package/adapters/common/assurance-producers.json +109 -0
  5. package/adapters/common/structured-assurance-facts.mjs +153 -0
  6. package/adapters/node-typescript/contract-families.json +2811 -0
  7. package/adapters/node-typescript/contract-families.md +90 -0
  8. package/benchmarks/production-v1/grade.mjs +20 -0
  9. package/benchmarks/production-v1/spend-control.v1.json +3 -3
  10. package/benchmarks/production-v2/grade.mjs +892 -0
  11. package/benchmarks/production-v2/project/README.md +7 -0
  12. package/benchmarks/production-v2/project/config/service.json +4 -0
  13. package/benchmarks/production-v2/project/data/audit-ledger.jsonl +1 -0
  14. package/benchmarks/production-v2/project/docs/ops.md +3 -0
  15. package/benchmarks/production-v2/project/logs/incident.log +2 -0
  16. package/benchmarks/production-v2/project/package.json +11 -0
  17. package/benchmarks/production-v2/project/scripts/check.mjs +21 -0
  18. package/benchmarks/production-v2/project/src/backend/auth.js +3 -0
  19. package/benchmarks/production-v2/project/src/backend/billing-window.js +4 -0
  20. package/benchmarks/production-v2/project/src/backend/cache.js +15 -0
  21. package/benchmarks/production-v2/project/src/backend/invoice.js +4 -0
  22. package/benchmarks/production-v2/project/src/backend/revocation-cache.js +3 -0
  23. package/benchmarks/production-v2/project/src/data/csv.js +3 -0
  24. package/benchmarks/production-v2/project/src/data/dedup.js +5 -0
  25. package/benchmarks/production-v2/project/src/data/migration.js +9 -0
  26. package/benchmarks/production-v2/project/src/data/ndjson-stream.js +5 -0
  27. package/benchmarks/production-v2/project/src/data/versioned-replay.js +8 -0
  28. package/benchmarks/production-v2/project/src/frontend/chat-events.js +7 -0
  29. package/benchmarks/production-v2/project/src/frontend/pagination.js +8 -0
  30. package/benchmarks/production-v2/project/src/frontend/request-lifecycle.js +15 -0
  31. package/benchmarks/production-v2/project/src/frontend/search-state.js +8 -0
  32. package/benchmarks/production-v2/project/src/frontend/unicode-search.js +7 -0
  33. package/benchmarks/production-v2/project/src/fullstack/contract-sync.js +10 -0
  34. package/benchmarks/production-v2/project/src/platform/args.js +10 -0
  35. package/benchmarks/production-v2/project/src/platform/config.js +7 -0
  36. package/benchmarks/production-v2/project/src/platform/workflow-session.js +9 -0
  37. package/benchmarks/production-v2/project/src/platform/workspace.js +13 -0
  38. package/benchmarks/production-v2/project/src/reliability/checkpoint.js +5 -0
  39. package/benchmarks/production-v2/project/src/reliability/expiry.js +5 -0
  40. package/benchmarks/production-v2/project/src/reliability/retry.js +15 -0
  41. package/benchmarks/production-v2/project/test/smoke.test.js +21 -0
  42. package/benchmarks/production-v2/project/vendor/README.md +1 -0
  43. package/benchmarks/production-v2/prompts/abort-reconnect-supersession.md +11 -0
  44. package/benchmarks/production-v2/prompts/backend-frontend-contract-sync.md +12 -0
  45. package/benchmarks/production-v2/prompts/billing-cutoff-clock-skew.md +11 -0
  46. package/benchmarks/production-v2/prompts/bounded-retry.md +7 -0
  47. package/benchmarks/production-v2/prompts/chunked-record-boundary.md +9 -0
  48. package/benchmarks/production-v2/prompts/cli-double-dash.md +7 -0
  49. package/benchmarks/production-v2/prompts/config-precedence.md +6 -0
  50. package/benchmarks/production-v2/prompts/destructive-history-refusal.md +3 -0
  51. package/benchmarks/production-v2/prompts/expiry-boundary.md +7 -0
  52. package/benchmarks/production-v2/prompts/idempotent-replay-conflict.md +11 -0
  53. package/benchmarks/production-v2/prompts/incident-diagnosis.md +4 -0
  54. package/benchmarks/production-v2/prompts/invoice-rounding.md +9 -0
  55. package/benchmarks/production-v2/prompts/journeys/config-precedence-scout.md +3 -0
  56. package/benchmarks/production-v2/prompts/journeys/expiry-boundary-scout.md +3 -0
  57. package/benchmarks/production-v2/prompts/journeys/quoted-csv-scout.md +3 -0
  58. package/benchmarks/production-v2/prompts/journeys/recover-after-uncertain-send.md +4 -0
  59. package/benchmarks/production-v2/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  60. package/benchmarks/production-v2/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  61. package/benchmarks/production-v2/prompts/journeys/stable-dedup-scout.md +3 -0
  62. package/benchmarks/production-v2/prompts/journeys/stale-search-response-scout.md +3 -0
  63. package/benchmarks/production-v2/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  64. package/benchmarks/production-v2/prompts/journeys/verify-current-contract.md +4 -0
  65. package/benchmarks/production-v2/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  66. package/benchmarks/production-v2/prompts/pagination-boundary.md +7 -0
  67. package/benchmarks/production-v2/prompts/protected-env-refusal.md +2 -0
  68. package/benchmarks/production-v2/prompts/quoted-csv.md +6 -0
  69. package/benchmarks/production-v2/prompts/reconnect-chat-event-order.md +19 -0
  70. package/benchmarks/production-v2/prompts/repository-prompt-injection.md +5 -0
  71. package/benchmarks/production-v2/prompts/resumable-checkpoint-partial-failure.md +11 -0
  72. package/benchmarks/production-v2/prompts/revoked-session-cache.md +10 -0
  73. package/benchmarks/production-v2/prompts/schema-migration.md +6 -0
  74. package/benchmarks/production-v2/prompts/stable-dedup.md +6 -0
  75. package/benchmarks/production-v2/prompts/stale-search-response.md +6 -0
  76. package/benchmarks/production-v2/prompts/tenant-cache-isolation.md +6 -0
  77. package/benchmarks/production-v2/prompts/tenant-role-authorization.md +6 -0
  78. package/benchmarks/production-v2/prompts/unicode-search.md +6 -0
  79. package/benchmarks/production-v2/prompts/workflow-switch-same-session.md +30 -0
  80. package/benchmarks/production-v2/prompts/workspace-order.md +7 -0
  81. package/benchmarks/production-v2/spend-control.v1.json +115 -0
  82. package/benchmarks/production-v2/suite.json +1009 -0
  83. package/benchmarks/production-v2/variant.mjs +169 -0
  84. package/benchmarks/production-v3/CONTRACT-REVISION-20260922.md +31 -0
  85. package/benchmarks/production-v3/calibration/corpus.v1.json +63 -0
  86. package/benchmarks/production-v3/calibration/human-review-rubric.v1.json +36 -0
  87. package/benchmarks/production-v3/grade.mjs +1017 -0
  88. package/benchmarks/production-v3/project/README.md +7 -0
  89. package/benchmarks/production-v3/project/config/service.json +4 -0
  90. package/benchmarks/production-v3/project/data/audit-ledger.jsonl +1 -0
  91. package/benchmarks/production-v3/project/docs/ops.md +3 -0
  92. package/benchmarks/production-v3/project/logs/incident.log +2 -0
  93. package/benchmarks/production-v3/project/package.json +11 -0
  94. package/benchmarks/production-v3/project/scripts/check.mjs +21 -0
  95. package/benchmarks/production-v3/project/src/backend/auth.js +3 -0
  96. package/benchmarks/production-v3/project/src/backend/billing-window.js +4 -0
  97. package/benchmarks/production-v3/project/src/backend/cache.js +15 -0
  98. package/benchmarks/production-v3/project/src/backend/invoice.js +4 -0
  99. package/benchmarks/production-v3/project/src/backend/revocation-cache.js +12 -0
  100. package/benchmarks/production-v3/project/src/data/csv.js +3 -0
  101. package/benchmarks/production-v3/project/src/data/dedup.js +5 -0
  102. package/benchmarks/production-v3/project/src/data/migration.js +9 -0
  103. package/benchmarks/production-v3/project/src/data/ndjson-stream.js +5 -0
  104. package/benchmarks/production-v3/project/src/data/versioned-replay.js +8 -0
  105. package/benchmarks/production-v3/project/src/frontend/chat-events.js +7 -0
  106. package/benchmarks/production-v3/project/src/frontend/pagination.js +8 -0
  107. package/benchmarks/production-v3/project/src/frontend/request-lifecycle.js +23 -0
  108. package/benchmarks/production-v3/project/src/frontend/search-state.js +8 -0
  109. package/benchmarks/production-v3/project/src/frontend/unicode-search.js +7 -0
  110. package/benchmarks/production-v3/project/src/fullstack/contract-sync.js +10 -0
  111. package/benchmarks/production-v3/project/src/platform/args.js +10 -0
  112. package/benchmarks/production-v3/project/src/platform/config.js +7 -0
  113. package/benchmarks/production-v3/project/src/platform/workflow-session.js +9 -0
  114. package/benchmarks/production-v3/project/src/platform/workspace.js +13 -0
  115. package/benchmarks/production-v3/project/src/reliability/checkpoint.js +5 -0
  116. package/benchmarks/production-v3/project/src/reliability/expiry.js +14 -0
  117. package/benchmarks/production-v3/project/src/reliability/retry.js +15 -0
  118. package/benchmarks/production-v3/project/test/smoke.test.js +21 -0
  119. package/benchmarks/production-v3/project/vendor/README.md +1 -0
  120. package/benchmarks/production-v3/prompts/abort-reconnect-supersession.md +11 -0
  121. package/benchmarks/production-v3/prompts/backend-frontend-contract-sync.md +20 -0
  122. package/benchmarks/production-v3/prompts/billing-cutoff-clock-skew.md +11 -0
  123. package/benchmarks/production-v3/prompts/bounded-retry.md +7 -0
  124. package/benchmarks/production-v3/prompts/chunked-record-boundary.md +11 -0
  125. package/benchmarks/production-v3/prompts/cli-double-dash.md +7 -0
  126. package/benchmarks/production-v3/prompts/config-precedence.md +6 -0
  127. package/benchmarks/production-v3/prompts/destructive-history-refusal.md +9 -0
  128. package/benchmarks/production-v3/prompts/expiry-boundary.md +14 -0
  129. package/benchmarks/production-v3/prompts/idempotent-replay-conflict.md +13 -0
  130. package/benchmarks/production-v3/prompts/incident-diagnosis.md +4 -0
  131. package/benchmarks/production-v3/prompts/invoice-rounding.md +9 -0
  132. package/benchmarks/production-v3/prompts/journeys/config-precedence-scout.md +3 -0
  133. package/benchmarks/production-v3/prompts/journeys/expiry-boundary-scout.md +3 -0
  134. package/benchmarks/production-v3/prompts/journeys/quoted-csv-scout.md +3 -0
  135. package/benchmarks/production-v3/prompts/journeys/recover-after-uncertain-send.md +4 -0
  136. package/benchmarks/production-v3/prompts/journeys/repository-prompt-injection-scout.md +4 -0
  137. package/benchmarks/production-v3/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
  138. package/benchmarks/production-v3/prompts/journeys/stable-dedup-scout.md +3 -0
  139. package/benchmarks/production-v3/prompts/journeys/stale-search-response-scout.md +3 -0
  140. package/benchmarks/production-v3/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
  141. package/benchmarks/production-v3/prompts/journeys/verify-current-contract.md +4 -0
  142. package/benchmarks/production-v3/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
  143. package/benchmarks/production-v3/prompts/pagination-boundary.md +9 -0
  144. package/benchmarks/production-v3/prompts/protected-env-refusal.md +8 -0
  145. package/benchmarks/production-v3/prompts/quoted-csv.md +6 -0
  146. package/benchmarks/production-v3/prompts/reconnect-chat-event-order.md +20 -0
  147. package/benchmarks/production-v3/prompts/repository-prompt-injection.md +5 -0
  148. package/benchmarks/production-v3/prompts/resumable-checkpoint-partial-failure.md +15 -0
  149. package/benchmarks/production-v3/prompts/revoked-session-cache.md +10 -0
  150. package/benchmarks/production-v3/prompts/schema-migration.md +6 -0
  151. package/benchmarks/production-v3/prompts/stable-dedup.md +6 -0
  152. package/benchmarks/production-v3/prompts/stale-search-response.md +6 -0
  153. package/benchmarks/production-v3/prompts/tenant-cache-isolation.md +6 -0
  154. package/benchmarks/production-v3/prompts/tenant-role-authorization.md +6 -0
  155. package/benchmarks/production-v3/prompts/unicode-search.md +6 -0
  156. package/benchmarks/production-v3/prompts/workflow-switch-same-session.md +30 -0
  157. package/benchmarks/production-v3/prompts/workspace-order.md +7 -0
  158. package/benchmarks/production-v3/public-checks/abort-reconnect-supersession.js +34 -0
  159. package/benchmarks/production-v3/public-checks/expiry-boundary.js +29 -0
  160. package/benchmarks/production-v3/public-checks/revoked-session-cache.js +20 -0
  161. package/benchmarks/production-v3/spend-control.v1.json +121 -0
  162. package/benchmarks/production-v3/suite.json +1010 -0
  163. package/benchmarks/production-v3/variant.mjs +178 -0
  164. package/catalog/capabilities.json +2 -2
  165. package/docs/benchmark-codex-mcp-metadata-contract-v1.md +159 -0
  166. package/docs/benchmark-codex-mcp-metadata-contract-v2.md +182 -0
  167. package/docs/benchmark-codex-mcp-metadata-contract-v3.md +194 -0
  168. package/docs/benchmark-public-contract-addendum-v2.md +85 -0
  169. package/docs/benchmark-public-contract-addendum-v3.md +116 -0
  170. package/docs/command-reference-vietnamese.md +10 -7
  171. package/docs/context-window-policy.md +3 -3
  172. package/docs/distribution-standard.md +9 -9
  173. package/docs/languages.json +2 -2
  174. package/docs/operator-manual-vietnamese.md +12 -12
  175. package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
  176. package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
  177. package/docs/piagent-core-improvement-plan.md +528 -0
  178. package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
  179. package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
  180. package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
  181. package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
  182. package/docs/piagent-open-session-wait.md +19 -0
  183. package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
  184. package/docs/publishing-for-teams.md +2 -0
  185. package/docs/quality-benchmark.md +128 -8
  186. package/docs/quickstart-vietnamese.md +2 -2
  187. package/docs/release-install-policy.md +32 -9
  188. package/docs/research/harness-next-evidence-review.md +113 -0
  189. package/docs/team-onboarding.md +7 -7
  190. package/docs/third-party-neutrality.md +7 -0
  191. package/docs/usage-observability.md +1 -1
  192. package/docs-site/architecture.html +1 -1
  193. package/docs-site/benchmark.html +1 -1
  194. package/docs-site/commands.html +1 -1
  195. package/docs-site/content/en/runtime.html +1 -1
  196. package/docs-site/content/en/whats-new.html +11 -0
  197. package/docs-site/content/runtime.html +2 -2
  198. package/docs-site/content/whats-new.html +11 -0
  199. package/docs-site/context-engine.html +1 -1
  200. package/docs-site/en/architecture.html +1 -1
  201. package/docs-site/en/benchmark.html +1 -1
  202. package/docs-site/en/commands.html +1 -1
  203. package/docs-site/en/context-engine.html +1 -1
  204. package/docs-site/en/index.html +1 -1
  205. package/docs-site/en/mcp-approval.html +1 -1
  206. package/docs-site/en/mcp-auth.html +1 -1
  207. package/docs-site/en/mcp-servers.html +1 -1
  208. package/docs-site/en/mcp.html +1 -1
  209. package/docs-site/en/permissions.html +1 -1
  210. package/docs-site/en/profiles.html +1 -1
  211. package/docs-site/en/quickstart.html +1 -1
  212. package/docs-site/en/runtime.html +2 -2
  213. package/docs-site/en/scope.html +1 -1
  214. package/docs-site/en/security.html +1 -1
  215. package/docs-site/en/team.html +1 -1
  216. package/docs-site/en/whats-new.html +12 -1
  217. package/docs-site/en/workflows.html +1 -1
  218. package/docs-site/index.html +1 -1
  219. package/docs-site/mcp-approval.html +1 -1
  220. package/docs-site/mcp-auth.html +1 -1
  221. package/docs-site/mcp-servers.html +1 -1
  222. package/docs-site/mcp.html +1 -1
  223. package/docs-site/permissions.html +1 -1
  224. package/docs-site/profiles.html +1 -1
  225. package/docs-site/quickstart.html +1 -1
  226. package/docs-site/runtime.html +3 -3
  227. package/docs-site/scope.html +1 -1
  228. package/docs-site/security.html +1 -1
  229. package/docs-site/team.html +1 -1
  230. package/docs-site/whats-new.html +12 -1
  231. package/docs-site/workflows.html +1 -1
  232. package/evals/architecture-conformance-v1/lane.json +18 -0
  233. package/evals/architecture-conformance-v1/runner.mjs +77 -0
  234. package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
  235. package/evals/fixtures/approved-host-contracts.valid.json +43 -0
  236. package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
  237. package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
  238. package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
  239. package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
  240. package/evals/fixtures/composite-criterion.invalid.json +10 -0
  241. package/evals/fixtures/composite-criterion.valid.json +33 -0
  242. package/evals/fixtures/contract-family-library.invalid.json +42 -0
  243. package/evals/fixtures/contract-family-library.valid.json +41 -0
  244. package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
  245. package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
  246. package/evals/fixtures/host-contract-plan.invalid.json +42 -0
  247. package/evals/fixtures/host-contract-plan.valid.json +41 -0
  248. package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
  249. package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
  250. package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
  251. package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
  252. package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
  253. package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
  254. package/evals/fs5-artifact-archive/README.md +32 -0
  255. package/evals/fs5-artifact-archive/manifest.json +148 -0
  256. package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
  257. package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
  258. package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
  259. package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
  260. package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
  261. package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
  262. package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
  263. package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
  264. package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
  265. package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
  266. package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
  267. package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
  268. package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
  269. package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
  270. package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
  271. package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
  272. package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
  273. package/evals/fs5-causal-arm.v1.json +9 -5
  274. package/evals/fs5-pilot-protocol.v1.json +1 -1
  275. package/evals/fs5-pilot-protocol.v4.json +4 -4
  276. package/evals/fs5-pilot-protocol.v5.json +6 -5
  277. package/evals/harness-next/development-corpus.mjs +106 -0
  278. package/evals/harness-next/resource-budget-probe.mjs +38 -0
  279. package/evals/harness-next/run-calibration.mjs +83 -0
  280. package/evals/harness-next/run-resource-probe.mjs +55 -0
  281. package/evals/harness-next/selected-development-corpus.mjs +27 -0
  282. package/evals/harness-next.v1.json +51 -0
  283. package/evals/long-horizon-v1/README.md +19 -0
  284. package/evals/long-horizon-v1/runner.mjs +116 -48
  285. package/evals/long-horizon-v1/worker.mjs +77 -30
  286. package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
  287. package/evals/private-holdout-v1/README.md +5 -2
  288. package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
  289. package/package.json +9 -4
  290. package/packages/piagent-core/README.md +2 -2
  291. package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
  292. package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
  293. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
  294. package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
  295. package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
  296. package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
  297. package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
  298. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
  299. package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
  300. package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
  301. package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
  302. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +2 -1
  303. package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
  304. package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
  305. package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
  306. package/packages/piagent-core/benchmark/benchmark-core.js +107 -107
  307. package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
  308. package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
  309. package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
  310. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
  311. package/packages/piagent-core/benchmark/benchmark-forensics.js +63 -50
  312. package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
  313. package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
  314. package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
  315. package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
  316. package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
  317. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
  318. package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
  319. package/packages/piagent-core/benchmark/benchmark-preflight.js +69 -8
  320. package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
  321. package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
  322. package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
  323. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +162 -45
  324. package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
  325. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
  326. package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
  327. package/packages/piagent-core/benchmark/benchmark-record-validation.js +269 -3
  328. package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
  329. package/packages/piagent-core/benchmark/benchmark-report.js +79 -4
  330. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
  331. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
  332. package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
  333. package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
  334. package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
  335. package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
  336. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +144 -128
  337. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
  338. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
  339. package/packages/piagent-core/benchmark/benchmark-suite.js +211 -4
  340. package/packages/piagent-core/benchmark/benchmark-summary-support.js +30 -2
  341. package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
  342. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
  343. package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
  344. package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
  345. package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
  346. package/packages/piagent-core/benchmark/benchmark-usage.js +395 -33
  347. package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
  348. package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
  349. package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
  350. package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
  351. package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
  352. package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
  353. package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
  354. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +264 -70
  355. package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
  356. package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
  357. package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
  358. package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
  359. package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
  360. package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
  361. package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
  362. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
  363. package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
  364. package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
  365. package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
  366. package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
  367. package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
  368. package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
  369. package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
  370. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
  371. package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
  372. package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
  373. package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
  374. package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
  375. package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
  376. package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
  377. package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
  378. package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
  379. package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
  380. package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
  381. package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
  382. package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
  383. package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
  384. package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
  385. package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
  386. package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
  387. package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
  388. package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
  389. package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
  390. package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
  391. package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
  392. package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
  393. package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
  394. package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
  395. package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
  396. package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
  397. package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
  398. package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
  399. package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
  400. package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
  401. package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
  402. package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
  403. package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
  404. package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
  405. package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
  406. package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
  407. package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
  408. package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
  409. package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
  410. package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
  411. package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
  412. package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
  413. package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
  414. package/packages/piagent-core/extensions/acceptance-receipt.js +139 -152
  415. package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
  416. package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
  417. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
  418. package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
  419. package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
  420. package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
  421. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
  422. package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
  423. package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
  424. package/packages/piagent-core/extensions/context-engine.js +11 -6
  425. package/packages/piagent-core/extensions/criterion-context-pack.js +96 -4
  426. package/packages/piagent-core/extensions/failure-types.ts +2 -2
  427. package/packages/piagent-core/extensions/guard-types.ts +5 -1
  428. package/packages/piagent-core/extensions/piagent-guard.ts +197 -155
  429. package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
  430. package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
  431. package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
  432. package/packages/piagent-core/extensions/task-contract-view.js +4 -4
  433. package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
  434. package/packages/piagent-core/extensions/task-journal.js +48 -3
  435. package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
  436. package/packages/piagent-core/extensions/task-state.js +74 -38
  437. package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
  438. package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
  439. package/packages/piagent-core/extensions/verification-intelligence.js +60 -8
  440. package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
  441. package/packages/piagent-core/extensions/workspace-revision.js +48 -0
  442. package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
  443. package/packages/piagent-core/package.json +3 -3
  444. package/packages/piagent-core/policies/base-policy.json +1 -0
  445. package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
  446. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
  447. package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
  448. package/packages/piagent-core/runtime/hooks/completion-hook.ts +76 -83
  449. package/packages/piagent-core/runtime/hooks/input-hook.ts +92 -7
  450. package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
  451. package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
  452. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +50 -18
  453. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +53 -20
  454. package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
  455. package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
  456. package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
  457. package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
  458. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
  459. package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
  460. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
  461. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +49 -8
  462. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +61 -15
  463. package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
  464. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
  465. package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
  466. package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
  467. package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
  468. package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
  469. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +12 -7
  470. package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
  471. package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
  472. package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
  473. package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
  474. package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
  475. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +11 -2
  476. package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
  477. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +192 -57
  478. package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
  479. package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
  480. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +27 -39
  481. package/packages/piagent-core/runtime/recovery/resume-state.ts +8 -5
  482. package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
  483. package/packages/piagent-core/runtime/registration/context-commands.ts +12 -8
  484. package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
  485. package/packages/piagent-core/runtime/registration/policy-tools.ts +5 -3
  486. package/packages/piagent-core/runtime/registration/session-commands.ts +9 -7
  487. package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
  488. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +27 -11
  489. package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
  490. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +5 -2
  491. package/packages/piagent-core/runtime/registration/task-start-tool.ts +23 -23
  492. package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
  493. package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
  494. package/packages/piagent-core/runtime/session/message-signals.ts +6 -22
  495. package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
  496. package/packages/piagent-core/runtime/session/runtime-state.ts +29 -35
  497. package/packages/piagent-core/runtime/session/system-prompt.ts +3 -3
  498. package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
  499. package/packages/piagent-core/runtime/session/usage.ts +4 -3
  500. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
  501. package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
  502. package/packages/piagent-core/runtime/tools/phase-tools.ts +3 -2
  503. package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
  504. package/packages/piagent-core/runtime/tools/tool-groups.ts +10 -3
  505. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
  506. package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
  507. package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
  508. package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
  509. package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
  510. package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
  511. package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
  512. package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
  513. package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
  514. package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
  515. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +11 -11
  516. package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
  517. package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
  518. package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
  519. package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
  520. package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
  521. package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
  522. package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
  523. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +44 -7
  524. package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
  525. package/packages/piagent-core/runtime/workflows/task-intake.ts +221 -242
  526. package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
  527. package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
  528. package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
  529. package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
  530. package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
  531. package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
  532. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-B4XehTCU.js → MarkdownMessage-DGk34zJT.js} +1 -1
  533. package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
  534. package/packages/piagent-webui/dist/client/assets/index-DiKRmCEP.js +176 -0
  535. package/packages/piagent-webui/dist/client/index.html +2 -2
  536. package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
  537. package/packages/piagent-webui/extension/piagent-webui.ts +10 -2
  538. package/packages/piagent-webui/extension/review-controller.ts +29 -6
  539. package/packages/piagent-webui/extension/same-session-bridge.ts +6 -7
  540. package/packages/piagent-webui/extension/session-stream-adapter.ts +60 -11
  541. package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
  542. package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
  543. package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
  544. package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
  545. package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
  546. package/packages/piagent-webui/gateway/gateway-session-stream.ts +141 -19
  547. package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
  548. package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
  549. package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
  550. package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
  551. package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
  552. package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
  553. package/packages/piagent-webui/gateway/session-inspection-registry.ts +11 -2
  554. package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
  555. package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
  556. package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
  557. package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
  558. package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
  559. package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
  560. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +114 -114
  561. package/packages/piagent-webui/server/core-inspection-provider.ts +73 -14
  562. package/packages/piagent-webui/server/loopback-server.ts +9 -7
  563. package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
  564. package/packages/piagent-webui/server/transcript-projection.ts +65 -12
  565. package/packages/piagent-webui/shared/message-correlation.ts +25 -0
  566. package/schemas/approved-host-contracts.schema.json +973 -0
  567. package/schemas/benchmark-attempt-outcome.schema.json +303 -0
  568. package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
  569. package/schemas/composite-criterion.schema.json +788 -0
  570. package/schemas/contract-family-library.schema.json +28 -0
  571. package/schemas/contract-selection-recipe.schema.json +31 -0
  572. package/schemas/failure-evidence.schema.json +2 -2
  573. package/schemas/helper-request.schema.json +16 -4
  574. package/schemas/host-contract-plan.schema.json +25 -0
  575. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
  576. package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
  577. package/schemas/piagent-webui/runtime-event-v2.schema.json +32 -1
  578. package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
  579. package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
  580. package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
  581. package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
  582. package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
  583. package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
  584. package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
  585. package/schemas/public-contracts/revocation-v1.schema.json +87 -0
  586. package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
  587. package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
  588. package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
  589. package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
  590. package/schemas/task-contract.schema.json +30 -0
  591. package/scripts/approve-independent-verification.mjs +57 -0
  592. package/scripts/benchmark-arm-observer.mjs +320 -0
  593. package/scripts/benchmark-budget-ipc.mjs +34 -0
  594. package/scripts/benchmark-budget-launcher.mjs +91 -0
  595. package/scripts/benchmark-budget-processes.mjs +133 -0
  596. package/scripts/benchmark-budget-publication.mjs +228 -0
  597. package/scripts/benchmark-budget-runtime.mjs +136 -0
  598. package/scripts/benchmark-candidate-ablation.mjs +265 -0
  599. package/scripts/benchmark-codex-journey.mjs +406 -0
  600. package/scripts/benchmark-independent-verification.mjs +628 -0
  601. package/scripts/benchmark-journey-outcome.mjs +92 -0
  602. package/scripts/benchmark-production-v3-human-review.mjs +192 -0
  603. package/scripts/benchmark-public-input-catalog.mjs +158 -0
  604. package/scripts/benchmark-registered-plan-author.mjs +355 -0
  605. package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
  606. package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
  607. package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
  608. package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
  609. package/scripts/benchmark-runner-completion.mjs +133 -0
  610. package/scripts/benchmark-runner-configuration.mjs +159 -0
  611. package/scripts/benchmark-runner-core.mjs +217 -388
  612. package/scripts/benchmark-runner-finalization.mjs +140 -27
  613. package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
  614. package/scripts/benchmark-runner-schedule.mjs +256 -0
  615. package/scripts/benchmark-runner-support.mjs +136 -4
  616. package/scripts/benchmark-runner.mjs +95 -18
  617. package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
  618. package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
  619. package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
  620. package/scripts/benchmark-scoped-pi-router.mjs +196 -0
  621. package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
  622. package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
  623. package/scripts/benchmark-scoped-session-custody.mjs +599 -0
  624. package/scripts/benchmark-scoped-session-factory.mjs +342 -0
  625. package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
  626. package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
  627. package/scripts/benchmark-session-evaluator.mjs +169 -0
  628. package/scripts/benchmark-session-provider-boundary.mjs +62 -0
  629. package/scripts/benchmark-session-usage.mjs +28 -0
  630. package/scripts/benchmark-session.mjs +343 -50
  631. package/scripts/benchmark-webui-journey.mjs +678 -0
  632. package/scripts/check-public-wording.mjs +46 -0
  633. package/scripts/fs4-readiness-evaluation.mjs +7 -1
  634. package/scripts/phase-tools-evaluation.mjs +1 -0
  635. package/scripts/pi-auto.sh +7 -1
  636. package/scripts/pi-usage-history.mjs +201 -11
  637. package/scripts/piagent-cli.mjs +8 -0
  638. package/scripts/private-holdout-readiness.mjs +7 -1
  639. package/scripts/public-evaluation-exposure.mjs +140 -0
  640. package/scripts/select-independent-verification.mjs +62 -0
  641. package/scripts/typescript-loader.mjs +135 -1
  642. package/scripts/update-global.mjs +6 -7
  643. package/scripts/verify-local.sh +36 -55
  644. package/scripts/verify-release-identity.mjs +5 -3
  645. package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +0 -176
@@ -1,22 +1,40 @@
1
1
  import { classifyContextTask } from "../../extensions/context-engine.js";
2
- import { matchesAnyPath, matchesProtectedPath, normalizePathCandidate } from "../../extensions/policy-core.js";
2
+ import { acceptanceContractConjuncts } from "../../extensions/acceptance-contract-conjunction.js";
3
+ import { matchesProtectedPath, normalizePathCandidate } from "../../extensions/policy-core.js";
3
4
  import type { ReviewLens } from "../../extensions/guard-types.js";
4
5
  import { LONG_INPUT_CHARS } from "../runtime-limits.ts";
6
+ import { classifyConditionalRepairIntent } from "./task-repair-intent.ts";
7
+ import {
8
+ foldChangeIntent,
9
+ hasChangeIntent,
10
+ isExplicitChangeRequest,
11
+ isLightweightNonAuthorizingChangeLanguage,
12
+ isNonAuthorizingChangeLanguage
13
+ } from "./change-clarification.ts";
14
+ import {
15
+ completedFollowupScope,
16
+ hasConditionalRepairIntent,
17
+ type PriorTaskScopeEvidence
18
+ } from "./task-followup-policy.ts";
5
19
  export { boundedRuntimeIntakeMessage } from "./runtime-intake-compaction.ts";
20
+ export { resolveTaskScopePatterns } from "./task-scope-resolution.ts";
21
+ export type { TaskScopeResolution } from "./task-scope-resolution.ts";
6
22
 
7
23
  const AUTO_INTAKE_MAX_PROMPT_CHARS = LONG_INPUT_CHARS;
8
24
  const AUTO_TASK_SUMMARY_CHARS = 700;
9
25
  const AUTO_ACCEPTANCE_CRITERION_CHARS = 600;
10
26
  const AUTO_ACCEPTANCE_CRITERIA_MAX = 12;
11
- const AUTO_INTAKE_CHANGE_INTENT = /\b(?:add|build|change|correct|create|fix|implement|modify|mutate|refactor|remove|rename|repair|replace|update|write|sua|them|doi|cap nhat|xoa|tao)\b/i;
12
27
  const AUTO_INTAKE_READ_ONLY_LEAD = /^\s*\/?(?:analy[sz]e|audit|check|discuss|explain|inspect|plan|research|review|scout|summari[sz]e|why|how|can\s+(?:you|we)|kiem tra|nghien cuu|giai thich|danh gia)\b/i;
13
28
  const AUTO_INTAKE_MANUAL_RISK = /\b(?:credential|database|deploy|destructive|encryption|external provider|payment|permission|production|publish|secret|token rotation)\b/i;
14
29
  const AUTO_READ_ONLY_INTENT = /\b(?:analy[sz]e|audit|check|diagnos(?:e|is)|explain|inspect|investigate|plan|research|review|scout|summari[sz]e|triage|kiem tra|nghien cuu|giai thich|danh gia)\b/i;
30
+ const AUTO_STANDALONE_NO_MUTATION = /\bwithout\s+(?:editing|changing|modifying|mutating|touching|writing)(?=\s*(?:[.!?]|$))/i;
15
31
  // Candidate wording is separated from the following qualifier. This keeps a
16
32
  // durable zero-delta instruction distinct from local path authority and from a
17
33
  // temporary "inspect first, edit later" instruction.
18
34
  const AUTO_NO_MUTATION_CANDIDATES = [
19
- /\b(?:do not|don't|must not|never)\s+(?:edit|change|modify|mutate|touch|write(?:\s+to)?)\s+(?:(?:any|all|the|this|entire)\s+)?(?:files?|code|source(?:\s+files?)?|project(?:\s+files?)?|workspace|repo(?:sitory)?|anything)\b/i,
35
+ AUTO_STANDALONE_NO_MUTATION,
36
+ /\b(?:do not|don't|must not|never)\s+(?:edit|change|modify|mutate|touch|write(?:\s+to)?)(?:\s+(?:or|and)\s+create)?\s+(?:(?:any|all|the|this|entire)\s+)?(?:files?|code|source(?:\s+files?)?|project(?:\s+files?)?|workspace|repo(?:sitory)?|anything)\b/i,
37
+ /\b(?:do not|don't|must not|never)\s+create\s+(?:or|and)\s+(?:edit|change|modify|mutate|touch|write(?:\s+to)?)\s+(?:(?:any|all|the|this|entire)\s+)?(?:files?|code|source(?:\s+files?)?|project(?:\s+files?)?|workspace|repo(?:sitory)?|anything)\b/i,
20
38
  /\b(?:do not|don't|must not|never)\s+make\s+(?:any\s+)?(?:changes?|edits?|mutations?)(?:\s+to\s+(?:(?:any|all|the)\s+)?(?:files?|code|source(?:\s+files?)?|project(?:\s+files?)?|workspace|repo(?:sitory)?))?\b/i,
21
39
  /\b(?:make\s+)?no\s+(?:(?:code|source|project|file|workspace|repo(?:sitory)?)\s+)?(?:changes?|edits?|mutations?)(?:\s+to\s+(?:(?:any|all|the)\s+)?(?:files?|code|source(?:\s+files?)?|project(?:\s+files?)?|workspace|repo(?:sitory)?))?\b/i,
22
40
  /\bno\s+(?:project|source)\s+files?\s+(?:are\s+)?(?:changed|edited|modified|mutated)\b/i,
@@ -28,16 +46,52 @@ const AUTO_NO_MUTATION_CANDIDATES = [
28
46
  const AUTO_BOUNDARY_TAIL_PREFIX = "^(?:\\s|[,.;:!?()\\[\\]{}—–-])*(?:but\\s+)?";
29
47
  const AUTO_LOCAL_BOUNDARY_TAIL = new RegExp(`${AUTO_BOUNDARY_TAIL_PREFIX}(?:outside|beyond|under|within|inside|in|on|for(?!\\s+now\\b)|except(?:\\s+for)?|other\\s+than|apart\\s+from|to\\b|only\\s+(?:(?:edit|change|modify|mutate|touch|write)\\b|(?:in|under|within|outside)\\b|(?:[a-z0-9_.@*?-]+\\/))|ngo(?:a|à)i\\b|tr(?:u|ừ)\\b)`, "i");
30
48
  const AUTO_TEMPORARY_BOUNDARY_TAIL = new RegExp(`${AUTO_BOUNDARY_TAIL_PREFIX}(?:(?:not\\s+)?yet\\b|right\\s+now\\b|for\\s+now\\b|at\\s+(?:(?:this|the\\s+current)\\s+(?:step|stage|phase|time)|the\\s+moment)\\b|during\\s+(?:(?:this|the\\s+current)\\s+)?(?:step|stage|phase|planning)\\b|while\\b|unless\\b|until\\b|before\\b|hi(?:e|ệ)n\\s+t(?:a|ạ)i\\b|b(?:a|â)y\\s+gi(?:o|ờ)\\b)`, "i");
49
+ const AUTO_GLOBAL_NO_ACCESS_BOUNDARY = /\b(?:do not|don't|must not|never)\s+(?:read|execute|write|delete|restore|hash|echo|compare)(?:\s*,\s*(?:read|execute|write|delete|restore|hash|echo|compare)){1,6}(?:\s*,?\s*or\s+(?:read|execute|write|delete|restore|hash|echo|compare))?\s+(?:any\s+|the\s+|this\s+)?(?:project|workspace|repository|repo|audit|environment)(?:\s+or\s+(?:project|workspace|repository|repo|audit|environment))?\s+(?:content|data|files?|records?|history)\b/i;
50
+ const AUTO_PROTECTED_ACCESS_DENIAL = /\b(?:do not|don't|must not|never)\s+(?:inspect|read|open|access|copy|print|echo|reveal|expose|export|disclose)\s+(?:(?:the|a|an|any|all|this|that|complete|raw)\s+){0,3}(?:protected(?:[- ](?:credentials?|files?|data|material|secrets?|tokens?))?|credentials?|secrets?|tokens?|passwords?|api[- ]?keys?|auth(?:entication)?(?:\s+(?:data|material|values?|tokens?))?)\b/i;
51
+ // Some refusal prompts establish the protected object in the preceding
52
+ // boundary sentence and then refer to it only as "the file". Admit that
53
+ // grammar only when both halves are explicit; a generic file denial alone is
54
+ // not protected-material authority.
55
+ const AUTO_PROTECTED_MATERIAL_BOUNDARY_CONTEXT = /\bthis\s+request\s+crosses\s+the\s+protected[- ]material\s+boundary\b/i;
56
+ const AUTO_GENERIC_FILE_ACCESS_DENIAL = /\b(?:do not|don't|must not|never)\s+(?:inspect|read|open|access)\s+(?:(?:the|this|that|requested|referenced|target(?:ed)?)\s+){0,2}(?:files?|paths?)\b/i;
57
+ const AUTO_DESTRUCTIVE_HISTORY_BOUNDARY_CONTEXT = /\bthis\s+request\s+crosses\s+the\s+destructive[- ]history\s+boundary\b/i;
58
+ const AUTO_AUDIT_LEDGER_ACCESS_DENIAL = /\b(?:do not|don't|must not|never)\s+(?:read|inspect|open|access)(?:\s*,\s*(?:truncate|delete|move|overwrite)){1,4}(?:\s*,?\s*(?:or|and)\s+(?:truncate|delete|move|overwrite))?\s+(?:the|this)\s+audit\s+(?:ledger|history|log)\b/i;
59
+ const AUTO_REFUSAL_INTENT = /\b(?:refuse|decline|reject)\b/i;
60
+ const AUTO_REFUSAL_NEGATION = /\b(?:do not|don't|must not|never)\s+(?:refuse|decline|reject)\b/i;
31
61
  const AUTO_GLOBAL_READ_ONLY_PATTERNS = [
32
62
  /^\s*\/?read-only\s*(?:$|[.!?:;—–-])/im,
33
63
  /^\s*\/?read-only\s+(?:task|run|session)\s*(?:$|[.!?:;—–-]|\b(?:to|for)\b)/im,
34
64
  /^\s*\/?read-only\s+(?:assessment|review)\s*(?:$|[.!?:;—–-]|\b(?:of|for)\b)/im,
35
65
  /\b(?:as|in)\s+(?:a\s+)?read-only\s+(?:mode|task|run|session|assessment|review)\b/i,
36
66
  /\b(?:use|perform|conduct|run)\s+(?:a\s+)?read-only\s+(?:task|run|assessment|review)\b/i,
37
- /\b(?:keep\s+)?(?:this\s+|the\s+)?(?:task|run|session|workspace|project|repo|repository)\s+(?:(?:is|must|should)\s+(?:be\s+|remain\s+)?|remain\s+)?read-only\b/i
67
+ /\b(?:keep\s+)?(?:this\s+|the\s+)?(?:task|run|session|workspace|project|repo|repository)\s+(?:(?:is|must|should)\s+(?:be\s+|remain\s+)?|remain\s+)?read-only\b/i,
68
+ // A task-wide refusal may forbid every material operation without using the
69
+ // literal phrase "read-only" or naming a file mutation. Keep this narrow:
70
+ // require a compound operation list and a global project/audit data object.
71
+ AUTO_GLOBAL_NO_ACCESS_BOUNDARY
38
72
  ];
39
73
  const AUTO_EXECUTION_INTENT = /(?:\b(?:run|execute|execution|rerun|re-run|chay)\b.{0,80}\b(?:tests?|build|checks?|gates?|lint|typecheck|package|pack|verify|verification)\b|\b(?:npm|pnpm|yarn|bun)\s+(?:test|pack|run\s+(?:build|check|lint|typecheck|verify))\b)/i;
40
74
 
75
+ function explicitSourceWorkflow(text: string): boolean {
76
+ const signal = classifyContextTask(text);
77
+ return Boolean(signal.workflowId && signal.changeMode === "source-change");
78
+ }
79
+
80
+ /** A question about whether to mutate is conversational context, not mutation authority. */
81
+ export function isNonAuthorizingChangeClarification(prompt: string): boolean {
82
+ const text = String(prompt ?? "").trim();
83
+ if (!text) return false;
84
+ if (explicitSourceWorkflow(text)) return false;
85
+ return isNonAuthorizingChangeLanguage(text);
86
+ }
87
+
88
+ /** Only a short yes/no-or-choice continuation may bypass repository retrieval. */
89
+ export function isLightweightNonAuthorizingChangeContinuation(prompt: string): boolean {
90
+ const text = String(prompt ?? "").trim();
91
+ if (!text || explicitSourceWorkflow(text)) return false;
92
+ return isLightweightNonAuthorizingChangeLanguage(text);
93
+ }
94
+
41
95
  export const AUTO_INTAKE_SNAPSHOT_PATTERNS = [
42
96
  "src/**", "app/**", "lib/**", "packages/**", "test/**", "tests/**", "spec/**", "__tests__/**"
43
97
  ];
@@ -46,12 +100,29 @@ function uniqueStrings(values: string[]): string[] {
46
100
  return [...new Set(values)];
47
101
  }
48
102
 
103
+ // Bare "without editing." is a directive only in prose, not quoted UI text,
104
+ // an example block, or repository data quoted by the operator.
105
+ function boundaryDirectiveProse(text: string): string {
106
+ let fence: string | undefined;
107
+ return text.split("\n").map(line => {
108
+ const marker = line.match(/^\s*(`{3,}|~{3,})/);
109
+ if (marker) {
110
+ if (!fence) fence = marker[1];
111
+ else if (marker[1][0] === fence[0] && marker[1].length >= fence.length) fence = undefined;
112
+ return "<quoted-content>";
113
+ }
114
+ if (fence || /^\s*>/.test(line)) return "<quoted-content>";
115
+ return line.replace(/`[^`\n]*`|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|“[^”]*”|‘[^’]*’/g, "<quoted-content>");
116
+ }).join("\n");
117
+ }
118
+
49
119
  function noMutationBoundarySignals(text: string): { taskWide: boolean; temporary: boolean } {
50
120
  let temporary = false;
51
121
  for (const pattern of AUTO_NO_MUTATION_CANDIDATES) {
122
+ const candidateText = pattern === AUTO_STANDALONE_NO_MUTATION ? boundaryDirectiveProse(text) : text;
52
123
  const matcher = new RegExp(pattern.source, `${pattern.flags}g`);
53
- for (const match of text.matchAll(matcher)) {
54
- const tail = text.slice((match.index ?? 0) + match[0].length, (match.index ?? 0) + match[0].length + 160);
124
+ for (const match of candidateText.matchAll(matcher)) {
125
+ const tail = candidateText.slice((match.index ?? 0) + match[0].length, (match.index ?? 0) + match[0].length + 160);
55
126
  if (AUTO_LOCAL_BOUNDARY_TAIL.test(tail)) continue;
56
127
  if (AUTO_TEMPORARY_BOUNDARY_TAIL.test(tail)) {
57
128
  temporary = true;
@@ -67,6 +138,21 @@ function hasGlobalReadOnlyBoundary(text: string): boolean {
67
138
  return AUTO_GLOBAL_READ_ONLY_PATTERNS.some((pattern) => pattern.test(text));
68
139
  }
69
140
 
141
+ function hasGlobalNoAccessBoundary(text: string): boolean {
142
+ return AUTO_GLOBAL_NO_ACCESS_BOUNDARY.test(text);
143
+ }
144
+
145
+ export function hasProtectedRefusalBoundary(text: string): boolean {
146
+ const accessDenied = AUTO_PROTECTED_ACCESS_DENIAL.test(text)
147
+ || (AUTO_PROTECTED_MATERIAL_BOUNDARY_CONTEXT.test(text) && AUTO_GENERIC_FILE_ACCESS_DENIAL.test(text));
148
+ const directive = boundaryDirectiveProse(text);
149
+ return AUTO_REFUSAL_INTENT.test(text)
150
+ && !AUTO_REFUSAL_NEGATION.test(text)
151
+ && ((accessDenied && noMutationBoundarySignals(text).taskWide)
152
+ || (AUTO_REFUSAL_INTENT.test(directive) && AUTO_DESTRUCTIVE_HISTORY_BOUNDARY_CONTEXT.test(directive)
153
+ && AUTO_AUDIT_LEDGER_ACCESS_DENIAL.test(directive)));
154
+ }
155
+
70
156
  const PLAUSIBLE_SCOPE_ROOT = /^(?:\.github|app|apps|bin|config|docs|examples|lib|logs|packages|pages|public|scripts|spec|src|test|tests|vendor|__tests__)(?:\/|$)/i;
71
157
  const PLAUSIBLE_SCOPE_FILE = /(?:^|\/)(?:\.[^/]+|[^/]+\.(?:bash|c|cc|cjs|cpp|css|csv|env|go|graphql|gql|h|hpp|html|java|js|json|jsx|kt|kts|md|mdx|mjs|php|proto|py|rb|rs|scss|sh|sql|svg|swift|toml|ts|tsx|txt|xml|yaml|yml))$/i;
72
158
 
@@ -79,21 +165,40 @@ function plausibleTaskScopePath(value: string): boolean {
79
165
  }
80
166
 
81
167
  export function automaticTaskSummary(prompt: string): string {
82
- return String(prompt ?? "").replace(/\s+/g, " ").trim().slice(0, AUTO_TASK_SUMMARY_CHARS);
83
- }
168
+ return String(prompt ?? "").replace(/\s+/g, " ").trim().slice(0, AUTO_TASK_SUMMARY_CHARS); }
84
169
 
85
170
  export function automaticTaskIntakeEligible(prompt: string, readProtectedPaths: string[]): boolean {
86
171
  const text = String(prompt ?? "").trim();
87
172
  if (!text || text.length > AUTO_INTAKE_MAX_PROMPT_CHARS) return false;
173
+ const folded = foldChangeIntent(text);
174
+ const explicitChange = isExplicitChangeRequest(folded);
175
+ if (isNonAuthorizingChangeClarification(text)) return false;
88
176
  const noMutationBoundary = noMutationBoundarySignals(text);
177
+ // Verification-only execution keeps the source-task lane so the configured
178
+ // verifier is available, with mutation forbidden by its separate policy.
179
+ // For every non-execution task, a durable zero-delta boundary wins over
180
+ // incidental mutation verbs inside the prohibition itself.
181
+ if (noMutationBoundary.taskWide && !AUTO_EXECUTION_INTENT.test(folded)) return false;
89
182
  if (noMutationBoundary.temporary && !noMutationBoundary.taskWide) return false;
183
+ if (hasGlobalReadOnlyBoundary(text)) return false;
90
184
  const signal = classifyContextTask(text);
91
- if (AUTO_EXECUTION_INTENT.test(text)) {
185
+ const conditionalRepair = hasConditionalRepairIntent(text);
186
+ // Explicit non-execution workflows own their operation semantics; an implementation verb inside
187
+ // /plan, /discuss, or a git workflow must not create a source-change task early.
188
+ // A review that explicitly makes repair conditional on observed evidence is
189
+ // different: it needs verifier authority and may legitimately finish with
190
+ // either zero delta or a scoped repair.
191
+ if (signal.workflow !== "task" && !(signal.workflow === "review" && conditionalRepair)) return false;
192
+ if (AUTO_EXECUTION_INTENT.test(folded)) {
193
+ if (/\bpiagent_task_start\b/i.test(text)) return false;
194
+ return !signal.paths.some((candidate) => matchesProtectedPath(candidate, readProtectedPaths));
195
+ }
196
+ if (conditionalRepair) {
92
197
  if (/\bpiagent_task_start\b/i.test(text)) return false;
93
198
  return !signal.paths.some((candidate) => matchesProtectedPath(candidate, readProtectedPaths));
94
199
  }
95
- if (signal.workflow !== "task" || !AUTO_INTAKE_CHANGE_INTENT.test(text)) return false;
96
- if (AUTO_INTAKE_READ_ONLY_LEAD.test(text) || AUTO_INTAKE_MANUAL_RISK.test(text)) return false;
200
+ if (!hasChangeIntent(folded) && !explicitChange) return false;
201
+ if ((AUTO_INTAKE_READ_ONLY_LEAD.test(folded) && !explicitChange) || AUTO_INTAKE_MANUAL_RISK.test(folded)) return false;
97
202
  if (/\bpiagent_task_start\b/i.test(text)) return false;
98
203
  return !signal.paths.some((candidate) => matchesProtectedPath(candidate, readProtectedPaths));
99
204
  }
@@ -101,102 +206,57 @@ export function automaticTaskIntakeEligible(prompt: string, readProtectedPaths:
101
206
  export function automaticReadOnlyTaskIntakeEligible(prompt: string, readProtectedPaths: string[]): boolean {
102
207
  const text = String(prompt ?? "").trim();
103
208
  if (!text || text.length > AUTO_INTAKE_MAX_PROMPT_CHARS) return false;
209
+ const folded = foldChangeIntent(text);
210
+ if (isNonAuthorizingChangeClarification(text)) return false;
104
211
  const signal = classifyContextTask(text);
105
- if (signal.workflow === "usage" || signal.workflow === "permission" || signal.workflow === "context") return false;
106
- const readOnlyBoundary = noMutationBoundarySignals(text).taskWide || hasGlobalReadOnlyBoundary(text);
107
- if (!AUTO_READ_ONLY_INTENT.test(text) && !readOnlyBoundary) return false;
108
- if (AUTO_INTAKE_CHANGE_INTENT.test(text) && !readOnlyBoundary) return false;
212
+ if (["usage", "permission", "context", "discuss", "plan", "release", "onboard"].includes(signal.workflow)) return false;
213
+ const protectedRefusalBoundary = hasProtectedRefusalBoundary(text);
214
+ const readOnlyBoundary = noMutationBoundarySignals(text).taskWide || hasGlobalReadOnlyBoundary(text) || protectedRefusalBoundary;
215
+ if (!AUTO_READ_ONLY_INTENT.test(folded) && !readOnlyBoundary) return false;
216
+ if (hasChangeIntent(folded) && !readOnlyBoundary) return false;
109
217
  if (/\bpiagent_task_start\b/i.test(text)) return false;
110
- return !signal.paths.some((candidate) => matchesProtectedPath(candidate, readProtectedPaths));
218
+ const protectedTarget = signal.paths.some((candidate) => matchesProtectedPath(candidate, readProtectedPaths));
219
+ return !protectedTarget || hasGlobalNoAccessBoundary(text) || protectedRefusalBoundary;
111
220
  }
112
221
 
113
222
  export function automaticTaskIntakeMode(prompt: string, readProtectedPaths: string[]): "source-change" | "read-only" | undefined {
114
223
  if (automaticTaskIntakeEligible(prompt, readProtectedPaths)) return "source-change";
115
- if (automaticReadOnlyTaskIntakeEligible(prompt, readProtectedPaths)) return "read-only";
116
- return undefined;
224
+ return automaticReadOnlyTaskIntakeEligible(prompt, readProtectedPaths) ? "read-only" : undefined;
117
225
  }
118
226
 
119
227
  export function automaticTaskMutationPolicy(
120
228
  prompt: string,
121
229
  changeMode: "source-change" | "read-only"
122
- ): "required" | "forbidden" {
230
+ ): "required" | "allowed" | "forbidden" {
123
231
  const text = String(prompt ?? "");
124
232
  // A feature can intentionally become read-only while the implementation
125
233
  // still requires source changes. Only a task-wide boundary may suppress
126
234
  // mutation; incidental domain wording such as "list/detail read-only" must
127
235
  // never convert a delegated implementation into a zero-delta task.
128
- return changeMode === "read-only"
129
- || noMutationBoundarySignals(text).taskWide
130
- || hasGlobalReadOnlyBoundary(text)
131
- ? "forbidden"
132
- : "required";
236
+ if (changeMode === "read-only" || noMutationBoundarySignals(text).taskWide || hasGlobalReadOnlyBoundary(text)) {
237
+ return "forbidden";
238
+ }
239
+ return classifyConditionalRepairIntent(text) === "conditional-only" ? "allowed" : "required";
133
240
  }
134
241
 
135
242
  export function automaticTaskRiskLane(prompt: string): "tiny" | "normal" {
136
243
  return classifyContextTask(prompt).lane === "tiny" ? "tiny" : "normal";
137
244
  }
138
245
 
139
- const ATOMIC_CLAUSE_LEAD = /^(?:accept|add|build|change|correct|create|do not|emit|ensure|fail|fix|handle|implement|invalid|missing|modify|must|never|parse|preserve|reject|repair|return|support|throw|treat|update|verify|without)\b/i;
140
-
141
- function topLevelImperativeClauses(value: string): string[] {
142
- const clauses: string[] = [];
143
- let current = "", quote = "", round = 0, square = 0, curly = 0;
144
- for (let index = 0; index < value.length; index += 1) {
145
- const character = value[index], previous = value[index - 1] ?? "", next = value[index + 1] ?? "";
146
- if (quote) {
147
- current += character;
148
- if (character === quote && previous !== "\\") quote = "";
149
- continue;
150
- }
151
- const apostropheInsideWord = character === "'" && /[\p{L}\p{N}]/u.test(previous) && /[\p{L}\p{N}]/u.test(next);
152
- if ((character === "`" || character === '"' || character === "'") && !apostropheInsideWord) {
153
- quote = character; current += character;
154
- continue;
155
- }
156
- if (character === "(") round += 1;
157
- else if (character === ")") round = Math.max(0, round - 1);
158
- else if (character === "[") square += 1;
159
- else if (character === "]") square = Math.max(0, square - 1);
160
- else if (character === "{") curly += 1;
161
- else if (character === "}") curly = Math.max(0, curly - 1);
162
- if (character === ";" && round === 0 && square === 0 && curly === 0 && ATOMIC_CLAUSE_LEAD.test(value.slice(index + 1).trimStart())) {
163
- if (current.trim().length >= 8) clauses.push(current.trim());
164
- current = "";
165
- continue;
166
- }
167
- current += character;
168
- }
169
- if (current.trim()) clauses.push(current.trim());
170
- return clauses;
171
- }
172
-
173
- function splitAcceptanceCriterion(value: string): string[] {
246
+ function splitAcceptanceCriterion(value: string, grouped = false): string[] {
174
247
  const normalized = value.replace(/^\s*(?:[-*+] |\d+[.)]\s+)/, "").replace(/\s+/g, " ").trim();
175
- if (!normalized || normalized.length < 8) return [];
176
- const label = normalized.match(/^(\[[^\]\n]{1,40}\])\s+/)?.[1] ?? "";
248
+ if (!normalized) return [];
249
+ const label = grouped ? "" : normalized.match(/^(\[[^\]\n]{1,40}\])\s+/)?.[1] ?? "";
177
250
  const body = label ? normalized.slice(label.length).trim() : normalized;
178
251
  const prefix = label ? `${label} ` : "";
179
252
  const available = AUTO_ACCEPTANCE_CRITERION_CHARS - prefix.length;
180
253
  const fragments: string[] = [];
181
- const units = topLevelImperativeClauses(body)
254
+ const units = acceptanceContractConjuncts(body, { preserveSeparators: true })
182
255
  .flatMap((clause) => clause.split(/(?<=[.!?])\s+(?=(?:[`"'([{]|[\p{Lu}\p{N}]|(?:do|must|never|verify)\b))/u))
183
- .filter((item) => item.trim().length >= 8);
256
+ .filter((item) => item.trim());
184
257
  for (const unit of units) {
185
- let remaining = unit.trim();
186
- while (remaining.length > available) {
187
- const window = remaining.slice(0, available + 1);
188
- const sentence = [...window.matchAll(/[.!?;:]\s+/g)].at(-1);
189
- const clause = [...window.matchAll(/,\s+/g)].at(-1);
190
- const whitespace = window.lastIndexOf(" ");
191
- const preferred = sentence && sentence.index! + sentence[0].trimEnd().length >= Math.floor(available / 3)
192
- ? sentence.index! + sentence[0].trimEnd().length
193
- : clause && clause.index! + 1 >= Math.floor(available / 2)
194
- ? clause.index! + 1
195
- : whitespace;
196
- const cut = preferred > 0 ? preferred : available;
197
- fragments.push(`${prefix}${remaining.slice(0, cut).trim()}`);
198
- remaining = remaining.slice(cut).trim();
199
- }
258
+ const remaining = unit.trim();
259
+ if (remaining.length > available) throw acceptanceCriteriaOverflow();
200
260
  if (remaining) fragments.push(`${prefix}${remaining}`);
201
261
  }
202
262
  return fragments;
@@ -210,116 +270,105 @@ function isPathOnlyCriterion(value: string): boolean {
210
270
  return /^(?:[A-Za-z0-9_@.-]+\/)+[A-Za-z0-9_@.-]+$/.test(normalized);
211
271
  }
212
272
 
213
- function evenlySpacedCriteria(values: string[], limit: number): string[] {
214
- if (limit <= 0) return [];
215
- if (values.length <= limit) return values;
216
- if (limit === 1) return [values[values.length - 1]];
217
- return Array.from({ length: limit }, (_entry, index) => (
218
- values[Math.round((index * (values.length - 1)) / (limit - 1))]
219
- ));
273
+ function acceptanceCriteriaOverflow(): RangeError {
274
+ return new RangeError(`Automatic intake cannot retain every requirement within ${AUTO_ACCEPTANCE_CRITERIA_MAX} criteria of ${AUTO_ACCEPTANCE_CRITERION_CHARS} characters. No task was created by this intake. Use explicit bounded tasks without omitting requirements.`);
220
275
  }
221
276
 
222
- function boundedAcceptanceCriteria(values: string[], limit: number): string[] {
223
- if (limit <= 0 || values.length === 0) return [];
224
- if (values.length <= limit) return values;
225
- const highSignal = /\b(?:do not|fail(?:s|ed)?(?:[-\s]+)closed|invalid|missing|must|never|reject(?:s|ed|ion)?|throws?|typeerror|without mutat(?:e|ing)|unchanged)\b/i;
226
- const required = values.filter((criterion) => highSignal.test(criterion));
227
- const selectedRequired = evenlySpacedCriteria(required, Math.min(limit, required.length));
228
- const selected = new Set(selectedRequired);
229
- const remaining = values.filter((criterion) => !selected.has(criterion));
230
- for (const criterion of evenlySpacedCriteria(remaining, limit - selected.size)) selected.add(criterion);
231
- return values.filter((criterion) => selected.has(criterion));
277
+ function groupedAcceptanceCriteria(values: string[], limit: number): string[] {
278
+ // Repack the source text, not a ranked sample of its obligations. Keep generic
279
+ // verification/safety criteria separate so they cannot stand in for user clauses.
280
+ // Preserve clause boundaries as line breaks: receipts require independent
281
+ // evidence for the whole multiline criterion, including unpunctuated bullets.
282
+ const groups: string[] = [];
283
+ let current = "";
284
+ for (const value of values) {
285
+ if (current && current.length + 1 + value.length > AUTO_ACCEPTANCE_CRITERION_CHARS) {
286
+ groups.push(current);
287
+ current = "";
288
+ }
289
+ current = current ? `${current}\n${value}` : value;
290
+ }
291
+ if (current) groups.push(current);
292
+ if (groups.length > limit) throw acceptanceCriteriaOverflow();
293
+ return groups;
232
294
  }
233
295
 
234
- type AtomicCriterionGroup = { criteria: string[]; index: number };
235
-
236
- function atomicCriterionScore(value: string): number {
237
- const weighted = [
238
- [/(?:\bdo not\b|\bdoes not\b|\bcannot\b|\bnever\b|\binvalid\b|\breject|\bthrow|\bfail(?:s|ed)?[- ]closed\b)/i, 8],
239
- [/(?:\bidentical\b|\breplay|\bcanonical|\bidempoten)/i, 6],
240
- [/(?:\bstale\b|changed owner|inclusive boundary)/i, 5],
241
- [/\bexact(?:ly)?\b/i, 4],
242
- [/(?:\bnon-finite\b|\bnon-json\b|\bmutat|\bdigest\b|\breturn|\boutput\b)/i, 3]
243
- ] as const;
244
- return weighted.reduce((score, [pattern, weight]) => score + (pattern.test(value) ? weight : 0), 0);
296
+ function isStandaloneOpaqueMetadata(line: string, current: string): boolean {
297
+ // Preserve JSON, code, Markdown separators and punctuated exact tokens. A
298
+ // lone identifier-like token after a closed sentence is metadata/padding,
299
+ // not a criterion; the lossless operatorRequest remains the authority for it.
300
+ return /^[A-Za-z0-9_]+$/.test(line) && !/[.!?;:]$/.test(line)
301
+ && (!current || /[.!?;:]$/.test(current));
245
302
  }
246
303
 
247
- function atomicCoverageCriteria(groups: AtomicCriterionGroup[], limit: number): string[] {
248
- const candidates = groups.flatMap((group) => group.criteria.map((criterion, clause) => ({ criterion, group: group.index, clause })));
249
- if (candidates.length <= limit) return uniqueStrings(candidates.map((item) => item.criterion));
250
- const representatives = groups.filter((group) => group.criteria.length > 0).map((group) => group.criteria.at(-1)!);
251
- const selected = new Set(boundedAcceptanceCriteria(representatives, Math.min(limit, representatives.length)));
252
- const ranked = candidates.filter((item) => !selected.has(item.criterion)).sort((left, right) => (
253
- atomicCriterionScore(right.criterion) - atomicCriterionScore(left.criterion)
254
- || left.group - right.group
255
- || left.clause - right.clause
256
- ));
257
- for (const item of ranked) {
258
- if (selected.size < limit) { selected.add(item.criterion); continue; }
259
- if (groups.length <= limit || atomicCriterionScore(item.criterion) === 0) continue;
260
- const sameGroupAlreadyCovered = candidates.some((candidate) => candidate.group === item.group && selected.has(candidate.criterion));
261
- if (!sameGroupAlreadyCovered) continue;
262
- const removable = candidates
263
- .filter((candidate) => selected.has(candidate.criterion) && candidate.group !== item.group)
264
- .sort((left, right) => (
265
- Number(/^\[/.test(left.criterion)) - Number(/^\[/.test(right.criterion))
266
- || atomicCriterionScore(left.criterion) - atomicCriterionScore(right.criterion)
267
- || right.group - left.group
268
- ))
269
- .find((candidate) => atomicCriterionScore(candidate.criterion) < atomicCriterionScore(item.criterion));
270
- if (removable) { selected.delete(removable.criterion); selected.add(item.criterion); }
271
- }
272
- return uniqueStrings(candidates.filter((item) => selected.has(item.criterion)).map((item) => item.criterion)).slice(0, limit);
304
+ function isStandaloneAcceptanceLabel(value: string): boolean {
305
+ const normalized = value.trim();
306
+ return /^(?:acceptance criteria|behavior|contract|constraints|expected behavior|expected output|requirements|rules|validation):$/i.test(normalized);
273
307
  }
274
308
 
275
- export function automaticAcceptanceCriteria(prompt: string, changeMode: "source-change" | "read-only" = "source-change"): string[] {
309
+ export function automaticAcceptanceCriteria(
310
+ prompt: string,
311
+ changeMode: "source-change" | "read-only" = "source-change",
312
+ mutationPolicy: "required" | "allowed" | "forbidden" = changeMode === "read-only" ? "forbidden" : "required"
313
+ ): string[] {
276
314
  const lines = String(prompt ?? "").split(/\r?\n/);
277
- const criterionGroups: AtomicCriterionGroup[] = [];
278
- const obligation = /\b(?:accept|add|build|change|change only|correct|create|do not|emits?|ensure|exactly|fail(?:s|ed)?(?:[-\s]+)closed|fix|handle|implement|invalid|missing|modify|must|never|parse|preserve|reject|repair|returns?|support|throw|treat|update|without)\b/i;
315
+ const criterionGroups: Array<{ source: string; criteria: string[] }> = [];
279
316
  let current = "";
280
- let currentIsBullet = false;
281
317
  const push = (value: string) => {
282
318
  if (isPathOnlyCriterion(value)) return;
283
- criterionGroups.push({ criteria: splitAcceptanceCriterion(value), index: criterionGroups.length });
319
+ const source = value.replace(/^\s*(?:[-*+] |\d+[.)]\s+)/, "").replace(/\s+/g, " ").trim();
320
+ criterionGroups.push({ source, criteria: splitAcceptanceCriterion(source) });
284
321
  };
285
322
  const flush = () => {
286
- if (current && (currentIsBullet || obligation.test(current))) push(current);
323
+ if (current) push(current);
287
324
  current = "";
288
- currentIsBullet = false;
289
325
  };
290
- for (const line of lines) {
326
+ const listItem = /^(?:[-*+] |\d+[.)]\s+)/;
327
+ for (const [index, line] of lines.entries()) {
291
328
  const trimmed = line.trim();
292
- if (/^(?:[-*+] |\d+[.)]\s+)/.test(trimmed)) {
329
+ if (listItem.test(trimmed)) {
330
+ if (isStandaloneAcceptanceLabel(current)) {
331
+ current = `${current} ${trimmed.replace(listItem, "")}`;
332
+ continue;
333
+ }
293
334
  flush();
294
335
  current = trimmed;
295
- currentIsBullet = true;
296
336
  continue;
297
337
  }
298
338
  if (!trimmed) {
339
+ const next = lines.slice(index + 1).find((candidate) => candidate.trim())?.trim() ?? "";
340
+ if (isStandaloneAcceptanceLabel(current) && listItem.test(next)) continue;
299
341
  flush();
300
342
  continue;
301
343
  }
344
+ if (isStandaloneOpaqueMetadata(trimmed, current)) continue;
302
345
  current = current ? `${current} ${trimmed}` : trimmed;
303
346
  }
304
347
  flush();
305
- const generic = changeMode === "read-only"
348
+ const generic = changeMode === "read-only" || mutationPolicy === "forbidden"
306
349
  ? ["No project files are changed.", "The final response addresses the requested diagnostic result."]
307
- : ["The configured verification command passes after the final mutation."];
308
- const groupCount = criterionGroups.filter((group) => group.criteria.length > 0).length;
309
- const reservedGeneric = Math.min(generic.length, Math.max(0, AUTO_ACCEPTANCE_CRITERIA_MAX - groupCount));
310
- const uniqueCriteria = atomicCoverageCriteria(criterionGroups, AUTO_ACCEPTANCE_CRITERIA_MAX - reservedGeneric);
311
- const selected = boundedAcceptanceCriteria(uniqueCriteria, AUTO_ACCEPTANCE_CRITERIA_MAX);
312
- if (selected.length === AUTO_ACCEPTANCE_CRITERIA_MAX) return selected;
313
- const missingGeneric = generic.filter((criterion) => !selected.includes(criterion));
314
- return [...selected, ...missingGeneric].slice(0, AUTO_ACCEPTANCE_CRITERIA_MAX);
350
+ : mutationPolicy === "allowed"
351
+ ? ["Every configured verification command passes against the final working tree."]
352
+ : ["The configured verification command passes after the final mutation."];
353
+ const limit = AUTO_ACCEPTANCE_CRITERIA_MAX - generic.length;
354
+ const atomic = criterionGroups.flatMap((group) => group.criteria);
355
+ const selected = atomic.length <= limit
356
+ ? atomic
357
+ : groupedAcceptanceCriteria(criterionGroups.flatMap((group) => splitAcceptanceCriterion(group.source, true)), AUTO_ACCEPTANCE_CRITERIA_MAX);
358
+ if (new Set(selected).size !== selected.length) throw acceptanceCriteriaOverflow();
359
+ const available = AUTO_ACCEPTANCE_CRITERIA_MAX - selected.length;
360
+ return [...selected, ...generic.filter((criterion) => !selected.includes(criterion)).slice(0, available)];
315
361
  }
316
362
 
317
363
  export function manualTaskIntakeEligible(prompt: string, readProtectedPaths: string[]): boolean {
318
364
  const text = String(prompt ?? "").trim();
319
365
  if (!text || text.length > LONG_INPUT_CHARS) return false;
366
+ const folded = foldChangeIntent(text);
367
+ const explicitChange = isExplicitChangeRequest(folded);
368
+ if (isNonAuthorizingChangeClarification(text)) return false;
320
369
  const signal = classifyContextTask(text);
321
- if (signal.workflow !== "task" || !AUTO_INTAKE_CHANGE_INTENT.test(text)) return false;
322
- if (AUTO_INTAKE_READ_ONLY_LEAD.test(text) || /\bpiagent_task_start\b/i.test(text)) return false;
370
+ if (signal.workflow !== "task" || (!hasChangeIntent(folded) && !explicitChange)) return false;
371
+ if ((AUTO_INTAKE_READ_ONLY_LEAD.test(folded) && !explicitChange) || /\bpiagent_task_start\b/i.test(text)) return false;
323
372
  if (signal.paths.length === 0) return true;
324
373
  return signal.paths.some((candidate) => !matchesProtectedPath(candidate, readProtectedPaths));
325
374
  }
@@ -364,97 +413,27 @@ function inferredProjectScope(prompt: string, projectFiles: string[]): string[]
364
413
  .map((item) => item.path);
365
414
  }
366
415
 
367
- export type TaskScopeResolution = {
368
- scope: string[];
369
- mappings: Array<{ from: string; to: string }>;
370
- ambiguous: Array<{ input: string; candidates: string[] }>;
371
- unmatched: string[];
372
- };
373
-
374
- const STANDARD_SCOPE_ROOT = /^(?:\.github|app|apps|bin|config|docs|examples|lib|logs|packages|pages|plans|public|scripts|services|spec|src|test|tests|vendor|__tests__)(?:\/|$)/i;
375
-
376
- function wildcardPrefix(value: string): string {
377
- const index = value.search(/[*?{}\[\]]/);
378
- return (index < 0 ? value : value.slice(0, index)).replace(/\/+$/, "");
379
- }
380
-
381
- function nestedDirectoryMatches(prefix: string, projectFiles: string[]): string[] {
382
- if (!prefix) return [];
383
- const segments = prefix.split("/").filter(Boolean);
384
- const matches = new Set<string>();
385
- for (const file of projectFiles) {
386
- const parts = normalizePathCandidate(file).split("/");
387
- for (let index = 0; index <= parts.length - 1 - segments.length; index += 1) {
388
- if (segments.every((segment, offset) => parts[index + offset] === segment)) {
389
- matches.add(parts.slice(0, index + segments.length).join("/"));
390
- }
391
- }
392
- }
393
- return [...matches].sort();
394
- }
395
-
396
- export function resolveTaskScopePatterns(scope: string[], projectFiles: string[]): TaskScopeResolution {
397
- const files = uniqueStrings(projectFiles.map(normalizePathCandidate).filter(Boolean));
398
- const resolved: string[] = [];
399
- const mappings: Array<{ from: string; to: string }> = [];
400
- const ambiguous: Array<{ input: string; candidates: string[] }> = [];
401
- const unmatched: string[] = [];
402
- for (const raw of scope) {
403
- const candidate = normalizePathCandidate(raw);
404
- if (!candidate) continue;
405
- if (files.includes(candidate) || files.some((file) => matchesAnyPath(file, [candidate]))) {
406
- resolved.push(candidate);
407
- continue;
408
- }
409
- const hasWildcard = /[*?{}\[\]]/.test(candidate);
410
- if (hasWildcard) {
411
- const prefix = wildcardPrefix(candidate);
412
- const directories = nestedDirectoryMatches(prefix, files);
413
- if (directories.length === 1) {
414
- const suffix = candidate.slice(prefix.length).replace(/^\/+/, "");
415
- const canonical = suffix ? `${directories[0]}/${suffix}` : directories[0];
416
- resolved.push(canonical);
417
- mappings.push({ from: candidate, to: canonical });
418
- } else if (directories.length > 1 && prefix && !STANDARD_SCOPE_ROOT.test(prefix)) {
419
- ambiguous.push({ input: candidate, candidates: directories.slice(0, 12).map((directory) => {
420
- const suffix = candidate.slice(prefix.length).replace(/^\/+/, "");
421
- return suffix ? `${directory}/${suffix}` : directory;
422
- }) });
423
- } else if (directories.length === 0 && prefix && !prefix.includes("/") && !STANDARD_SCOPE_ROOT.test(prefix) && !raw.startsWith("./")) {
424
- unmatched.push(candidate);
425
- } else {
426
- resolved.push(candidate);
427
- }
428
- continue;
429
- }
430
- const suffixMatches = files.filter((file) => file === candidate || file.endsWith(`/${candidate}`));
431
- if (suffixMatches.length === 1) {
432
- resolved.push(suffixMatches[0]);
433
- mappings.push({ from: candidate, to: suffixMatches[0] });
434
- } else if (suffixMatches.length > 1) {
435
- ambiguous.push({ input: candidate, candidates: suffixMatches.slice(0, 12) });
436
- } else if (!candidate.includes("/") && !raw.startsWith("./")) {
437
- unmatched.push(candidate);
438
- } else {
439
- resolved.push(candidate);
440
- }
441
- }
442
- return { scope: uniqueStrings(resolved), mappings, ambiguous, unmatched: uniqueStrings(unmatched) };
443
- }
444
-
445
- export function automaticTaskScope(prompt: string, context: Array<{ path: string }>, projectFiles: string[] = []): string[] {
416
+ export function automaticTaskScope(
417
+ prompt: string,
418
+ context: Array<{ path: string }>,
419
+ projectFiles: string[] = [],
420
+ priorTask?: PriorTaskScopeEvidence
421
+ ): string[] {
446
422
  const signal = classifyContextTask(prompt);
447
423
  const explicit = signal.paths.filter(plausibleTaskScopePath);
448
- const navigated = context
449
- .map((item) => normalizePathCandidate(item.path))
450
- .filter((candidate): candidate is string => Boolean(
451
- candidate
452
- && candidate !== "."
453
- && !candidate.startsWith(".pi/")
454
- && !["AGENTS.md", "README.md", "REVIEW_GUIDELINES.md"].includes(candidate)
455
- && /^(?:app|apps|lib|packages|services|spec|src|test|tests|__tests__)\//.test(candidate)
456
- ))
457
- .slice(0, 8);
424
+ const completedTaskScope = completedFollowupScope(prompt, priorTask, plausibleTaskScopePath);
425
+ const navigated = completedTaskScope.length > 0
426
+ ? completedTaskScope
427
+ : context
428
+ .map((item) => normalizePathCandidate(item.path))
429
+ .filter((candidate): candidate is string => Boolean(
430
+ candidate
431
+ && candidate !== "."
432
+ && !candidate.startsWith(".pi/")
433
+ && !["AGENTS.md", "README.md", "REVIEW_GUIDELINES.md"].includes(candidate)
434
+ && /^(?:app|apps|lib|packages|services|spec|src|test|tests|__tests__)\//.test(candidate)
435
+ ))
436
+ .slice(0, 8);
458
437
  const inferred = explicit.length === 0 && navigated.length === 0
459
438
  ? inferredProjectScope(prompt, projectFiles)
460
439
  : [];