@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
@@ -0,0 +1,193 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+
5
+ // Parent workspaces commonly carry shared plans, verifier scripts, and agent
6
+ // configuration beside their child repositories. Keep the traversal bounded,
7
+ // but leave enough room for a real multi-repository workspace instead of
8
+ // silently dropping evidence at the former 2,000-file ceiling.
9
+ const WORKSPACE_EVIDENCE_MAX_FILES = 20_000;
10
+ // These names are not merely noisy build output: they carry repository
11
+ // ownership, Piagent authority, or provider credentials. Evidence discovery
12
+ // excludes them and the mutation guard protects them independently of task
13
+ // focus, so broad monorepo access cannot create an unaudited private-state gap.
14
+ export const WORKSPACE_PRIVATE_STATE_PATTERNS = Object.freeze([
15
+ "**/.git/**", "**/.hg/**", "**/.svn/**", "**/.pi/**",
16
+ "**/.aws/**", "**/.azure/**", "**/.docker/**", "**/.gnupg/**", "**/.kube/**", "**/.ssh/**",
17
+ "**/.git-credentials", "**/.netrc", "**/.npmrc", "**/.pypirc",
18
+ "**/.env", "**/.env.*",
19
+ "**/auth.json", "**/credential.json", "**/credentials.json", "**/secret.json", "**/secrets.json",
20
+ "**/token.json", "**/tokens.json"
21
+ ]);
22
+ const WORKSPACE_EVIDENCE_SKIP_NAMES = new Set([
23
+ ".git", ".hg", ".svn", ".pi", "node_modules", "dist", "build", ".next", "coverage",
24
+ ".cache", ".npm", ".pnpm-store", ".yarn", ".turbo", ".aws", ".azure", ".docker",
25
+ ".gnupg", ".kube", ".ssh", ".ds_store", ".git-credentials", ".netrc", ".npmrc", ".pypirc"
26
+ ]);
27
+ const WORKSPACE_EVIDENCE_PRIORITY_NAMES = new Map([["plans", 0]]);
28
+
29
+ function excludedWorkspaceEvidenceName(value) {
30
+ const name = String(value ?? "");
31
+ return WORKSPACE_EVIDENCE_SKIP_NAMES.has(name.toLowerCase())
32
+ || /^\.env(?:\.|$)/i.test(name)
33
+ || /^(?:auth|credentials?|secrets?|tokens?)\.json$/i.test(name);
34
+ }
35
+
36
+ export function gitOutput(cwd, args, options = {}) {
37
+ return execFileSync("git", ["-C", cwd, ...args], {
38
+ encoding: options.encoding ?? "utf8",
39
+ maxBuffer: options.maxBuffer ?? 16 * 1024 * 1024,
40
+ stdio: ["ignore", "pipe", "ignore"]
41
+ });
42
+ }
43
+
44
+ export function isGitWorkingTree(cwd) {
45
+ try {
46
+ return gitOutput(cwd, ["rev-parse", "--is-inside-work-tree"]).trim() === "true";
47
+ } catch {
48
+ return false;
49
+ }
50
+ }
51
+
52
+ export function normalizedGitPath(value) {
53
+ return String(value ?? "").replaceAll("\\", "/").replace(/^\/+/, "");
54
+ }
55
+
56
+ export function prefixedGitPath(prefix, file) {
57
+ const normalized = normalizedGitPath(file);
58
+ return prefix ? `${prefix}/${normalized}` : normalized;
59
+ }
60
+
61
+ function directChildGitEvidenceRootDetails(cwd) {
62
+ const roots = [];
63
+ let complete = true;
64
+ let entries;
65
+ try {
66
+ entries = fs.readdirSync(cwd, { withFileTypes: true });
67
+ } catch {
68
+ return { roots, complete: false };
69
+ }
70
+ for (const entry of entries) {
71
+ if (!entry.isDirectory() || entry.name.startsWith(".") || entry.name === "node_modules") continue;
72
+ const child = path.join(cwd, entry.name);
73
+ try {
74
+ if (fs.lstatSync(child).isSymbolicLink()) continue;
75
+ let gitMarker;
76
+ try {
77
+ gitMarker = fs.lstatSync(path.join(child, ".git"));
78
+ } catch (error) {
79
+ if (error?.code === "ENOENT") continue;
80
+ complete = false;
81
+ continue;
82
+ }
83
+ if (!gitMarker.isDirectory() && !gitMarker.isFile()) {
84
+ complete = false;
85
+ continue;
86
+ }
87
+ if (!isGitWorkingTree(child)) {
88
+ complete = false;
89
+ continue;
90
+ }
91
+ const topLevel = gitOutput(child, ["rev-parse", "--show-toplevel"]).trim();
92
+ if (fs.realpathSync(topLevel) !== fs.realpathSync(child)) {
93
+ complete = false;
94
+ continue;
95
+ }
96
+ roots.push({ cwd: child, prefix: normalizedGitPath(entry.name) });
97
+ } catch {
98
+ complete = false;
99
+ }
100
+ }
101
+ return { roots: roots.sort((left, right) => left.prefix.localeCompare(right.prefix)), complete };
102
+ }
103
+
104
+ export function directChildGitEvidenceRoots(cwd) {
105
+ return directChildGitEvidenceRootDetails(cwd).roots;
106
+ }
107
+
108
+ export function gitEvidenceRootDetails(cwd) {
109
+ if (isGitWorkingTree(cwd)) return { roots: [{ cwd, prefix: "" }], complete: true };
110
+ // A present Git marker combined with a failed Git probe is ambiguous (for
111
+ // example a broken worktree pointer or a transient command failure). Do not
112
+ // reinterpret that repository as an ordinary complete non-Git directory.
113
+ try {
114
+ fs.lstatSync(path.join(cwd, ".git"));
115
+ return { roots: [], complete: false };
116
+ } catch (error) {
117
+ if (error?.code !== "ENOENT") return { roots: [], complete: false };
118
+ }
119
+ return directChildGitEvidenceRootDetails(cwd);
120
+ }
121
+
122
+ export function gitEvidenceRoots(cwd) {
123
+ return gitEvidenceRootDetails(cwd).roots;
124
+ }
125
+
126
+ function workspaceEvidenceFileLimit(value) {
127
+ return Number.isInteger(value)
128
+ ? Math.max(1, Math.min(WORKSPACE_EVIDENCE_MAX_FILES, value))
129
+ : WORKSPACE_EVIDENCE_MAX_FILES;
130
+ }
131
+
132
+ export function nonGitWorkspaceFileDetails(cwd, gitRootPrefixes, maxFiles = WORKSPACE_EVIDENCE_MAX_FILES) {
133
+ const files = [];
134
+ let complete = true;
135
+ const limit = workspaceEvidenceFileLimit(maxFiles);
136
+ const gitRoots = new Set(gitRootPrefixes.filter(Boolean));
137
+ const orderedEntries = (entries) => [...entries].sort((left, right) => {
138
+ const leftPriority = WORKSPACE_EVIDENCE_PRIORITY_NAMES.get(left.name.toLowerCase()) ?? 10;
139
+ const rightPriority = WORKSPACE_EVIDENCE_PRIORITY_NAMES.get(right.name.toLowerCase()) ?? 10;
140
+ return leftPriority - rightPriority || left.name.localeCompare(right.name, "en-US");
141
+ });
142
+ function visit(directory, relativeDirectory) {
143
+ if (files.length >= limit) {
144
+ complete = false;
145
+ return;
146
+ }
147
+ let entries;
148
+ try {
149
+ entries = fs.readdirSync(directory, { withFileTypes: true });
150
+ } catch {
151
+ complete = false;
152
+ return;
153
+ }
154
+ for (const entry of orderedEntries(entries)) {
155
+ if (files.length >= limit) {
156
+ complete = false;
157
+ return;
158
+ }
159
+ // A parent workspace can own real project source in hidden directories
160
+ // (for example shared verifier scripts). Evidence discovery therefore
161
+ // excludes explicit private/cache/credential names instead of treating
162
+ // every dot-prefixed path as non-project state.
163
+ if (excludedWorkspaceEvidenceName(entry.name)) continue;
164
+ const relative = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
165
+ if (gitRoots.has(relative.split("/")[0])) continue;
166
+ const absolute = path.join(directory, entry.name);
167
+ try {
168
+ if (fs.lstatSync(absolute).isSymbolicLink()) continue;
169
+ } catch {
170
+ complete = false;
171
+ continue;
172
+ }
173
+ if (entry.isDirectory()) visit(absolute, relative);
174
+ else if (entry.isFile()) files.push(normalizedGitPath(relative));
175
+ }
176
+ }
177
+ visit(cwd, "");
178
+ return { files: files.sort(), complete };
179
+ }
180
+
181
+ export function nonGitWorkspaceFiles(cwd, gitRootPrefixes, maxFiles = WORKSPACE_EVIDENCE_MAX_FILES) {
182
+ return nonGitWorkspaceFileDetails(cwd, gitRootPrefixes, maxFiles).files;
183
+ }
184
+
185
+ export function pathWithinNonGitWorkspaceEvidenceRoot(candidate, gitRootPrefixes) {
186
+ const segments = candidate.split("/").filter(Boolean);
187
+ const topSegment = segments[0];
188
+ return Boolean(
189
+ topSegment
190
+ && !segments.some(excludedWorkspaceEvidenceName)
191
+ && !gitRootPrefixes.includes(topSegment)
192
+ );
193
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piagent/core",
3
- "version": "1.5.5",
3
+ "version": "1.6.1",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "license": "MIT",
@@ -3,7 +3,27 @@
3
3
  "name": "piagent-base-policy",
4
4
  "protectedPaths": [
5
5
  ".git/**",
6
+ "**/.git/**",
7
+ "**/.hg/**",
8
+ "**/.svn/**",
9
+ "**/.pi/**",
10
+ "**/.aws/**",
11
+ "**/.azure/**",
12
+ "**/.docker/**",
13
+ "**/.gnupg/**",
14
+ "**/.kube/**",
15
+ "**/.ssh/**",
16
+ "**/.git-credentials",
17
+ "**/.netrc",
18
+ "**/.npmrc",
19
+ "**/.pypirc",
6
20
  "**/auth.json",
21
+ "**/credential.json",
22
+ "**/credentials.json",
23
+ "**/secret.json",
24
+ "**/secrets.json",
25
+ "**/token.json",
26
+ "**/tokens.json",
7
27
  "**/.env",
8
28
  "**/.env.*",
9
29
  "**/node_modules/**",
@@ -16,7 +36,27 @@
16
36
  ],
17
37
  "shellProtectedPaths": [
18
38
  ".git/**",
39
+ "**/.git/**",
40
+ "**/.hg/**",
41
+ "**/.svn/**",
42
+ "**/.pi/**",
43
+ "**/.aws/**",
44
+ "**/.azure/**",
45
+ "**/.docker/**",
46
+ "**/.gnupg/**",
47
+ "**/.kube/**",
48
+ "**/.ssh/**",
49
+ "**/.git-credentials",
50
+ "**/.netrc",
51
+ "**/.npmrc",
52
+ "**/.pypirc",
19
53
  "**/auth.json",
54
+ "**/credential.json",
55
+ "**/credentials.json",
56
+ "**/secret.json",
57
+ "**/secrets.json",
58
+ "**/token.json",
59
+ "**/tokens.json",
20
60
  "**/.env",
21
61
  "**/.env.*",
22
62
  ".pi/piagent-state/**",
@@ -107,6 +147,7 @@
107
147
  },
108
148
  "contextBudget": {
109
149
  "defaultMode": "enforce",
150
+ "contextDeltaShadow": "sample",
110
151
  "maxContextFileChars": 50000,
111
152
  "maxMemoryFileChars": 20000,
112
153
  "maxManifestFiles": 80,
@@ -155,6 +196,7 @@
155
196
  "ls": ["filesystem-readonly"],
156
197
  "write": ["filesystem-write"],
157
198
  "edit": ["filesystem-write"],
199
+ "apply_patch": ["filesystem-write"],
158
200
  "browser": ["browser"],
159
201
  "github": ["github"]
160
202
  }
@@ -230,7 +272,7 @@
230
272
  },
231
273
  "orchestrationPolicy": {
232
274
  "defaultMode": "solo-first",
233
- "maxConcurrentSubagents": 2,
275
+ "maxConcurrentSubagents": 1,
234
276
  "defaultReviewLenses": [
235
277
  "correctness",
236
278
  "tests",
@@ -238,7 +280,7 @@
238
280
  ],
239
281
  "roleModelGuidance": {
240
282
  "planner": "Use the strongest available model for decomposition, architecture, risk, and acceptance criteria.",
241
- "worker": "Use the fastest reliable model for a bounded, already-planned single write set.",
283
+ "worker": "Disabled by default. The parent model owns all implementation and mutation.",
242
284
  "reviewer": "Use a model or thinking setting decorrelated from the worker when review quality matters.",
243
285
  "watchdog": "Use a strong model only for final risk review, security, release, or high-impact changes."
244
286
  },
@@ -34,7 +34,7 @@
34
34
  "CAP-11": "advisory",
35
35
  "CAP-12": "on",
36
36
  "CAP-13": "off",
37
- "CAP-14": "recommend",
37
+ "CAP-14": "off",
38
38
  "CAP-15": "off",
39
39
  "CAP-16": "on",
40
40
  "CAP-17": "on"
@@ -80,7 +80,7 @@
80
80
  "CAP-11": "advisory",
81
81
  "CAP-12": "on",
82
82
  "CAP-13": "strict",
83
- "CAP-14": "recommend",
83
+ "CAP-14": "off",
84
84
  "CAP-15": "off",
85
85
  "CAP-16": "on",
86
86
  "CAP-17": "on"
@@ -314,7 +314,7 @@
314
314
  "layer": "L3",
315
315
  "configKey": "helpers",
316
316
  "configSources": ["manifest", "PIAGENT_HELPERS_MODE"],
317
- "defaultMode": "recommend",
317
+ "defaultMode": "off",
318
318
  "killSwitchMode": "off",
319
319
  "dependencies": ["CAP-02", "CAP-05", "CAP-08"],
320
320
  "modeMappings": [
@@ -26,13 +26,7 @@ Flow:
26
26
  - BE scout: read-only.
27
27
  - FE implementation: source-write.
28
28
  - Auth/data migration/external provider: high-risk, ask before implementation.
29
- 4. Use bounded read-only subagents only when BE/FE mapping has independent lanes worth the extra token/tool cost:
30
- - `piagent-scout` maps backend contract read-only;
31
- - `piagent-scout` maps frontend touchpoints read-only;
32
- - builtin `context-builder` may create handoff context when the BE→FE mapping touches multiple journeys/forms/contracts;
33
- - `piagent-planner` produces the FE implementation plan when the contract touches multiple layers;
34
- - `piagent-reviewer` reviews diff/verification after implementation.
35
- Continue single-agent if subagents are unavailable, the task is tiny, or requirements are unresolved.
29
+ 4. Keep BE scouting and FE implementation in the parent by default. At most one fresh read-only `piagent-scout` may map either the BE contract or FE touchpoints only when runtime evidence proves two independent lanes and at least 30% projected total token savings after handoff/merge. Never launch two scouts, delegate FE writes/planning/review, inherit the parent transcript, or retry a deterministic helper failure.
36
30
  5. Scout backend contract read-only:
37
31
  - controller/route/handler;
38
32
  - request/response DTO/schema;
@@ -53,7 +47,7 @@ Flow:
53
47
  - route/page/component/form;
54
48
  - tests/e2e.
55
49
  9. Call `piagent_task_start` exactly once before FE source writes and reuse an active contract.
56
- 10. Implement FE only with one writer by default.
50
+ 10. Implement FE in the parent; helper workers are disabled.
57
51
  11. Run every exact command returned in `task.verifyCommands` after the latest mutation. For a normal default plan, review the final diff and mark only its review step done with `piagent_task_progress`.
58
52
  12. Let runtime hooks record context, verification, trace, and final-gate state. Use recovery tools only if the runtime reports missing evidence.
59
53
  13. Do not paste full test/build/tool logs into chat or final output. Summarize the signal and quote only relevant failing lines.
@@ -17,7 +17,7 @@ Rules:
17
17
  4. Read `.pi/project-context.md`; if it is missing or still pending, recommend `/onboard-project run` before implementation.
18
18
  5. Read required context.
19
19
  6. Identify protected paths and external/high-risk actions.
20
- 7. Decide whether subagents are useful enough to justify extra token/tool cost. If the bundled `pi-subagents` parent skill is available, use it for delegation patterns and safety boundaries. If `pi-subagents`/`subagent(...)` is available, use `piagent-scout` for independent read-only repo/spec mapping before medium/large plans. Use builtin `context-builder` when the task needs a handoff context/meta-prompt. Use `piagent-oracle` for architecture/risk challenge when the decision is non-obvious. Continue single-agent for tiny plans or unavailable subagent tooling.
20
+ 7. Keep planning in the parent. At most one fresh read-only helper may run only when runtime evidence proves two independent workstreams, no dependency on later parent output, and at least 30% projected total token savings after transfer/merge. Never delegate implementation, fork parent history, retry a deterministic helper failure, or add a helper only for review quality.
21
21
  8. Produce a compact task tree/workPlan with exact files, commands, owner role, review lenses, and verify gates.
22
22
  9. Do not implement yet unless the user explicitly asks.
23
23
 
@@ -23,18 +23,14 @@ Flow:
23
23
  1. Use runtime automatic intake for a bounded platform change. If runtime pauses for broad, high-risk, or ambiguous scope, call `piagent_task_start` exactly once with project-relative path/glob scope and reuse an active contract.
24
24
  2. Read the narrow current implementation, its tests, and the relevant policy/schema/docs. Runtime hooks inject bounded navigation context when useful.
25
25
  3. Treat memory and generated context as advisory; verify against current files.
26
- 4. Use bounded subagents only when independent lanes justify their extra token/tool cost:
27
- - use `piagent-scout` for read-only code/package mapping;
28
- - use `piagent-planner` for a plan when multiple modules are affected;
29
- - use `piagent-reviewer` for diff, docs, and verification review;
30
- - continue single-agent for small, localized edits.
26
+ 4. Keep platform analysis, planning, implementation, and review in the parent. At most one fresh read-only helper may map a genuinely independent lane only when runtime evidence projects at least 30% lower total tokens after handoff/merge. Do not delegate writes, fork parent history, run parallel helpers, or retry deterministic runtime/scope failures.
31
27
  5. If the task needs external repository context provided by the user, use a targeted read-only checkout when available.
32
28
  6. Produce an implementation matrix only when multiple platform areas are affected:
33
29
 
34
30
  | Area | Current behavior | Target behavior | Files/config | Verification |
35
31
  |---|---|---|---|---|
36
32
 
37
- 7. Implement only the bounded target behavior with one writer by default.
33
+ 7. Implement only the bounded target behavior in the parent.
38
34
  8. If runtime behavior changes, update README/docs and add or adjust a decision note when appropriate.
39
35
  9. Run every exact command returned in `task.verifyCommands` after the latest mutation. For a normal default plan, review the final diff and mark only its review step done with `piagent_task_progress`.
40
36
  10. Let runtime hooks record context, verification, trace, and final-gate state. Use recovery tools only if the runtime reports missing evidence.
@@ -14,13 +14,8 @@ Rules:
14
14
  1. Read the current diff and the narrow surrounding source/tests. Runtime hooks inject bounded navigation context when useful.
15
15
  2. Select review lenses from the actual change risk; do not load orchestration or diagnostic tools just to choose them.
16
16
  3. Stay read-only unless explicitly asked to write a report.
17
- 4. Check protected paths, scope drift, acceptance behavior, and verify-command coverage.
18
- 5. For a non-trivial diff, use bounded read-only reviewers only when independent lanes justify their token cost:
19
- - correctness/edge cases;
20
- - tests/verification;
21
- - scope drift/protected paths;
22
- - security/high-risk only when relevant.
23
- If the user asks for a loop, use `/review-loop` semantics or equivalent parent-controlled max-round loop. Continue single-agent for tiny diffs or unavailable subagent tooling.
17
+ 4. Check protected paths, unrelated change drift, acceptance behavior, and verify-command coverage. Treat task scope as an initial focus, not write authority.
18
+ 5. Review directly in the parent. A non-trivial diff does not itself justify another model run. At most one fresh read-only reviewer is eligible only when a runtime estimate proves an independent lane and at least 30% projected total token savings after handoff/merge; never run parallel review or retry a deterministic helper failure. If the user explicitly asks for a loop, keep it parent-controlled and bounded.
24
19
  6. Report findings by severity.
25
20
  7. Do not call diagnostic Piagent tools for routine review and do not paste full diff/test/tool logs. Summarize the signal and quote only relevant lines.
26
21
 
@@ -15,7 +15,7 @@ Lean scouting flow:
15
15
 
16
16
  1. Read targeted current files and return cited evidence. Runtime hooks inject bounded navigation context when useful and enforce read boundaries.
17
17
  2. Create a read-only contract with `piagent_task_start` only for a broad governed scout that needs persisted scope or handoff. Tiny default scouts complete from observed reads; for a normal default scout, review the evidence and mark only the returned review step done with `piagent_task_progress`.
18
- 3. Use memory, vendor documentation, or a read-only subagent only when current source is insufficient or the work has independent lanes. Verify advisory material against current files.
18
+ 3. Use memory or vendor documentation only when current source is insufficient. Keep scouting in the parent; a helper requires separate runtime proof of two independent lanes and at least 30% projected net token saving.
19
19
  4. A low-confidence search may trigger one bounded finder pass. Stop broad search when the requested evidence is covered.
20
20
  5. Do not call diagnostic Piagent tools for a routine scout. Load them only when the runtime reports a recovery need or the operator explicitly asks for diagnostics.
21
21
  6. Do not edit source or paste full command output. Summarize relevant evidence and unknowns.
@@ -11,9 +11,9 @@ $ARGUMENTS
11
11
 
12
12
  Core flow:
13
13
 
14
- 1. Use the runtime-created contract for a bounded source task; do not call task-management tools during automatic intake. If runtime pauses for broad, high-risk, or ambiguous scope, call `piagent_task_start` exactly once with project-relative path/glob scope and reuse an active contract.
14
+ 1. Use the runtime-created contract for a bounded source task; do not call task-management tools during automatic intake. If runtime pauses for a broad, high-risk, or ambiguous task, call `piagent_task_start` exactly once with project-relative focus paths/globs and reuse an active contract.
15
15
  2. Read the likely target and nearest relevant test. The runtime injects bounded navigation context when useful.
16
- 3. Make the smallest in-scope change with ordinary tools and one writer.
16
+ 3. Make the smallest complete evidence-backed change with ordinary tools and one writer. Initial task scope guides retrieval/review but does not restrict necessary FE, BE, test, config, or child-repository edits.
17
17
  4. Run every exact command returned in `task.verifyCommands` after the latest mutation.
18
18
  5. Automatic tasks need no lifecycle calls. Manual high-risk and explicitly requested custom plans keep their returned checkpoints.
19
19
  6. Let runtime hooks record context, changed files, verification, trace, and final-gate state. Load recovery tools only if the runtime reports missing evidence.
@@ -21,13 +21,14 @@ Core flow:
21
21
  Risk-adaptive enrichment:
22
22
 
23
23
  - `tiny`: stay targeted; no diagnostic Piagent tools or subagents.
24
- - `normal`: stop searching once current-file evidence is sufficient. Use a read-only subagent only for a genuinely independent lane.
24
+ - `normal`: stop searching once current-file evidence is sufficient. Keep the parent direct. One fresh read-only helper is eligible only when runtime evidence proves at least two independent lanes and at least 30% projected total token savings after handoff/merge.
25
25
  - `high-risk`: inspect current source, relevant vendor documentation, and explicit security/data/release review lenses; keep required human confirmations.
26
26
 
27
27
  Always:
28
28
 
29
29
  - Treat memory, context-index, and generated tech snapshots as advisory; verify against current files.
30
30
  - If navigation confidence is low, run at most one bounded read-only finder pass; do not start an open-ended scout loop.
31
+ - Never delegate implementation, fork/inherit the parent transcript, run more than one helper, or retry a deterministic helper/runtime/scope failure.
31
32
  - Do not touch protected paths or use undeclared capabilities.
32
33
  - If verification cannot run, report `blocked` or `partial`, never done. If runtime schedules a continuation, keep working in the same task and do not repeat management tools.
33
34
  - Do not paste full test/build/tool logs. Summarize the signal and quote only relevant failures.
@@ -0,0 +1,103 @@
1
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+
3
+ import type { TaskContract } from "../../extensions/guard-types.js";
4
+ import type { PendingContextDelivery, RuntimeSessionState, ObservedTaskContext } from "../session/runtime-state.ts";
5
+
6
+ export type ContextDeliveryConfirmationDependencies = {
7
+ state: RuntimeSessionState;
8
+ maxManifestFiles: number;
9
+ activeTask: (ctx: ExtensionContext) => TaskContract | undefined;
10
+ flushObservedTaskContext: (
11
+ pi: ExtensionAPI,
12
+ ctx: ExtensionContext,
13
+ pendingContext: ObservedTaskContext[],
14
+ maxManifestFiles: number,
15
+ event: string
16
+ ) => TaskContract | undefined;
17
+ telemetry: (ctx: ExtensionContext, payload: Record<string, unknown>) => void;
18
+ };
19
+
20
+ export function contextDeliveryIdFromDetails(details: unknown): string | undefined {
21
+ if (!details || typeof details !== "object" || Array.isArray(details)) return undefined;
22
+ const rawDelivery = (details as { contextDelivery?: unknown }).contextDelivery;
23
+ if (!rawDelivery || typeof rawDelivery !== "object" || Array.isArray(rawDelivery)) return undefined;
24
+ const deliveryId = (rawDelivery as { deliveryId?: unknown }).deliveryId;
25
+ return typeof deliveryId === "string" && deliveryId.length > 0 && deliveryId.length <= 200
26
+ ? deliveryId
27
+ : undefined;
28
+ }
29
+
30
+ export function confirmContextDelivery(
31
+ pi: ExtensionAPI,
32
+ ctx: ExtensionContext,
33
+ deliveryId: string,
34
+ dependencies: ContextDeliveryConfirmationDependencies
35
+ ): TaskContract | undefined {
36
+ const delivery = dependencies.state.takeContextDelivery(ctx, deliveryId);
37
+ if (!delivery) return undefined;
38
+ const task = dependencies.activeTask(ctx);
39
+ if (!task || task.trace.outcome !== "pending" || task.taskRunId !== delivery.taskRunId) {
40
+ dependencies.telemetry(ctx, { event: "context_delivery_rejected", deliveryId, reason: "task-identity-mismatch" });
41
+ return undefined;
42
+ }
43
+ for (const entry of delivery.entries) {
44
+ dependencies.state.rememberObservedContext(ctx, entry);
45
+ dependencies.state.rememberQualifiedContextEvidence(ctx, delivery.taskRunId, entry);
46
+ }
47
+ const written = dependencies.flushObservedTaskContext(
48
+ pi,
49
+ ctx,
50
+ dependencies.state.qualifiedContextEvidence(ctx, delivery.taskRunId),
51
+ dependencies.maxManifestFiles,
52
+ "context_delivery_confirmed"
53
+ );
54
+ if (!written || written.taskRunId !== delivery.taskRunId) return undefined;
55
+ if (delivery.pack) {
56
+ const { retrievalKey, ...pack } = delivery.pack;
57
+ dependencies.state.rememberInjectedContextPack(ctx, retrievalKey, pack);
58
+ }
59
+ dependencies.telemetry(ctx, {
60
+ event: "context_delivery_confirmed",
61
+ deliveryId,
62
+ turnId: delivery.turnId,
63
+ taskId: written.taskId,
64
+ taskRunId: written.taskRunId,
65
+ selectedPaths: delivery.entries.map((entry) => entry.path),
66
+ selected: delivery.entries.length
67
+ });
68
+ if (delivery.injection) dependencies.telemetry(ctx, {
69
+ event: "context_pack_injected",
70
+ injectionId: deliveryId,
71
+ turnId: delivery.turnId,
72
+ ...delivery.injection,
73
+ selectedPaths: delivery.injection.selectedItems.map((item) => item.path)
74
+ });
75
+ return written;
76
+ }
77
+
78
+ export function stageContextDelivery(
79
+ ctx: ExtensionContext,
80
+ delivery: PendingContextDelivery,
81
+ dependencies: Pick<ContextDeliveryConfirmationDependencies, "state" | "telemetry">
82
+ ): void {
83
+ dependencies.state.stageContextDelivery(ctx, delivery);
84
+ if (!delivery.injection) return;
85
+ dependencies.telemetry(ctx, {
86
+ event: "context_pack_offered",
87
+ deliveryId: delivery.deliveryId,
88
+ turnId: delivery.turnId,
89
+ ...delivery.injection,
90
+ selectedPaths: delivery.injection.selectedItems.map((item) => item.path)
91
+ });
92
+ }
93
+
94
+ export function confirmContextDeliveryFromToolResult(
95
+ pi: ExtensionAPI,
96
+ ctx: ExtensionContext,
97
+ event: { details?: unknown; isError?: boolean },
98
+ dependencies: ContextDeliveryConfirmationDependencies
99
+ ): TaskContract | undefined {
100
+ if (event.isError === true) return undefined;
101
+ const deliveryId = contextDeliveryIdFromDetails(event.details);
102
+ return deliveryId ? confirmContextDelivery(pi, ctx, deliveryId, dependencies) : undefined;
103
+ }
@@ -0,0 +1,53 @@
1
+ import crypto from "node:crypto";
2
+ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
3
+
4
+ import { buildContextPack, ensureContextIndexV2 } from "../../extensions/context-engine.js";
5
+ import { durableContextEvidenceEntries } from "../../extensions/context-evidence.js";
6
+ import type { TaskContract } from "../../extensions/guard-types.js";
7
+
8
+ export type ContextDeltaShadowMode = "off" | "sample" | "on";
9
+
10
+ type ShadowInput = {
11
+ ctx: ExtensionContext;
12
+ query: string;
13
+ turnId: string;
14
+ task: TaskContract;
15
+ mode: ContextDeltaShadowMode;
16
+ protectedTarget: boolean;
17
+ excludePatterns: string[];
18
+ telemetry: (ctx: ExtensionContext, payload: Record<string, unknown>) => void;
19
+ };
20
+
21
+ function sampled(taskRunId: string, query: string): boolean {
22
+ const byte = crypto.createHash("sha256").update(`${taskRunId}\0${query}`).digest()[0];
23
+ return byte < 64;
24
+ }
25
+
26
+ export async function measureContextDeltaShadow(input: ShadowInput): Promise<void> {
27
+ if (input.mode === "off" || input.protectedTarget || (input.mode === "sample" && !sampled(input.task.taskRunId, input.query))) return;
28
+ const usage = input.ctx.getContextUsage();
29
+ if (usage && Number(usage.percent ?? 0) >= 80) return;
30
+ try {
31
+ const { status } = await ensureContextIndexV2(input.ctx.cwd, { excludePatterns: input.excludePatterns, rebuildMissing: false });
32
+ if (!status.exists || status.stale) return;
33
+ const pack = await buildContextPack(input.ctx.cwd, input.query, {
34
+ budgetTokens: 1_200,
35
+ includeCode: false,
36
+ limit: 10,
37
+ excludePatterns: input.excludePatterns
38
+ });
39
+ const manifested = new Set(durableContextEvidenceEntries(input.task).map((entry) => entry.path));
40
+ const duplicateItems = pack.selected.filter((item) => manifested.has(item.path));
41
+ input.telemetry(input.ctx, {
42
+ event: "context_delta_shadow",
43
+ turnId: input.turnId,
44
+ queryHash: pack.queryHash,
45
+ candidatePaths: pack.selected.map((item) => item.path),
46
+ pathsAlreadyManifested: duplicateItems.map((item) => item.path),
47
+ candidateTokens: pack.selected.reduce((sum, item) => sum + item.estimatedTokens, 0),
48
+ duplicateCandidateTokens: duplicateItems.reduce((sum, item) => sum + item.estimatedTokens, 0)
49
+ });
50
+ } catch (error) {
51
+ input.telemetry(input.ctx, { event: "context_delta_shadow", turnId: input.turnId, skipped: "error", error: error instanceof Error ? error.message : String(error) });
52
+ }
53
+ }
@@ -0,0 +1,47 @@
1
+ type ContextEfficiencyReport = {
2
+ metrics: {
3
+ contextWasteScore: number | null;
4
+ contextWasteScoreEstimate: number;
5
+ contextWasteScoreEvidenceCoverage: number;
6
+ averageActiveTools: number;
7
+ toolSchemaPrefixShare: number;
8
+ toolSchemaToSystemRatio: number;
9
+ duplicateReads: number;
10
+ comparableReadCalls: number;
11
+ readCalls: number;
12
+ readEvidenceCoverage: number;
13
+ contextFallbackRereads: number;
14
+ contextSelections: number;
15
+ duplicateOutputRate: number;
16
+ lowConfidencePacks: number;
17
+ editRecoveryContextCount: number;
18
+ editRecoveryFailures: number;
19
+ editRecoverySuppressedFailures: number;
20
+ editRecoveryEstimatedTokens: number;
21
+ editRecoveryFailureEvidenceCoverage: number;
22
+ };
23
+ coverage: { wasteScore: { status: string } };
24
+ sample: { contextPacks: number };
25
+ recommendations: string[];
26
+ };
27
+
28
+ export function formatContextEfficiencyReport(
29
+ report: ContextEfficiencyReport,
30
+ formatPercent: (value: number) => string
31
+ ): string {
32
+ const wasteScore = report.metrics.contextWasteScore === null
33
+ ? `unavailable (diagnostic estimate ${report.metrics.contextWasteScoreEstimate}/100; evidence ${formatPercent(report.metrics.contextWasteScoreEvidenceCoverage)}, ${report.coverage.wasteScore.status})`
34
+ : `${report.metrics.contextWasteScore}/100 (lower is better; evidence ${formatPercent(report.metrics.contextWasteScoreEvidenceCoverage)}, ${report.coverage.wasteScore.status})`;
35
+ return [
36
+ `contextWasteScore: ${wasteScore}`,
37
+ `activeTools: ${report.metrics.averageActiveTools}`,
38
+ `toolSchemaPrefixShare: ${formatPercent(report.metrics.toolSchemaPrefixShare)}`,
39
+ `toolSchemaToSystemRatio: ${report.metrics.toolSchemaToSystemRatio}`,
40
+ `duplicateReads: ${report.metrics.duplicateReads}/${report.metrics.comparableReadCalls} comparable (${report.metrics.readCalls} observed; coverage ${formatPercent(report.metrics.readEvidenceCoverage)})`,
41
+ `fallbackRereads: ${report.metrics.contextFallbackRereads}/${report.metrics.contextSelections}`,
42
+ `duplicateOutput: ${formatPercent(report.metrics.duplicateOutputRate)}`,
43
+ `lowConfidencePacks: ${report.metrics.lowConfidencePacks}/${report.sample.contextPacks}`,
44
+ `editRecovery: ${report.metrics.editRecoveryContextCount}/${report.metrics.editRecoveryFailures} failures returned context; ${report.metrics.editRecoverySuppressedFailures} suppressed; ${report.metrics.editRecoveryEstimatedTokens} estimated tokens; classification coverage ${formatPercent(report.metrics.editRecoveryFailureEvidenceCoverage)}`,
45
+ ...report.recommendations.map((recommendation) => `- ${recommendation}`)
46
+ ].join("\n");
47
+ }