@piagent/platform 1.5.5 → 1.6.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 (323) hide show
  1. package/CHANGELOG.md +166 -0
  2. package/README.md +25 -21
  3. package/README.vi.md +34 -5
  4. package/adapters/web-frontend/profile.json +2 -4
  5. package/architecture/layers.json +18 -3
  6. package/benchmarks/deep-logic-v1/SPECIALIST_PROTOCOL.vi.md +122 -0
  7. package/benchmarks/deep-logic-v1/grade.mjs +272 -10
  8. package/benchmarks/deep-logic-v1/project/apps/admin/src/billing-summary.js +3 -0
  9. package/benchmarks/deep-logic-v1/project/benchmark-contract/public-smoke.test.js +166 -0
  10. package/benchmarks/deep-logic-v1/project/package.json +1 -1
  11. package/benchmarks/deep-logic-v1/project/packages/billing/src/close-period.js +3 -0
  12. package/benchmarks/deep-logic-v1/project/packages/billing/src/plan-timeline.js +3 -0
  13. package/benchmarks/deep-logic-v1/project/test/smoke.test.js +7 -1
  14. package/benchmarks/deep-logic-v1/prompts/budgeted-context-graph.md +2 -0
  15. package/benchmarks/deep-logic-v1/prompts/fair-dependency-scheduler.md +2 -0
  16. package/benchmarks/deep-logic-v1/prompts/layered-policy-resolution.md +2 -0
  17. package/benchmarks/deep-logic-v1/prompts/resumable-stream-assembly.md +3 -1
  18. package/benchmarks/deep-logic-v1/prompts/revision-event-reconciliation.md +2 -0
  19. package/benchmarks/deep-logic-v1/prompts/temporal-usage-billing-close.md +123 -0
  20. package/benchmarks/deep-logic-v1/prompts/transactional-config-merge.md +2 -0
  21. package/benchmarks/deep-logic-v1/suite.json +51 -3
  22. package/benchmarks/deep-logic-v1/variant.mjs +22 -1
  23. package/benchmarks/production-v1/spend-control.v1.json +92 -0
  24. package/benchmarks/production-v1/suite.json +46 -3
  25. package/catalog/capabilities.json +18 -18
  26. package/docs/authority-manifest.md +1 -1
  27. package/docs/auto-delegation-policy.md +38 -73
  28. package/docs/command-reference-vietnamese.md +27 -35
  29. package/docs/context-engine.md +12 -4
  30. package/docs/context-window-policy.md +37 -1
  31. package/docs/distribution-standard.md +7 -7
  32. package/docs/en/architecture.md +27 -13
  33. package/docs/languages.json +4 -4
  34. package/docs/model-options.md +8 -5
  35. package/docs/operator-manual-vietnamese.md +27 -45
  36. package/docs/project-adapters.md +2 -2
  37. package/docs/publishing-for-teams.md +10 -0
  38. package/docs/quality-benchmark.md +427 -62
  39. package/docs/release-install-policy.md +10 -9
  40. package/docs/runtime-harness-standard.md +3 -3
  41. package/docs/runtime-policy-design.md +4 -4
  42. package/docs/runtime-quality-baseline.md +13 -6
  43. package/docs/security-threat-model.md +2 -2
  44. package/docs/subagent-orchestration-capabilities.md +19 -51
  45. package/docs/subagents-and-multiagent.md +21 -47
  46. package/docs/task-implementation-contract.md +3 -3
  47. package/docs/task-lifecycle-vietnamese.md +3 -3
  48. package/docs/team-onboarding.md +2 -2
  49. package/docs/usage-observability.md +7 -2
  50. package/docs/vi/architecture.md +27 -13
  51. package/docs-site/architecture.html +1 -1
  52. package/docs-site/benchmark.html +89 -95
  53. package/docs-site/commands.html +1 -1
  54. package/docs-site/content/benchmark.html +88 -94
  55. package/docs-site/content/en/benchmark.html +134 -90
  56. package/docs-site/content/en/index.html +19 -19
  57. package/docs-site/content/en/runtime.html +4 -4
  58. package/docs-site/content/en/whats-new.html +12 -1
  59. package/docs-site/content/en/workflows.html +2 -2
  60. package/docs-site/content/index.html +19 -19
  61. package/docs-site/content/runtime.html +4 -4
  62. package/docs-site/content/whats-new.html +12 -1
  63. package/docs-site/content/workflows.html +2 -2
  64. package/docs-site/context-engine.html +1 -1
  65. package/docs-site/en/architecture.html +1 -1
  66. package/docs-site/en/benchmark.html +135 -91
  67. package/docs-site/en/commands.html +1 -1
  68. package/docs-site/en/context-engine.html +1 -1
  69. package/docs-site/en/index.html +20 -20
  70. package/docs-site/en/mcp-approval.html +1 -1
  71. package/docs-site/en/mcp-auth.html +1 -1
  72. package/docs-site/en/mcp-servers.html +1 -1
  73. package/docs-site/en/mcp.html +1 -1
  74. package/docs-site/en/permissions.html +1 -1
  75. package/docs-site/en/profiles.html +1 -1
  76. package/docs-site/en/quickstart.html +1 -1
  77. package/docs-site/en/runtime.html +5 -5
  78. package/docs-site/en/scope.html +1 -1
  79. package/docs-site/en/security.html +1 -1
  80. package/docs-site/en/team.html +1 -1
  81. package/docs-site/en/whats-new.html +13 -2
  82. package/docs-site/en/workflows.html +3 -3
  83. package/docs-site/index.html +20 -20
  84. package/docs-site/mcp-approval.html +1 -1
  85. package/docs-site/mcp-auth.html +1 -1
  86. package/docs-site/mcp-servers.html +1 -1
  87. package/docs-site/mcp.html +1 -1
  88. package/docs-site/permissions.html +1 -1
  89. package/docs-site/profiles.html +1 -1
  90. package/docs-site/quickstart.html +1 -1
  91. package/docs-site/runtime.html +5 -5
  92. package/docs-site/scope.html +1 -1
  93. package/docs-site/security.html +1 -1
  94. package/docs-site/team.html +1 -1
  95. package/docs-site/whats-new.html +13 -2
  96. package/docs-site/workflows.html +3 -3
  97. package/evals/fixtures/benchmark-assurance-evidence.invalid.json +1 -1
  98. package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
  99. package/evals/fixtures/codex-relative-efficiency-v1.invalid.json +4 -0
  100. package/evals/fixtures/codex-relative-efficiency-v1.valid.json +94 -0
  101. package/evals/fixtures/helper-request.invalid.json +1 -1
  102. package/evals/fixtures/helper-request.valid.json +1 -1
  103. package/evals/fixtures/piagent-webui/session-live-state-v1.invalid.json +18 -0
  104. package/evals/fixtures/piagent-webui/session-live-state-v1.valid.json +27 -0
  105. package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +7 -0
  106. package/evals/fixtures/task-authority-snapshot.valid.json +4 -4
  107. package/evals/fs4-readiness-matrix.v1.json +2 -2
  108. package/evals/fs5-causal-arm.v1.json +3 -3
  109. package/evals/fs5-pilot-protocol.v1.json +3 -3
  110. package/evals/fs5-pilot-protocol.v2.json +8 -8
  111. package/evals/fs5-pilot-protocol.v3.json +8 -8
  112. package/evals/fs5-pilot-protocol.v4.json +7 -6
  113. package/evals/fs5-pilot-protocol.v5.json +9 -7
  114. package/evals/private-holdout-v1/public-exposure.v1.json +1 -1
  115. package/evals/runtime-conformance-v1/README.md +43 -0
  116. package/evals/runtime-conformance-v1/evaluate-paid-canary.mjs +198 -0
  117. package/evals/runtime-conformance-v1/lane.json +57 -0
  118. package/evals/runtime-conformance-v1/paid-canary.json +31 -0
  119. package/evals/runtime-conformance-v1/runner.mjs +456 -0
  120. package/package.json +3 -1
  121. package/packages/piagent-core/README.md +13 -4
  122. package/packages/piagent-core/benchmark/benchmark-assurance.js +4 -1
  123. package/packages/piagent-core/benchmark/benchmark-bootstrap.js +91 -9
  124. package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +38 -7
  125. package/packages/piagent-core/benchmark/benchmark-cli.js +7 -7
  126. package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +698 -0
  127. package/packages/piagent-core/benchmark/benchmark-codex.js +3 -1
  128. package/packages/piagent-core/benchmark/benchmark-comparison.js +271 -2
  129. package/packages/piagent-core/benchmark/benchmark-core.js +736 -664
  130. package/packages/piagent-core/benchmark/benchmark-execution-guard.js +7 -5
  131. package/packages/piagent-core/benchmark/benchmark-forensics.js +441 -4
  132. package/packages/piagent-core/benchmark/benchmark-host-readiness.js +639 -0
  133. package/packages/piagent-core/benchmark/benchmark-matrix.js +22 -4
  134. package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +317 -0
  135. package/packages/piagent-core/benchmark/benchmark-preflight.js +5 -1
  136. package/packages/piagent-core/benchmark/benchmark-process.js +6 -5
  137. package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +345 -0
  138. package/packages/piagent-core/benchmark/benchmark-provider-wire.js +126 -0
  139. package/packages/piagent-core/benchmark/benchmark-record-validation.js +252 -0
  140. package/packages/piagent-core/benchmark/benchmark-report.js +130 -12
  141. package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +14 -0
  142. package/packages/piagent-core/benchmark/benchmark-runner-policy.js +26 -0
  143. package/packages/piagent-core/benchmark/benchmark-runtime-causal.js +244 -0
  144. package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +979 -0
  145. package/packages/piagent-core/benchmark/benchmark-statistics.js +64 -0
  146. package/packages/piagent-core/benchmark/benchmark-stop-policy.js +8 -5
  147. package/packages/piagent-core/benchmark/benchmark-suite-identity.js +31 -0
  148. package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +13 -9
  149. package/packages/piagent-core/benchmark/benchmark-suite.js +149 -2
  150. package/packages/piagent-core/benchmark/benchmark-summary-support.js +380 -0
  151. package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +971 -0
  152. package/packages/piagent-core/benchmark/benchmark-usage.js +322 -0
  153. package/packages/piagent-core/benchmark/benchmark-workflow.js +166 -0
  154. package/packages/piagent-core/capabilities/runtime-integrity.js +3 -0
  155. package/packages/piagent-core/docs/context-efficiency-improvement-plan.md +1080 -0
  156. package/packages/piagent-core/extensions/acceptance-behavior-proof.js +806 -0
  157. package/packages/piagent-core/extensions/acceptance-contract-semantics.js +83 -69
  158. package/packages/piagent-core/extensions/acceptance-error-classes.js +160 -0
  159. package/packages/piagent-core/extensions/acceptance-executable-evidence.js +12 -9
  160. package/packages/piagent-core/extensions/acceptance-receipt.js +123 -59
  161. package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +518 -0
  162. package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +60 -0
  163. package/packages/piagent-core/extensions/context-efficiency-metrics.js +302 -0
  164. package/packages/piagent-core/extensions/context-efficiency-report.js +167 -0
  165. package/packages/piagent-core/extensions/context-engine.js +149 -156
  166. package/packages/piagent-core/extensions/context-evidence.js +48 -0
  167. package/packages/piagent-core/extensions/context-import-links.js +296 -0
  168. package/packages/piagent-core/extensions/context-index-policy.js +4 -0
  169. package/packages/piagent-core/extensions/context-query-paths.js +57 -0
  170. package/packages/piagent-core/extensions/context-telemetry-integrity.js +65 -0
  171. package/packages/piagent-core/extensions/criterion-context-pack.js +435 -7
  172. package/packages/piagent-core/extensions/criterion-graph.js +82 -9
  173. package/packages/piagent-core/extensions/fallback-base-policy.ts +101 -0
  174. package/packages/piagent-core/extensions/guard-types.ts +6 -0
  175. package/packages/piagent-core/extensions/javascript-regex-evidence.js +32 -0
  176. package/packages/piagent-core/extensions/piagent-guard.ts +420 -260
  177. package/packages/piagent-core/extensions/task-contract-view.js +17 -3
  178. package/packages/piagent-core/extensions/task-lifecycle.js +39 -2
  179. package/packages/piagent-core/extensions/task-state.js +109 -142
  180. package/packages/piagent-core/extensions/verification-intelligence.js +52 -13
  181. package/packages/piagent-core/extensions/workspace-evidence-roots.js +193 -0
  182. package/packages/piagent-core/package.json +1 -1
  183. package/packages/piagent-core/policies/base-policy.json +44 -2
  184. package/packages/piagent-core/policy/authority-manifest.v1.json +3 -3
  185. package/packages/piagent-core/prompts/be-to-fe.md +2 -8
  186. package/packages/piagent-core/prompts/plan.md +1 -1
  187. package/packages/piagent-core/prompts/platform-improve.md +2 -6
  188. package/packages/piagent-core/prompts/review.md +2 -7
  189. package/packages/piagent-core/prompts/scout.md +1 -1
  190. package/packages/piagent-core/prompts/task.md +4 -3
  191. package/packages/piagent-core/runtime/context/context-delivery.ts +103 -0
  192. package/packages/piagent-core/runtime/context/context-delta-shadow.ts +53 -0
  193. package/packages/piagent-core/runtime/context/context-efficiency-format.ts +47 -0
  194. package/packages/piagent-core/runtime/context/context-evidence-qualification.ts +32 -0
  195. package/packages/piagent-core/runtime/context/prefix-telemetry.ts +47 -0
  196. package/packages/piagent-core/runtime/context/repository-memory-hints.ts +27 -0
  197. package/packages/piagent-core/runtime/hooks/agent-prompt-telemetry.ts +56 -0
  198. package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +162 -102
  199. package/packages/piagent-core/runtime/hooks/completion-hook.ts +12 -12
  200. package/packages/piagent-core/runtime/hooks/input-hook.ts +17 -1
  201. package/packages/piagent-core/runtime/hooks/session-hooks.ts +22 -2
  202. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +107 -3
  203. package/packages/piagent-core/runtime/hooks/tool-result-content-guards.ts +95 -0
  204. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +134 -166
  205. package/packages/piagent-core/runtime/hooks/tool-result-value-helpers.ts +66 -0
  206. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +4 -2
  207. package/packages/piagent-core/runtime/inspection/activity-recovery.ts +104 -0
  208. package/packages/piagent-core/runtime/inspection/bounded-emission-guard.ts +286 -0
  209. package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +37 -7
  210. package/packages/piagent-core/runtime/inspection/task-compaction-history.ts +1 -1
  211. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +1 -1
  212. package/packages/piagent-core/runtime/inspection/task-subagent-tree.ts +27 -4
  213. package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +70 -0
  214. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +73 -9
  215. package/packages/piagent-core/runtime/model/authenticated-catalog.ts +17 -9
  216. package/packages/piagent-core/runtime/model/openai-codex-reasoning.ts +83 -0
  217. package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +238 -0
  218. package/packages/piagent-core/runtime/orchestration/helper-lifecycle.ts +16 -12
  219. package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +71 -0
  220. package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +28 -20
  221. package/packages/piagent-core/runtime/orchestration/role-policy.ts +27 -9
  222. package/packages/piagent-core/runtime/orchestration/subagent-tool-policy.ts +329 -0
  223. package/packages/piagent-core/runtime/policy/block-remedy.ts +0 -4
  224. package/packages/piagent-core/runtime/product/activity-inspector.ts +7 -2
  225. package/packages/piagent-core/runtime/product/efficiency-metrics.ts +7 -2
  226. package/packages/piagent-core/runtime/quality/edit-freshness-guard.ts +102 -0
  227. package/packages/piagent-core/runtime/quality/exact-output-contract.ts +22 -11
  228. package/packages/piagent-core/runtime/quality/performance-assurance-signals.ts +23 -0
  229. package/packages/piagent-core/runtime/quality/performance-assurance.ts +9 -5
  230. package/packages/piagent-core/runtime/recovery/continuation-budget.ts +1 -1
  231. package/packages/piagent-core/runtime/recovery/edit-recovery-context.ts +113 -0
  232. package/packages/piagent-core/runtime/recovery/edit-recovery-delivery.ts +42 -0
  233. package/packages/piagent-core/runtime/recovery/handoff-projection.ts +4 -1
  234. package/packages/piagent-core/runtime/recovery/pristine-task-policy-refresh.ts +91 -0
  235. package/packages/piagent-core/runtime/recovery/recovery-policy.ts +7 -4
  236. package/packages/piagent-core/runtime/recovery/resume-state.ts +112 -14
  237. package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +60 -13
  238. package/packages/piagent-core/runtime/recovery/semantic-repair-runtime.ts +55 -2
  239. package/packages/piagent-core/runtime/recovery/task-evidence-coverage-refresh.ts +217 -0
  240. package/packages/piagent-core/runtime/registration/context-commands.ts +82 -7
  241. package/packages/piagent-core/runtime/registration/knowledge-tools.ts +9 -5
  242. package/packages/piagent-core/runtime/registration/operator-request-intake.ts +49 -0
  243. package/packages/piagent-core/runtime/registration/policy-tools.ts +50 -15
  244. package/packages/piagent-core/runtime/registration/session-commands.ts +1 -1
  245. package/packages/piagent-core/runtime/registration/task-completion-tools.ts +61 -25
  246. package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +21 -12
  247. package/packages/piagent-core/runtime/registration/task-start-guidance.ts +169 -0
  248. package/packages/piagent-core/runtime/registration/task-start-manifest.ts +54 -0
  249. package/packages/piagent-core/runtime/registration/task-start-retry-helpers.ts +37 -0
  250. package/packages/piagent-core/runtime/registration/task-start-tool.ts +108 -103
  251. package/packages/piagent-core/runtime/runtime-limits.ts +16 -2
  252. package/packages/piagent-core/runtime/session/adaptive-context-analysis.ts +461 -0
  253. package/packages/piagent-core/runtime/session/adaptive-context-governor.ts +464 -0
  254. package/packages/piagent-core/runtime/session/adaptive-context-ledger.ts +265 -0
  255. package/packages/piagent-core/runtime/session/message-signals.ts +7 -3
  256. package/packages/piagent-core/runtime/session/operator-request-carry.ts +44 -0
  257. package/packages/piagent-core/runtime/session/runtime-state.ts +161 -5
  258. package/packages/piagent-core/runtime/session/source-checkout-read-grants.ts +35 -0
  259. package/packages/piagent-core/runtime/session/system-prompt.ts +76 -14
  260. package/packages/piagent-core/runtime/session/task-contract-presentation.ts +39 -0
  261. package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +500 -0
  262. package/packages/piagent-core/runtime/tools/phase-tools.ts +8 -8
  263. package/packages/piagent-core/runtime/tools/tool-groups.ts +12 -2
  264. package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +2 -1
  265. package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +101 -0
  266. package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +164 -0
  267. package/packages/piagent-core/runtime/workflows/task-intake.ts +207 -38
  268. package/packages/piagent-core/security/sensitive-data.js +13 -218
  269. package/packages/piagent-core/security/sensitive-project-file.js +42 -0
  270. package/packages/piagent-core/security/sensitive-source-expression.js +330 -0
  271. package/packages/piagent-core/security/sensitive-source-formats.js +394 -0
  272. package/packages/piagent-core/security/sensitive-text.js +234 -0
  273. package/packages/piagent-core/subagents/piagent-oracle.md +5 -3
  274. package/packages/piagent-core/subagents/piagent-planner.md +6 -4
  275. package/packages/piagent-core/subagents/piagent-reviewer.md +5 -3
  276. package/packages/piagent-core/subagents/piagent-scout.md +4 -2
  277. package/packages/piagent-core/subagents/piagent-worker.md +7 -5
  278. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-rD9WJKxs.js → MarkdownMessage-B4XehTCU.js} +1 -1
  279. package/packages/piagent-webui/dist/client/assets/index-CgOEyRPG.js +176 -0
  280. package/packages/piagent-webui/dist/client/index.html +1 -1
  281. package/packages/piagent-webui/extension/piagent-webui.ts +3 -1
  282. package/packages/piagent-webui/extension/same-session-bridge.ts +1 -1
  283. package/packages/piagent-webui/extension/session-stream-adapter.ts +33 -10
  284. package/packages/piagent-webui/gateway/gateway-events.ts +109 -5
  285. package/packages/piagent-webui/gateway/gateway-service.ts +3 -0
  286. package/packages/piagent-webui/gateway/gateway-session-stream.ts +122 -20
  287. package/packages/piagent-webui/gateway/session-command-controller.ts +18 -3
  288. package/packages/piagent-webui/gateway/session-effective-options.ts +47 -0
  289. package/packages/piagent-webui/gateway/session-live-state.ts +21 -0
  290. package/packages/piagent-webui/gateway/session-operation-lifecycle.ts +237 -0
  291. package/packages/piagent-webui/gateway/session-operation-retry-control.ts +38 -0
  292. package/packages/piagent-webui/gateway/session-operation-start.ts +5 -1
  293. package/packages/piagent-webui/gateway/session-operation-watchdog.ts +165 -0
  294. package/packages/piagent-webui/gateway/session-runtime-factory.ts +45 -0
  295. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +141 -125
  296. package/packages/piagent-webui/ownership/session-lease-store.ts +5 -2
  297. package/packages/piagent-webui/server/core-inspection-provider.ts +2 -1
  298. package/packages/piagent-webui/server/loopback-server.ts +8 -0
  299. package/packages/piagent-webui/server/transcript-projection.ts +113 -9
  300. package/packages/piagent-webui/shared/text-visibility.ts +10 -0
  301. package/schemas/codex-relative-efficiency-v1.schema.json +155 -0
  302. package/schemas/piagent-webui/catalog-v1.json +9 -0
  303. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +53 -3
  304. package/schemas/piagent-webui/runtime-event-v2.schema.json +15 -5
  305. package/schemas/piagent-webui/session-live-state-v1.schema.json +76 -0
  306. package/schemas/piagent-webui/subagent-tree-v1.schema.json +11 -1
  307. package/schemas/project-profile.schema.json +1 -1
  308. package/schemas/task-contract.schema.json +27 -1
  309. package/scripts/benchmark-runner-core.mjs +367 -363
  310. package/scripts/benchmark-runner-finalization.mjs +313 -0
  311. package/scripts/benchmark-runner-host-readiness.mjs +94 -0
  312. package/scripts/benchmark-runner-support.mjs +200 -0
  313. package/scripts/benchmark-session.mjs +95 -41
  314. package/scripts/configure-model-scope.sh +4 -3
  315. package/scripts/configure-subagents.sh +42 -34
  316. package/scripts/helper-evaluation.mjs +2 -2
  317. package/scripts/install-global.sh +2 -2
  318. package/scripts/pi-usage-history.mjs +37 -10
  319. package/scripts/setup.sh +2 -2
  320. package/scripts/team-doctor.sh +1 -1
  321. package/scripts/verify-local.sh +10 -1
  322. package/templates/global/settings.json +2 -1
  323. package/packages/piagent-webui/dist/client/assets/index-BZRFw1u6.js +0 -174
@@ -1,46 +1,28 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { exactFinalOutputGuidance } from "../quality/exact-output-contract.ts";
3
- import { taskPerformanceAssurance } from "../quality/performance-assurance.ts";
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { exactFinalOutputGuidance } from "../quality/exact-output-contract.ts"; import { taskPerformanceAssurance } from "../quality/performance-assurance.ts";
4
2
  import { automaticTaskSummary, boundedRuntimeIntakeMessage } from "../workflows/task-intake.ts";
5
3
  import { WORKING_TREE_DIGEST_ALGORITHM } from "../../extensions/working-tree-digest.js";
4
+ import { TASK_ACCEPTANCE_CRITERIA_MAX, TASK_ACCEPTANCE_CRITERION_MAX_CHARS, TASK_EXPECTED_OUTPUT_MAX_CHARS, TASK_SUMMARY_MAX_CHARS, operatorRequestDigest } from "../../extensions/task-state.js";
6
5
  import { createEnvironmentBoundTaskAuthority } from "../policy/task-authority-runtime.ts";
7
6
  import { authorityReplacementState } from "../policy/authority-resume-policy.ts";
8
- import { compileCriterionGraph, criterionGraphContextSelection, criterionGraphGuidance, criterionGraphMode } from "../../extensions/criterion-graph.js";
7
+ import { compileCriterionGraph, criterionGraphContextSelection, criterionGraphContextSelectionDetails, criterionGraphGuidance, criterionGraphMode } from "../../extensions/criterion-graph.js";
9
8
  import { captureTaskStartBaseline } from "../inspection/task-baseline-start-capture.ts";
10
- type ExtensionContext = any;
11
- type TaskContract = any;
12
- type TaskStartParameters = any;
13
- function sameStringRecord(left: Record<string, string>, right: Record<string, string>): boolean {
14
- const leftEntries = Object.entries(left).sort(([a], [b]) => a.localeCompare(b));
15
- const rightEntries = Object.entries(right).sort(([a], [b]) => a.localeCompare(b));
16
- return leftEntries.length === rightEntries.length
17
- && leftEntries.every(([key, value], index) => rightEntries[index]?.[0] === key && rightEntries[index]?.[1] === value);
18
- }
19
- function satisfiesAuthorityReplacement(task: TaskContract, state: ReturnType<typeof authorityReplacementState>): boolean {
20
- if (!task.authoritySnapshot) return false;
21
- if (state.reason === "mechanical-rollback-requested") {
22
- return task.authoritySnapshot.profile === "mechanical-only";
23
- }
24
- if (state.reason === "capability-kill-switch-requested") {
25
- return state.killedCapabilities.length > 0 && state.killedCapabilities.every((capabilityId) => (
26
- task.authoritySnapshot.capabilities.some((entry: any) => entry.id === capabilityId && entry.authority === "off")
27
- ));
28
- }
29
- return true;
30
- }
9
+ import { sameStringRecord, satisfiesAuthorityReplacement } from "./task-start-retry-helpers.ts"; import { automaticTaskExecutionGuidance, EXACT_VERIFIER_EXECUTION_GUIDANCE, RUNTIME_SOURCE_REUSE_GUIDANCE, taskCriticalProofSection } from "./task-start-guidance.ts";
10
+ import { resolveTaskStartRepositoryManifestProvider } from "./task-start-manifest.ts"; import { boundedOperatorRequest, latestOperatorRequest } from "./operator-request-intake.ts";
11
+ type ExtensionContext = any; type TaskContract = any; type TaskStartParameters = Record<string, any> & { operatorRequest?: string }; function taskReferenceDetails(task: TaskContract, reasonCode: string): Record<string, unknown> { const scope = Array.isArray(task.scope) ? task.scope.slice(0, 50) : []; return { reasonCode, taskId: task.taskId, taskRunId: task.taskRunId, outcome: task.trace?.outcome, attempt: task.attempt, ...(reasonCode === "task-already-active" ? { scope, scopeTruncated: scope.length < task.scope.length } : {}) }; }
31
12
  export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any>): any {
32
13
  const {
33
14
  DEFAULT_MAX_TASK_ATTEMPTS, ORCHESTRATION_ROLES, REVIEW_LENSES, StringEnum, Type,
34
15
  activateToolGroups, activeSessionTask, activeTaskToolGroups, appendSessionTrace, appendTrace,
35
- applyRuntimeLifecycleObservation, automaticAcceptanceCriteria, automaticReadOnlyTaskScope, automaticReviewLenses, automaticTaskIntakeMode, automaticTaskRiskLane, automaticTaskScope,
36
- acceptanceBaselineGuidance, acceptanceProofGuidance, bindSessionTask, buildAcceptanceReceipt, compactTaskDetails, contextBudgetConfig, createTaskRunId,
16
+ applyRuntimeLifecycleObservation, automaticAcceptanceCriteria, automaticReadOnlyTaskScope, automaticReviewLenses, automaticTaskIntakeMode, automaticTaskMutationPolicy, automaticTaskRiskLane, automaticTaskScope,
17
+ acceptanceBaselineGuidance, acceptanceLanguageAdapterForPath, acceptanceProofGuidance, bindSessionTask, buildAcceptanceReceipt, compactTaskDetails, contextBudgetConfig, createTaskRunId,
37
18
  currentSessionName, defaultWorkPlan, effectiveProtectedPaths, hasGitEvidenceRoot, hasOperatorSessionName,
38
- loadProfileFromContext, matchesProtectedPath, normalizeReviewLenses, normalizeWorkPlanSteps, nowIso, policy,
19
+ isAcceptanceTestPath, loadProfileFromContext, matchesProtectedPath, normalizeReviewLenses, normalizeWorkPlanSteps, nowIso, policy,
39
20
  priorTaskAttempts, recordTaskStartCheckpoint, redactText, redactTextArray, registerRuntimeTool,
40
21
  repositoryFileManifest, resolveOrchestrationPolicy, resolveTaskScopePatterns, runtimeLifecycleMode, runtimeState, safeTaskId, selectVerificationPlan,
41
- summarizeAttempt, validTaskScopePattern, validateNewWorkPlan, verifierCommandInstructions, workingTreeEvidenceDigest, workingTreeSnapshot, workingTreeSnapshotHasUnavailableEvidence,
22
+ summarizeAttempt, telemetry, validTaskScopePattern, validateNewWorkPlan, verifierCommandInstructions, workingTreeEvidenceDigest, workingTreeSnapshot, workingTreeSnapshotHasUnavailableEvidence,
42
23
  writeTask
43
24
  } = deps;
25
+ const repositoryManifestProvider = resolveTaskStartRepositoryManifestProvider(deps);
44
26
  const taskStartTool = {
45
27
  name: "piagent_task_start",
46
28
  label: "Piagent Task Start",
@@ -48,27 +30,28 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
48
30
  promptSnippet: "Start a governed project task and persist the task contract.",
49
31
  promptGuidelines: [
50
32
  "Call this exactly once before source edits in a project managed by Pi Agent Platform.",
51
- "Use source-change for project command execution, including tests, builds, lint, typecheck, verification, and package dry-runs, even when the operator requires source files to remain unchanged. Read-only intentionally blocks shell execution.",
33
+ "Use source-change for project verifier execution or edits. For an assessment, report, or plan with no source changes, set mutationPolicy=forbidden; use read-only when no project verifier needs to execute.",
52
34
  "Do not call context, status, policy, evidence-recording, trace, or gate tools first; runtime hooks provide those checks automatically.",
53
35
  "Use tiny for a bounded low-risk change, normal for ordinary multi-file work, and high-risk for security, data, release, migration, or external-impact work.",
54
- "Every scope entry must be a project-relative path or glob such as src/file.ts, src/**, or test/**; never put prose in scope.",
36
+ "Every scope entry is an initial retrieval/review focus and must be a project-relative path or glob such as src/file.ts, src/**, or test/**; it is not a source-mutation boundary.",
55
37
  "Leave workPlan unset for ordinary tiny/normal tasks so runtime automation stays active; pass a custom workPlan only when the operator explicitly requests custom subagent or checkpoint orchestration.",
56
38
  "Tiny tasks use automatic lifecycle evidence; normal tasks retain one explicit review step; high-risk/custom plans keep manual checkpoints."
57
39
  ],
58
40
  parameters: Type.Object({
59
41
  taskId: Type.Optional(Type.String({ minLength: 1 })),
60
- summary: Type.String({ minLength: 10 }),
42
+ summary: Type.String({ minLength: 10, maxLength: TASK_SUMMARY_MAX_CHARS }),
61
43
  riskLane: StringEnum(["tiny", "normal", "high-risk"] as const),
62
44
  changeMode: Type.Optional(StringEnum(["source-change", "read-only"] as const, {
63
- description: "Use source-change for project command execution as well as edits; use read-only only for inspection that needs no shell execution."
45
+ description: "Use source-change for project verifier execution or edits; use read-only for bounded inspection."
64
46
  })),
47
+ mutationPolicy: Type.Optional(StringEnum(["required", "forbidden"] as const, { description: "Required demands a final diff; forbidden allows exact verification, rejects source mutation, and requires a zero task delta." })),
65
48
  maxAttempts: Type.Optional(Type.Number({ minimum: 1, maximum: 10 })),
66
- expectedOutput: Type.String({ minLength: 10 }),
67
- acceptanceCriteria: Type.Array(Type.String({ minLength: 1 }), { minItems: 1, maxItems: 12 }),
49
+ expectedOutput: Type.String({ minLength: 10, maxLength: TASK_EXPECTED_OUTPUT_MAX_CHARS }),
50
+ acceptanceCriteria: Type.Array(Type.String({ minLength: 1, maxLength: TASK_ACCEPTANCE_CRITERION_MAX_CHARS }), { minItems: 1, maxItems: TASK_ACCEPTANCE_CRITERIA_MAX }),
68
51
  scope: Type.Array(Type.String({
69
52
  minLength: 1,
70
- description: "Project-relative path or glob only (for example src/file.ts, src/**, or test/**); do not use prose."
71
- }), { minItems: 1 }),
53
+ description: "Advisory retrieval/review focus as a project-relative path or glob (for example src/file.ts, src/**, or test/**); source changes may follow repository evidence beyond it."
54
+ }), { minItems: 1, maxItems: 2000 }),
72
55
  outOfScope: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),
73
56
  reviewLenses: Type.Optional(Type.Array(StringEnum(REVIEW_LENSES))),
74
57
  workPlan: Type.Optional(Type.Array(Type.Object({
@@ -88,13 +71,20 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
88
71
  _onUpdate: ((update: unknown) => void) | undefined,
89
72
  ctx: ExtensionContext
90
73
  ) {
91
- const profile = loadProfileFromContext(ctx);
92
- const createdAt = nowIso();
93
- const safeSummary = redactText(params.summary);
74
+ const profile = loadProfileFromContext(ctx), createdAt = nowIso();
75
+ const operatorRequest = typeof params.operatorRequest === "string"
76
+ ? params.operatorRequest
77
+ : latestOperatorRequest(ctx);
78
+ const safeSummary = redactText(params.summary), safeOperatorRequest = boundedOperatorRequest(operatorRequest, redactText);
94
79
  const taskId = safeTaskId(redactText(params.taskId ?? params.summary));
95
- const sessionId = ctx.sessionManager.getSessionId();
96
- const sessionName = currentSessionName(ctx);
80
+ const sessionId = ctx.sessionManager.getSessionId(), sessionName = currentSessionName(ctx);
97
81
  const active = activeSessionTask(ctx.cwd, sessionId) as TaskContract | undefined;
82
+ if (active && active.trace.outcome !== "pending" && runtimeState.taskIdentity(ctx)?.taskRunId === active.taskRunId) {
83
+ runtimeState.clearTaskBoundary(ctx, active.taskRunId);
84
+ } else if (!active) {
85
+ const cachedTask = runtimeState.taskIdentity(ctx);
86
+ if (cachedTask) runtimeState.clearTaskBoundary(ctx, cachedTask.taskRunId);
87
+ }
98
88
  const activeAuthorityReplacement = active ? authorityReplacementState(ctx.cwd, active) : undefined;
99
89
  if (activeAuthorityReplacement && !activeAuthorityReplacement.enforcementSafe) {
100
90
  return {
@@ -143,12 +133,12 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
143
133
  }
144
134
  return {
145
135
  content: [{ type: "text", text: `Task already active in this session: ${active.taskId} (${active.taskRunId}). Reusing it instead of overwriting state.` }],
146
- details: compactTaskDetails(active)
136
+ details: taskReferenceDetails(active, "task-already-active")
147
137
  };
148
138
  }
149
139
  return {
150
140
  content: [{ type: "text", text: `Session already has pending task ${active.taskId} (${active.taskRunId}). Complete or stop it before starting another task in this conversation.` }],
151
- details: active,
141
+ details: taskReferenceDetails(active, "session-task-already-pending"),
152
142
  isError: true
153
143
  };
154
144
  }
@@ -163,24 +153,15 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
163
153
  };
164
154
  }
165
155
  const scopeResolution = resolveTaskScopePatterns(params.scope, repositoryFileManifest(ctx.cwd));
166
- if (scopeResolution.ambiguous.length > 0) {
167
- const details = scopeResolution.ambiguous
168
- .map((item) => `${item.input}: ${item.candidates.join(", ")}`)
169
- .join("; ");
170
- return {
171
- content: [{ type: "text", text: `Task start refused: scope is ambiguous (${details}). Use one exact project-relative candidate for each ambiguous entry.` }],
172
- details: scopeResolution,
173
- isError: true
174
- };
175
- }
176
- if (scopeResolution.unmatched.length > 0) {
177
- return {
178
- content: [{ type: "text", text: `Task start refused: scope entries do not identify an existing repository path (${scopeResolution.unmatched.join(", ")}). Use an exact project-relative path for a new file, such as src/name.ts, instead of a basename or guessed top-level alias.` }],
179
- details: scopeResolution,
180
- isError: true
181
- };
182
- }
183
- const resolvedScope = scopeResolution.scope;
156
+ // Scope guides context selection and review; it is not filesystem
157
+ // authority. Keep unresolved focus entries instead of preventing work in
158
+ // a parent workspace where several child repositories share names such
159
+ // as src/, app/, tests/, or package.json.
160
+ const unresolvedFocus = [
161
+ ...scopeResolution.ambiguous.map((item) => item.input),
162
+ ...scopeResolution.unmatched
163
+ ];
164
+ const resolvedScope = [...new Set([...scopeResolution.scope, ...unresolvedFocus])];
184
165
  const priorAttempts = priorTaskAttempts(ctx.cwd, taskId) as TaskContract[];
185
166
  const authorityStates = new Map(priorAttempts.map((task) => [task.taskRunId, authorityReplacementState(ctx.cwd, task)]));
186
167
  const unsafeAuthorityState = [...authorityStates.entries()].find(([, state]) => !state.enforcementSafe);
@@ -197,7 +178,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
197
178
  if (pendingElsewhere) {
198
179
  return {
199
180
  content: [{ type: "text", text: `Task ${taskId} is already active in session ${pendingElsewhere.sessionName ?? pendingElsewhere.sessionId} (${pendingElsewhere.taskRunId}).` }],
200
- details: pendingElsewhere,
181
+ details: taskReferenceDetails(pendingElsewhere, "task-active-in-another-session"),
201
182
  isError: true
202
183
  };
203
184
  }
@@ -205,7 +186,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
205
186
  if (latestCompleted) {
206
187
  return {
207
188
  content: [{ type: "text", text: `Task ${taskId} already completed as ${latestCompleted.taskRunId}. Use a distinct taskId for new work instead of replacing its evidence.` }],
208
- details: latestCompleted,
189
+ details: taskReferenceDetails(latestCompleted, "task-already-completed"),
209
190
  isError: true
210
191
  };
211
192
  }
@@ -246,6 +227,8 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
246
227
  }
247
228
  const orchestration = resolveOrchestrationPolicy(profile, policy);
248
229
  const changeMode = params.changeMode === "read-only" ? "read-only" : "source-change";
230
+ const mutationPolicy = changeMode === "read-only" || params.mutationPolicy === "forbidden" ? "forbidden" : "required";
231
+ if (changeMode === "read-only" && params.mutationPolicy === "required") return { content: [{ type: "text", text: "Task start refused: read-only tasks cannot require source mutation." }], isError: true };
249
232
  if (changeMode === "source-change" && !hasGitEvidenceRoot(ctx.cwd)) {
250
233
  return {
251
234
  content: [{ type: "text", text: "Task start refused: source-change tasks require a Git working tree, or a workspace parent with direct child Git repositories, so changed-file evidence cannot silently disappear. Initialize Git, open the parent that contains the repos, or use read-only mode." }],
@@ -263,14 +246,14 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
263
246
  const reviewLenses = normalizeReviewLenses(params.reviewLenses, orchestration.defaultReviewLenses);
264
247
  const providedWorkPlan = normalizeWorkPlanSteps(params.workPlan);
265
248
  const defaultPlanLane = params.intakeMode === "runtime" && params.riskLane === "normal" ? "tiny" : params.riskLane;
266
- const workPlan = providedWorkPlan.length ? providedWorkPlan : defaultWorkPlan(safeSummary, defaultPlanLane, changeMode);
249
+ const workPlan = providedWorkPlan.length ? providedWorkPlan : defaultWorkPlan(safeSummary, defaultPlanLane, changeMode, mutationPolicy);
267
250
  const workPlanError = validateNewWorkPlan(workPlan);
268
251
  if (workPlanError) {
269
- return { content: [{ type: "text", text: `Task start refused: ${workPlanError}.` }], details: workPlan, isError: true };
252
+ return { content: [{ type: "text", text: `Task start refused: ${workPlanError}.` }], details: { reasonCode: "invalid-work-plan" }, isError: true };
270
253
  }
271
254
  const firstReady = workPlan.find((step) => (step.dependsOn ?? []).length === 0);
272
255
  if (!firstReady) {
273
- return { content: [{ type: "text", text: "Task start refused: work plan has no dependency-ready first step." }], details: workPlan, isError: true };
256
+ return { content: [{ type: "text", text: "Task start refused: work plan has no dependency-ready first step." }], details: { reasonCode: "work-plan-has-no-ready-step" }, isError: true };
274
257
  }
275
258
  firstReady.status = "in-progress";
276
259
  firstReady.updatedAt = createdAt;
@@ -293,12 +276,19 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
293
276
  expectedOutput: redactText(params.expectedOutput),
294
277
  acceptanceCriteria: redactTextArray(params.acceptanceCriteria),
295
278
  changeMode,
279
+ mutationPolicy,
280
+ outOfScope: redactTextArray(params.outOfScope),
281
+ protectedPaths: profile.protectedPaths ?? [],
296
282
  source: params.intakeMode === "runtime" ? "runtime" : "model",
297
283
  generatedAt: createdAt
298
284
  });
299
285
  const criterionGraph = compileCriterionGraph({ acceptanceCriteria: acceptance.acceptanceCriteria, scope: resolvedScope,
300
286
  verifyCommands: verifyPlan.commands, changeMode, mode: criterionGraphMode(), createdAt });
301
- const seededContext = criterionGraphContextSelection(criterionGraph, repositoryFileManifest(ctx.cwd), runtimeState.observedContext(ctx), contextBudgetConfig(policy).maxManifestFiles);
287
+ const projectManifest = repositoryManifestProvider.read(ctx.cwd), projectFiles = projectManifest.files;
288
+ const maxManifestFiles = contextBudgetConfig(policy).maxManifestFiles;
289
+ const plannedSelection = criterionGraphContextSelectionDetails(criterionGraph, projectFiles, [], maxManifestFiles, projectManifest.complete, resolvedScope);
290
+ const plannedContext = plannedSelection.entries;
291
+ const observedContext = criterionGraphContextSelection(undefined, [], runtimeState.preTaskContext(ctx), maxManifestFiles);
302
292
  const task: TaskContract = {
303
293
  schemaVersion: 2,
304
294
  taskRunId,
@@ -306,10 +296,12 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
306
296
  sessionId,
307
297
  sessionName,
308
298
  changeMode,
299
+ mutationPolicy,
309
300
  attempt,
310
301
  maxAttempts,
311
302
  previousAttempts: priorAttempts.filter((task) => task.trace.outcome !== "pending").slice(0, 10).reverse().map(summarizeAttempt),
312
303
  summary: safeSummary,
304
+ ...(safeOperatorRequest ? { operatorRequest: safeOperatorRequest, operatorRequestDigest: operatorRequestDigest(safeOperatorRequest) } : {}),
313
305
  riskLane: params.riskLane,
314
306
  intakeMode: params.intakeMode === "runtime" ? "runtime" : "model",
315
307
  expectedOutput: redactText(params.expectedOutput),
@@ -319,7 +311,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
319
311
  outOfScope: redactTextArray(params.outOfScope),
320
312
  protectedPaths: profile.protectedPaths ?? [],
321
313
  requiredContext: profile.requiredContext ?? [],
322
- contextManifest: seededContext,
314
+ contextManifest: observedContext,
323
315
  memoryCitations: [],
324
316
  mcpCapabilities: profile.mcpCapabilities ?? [],
325
317
  verifyGroup: verifyPlan.group,
@@ -332,7 +324,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
332
324
  orchestration: {
333
325
  mode: orchestration.defaultMode,
334
326
  subagents: "not-used",
335
- reason: "Task starts in solo-first mode; use bounded subagents only for independent scout, planning, or review work.",
327
+ reason: "Parent works directly by default. One fresh read-only helper is eligible only with two independent lanes and at least 30% projected net token savings; workers and retries are disabled.",
336
328
  fieldGuidePath: orchestration.fieldGuide.enabled ? orchestration.fieldGuide.path : undefined,
337
329
  modelRoles: orchestration.roleModelGuidance
338
330
  },
@@ -347,16 +339,20 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
347
339
  createdAt,
348
340
  updatedAt: createdAt
349
341
  };
350
- if (changeMode === "read-only" && seededContext.length > 0) {
342
+ if (mutationPolicy === "forbidden" && observedContext.length > 0) {
351
343
  applyRuntimeLifecycleObservation(task, "context-complete", createdAt);
352
344
  }
353
345
  const written = writeTask(ctx.cwd, task);
354
- const baselineGuidance = changeMode === "source-change"
346
+ runtimeState.promotePreTaskContext(ctx, written.taskRunId, observedContext);
347
+ const baselineGuidance = changeMode === "source-change" && mutationPolicy === "required"
355
348
  ? acceptanceBaselineGuidance(written, { cwd: ctx.cwd })
356
349
  : [];
357
- const exactOutputGuidance = changeMode === "read-only"
358
- ? exactFinalOutputGuidance(written.summary)
350
+ const exactOutputGuidance = mutationPolicy === "forbidden"
351
+ ? exactFinalOutputGuidance(written)
359
352
  : [];
353
+ const criticalProof = taskCriticalProofSection(
354
+ written, plannedContext, projectFiles, acceptanceProofGuidance, isAcceptanceTestPath, acceptanceLanguageAdapterForPath,
355
+ taskPerformanceAssurance(written).requiresReview);
360
356
  bindSessionTask(ctx.cwd, sessionId, sessionName, written);
361
357
  runtimeState.cacheTaskIdentity(ctx, written);
362
358
  if (written.intakeMode !== "runtime") {
@@ -367,18 +363,28 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
367
363
  }
368
364
  const lifecycleMode = runtimeLifecycleMode(written);
369
365
  const scopeMappings = scopeResolution.mappings.map((item) => `${item.from} -> ${item.to}`);
370
- appendTrace(ctx.cwd, { taskId, taskRunId, sessionId, sessionName, attempt, event: "task_start", summary: task.summary, riskLane: params.riskLane, intakeMode: task.intakeMode, changeMode: task.changeMode, lifecycleMode, criterionGraphMode: written.criterionGraph.mode, criterionGraphDigest: written.criterionGraph.graphDigest, authorityProfile: written.authoritySnapshot.profile, authoritySnapshotDigest: written.authoritySnapshot.snapshotDigest, scopeMappings, seededContext: seededContext.map((item) => item.path) });
371
- appendSessionTrace(pi, { taskId, taskRunId, sessionId, sessionName, attempt, event: "task_start", summary: task.summary, riskLane: params.riskLane, intakeMode: task.intakeMode, changeMode: task.changeMode, lifecycleMode, criterionGraphMode: written.criterionGraph.mode, criterionGraphDigest: written.criterionGraph.graphDigest, authorityProfile: written.authoritySnapshot.profile, authoritySnapshotDigest: written.authoritySnapshot.snapshotDigest, scopeMappings, seededContext: seededContext.map((item) => item.path) });
366
+ appendTrace(ctx.cwd, { taskId, taskRunId, sessionId, sessionName, attempt, event: "task_start", turnId: runtimeState.currentTurn(ctx)?.turnId, summary: task.summary, riskLane: params.riskLane, intakeMode: task.intakeMode, changeMode: task.changeMode, mutationPolicy: task.mutationPolicy, lifecycleMode, criterionGraphMode: written.criterionGraph.mode, criterionGraphDigest: written.criterionGraph.graphDigest, authorityProfile: written.authoritySnapshot.profile, authoritySnapshotDigest: written.authoritySnapshot.snapshotDigest, scopeMappings, plannedContext: plannedContext.map((item) => item.path), plannedContextComplete: plannedSelection.complete, plannedContextCandidateCount: plannedSelection.candidateCount, repositoryManifestProvider: projectManifest.provider, repositoryManifestCompatibilityReason: projectManifest.compatibilityReason, observedContext: observedContext.map((item) => item.path) });
367
+ appendSessionTrace(pi, { taskId, taskRunId, sessionId, sessionName, attempt, event: "task_start", turnId: runtimeState.currentTurn(ctx)?.turnId, summary: task.summary, riskLane: params.riskLane, intakeMode: task.intakeMode, changeMode: task.changeMode, mutationPolicy: task.mutationPolicy, lifecycleMode, criterionGraphMode: written.criterionGraph.mode, criterionGraphDigest: written.criterionGraph.graphDigest, authorityProfile: written.authoritySnapshot.profile, authoritySnapshotDigest: written.authoritySnapshot.snapshotDigest, scopeMappings, plannedContext: plannedContext.map((item) => item.path), plannedContextComplete: plannedSelection.complete, plannedContextCandidateCount: plannedSelection.candidateCount, repositoryManifestProvider: projectManifest.provider, repositoryManifestCompatibilityReason: projectManifest.compatibilityReason, observedContext: observedContext.map((item) => item.path) });
368
+ telemetry(ctx, { event: "turn_task_bound", turnId: runtimeState.currentTurn(ctx)?.turnId, taskRunId });
372
369
  recordTaskStartCheckpoint(ctx, written, firstReady.id, lifecycleMode);
373
370
  return {
374
371
  content: [{
375
372
  type: "text",
376
373
  text: [
377
374
  `Task ${taskId} started (${params.riskLane}, ${lifecycleMode}; attempt ${attempt}/${maxAttempts}).`,
378
- ...(scopeMappings.length > 0 ? [`Canonical scope: ${scopeMappings.join("; ")}.`] : []),
375
+ ...(scopeMappings.length > 0 ? [`Initial focus mapping: ${scopeMappings.join("; ")}.`] : []),
376
+ ...(scopeResolution.ambiguous.length > 0
377
+ ? [`Ambiguous focus retained as advisory: ${scopeResolution.ambiguous.map((item) => item.input).join(", ")}.`]
378
+ : []),
379
+ ...(scopeResolution.unmatched.length > 0
380
+ ? [`Unmatched focus retained for discovery or new files: ${scopeResolution.unmatched.join(", ")}.`]
381
+ : []),
379
382
  written.verifyCommands.length > 0
380
383
  ? ["Exact verifier commands:", ...verifierCommandInstructions(written.verifyCommands)].join("\n")
381
384
  : "Verify: none (read-only).",
385
+ ...(written.verifyCommands.length > 0
386
+ ? [EXACT_VERIFIER_EXECUTION_GUIDANCE]
387
+ : []),
382
388
  written.acceptanceCriteria.length > 0
383
389
  ? ["Acceptance focus:", ...written.acceptanceCriteria.map((criterion, index) => `${index + 1}. ${criterion}`)].join("\n")
384
390
  : "Acceptance focus: not recorded.",
@@ -386,9 +392,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
386
392
  ? [["Execution map (planning only; verifier remains authoritative):", ...criterionGraphGuidance(written.criterionGraph).map((line: string) => `- ${line}`)].join("\n")]
387
393
  : []),
388
394
  ...exactOutputGuidance,
389
- ...(changeMode === "source-change" && acceptanceProofGuidance(written).length > 0
390
- ? [["Critical behavioral proof:", ...acceptanceProofGuidance(written).map((item: string) => `- ${item}`), "Map every proof item above to a live focused assertion or explicit test matrix before the verifier; happy-path coverage and prose claims are insufficient."].join("\n")]
391
- : []),
395
+ ...criticalProof,
392
396
  ...(baselineGuidance.length > 0
393
397
  ? [["Existing public contract:", ...baselineGuidance.map((item: string) => `- ${item}`)].join("\n")]
394
398
  : []),
@@ -396,6 +400,7 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
396
400
  ? "Runtime records targeted reads and final completion automatically. Stay read-only and report cited evidence."
397
401
  : lifecycleMode === "assisted-readonly"
398
402
  ? "Runtime records read-only evidence automatically; complete only the explicit evidence-review step before handoff."
403
+ : mutationPolicy === "forbidden" ? "Runtime permits bounded inspection and exact configured verifier commands only. Source mutation is blocked, and completion requires a zero task delta."
399
404
  : lifecycleMode === "automatic"
400
405
  ? "Runtime will record reads, changes, exact verifier results, and final completion automatically. Continue with ordinary read/edit/bash work."
401
406
  : lifecycleMode === "assisted"
@@ -408,31 +413,31 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
408
413
  }
409
414
  };
410
415
  registerRuntimeTool(pi, taskStartTool);
411
- async function maybeStartAutomaticTask(prompt: string, ctx: ExtensionContext): Promise<{ started: boolean; text: string; task?: TaskContract } | undefined> {
416
+ async function maybeStartAutomaticTask(prompt: string, ctx: ExtensionContext): Promise<{ started: boolean; text: string; task?: TaskContract; plannedContext?: Array<{ path: string; reason: string }>; plannedContextComplete?: boolean } | undefined> {
412
417
  const profile = loadProfileFromContext(ctx);
413
418
  const readProtectedPaths = effectiveProtectedPaths(policy, profile).readProtectedPaths;
414
419
  const intakeMode = automaticTaskIntakeMode(prompt, readProtectedPaths);
415
420
  if (!intakeMode) return undefined;
416
- const active = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined;
421
+ const mutationPolicy = automaticTaskMutationPolicy(prompt, intakeMode), active = activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()) as TaskContract | undefined;
417
422
  if (active?.trace.outcome === "pending") return undefined;
418
423
  const summary = redactText(automaticTaskSummary(prompt));
419
424
  const sessionName = currentSessionName(ctx);
420
- const projectFiles = repositoryFileManifest(ctx.cwd);
425
+ const projectManifest = repositoryManifestProvider.read(ctx.cwd), projectFiles = projectManifest.files;
421
426
  const scope = intakeMode === "read-only"
422
- ? automaticReadOnlyTaskScope(prompt, runtimeState.observedContext(ctx))
423
- : automaticTaskScope(prompt, runtimeState.observedContext(ctx), projectFiles);
427
+ ? automaticReadOnlyTaskScope(prompt, runtimeState.preTaskContext(ctx))
428
+ : automaticTaskScope(prompt, runtimeState.preTaskContext(ctx), projectFiles);
424
429
  const started = await taskStartTool.execute(
425
430
  `runtime-intake-${ctx.sessionManager.getSessionId()}`,
426
431
  {
427
432
  taskId: active && active.trace.outcome !== "pending" ? summary : hasOperatorSessionName(sessionName) ? sessionName : summary,
428
- summary,
433
+ summary, operatorRequest: prompt,
429
434
  riskLane: automaticTaskRiskLane(prompt),
430
435
  intakeMode: "runtime",
431
436
  changeMode: intakeMode,
432
- expectedOutput: intakeMode === "read-only"
433
- ? "The requested read-only investigation is answered from observed project evidence without mutating files."
437
+ mutationPolicy,
438
+ expectedOutput: mutationPolicy === "forbidden" ? "The requested read-only investigation is answered from observed project evidence without mutating files."
434
439
  : "The requested bounded change is implemented and passes the configured verification.",
435
- acceptanceCriteria: automaticAcceptanceCriteria(prompt, intakeMode),
440
+ acceptanceCriteria: automaticAcceptanceCriteria(prompt, mutationPolicy === "forbidden" ? "read-only" : intakeMode),
436
441
  scope,
437
442
  outOfScope: ["Unrelated files and behavior outside the operator request."],
438
443
  reviewLenses: automaticReviewLenses(prompt)
@@ -458,22 +463,26 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
458
463
  };
459
464
  }
460
465
  const assurance = taskPerformanceAssurance(task);
461
- const baselineGuidance = task.changeMode === "source-change"
466
+ const plannedSelection = criterionGraphContextSelectionDetails(task.criterionGraph, projectFiles, [], contextBudgetConfig(policy).maxManifestFiles, projectManifest.complete, task.scope);
467
+ const plannedContext = plannedSelection.entries;
468
+ const baselineGuidance = task.changeMode === "source-change" && task.mutationPolicy !== "forbidden"
462
469
  ? acceptanceBaselineGuidance(task, { cwd: ctx.cwd })
463
470
  : [];
464
- const exactOutputGuidance = task.changeMode === "read-only"
465
- ? exactFinalOutputGuidance(task.summary)
466
- : [];
471
+ const exactOutputGuidance = task.changeMode === "read-only" || task.mutationPolicy === "forbidden" ? exactFinalOutputGuidance(task) : [];
472
+ const criticalProof = taskCriticalProofSection(
473
+ task, plannedContext, projectFiles, acceptanceProofGuidance, isAcceptanceTestPath, acceptanceLanguageAdapterForPath,
474
+ assurance.requiresReview
475
+ );
467
476
  return {
468
477
  started: true,
469
478
  task,
479
+ plannedContext,
480
+ plannedContextComplete: plannedSelection.complete,
470
481
  text: boundedRuntimeIntakeMessage([
471
- `Piagent runtime task: ${task.taskId}; scope: ${task.scope.join(", ")}.`,
482
+ `Piagent runtime task: ${task.taskId}; initial focus (advisory): ${task.scope.join(", ")}.`,
472
483
  "The complete operator request above is the authoritative acceptance contract; runtime keeps its full criteria, so do not restate or re-scout it.",
473
484
  `Assurance: ${assurance.tier} (${assurance.reasonCodes.join(", ") || "bounded-runtime"}).`,
474
- ...(task.changeMode === "source-change" && acceptanceProofGuidance(task).length > 0
475
- ? [["Critical behavioral proof:", ...acceptanceProofGuidance(task).map((item: string) => `- ${item}`), "Map every proof item above to a live focused assertion or explicit test matrix before the verifier; happy-path coverage is insufficient."].join("\n")]
476
- : []),
485
+ ...criticalProof,
477
486
  ...(baselineGuidance.length > 0
478
487
  ? [["Existing public contract:", ...baselineGuidance.map((item: string) => `- ${item}`)].join("\n")]
479
488
  : []),
@@ -481,15 +490,11 @@ export function registerTaskStartTool(pi: ExtensionAPI, deps: Record<string, any
481
490
  "Exact verifier commands:",
482
491
  ...(task.verifyCommands.length > 0 ? verifierCommandInstructions(task.verifyCommands) : ["none"]),
483
492
  ...(criterionGraphGuidance(task.criterionGraph).length > 0 ? [["Execution map (planning only):", ...criterionGraphGuidance(task.criterionGraph).map((line: string) => `- ${line}`)].join("\n")] : []),
493
+ RUNTIME_SOURCE_REUSE_GUIDANCE,
484
494
  "Root project instructions are loaded. Do not re-read root AGENTS.md or inspect Piagent/platform files; work directly in relevant source/tests with ordinary tools.",
485
- task.changeMode === "read-only"
486
- ? "Stay read-only. Runtime records targeted reads and completion evidence; do not call task-management tools."
487
- : task.criterionGraph?.mode === "criterion-graph"
488
- ? "Follow the execution map: batch context reads by target, implement dependency-ready criteria, then run the exact verifier once; rerun only after a later mutation. The map plans work but never overrides the operator request or verifier."
489
- : "Before mutating, privately map every operator criterion to implementation and focused-test coverage; batch independent reads or writes. Finish intended edits and one criterion-by-criterion self-review, then run the exact verifier once; rerun only after a later mutation. Runtime records evidence and completion; do not call task-management tools."
495
+ automaticTaskExecutionGuidance(task)
490
496
  ].join("\n"))
491
497
  };
492
498
  }
493
-
494
499
  return maybeStartAutomaticTask;
495
500
  }
@@ -6,10 +6,24 @@ export const CONTEXT_COMPACT_PERCENT = 70;
6
6
  export const CONTEXT_FRESH_PERCENT = 82;
7
7
  export const LONG_INPUT_CHARS = 8000;
8
8
  export const MAX_INLINE_COLLAPSED_TASK_CHARS = 2200;
9
- export const RUNTIME_INTAKE_MESSAGE_MAX_CHARS = 6_000;
10
- export const SEMANTIC_COMPACTION_MAX_CHARS = 8_000;
9
+ export const RUNTIME_INTAKE_COMPACT_CHARS = 3_500;
10
+ export const RUNTIME_INTAKE_MESSAGE_MAX_CHARS = 3_500;
11
+ export const SEMANTIC_COMPACTION_MAX_CHARS = 12_000;
11
12
  export const CONTEXT_PACK_MAX_TOKENS = 900;
12
13
 
14
+ // The host's default compaction reserve is primarily an overflow guard. Piagent's
15
+ // governor acts earlier because repeatedly replaying a valid 200k+ context can
16
+ // burn substantially more tokens than the task itself. These are working-set
17
+ // limits, not capability limits: high-value task truth is carried forward while
18
+ // stale tool transcripts remain in the durable session history.
19
+ export const CONTEXT_PROVIDER_PROMPT_CEILING_TOKENS = 240_000;
20
+ export const CONTEXT_GOVERNOR_PRESSURE_TOKENS = 160_000;
21
+ export const CONTEXT_GOVERNOR_TARGET_MESSAGE_TOKENS = 72_000;
22
+ export const CONTEXT_GOVERNOR_RECENT_MESSAGE_TOKENS = 40_000;
23
+ export const CONTEXT_GOVERNOR_SEMANTIC_BOUNDARY_TOKENS = 48_000;
24
+ export const CONTEXT_GOVERNOR_TOOL_ROUND_LIMIT = 24;
25
+ export const CONTEXT_GOVERNOR_LEDGER_MAX_CHARS = 12_000;
26
+
13
27
  export const TOOL_RESULT_COMPACT_CHAR_THRESHOLD = 12_000;
14
28
  export const TOOL_RESULT_COMPACT_LINE_THRESHOLD = 180;
15
29
  export const TOOL_RESULT_PREVIEW_HEAD_LINES = 24;