@piagent/platform 1.3.1 → 1.4.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 (329) hide show
  1. package/CHANGELOG.md +132 -0
  2. package/README.md +10 -4
  3. package/README.vi.md +27 -0
  4. package/architecture/layers.json +96 -1
  5. package/docs/README.md +1 -0
  6. package/docs/architecture.md +1 -0
  7. package/docs/authority-manifest.md +1 -0
  8. package/docs/auto-delegation-policy.md +1 -0
  9. package/docs/capability-packs.md +1 -0
  10. package/docs/command-reference-vietnamese.md +5 -4
  11. package/docs/context-engine.md +1 -0
  12. package/docs/context-window-policy.md +1 -0
  13. package/docs/distribution-standard.md +8 -7
  14. package/docs/en/architecture.md +13 -0
  15. package/docs/herdr-workflow.md +1 -0
  16. package/docs/languages.json +20 -4
  17. package/docs/mcp-and-tools.md +125 -9
  18. package/docs/memory-policy.md +1 -0
  19. package/docs/model-options.md +1 -0
  20. package/docs/oauth-providers.md +1 -0
  21. package/docs/operator-manual-vietnamese.md +15 -12
  22. package/docs/package-architecture-notes.md +1 -0
  23. package/docs/project-adapters.md +1 -0
  24. package/docs/project-onboarding.md +1 -0
  25. package/docs/publishing-for-teams.md +37 -0
  26. package/docs/quality-benchmark.md +1 -0
  27. package/docs/quickstart-vietnamese.md +3 -2
  28. package/docs/release-install-policy.md +22 -8
  29. package/docs/runtime-harness-standard.md +2 -1
  30. package/docs/runtime-policy-design.md +1 -0
  31. package/docs/runtime-quality-baseline.md +1 -0
  32. package/docs/security-redaction-benchmark.md +1 -0
  33. package/docs/security-threat-model.md +2 -1
  34. package/docs/subagent-orchestration-capabilities.md +1 -0
  35. package/docs/subagents-and-multiagent.md +1 -0
  36. package/docs/task-implementation-contract.md +12 -4
  37. package/docs/task-lifecycle-vietnamese.md +1 -0
  38. package/docs/team-onboarding.md +3 -2
  39. package/docs/third-party-neutrality.md +26 -0
  40. package/docs/usage-observability.md +71 -0
  41. package/docs/vercel-docs-site.md +1 -0
  42. package/docs/vi/architecture.md +13 -0
  43. package/docs/workflow-recipes.md +1 -0
  44. package/docs-site/architecture.html +5 -1
  45. package/docs-site/benchmark.html +5 -1
  46. package/docs-site/commands.html +5 -1
  47. package/docs-site/content/en/index.html +49 -0
  48. package/docs-site/content/en/runtime.html +13 -0
  49. package/docs-site/content/index.html +49 -0
  50. package/docs-site/content/runtime.html +28 -0
  51. package/docs-site/context-engine.html +5 -1
  52. package/docs-site/en/architecture.html +5 -1
  53. package/docs-site/en/benchmark.html +5 -1
  54. package/docs-site/en/commands.html +5 -1
  55. package/docs-site/en/context-engine.html +5 -1
  56. package/docs-site/en/index.html +54 -1
  57. package/docs-site/en/mcp-approval.html +5 -1
  58. package/docs-site/en/mcp-auth.html +5 -1
  59. package/docs-site/en/mcp-servers.html +5 -1
  60. package/docs-site/en/mcp.html +5 -1
  61. package/docs-site/en/permissions.html +5 -1
  62. package/docs-site/en/profiles.html +5 -1
  63. package/docs-site/en/quickstart.html +5 -1
  64. package/docs-site/en/runtime.html +18 -1
  65. package/docs-site/en/scope.html +5 -1
  66. package/docs-site/en/security.html +5 -1
  67. package/docs-site/en/team.html +5 -1
  68. package/docs-site/en/whats-new.html +5 -1
  69. package/docs-site/en/workflows.html +5 -1
  70. package/docs-site/index.html +54 -1
  71. package/docs-site/mcp-approval.html +5 -1
  72. package/docs-site/mcp-auth.html +5 -1
  73. package/docs-site/mcp-servers.html +5 -1
  74. package/docs-site/mcp.html +5 -1
  75. package/docs-site/permissions.html +5 -1
  76. package/docs-site/profiles.html +5 -1
  77. package/docs-site/quickstart.html +5 -1
  78. package/docs-site/runtime.html +33 -1
  79. package/docs-site/scope.html +5 -1
  80. package/docs-site/security.html +5 -1
  81. package/docs-site/team.html +5 -1
  82. package/docs-site/whats-new.html +5 -1
  83. package/docs-site/workflows.html +5 -1
  84. package/evals/fixtures/mutation-provenance-record.invalid.json +17 -0
  85. package/evals/fixtures/mutation-provenance-record.valid.json +27 -0
  86. package/evals/fixtures/piagent-webui/approval-v1.invalid.json +54 -0
  87. package/evals/fixtures/piagent-webui/approval-v1.valid.json +58 -0
  88. package/evals/fixtures/piagent-webui/attachment-v1.invalid.json +25 -0
  89. package/evals/fixtures/piagent-webui/attachment-v1.valid.json +25 -0
  90. package/evals/fixtures/piagent-webui/capabilities-v1.invalid.json +51 -0
  91. package/evals/fixtures/piagent-webui/capabilities-v1.valid.json +122 -0
  92. package/evals/fixtures/piagent-webui/commit-summary-v1.invalid.json +10 -0
  93. package/evals/fixtures/piagent-webui/commit-summary-v1.valid.json +25 -0
  94. package/evals/fixtures/piagent-webui/control-command-v1.invalid.json +37 -0
  95. package/evals/fixtures/piagent-webui/control-command-v1.valid.json +35 -0
  96. package/evals/fixtures/piagent-webui/diff-v1.invalid.json +13 -0
  97. package/evals/fixtures/piagent-webui/diff-v1.valid.json +141 -0
  98. package/evals/fixtures/piagent-webui/gateway-capabilities-v1.invalid.json +35 -0
  99. package/evals/fixtures/piagent-webui/gateway-capabilities-v1.valid.json +35 -0
  100. package/evals/fixtures/piagent-webui/gateway-protocol-v1.invalid.json +14 -0
  101. package/evals/fixtures/piagent-webui/gateway-protocol-v1.valid.json +14 -0
  102. package/evals/fixtures/piagent-webui/handoff-history-v1.invalid.json +16 -0
  103. package/evals/fixtures/piagent-webui/handoff-history-v1.valid.json +16 -0
  104. package/evals/fixtures/piagent-webui/model-catalog-v1.invalid.json +31 -0
  105. package/evals/fixtures/piagent-webui/model-catalog-v1.valid.json +43 -0
  106. package/evals/fixtures/piagent-webui/queue-v1.invalid.json +29 -0
  107. package/evals/fixtures/piagent-webui/queue-v1.valid.json +44 -0
  108. package/evals/fixtures/piagent-webui/recovery-history-v1.invalid.json +17 -0
  109. package/evals/fixtures/piagent-webui/recovery-history-v1.valid.json +20 -0
  110. package/evals/fixtures/piagent-webui/release-monitor-v1.invalid.json +12 -0
  111. package/evals/fixtures/piagent-webui/release-monitor-v1.valid.json +29 -0
  112. package/evals/fixtures/piagent-webui/review-state-v1.invalid.json +25 -0
  113. package/evals/fixtures/piagent-webui/review-state-v1.valid.json +38 -0
  114. package/evals/fixtures/piagent-webui/runtime-event-v2.invalid.json +49 -0
  115. package/evals/fixtures/piagent-webui/runtime-event-v2.valid.json +49 -0
  116. package/evals/fixtures/piagent-webui/session-catalog-v1.invalid.json +17 -0
  117. package/evals/fixtures/piagent-webui/session-catalog-v1.valid.json +58 -0
  118. package/evals/fixtures/piagent-webui/session-command-v1.invalid.json +19 -0
  119. package/evals/fixtures/piagent-webui/session-command-v1.valid.json +19 -0
  120. package/evals/fixtures/piagent-webui/snapshot-v1.invalid.json +5 -0
  121. package/evals/fixtures/piagent-webui/snapshot-v1.valid.json +191 -0
  122. package/evals/fixtures/piagent-webui/source-change-v1.invalid.json +57 -0
  123. package/evals/fixtures/piagent-webui/source-change-v1.valid.json +98 -0
  124. package/evals/fixtures/piagent-webui/source-mutation-v1.invalid.json +19 -0
  125. package/evals/fixtures/piagent-webui/source-mutation-v1.valid.json +38 -0
  126. package/evals/fixtures/piagent-webui/source-revert-v1.invalid.json +20 -0
  127. package/evals/fixtures/piagent-webui/source-revert-v1.valid.json +62 -0
  128. package/evals/fixtures/piagent-webui/subagent-tree-v1.invalid.json +26 -0
  129. package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +39 -0
  130. package/evals/fixtures/piagent-webui/task-index-v1.invalid.json +15 -0
  131. package/evals/fixtures/piagent-webui/task-index-v1.valid.json +15 -0
  132. package/evals/fixtures/piagent-webui/task-timeline-v1.invalid.json +14 -0
  133. package/evals/fixtures/piagent-webui/task-timeline-v1.valid.json +16 -0
  134. package/evals/fixtures/piagent-webui/transcript-v1.invalid.json +35 -0
  135. package/evals/fixtures/piagent-webui/transcript-v1.valid.json +55 -0
  136. package/evals/fixtures/task-baseline-manifest.invalid.json +16 -0
  137. package/evals/fixtures/task-baseline-manifest.valid.json +41 -0
  138. package/evals/fixtures/verifier-file-snapshot.invalid.json +21 -0
  139. package/evals/fixtures/verifier-file-snapshot.valid.json +21 -0
  140. package/package.json +43 -4
  141. package/packages/piagent-core/README.md +3 -2
  142. package/packages/piagent-core/benchmark/benchmark-candidate.d.ts +1 -0
  143. package/packages/piagent-core/benchmark/benchmark-forensics.d.ts +1 -0
  144. package/packages/piagent-core/benchmark/benchmark-ledger.d.ts +4 -0
  145. package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +1 -0
  146. package/packages/piagent-core/benchmark/benchmark-runtime.d.ts +1 -0
  147. package/packages/piagent-core/capabilities/capability-core.js +2 -2
  148. package/packages/piagent-core/capabilities/capability-verification-cache.js +17 -7
  149. package/packages/piagent-core/capabilities/runtime-integrity.js +190 -0
  150. package/packages/piagent-core/extensions/piagent-guard.ts +80 -272
  151. package/packages/piagent-core/extensions/redaction-core.d.ts +2 -0
  152. package/packages/piagent-core/extensions/runtime-evidence.js +12 -1
  153. package/packages/piagent-core/extensions/shell-reach.ts +250 -0
  154. package/packages/piagent-core/extensions/task-journal.js +30 -1
  155. package/packages/piagent-core/extensions/task-state.js +33 -36
  156. package/packages/piagent-core/mcp/mcp-command-actions.js +1 -1
  157. package/packages/piagent-core/mcp/mcp-server-catalog.js +139 -9
  158. package/packages/piagent-core/package.json +1 -1
  159. package/packages/piagent-core/runtime/hooks/session-start-hook.ts +2 -2
  160. package/packages/piagent-core/runtime/hooks/tool-call-hook.ts +12 -2
  161. package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +20 -19
  162. package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +13 -0
  163. package/packages/piagent-core/runtime/input/chat-images.ts +2 -2
  164. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +94 -0
  165. package/packages/piagent-core/runtime/inspection/approval-broker.ts +318 -0
  166. package/packages/piagent-core/runtime/inspection/commit-summary-projection.ts +59 -0
  167. package/packages/piagent-core/runtime/inspection/context-telemetry-inspection.ts +37 -0
  168. package/packages/piagent-core/runtime/inspection/criteria-links.ts +295 -0
  169. package/packages/piagent-core/runtime/inspection/diff-projection.ts +499 -0
  170. package/packages/piagent-core/runtime/inspection/git-filter-safety.ts +38 -0
  171. package/packages/piagent-core/runtime/inspection/git-numstat-adapter.ts +71 -0
  172. package/packages/piagent-core/runtime/inspection/git-status-adapter.ts +493 -0
  173. package/packages/piagent-core/runtime/inspection/git-tree-adapter.ts +108 -0
  174. package/packages/piagent-core/runtime/inspection/mcp-control.ts +10 -0
  175. package/packages/piagent-core/runtime/inspection/mutation-provenance-contract.ts +131 -0
  176. package/packages/piagent-core/runtime/inspection/mutation-provenance-recorder.ts +48 -0
  177. package/packages/piagent-core/runtime/inspection/mutation-provenance-store.ts +161 -0
  178. package/packages/piagent-core/runtime/inspection/project-runtime-inspection.ts +36 -0
  179. package/packages/piagent-core/runtime/inspection/review-state-contract.ts +108 -0
  180. package/packages/piagent-core/runtime/inspection/review-state-projection.ts +93 -0
  181. package/packages/piagent-core/runtime/inspection/review-state-store.ts +112 -0
  182. package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +262 -0
  183. package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +103 -0
  184. package/packages/piagent-core/runtime/inspection/source-change-projection.ts +471 -0
  185. package/packages/piagent-core/runtime/inspection/source-evidence-contract.ts +139 -0
  186. package/packages/piagent-core/runtime/inspection/source-evidence-store.ts +315 -0
  187. package/packages/piagent-core/runtime/inspection/source-handoff-store.ts +70 -0
  188. package/packages/piagent-core/runtime/inspection/source-inspection-plan.ts +34 -0
  189. package/packages/piagent-core/runtime/inspection/source-mutation-projection.ts +164 -0
  190. package/packages/piagent-core/runtime/inspection/source-mutation-store.ts +168 -0
  191. package/packages/piagent-core/runtime/inspection/source-open-target.ts +38 -0
  192. package/packages/piagent-core/runtime/inspection/source-revert-projection.ts +147 -0
  193. package/packages/piagent-core/runtime/inspection/task-baseline-start-capture.ts +22 -0
  194. package/packages/piagent-core/runtime/inspection/task-compaction-history.ts +160 -0
  195. package/packages/piagent-core/runtime/inspection/task-control-journal.ts +131 -0
  196. package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +95 -0
  197. package/packages/piagent-core/runtime/inspection/task-provenance-projection.ts +60 -0
  198. package/packages/piagent-core/runtime/inspection/task-recovery-timeline.ts +88 -0
  199. package/packages/piagent-core/runtime/inspection/task-run-index.ts +87 -0
  200. package/packages/piagent-core/runtime/inspection/task-source-projection.ts +401 -0
  201. package/packages/piagent-core/runtime/inspection/task-subagent-tree.ts +101 -0
  202. package/packages/piagent-core/runtime/inspection/text-diff.ts +60 -0
  203. package/packages/piagent-core/runtime/inspection/verifier-snapshot-contract.ts +114 -0
  204. package/packages/piagent-core/runtime/inspection/verifier-snapshot-store.ts +189 -0
  205. package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +320 -0
  206. package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +132 -0
  207. package/packages/piagent-core/runtime/inspection/workspace-source-projection.ts +96 -0
  208. package/packages/piagent-core/runtime/inspection/zero-turn-conformance.ts +175 -0
  209. package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +93 -6
  210. package/packages/piagent-core/runtime/policy/block-remedy.ts +139 -0
  211. package/packages/piagent-core/runtime/policy/source-index-transaction.ts +173 -0
  212. package/packages/piagent-core/runtime/policy/source-mutation-guard-binding.ts +42 -0
  213. package/packages/piagent-core/runtime/policy/source-mutation-guard.ts +184 -0
  214. package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +105 -0
  215. package/packages/piagent-core/runtime/product/activity-inspector-footer.ts +5 -3
  216. package/packages/piagent-core/runtime/product/activity-inspector.ts +85 -343
  217. package/packages/piagent-core/runtime/recovery/resume-state.ts +38 -1
  218. package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +68 -14
  219. package/packages/piagent-core/runtime/registration/task-start-tool.ts +22 -27
  220. package/packages/piagent-core/runtime/session/model-authorship-state.ts +31 -3
  221. package/packages/piagent-core/runtime/session/runtime-state.ts +11 -1
  222. package/packages/piagent-core/runtime/session/token-economics.js +34 -0
  223. package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +2 -1
  224. package/packages/piagent-core/runtime/workflows/task-intake.ts +5 -0
  225. package/packages/piagent-core/security/sensitive-data.js +7 -0
  226. package/packages/piagent-webui/dist/client/assets/index-DwKCWbwd.css +1 -0
  227. package/packages/piagent-webui/dist/client/assets/index-bu7XpD9Q.js +172 -0
  228. package/packages/piagent-webui/dist/client/index.html +16 -0
  229. package/packages/piagent-webui/extension/attachment-store.ts +323 -0
  230. package/packages/piagent-webui/extension/held-message-queue.ts +311 -0
  231. package/packages/piagent-webui/extension/lifecycle-controller.ts +423 -0
  232. package/packages/piagent-webui/extension/lifecycle-event-adapter.ts +23 -0
  233. package/packages/piagent-webui/extension/piagent-webui.ts +470 -0
  234. package/packages/piagent-webui/extension/review-controller.ts +160 -0
  235. package/packages/piagent-webui/extension/same-session-bridge.ts +500 -0
  236. package/packages/piagent-webui/extension/session-options-controller.ts +281 -0
  237. package/packages/piagent-webui/extension/session-stream-adapter.ts +249 -0
  238. package/packages/piagent-webui/extension/source-mutation-controller.ts +215 -0
  239. package/packages/piagent-webui/extension/source-open-controller.ts +136 -0
  240. package/packages/piagent-webui/extension/source-revert-controller.ts +189 -0
  241. package/packages/piagent-webui/extension/terminal-session-adapter.ts +73 -0
  242. package/packages/piagent-webui/extension/vscode-handoff.ts +51 -0
  243. package/packages/piagent-webui/gateway/control-socket.ts +92 -0
  244. package/packages/piagent-webui/gateway/extension-authority.ts +47 -0
  245. package/packages/piagent-webui/gateway/gateway-events.ts +60 -0
  246. package/packages/piagent-webui/gateway/gateway-protocol-service.ts +64 -0
  247. package/packages/piagent-webui/gateway/gateway-service.ts +215 -0
  248. package/packages/piagent-webui/gateway/gateway-session-stream.ts +110 -0
  249. package/packages/piagent-webui/gateway/mcp-auth-broker.ts +158 -0
  250. package/packages/piagent-webui/gateway/native-project-picker.ts +29 -0
  251. package/packages/piagent-webui/gateway/pi-host.ts +41 -0
  252. package/packages/piagent-webui/gateway/profile-state.ts +1 -0
  253. package/packages/piagent-webui/gateway/project-registry.ts +108 -0
  254. package/packages/piagent-webui/gateway/provider-auth-broker.ts +172 -0
  255. package/packages/piagent-webui/gateway/session-catalog.ts +128 -0
  256. package/packages/piagent-webui/gateway/session-command-controller.ts +237 -0
  257. package/packages/piagent-webui/gateway/session-command-store.ts +224 -0
  258. package/packages/piagent-webui/gateway/session-inspection-registry.ts +239 -0
  259. package/packages/piagent-webui/gateway/session-lease-store.ts +1 -0
  260. package/packages/piagent-webui/gateway/session-metadata-store.ts +152 -0
  261. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +489 -0
  262. package/packages/piagent-webui/ownership/gateway-runtime-context.ts +8 -0
  263. package/packages/piagent-webui/ownership/profile-state.ts +117 -0
  264. package/packages/piagent-webui/ownership/session-lease-store.ts +329 -0
  265. package/packages/piagent-webui/ownership/session-refs.ts +8 -0
  266. package/packages/piagent-webui/package.json +33 -0
  267. package/packages/piagent-webui/server/README.md +4 -0
  268. package/packages/piagent-webui/server/benchmark-release-monitor.ts +230 -0
  269. package/packages/piagent-webui/server/core-inspection-provider.ts +403 -0
  270. package/packages/piagent-webui/server/gateway-websocket.ts +143 -0
  271. package/packages/piagent-webui/server/http-security.ts +27 -0
  272. package/packages/piagent-webui/server/ipc-read-model-client.ts +89 -0
  273. package/packages/piagent-webui/server/loopback-server.ts +368 -0
  274. package/packages/piagent-webui/server/read-model-provider.ts +37 -0
  275. package/packages/piagent-webui/server/read-only-router.ts +105 -0
  276. package/packages/piagent-webui/server/session-auth.ts +88 -0
  277. package/packages/piagent-webui/server/sidecar-main.ts +86 -0
  278. package/packages/piagent-webui/server/sse-hub.ts +76 -0
  279. package/packages/piagent-webui/server/static-bundle.ts +40 -0
  280. package/packages/piagent-webui/server/transcript-projection.ts +125 -0
  281. package/schemas/mutation-provenance-record.schema.json +100 -0
  282. package/schemas/piagent-webui/approval-v1.schema.json +654 -0
  283. package/schemas/piagent-webui/attachment-v1.schema.json +267 -0
  284. package/schemas/piagent-webui/capabilities-v1.schema.json +729 -0
  285. package/schemas/piagent-webui/catalog-v1.json +240 -0
  286. package/schemas/piagent-webui/commit-summary-v1.schema.json +63 -0
  287. package/schemas/piagent-webui/common-v1.schema.json +479 -0
  288. package/schemas/piagent-webui/control-command-v1.schema.json +1780 -0
  289. package/schemas/piagent-webui/diff-v1.schema.json +826 -0
  290. package/schemas/piagent-webui/gateway-capabilities-v1.schema.json +136 -0
  291. package/schemas/piagent-webui/gateway-protocol-v1.schema.json +456 -0
  292. package/schemas/piagent-webui/handoff-history-v1.schema.json +92 -0
  293. package/schemas/piagent-webui/model-catalog-v1.schema.json +95 -0
  294. package/schemas/piagent-webui/queue-v1.schema.json +99 -0
  295. package/schemas/piagent-webui/recovery-history-v1.schema.json +144 -0
  296. package/schemas/piagent-webui/release-monitor-v1.schema.json +173 -0
  297. package/schemas/piagent-webui/review-state-v1.schema.json +206 -0
  298. package/schemas/piagent-webui/runtime-event-v2.schema.json +5206 -0
  299. package/schemas/piagent-webui/session-catalog-v1.schema.json +222 -0
  300. package/schemas/piagent-webui/session-command-v1.schema.json +390 -0
  301. package/schemas/piagent-webui/snapshot-v1.schema.json +2622 -0
  302. package/schemas/piagent-webui/source-change-v1.schema.json +763 -0
  303. package/schemas/piagent-webui/source-mutation-v1.schema.json +96 -0
  304. package/schemas/piagent-webui/source-revert-v1.schema.json +130 -0
  305. package/schemas/piagent-webui/subagent-tree-v1.schema.json +88 -0
  306. package/schemas/piagent-webui/task-index-v1.schema.json +74 -0
  307. package/schemas/piagent-webui/task-timeline-v1.schema.json +49 -0
  308. package/schemas/piagent-webui/transcript-v1.schema.json +243 -0
  309. package/schemas/task-baseline-manifest.schema.json +122 -0
  310. package/schemas/verifier-file-snapshot.schema.json +81 -0
  311. package/scripts/build-docs-site.mjs +21 -1
  312. package/scripts/check-architecture.mjs +1 -0
  313. package/scripts/check-doc-languages.mjs +19 -2
  314. package/scripts/check-third-party-neutrality.mjs +43 -0
  315. package/scripts/explain-command.mjs +240 -0
  316. package/scripts/install-global.sh +105 -4
  317. package/scripts/mcp-manage.mjs +17 -4
  318. package/scripts/pi-session-stats.sh +10 -2
  319. package/scripts/piagent-cli.mjs +30 -3
  320. package/scripts/piagent-dashboard.mjs +261 -0
  321. package/scripts/piagent-webui-launcher.mjs +121 -0
  322. package/scripts/setup.sh +69 -33
  323. package/scripts/traffic-snapshot.mjs +214 -0
  324. package/scripts/typescript-loader.mjs +42 -1
  325. package/scripts/uninstall-global.sh +53 -2
  326. package/scripts/update-global.mjs +33 -1
  327. package/scripts/verify-local.sh +257 -0
  328. package/scripts/verify-release-identity.mjs +4 -1
  329. package/scripts/verify-translation-pairing.mjs +121 -0
@@ -0,0 +1,16 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "piagent-webui-task-timeline-v1",
4
+ "generatedAt": "2026-08-14T11:00:00.000Z",
5
+ "identity": { "projectRef": "project.fixture", "runtimeInstanceId": "runtime.fixture", "sessionRef": "session.fixture", "taskId": "task-active", "taskRunId": "task-active-run", "agentOperationId": null, "toolCallId": null },
6
+ "runRef": "run.fixture",
7
+ "state": "ready",
8
+ "timelineRevision": "timeline.fixture",
9
+ "continuity": { "crashEvidence": "unknown", "recoveryDecision": "paused", "latestCheckpointRef": "checkpoint.fixture", "reasonCode": "no-explicit-crash-evidence" },
10
+ "events": [
11
+ { "eventRef": "event.fixture", "evidenceRef": "journal.fixture", "sequence": 1, "recordedAt": "2026-08-14T10:00:00.000Z", "kind": "checkpoint", "state": "observed", "title": "Checkpoint paused", "detail": "verify · paused", "checkpointRef": "checkpoint.fixture" }
12
+ ],
13
+ "page": { "total": 1, "returned": 1, "truncated": false },
14
+ "warnings": [{ "code": "crash-not-observed", "count": 1, "message": "No explicit crash fact was recorded." }],
15
+ "health": { "state": "degraded", "reasonCode": "timeline-warning", "message": "Some continuity facts remain unknown." }
16
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "piagent-webui-transcript-v1",
4
+ "generatedAt": "2026-08-13T14:00:00.000Z",
5
+ "identity": {
6
+ "projectRef": "project_01",
7
+ "runtimeInstanceId": "runtime_01",
8
+ "sessionRef": "session_01",
9
+ "taskId": null,
10
+ "taskRunId": null,
11
+ "agentOperationId": "operation_smuggled",
12
+ "toolCallId": null
13
+ },
14
+ "revision": {
15
+ "runtimeRevision": "runtime_rev_01",
16
+ "taskRevision": null,
17
+ "controlRevision": null,
18
+ "workspaceRevision": null,
19
+ "indexRevision": null,
20
+ "approvalRevision": null,
21
+ "sessionOptionRevision": null,
22
+ "queueRevision": null
23
+ },
24
+ "eventCursor": "cursor_01",
25
+ "state": "unavailable",
26
+ "items": [{ "rawSessionMessage": "secret" }],
27
+ "page": {
28
+ "beforeCursor": null,
29
+ "nextBeforeCursor": "cursor_invented",
30
+ "hasOlder": false,
31
+ "limit": 50,
32
+ "truncated": false
33
+ },
34
+ "reasonCode": null
35
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "piagent-webui-transcript-v1",
4
+ "generatedAt": "2026-08-13T14:00:00.000Z",
5
+ "identity": {
6
+ "projectRef": "project_01",
7
+ "runtimeInstanceId": "runtime_01",
8
+ "sessionRef": "session_01",
9
+ "taskId": null,
10
+ "taskRunId": null,
11
+ "agentOperationId": null,
12
+ "toolCallId": null
13
+ },
14
+ "revision": {
15
+ "runtimeRevision": "runtime_rev_01",
16
+ "taskRevision": null,
17
+ "controlRevision": null,
18
+ "workspaceRevision": null,
19
+ "indexRevision": null,
20
+ "approvalRevision": null,
21
+ "sessionOptionRevision": null,
22
+ "queueRevision": "queue_rev_01"
23
+ },
24
+ "eventCursor": "cursor_01",
25
+ "state": "ready",
26
+ "items": [
27
+ {
28
+ "messageRef": "message_01",
29
+ "parentMessageRef": null,
30
+ "role": "user",
31
+ "recordedAt": "2026-08-13T13:59:59.000Z",
32
+ "agentOperationId": "operation_01",
33
+ "turnIndex": 0,
34
+ "content": {
35
+ "state": "available",
36
+ "text": "Continue the current task.",
37
+ "textChars": 26,
38
+ "digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
39
+ "truncated": false,
40
+ "redacted": false,
41
+ "imageCount": 0,
42
+ "reasonCode": null
43
+ },
44
+ "toolCalls": []
45
+ }
46
+ ],
47
+ "page": {
48
+ "beforeCursor": null,
49
+ "nextBeforeCursor": null,
50
+ "hasOlder": false,
51
+ "limit": 50,
52
+ "truncated": false
53
+ },
54
+ "reasonCode": null
55
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "piagent-task-baseline-manifest-v1",
4
+ "taskId": "task-01",
5
+ "taskRunId": "task-01-run-1",
6
+ "sessionIdentityHash": "raw-session-id",
7
+ "capturedAt": "2026-08-13",
8
+ "retentionUntil": "2026-09-12",
9
+ "baselineDigestAlgorithm": "sha1",
10
+ "baselineTreeDigest": "unknown",
11
+ "captureState": "current",
12
+ "reasonCode": "invented-current-error",
13
+ "limits": { "maxEntries": 3000, "maxFileBytes": 0, "maxTotalBytes": 0, "capturedBytes": -1 },
14
+ "roots": [],
15
+ "integrityDigest": "not-a-digest"
16
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "piagent-task-baseline-manifest-v1",
4
+ "taskId": "task-01",
5
+ "taskRunId": "task-01-run-1",
6
+ "sessionIdentityHash": "sha256:1111111111111111111111111111111111111111111111111111111111111111",
7
+ "capturedAt": "2026-08-13T12:00:00.000Z",
8
+ "retentionUntil": "2026-09-12T12:00:00.000Z",
9
+ "baselineDigestAlgorithm": "wt-content-v2",
10
+ "baselineTreeDigest": "wt-content-v2:2222222222222222222222222222222222222222222222222222222222222222",
11
+ "captureState": "current",
12
+ "reasonCode": null,
13
+ "limits": { "maxEntries": 2000, "maxFileBytes": 4194304, "maxTotalBytes": 67108864, "capturedBytes": 5 },
14
+ "roots": [
15
+ {
16
+ "repoRef": "repo.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
17
+ "projectPath": ".",
18
+ "headState": "head",
19
+ "headOid": "3333333333333333333333333333333333333333",
20
+ "workspaceRevision": "workspace.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
21
+ "indexRevision": "index.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
22
+ "state": "current",
23
+ "reasonCode": null,
24
+ "entries": [
25
+ {
26
+ "pathRef": "path.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
27
+ "pathDigest": "sha256:4444444444444444444444444444444444444444444444444444444444444444",
28
+ "repoPathBase64": "YS50eHQ",
29
+ "state": "blob",
30
+ "reasonCode": null,
31
+ "contentRef": "sha256:5555555555555555555555555555555555555555555555555555555555555555",
32
+ "byteLength": 5,
33
+ "mode": "100644",
34
+ "headObject": "6666666666666666666666666666666666666666",
35
+ "indexObject": "7777777777777777777777777777777777777777"
36
+ }
37
+ ]
38
+ }
39
+ ],
40
+ "integrityDigest": "sha256:19a3c69ef5e5abeeb505725d52b481744c60d3fec4bd8c46ec19a4800f64e59d"
41
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "piagent-verifier-file-snapshot-v1",
4
+ "attemptId": "verifier.invalid",
5
+ "attemptRef": "verifier-evidence.invalid",
6
+ "taskId": "task-01",
7
+ "taskRunId": "task-01-run-01",
8
+ "sessionIdentityHash": "raw-session",
9
+ "toolCallIdentityHash": "raw-tool",
10
+ "commandDigest": "raw-command",
11
+ "observedAt": "invalid",
12
+ "capturedAt": "invalid",
13
+ "retentionUntil": "invalid",
14
+ "exitCode": 1,
15
+ "outcome": "passed",
16
+ "treeDigest": "unknown",
17
+ "fileCount": 1,
18
+ "exposedPathCount": 1,
19
+ "files": [],
20
+ "integrityDigest": "sha256:0000000000000000000000000000000000000000000000000000000000000000"
21
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "piagent-verifier-file-snapshot-v1",
4
+ "attemptId": "verifier.165224a1269311b35faa7c68a3285dec225f563a761d8984b3f0e5525a3837d9",
5
+ "attemptRef": "verifier-evidence.165224a1269311b35faa7c68a3285dec225f563a761d8984b3f0e5525a3837d9",
6
+ "taskId": "task-01",
7
+ "taskRunId": "task-01-run-01",
8
+ "sessionIdentityHash": "sha256:6e165fadbb274b7254278eadb81c25aaa7fda6b62c3f2c6f8ca393b34f90834e",
9
+ "toolCallIdentityHash": "sha256:4dd7feedf5ee29f32ee3a58080756f540d67d815fb658d836f77d959b6c33c49",
10
+ "commandDigest": "sha256:328e123c63857fd8473bd4bd3581e655b08b7440d7f5d2c31cc375607582f539",
11
+ "observedAt": "2026-08-13T16:00:00.000Z",
12
+ "capturedAt": "2026-08-13T16:00:01.000Z",
13
+ "retentionUntil": "2026-09-12T16:00:01.000Z",
14
+ "exitCode": 0,
15
+ "outcome": "passed",
16
+ "treeDigest": "wt-content-v2:19d7d78c84028ca50754225c92b10733bc8a5bf2fe4dbf89042aa14352159f46",
17
+ "fileCount": 0,
18
+ "exposedPathCount": 0,
19
+ "files": [],
20
+ "integrityDigest": "sha256:afcb27f99d5ba2c52410075f4c42a3bb00209354df9edb8349ee463579e1fc66"
21
+ }
package/package.json CHANGED
@@ -1,19 +1,30 @@
1
1
  {
2
2
  "name": "@piagent/platform",
3
- "version": "1.3.1",
3
+ "version": "1.4.1",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "provenance": true
8
8
  },
9
9
  "type": "module",
10
- "description": "Reusable Pi agent platform, project adapters, MCP/tool policy, and coding workflow harness.",
10
+ "description": "Guardrails for AI coding agents: blocks secret reads, destructive commands, and unapproved MCP servers before the tool call runs. Ships project profiles, capability locks, a context engine, and task verification.",
11
11
  "homepage": "https://piagent.io.vn",
12
12
  "repository": {
13
13
  "type": "git",
14
14
  "url": "git+https://github.com/Vt-mmm/piagent.git"
15
15
  },
16
16
  "keywords": [
17
+ "ai-agent",
18
+ "coding-agent",
19
+ "agent-guardrails",
20
+ "agent-security",
21
+ "llm-tool-policy",
22
+ "prompt-injection",
23
+ "mcp",
24
+ "mcp-security",
25
+ "secret-redaction",
26
+ "context-engineering",
27
+ "developer-tools",
17
28
  "pi-package",
18
29
  "pi-extension",
19
30
  "pi-skill",
@@ -43,12 +54,20 @@
43
54
  "packs/",
44
55
  "packages/piagent-core/",
45
56
  "!packages/piagent-core/extensions/core-services.js",
57
+ "packages/piagent-webui/package.json",
58
+ "packages/piagent-webui/server/",
59
+ "packages/piagent-webui/extension/",
60
+ "packages/piagent-webui/gateway/",
61
+ "packages/piagent-webui/ownership/",
62
+ "packages/piagent-webui/dist/client/",
46
63
  "schemas/",
47
64
  "scripts/",
48
65
  "templates/",
49
66
  "types/"
50
67
  ],
51
68
  "bin": {
69
+ "piagent": "scripts/piagent-cli.mjs",
70
+ "piagent-dashboard": "scripts/piagent-cli.mjs",
52
71
  "piagent-setup": "scripts/piagent-cli.mjs",
53
72
  "piagent-install": "scripts/piagent-cli.mjs",
54
73
  "piagent-update": "scripts/piagent-cli.mjs",
@@ -66,11 +85,14 @@
66
85
  "piagent-migrate": "scripts/piagent-cli.mjs",
67
86
  "piagent-import-instructions": "scripts/piagent-cli.mjs",
68
87
  "piagent-auto": "scripts/piagent-cli.mjs",
69
- "piagent-context": "scripts/piagent-cli.mjs"
88
+ "piagent-context": "scripts/piagent-cli.mjs",
89
+ "piagent-explain": "scripts/piagent-cli.mjs",
90
+ "piagent-webui": "scripts/piagent-cli.mjs"
70
91
  },
71
92
  "pi": {
72
93
  "extensions": [
73
- "packages/piagent-core/extensions/piagent-guard.ts"
94
+ "packages/piagent-core/extensions/piagent-guard.ts",
95
+ "packages/piagent-webui/extension/piagent-webui.ts"
74
96
  ],
75
97
  "skills": [
76
98
  "packages/piagent-core/skills"
@@ -84,6 +106,13 @@
84
106
  ]
85
107
  }
86
108
  },
109
+ "piagent": {
110
+ "runtimeIntegrityEntrypoints": [
111
+ "packages/piagent-webui/server/sidecar-main.ts",
112
+ "scripts/register-typescript-loader.mjs",
113
+ "scripts/typescript-loader.mjs"
114
+ ]
115
+ },
87
116
  "peerDependencies": {
88
117
  "@earendil-works/pi-ai": "0.84.1",
89
118
  "@earendil-works/pi-coding-agent": "0.84.1",
@@ -100,8 +129,16 @@
100
129
  "optional": true
101
130
  }
102
131
  },
132
+ "dependencies": {
133
+ "ws": "8.21.3"
134
+ },
103
135
  "devDependencies": {
136
+ "@axe-core/playwright": "4.13.0",
137
+ "@playwright/test": "1.62.1",
104
138
  "@types/node": "^26.1.1",
139
+ "@types/ws": "8.18.1",
140
+ "ajv": "^8.20.0",
141
+ "ajv-formats": "^3.0.1",
105
142
  "typescript": "^7.0.2"
106
143
  },
107
144
  "workspaces": [
@@ -110,6 +147,7 @@
110
147
  "scripts": {
111
148
  "verify": "bash scripts/verify-local.sh",
112
149
  "test": "PIAGENT_NO_UPDATE_CHECK=1 node --test tests/*.test.mjs",
150
+ "test:webui:e2e": "playwright test --config playwright.webui.config.mjs",
113
151
  "test:policy": "node --test tests/policy-core.test.mjs",
114
152
  "test:golden": "node --test tests/golden-enforcement.test.mjs",
115
153
  "typecheck": "tsc --noEmit",
@@ -129,6 +167,7 @@
129
167
  "site:check": "node scripts/check-published-site.mjs",
130
168
  "architecture:check": "node scripts/check-architecture.mjs",
131
169
  "docs:check": "node scripts/check-doc-languages.mjs",
170
+ "docs:neutrality": "node scripts/check-third-party-neutrality.mjs",
132
171
  "smoke": "bash scripts/runtime-policy-smoke.sh",
133
172
  "usage": "bash scripts/pi-session-stats.sh",
134
173
  "auto": "bash scripts/pi-auto.sh",
@@ -179,8 +179,9 @@ Project-local state belongs in `.pi/.gitignore`.
179
179
  Task files use schema v2 and bind one unique `taskRunId` to one Pi `sessionId`.
180
180
  They record attempt/max-attempt history, dependency-safe work-plan progress,
181
181
  Git baseline/final digests, observed changes, all exact verify results and final
182
- trace. A terminal task is immutable; retry starts in a fresh session and carries
183
- the prior failure/ruled-out evidence. Legacy v1 state is migrated and archived
182
+ trace. A terminal task is immutable; the same conversation may bind a new task
183
+ or retry attempt after the prior task closes, while keeping only one task pending
184
+ at a time and carrying prior failure/ruled-out evidence. Legacy v1 state is migrated and archived
184
185
  without requiring project onboarding again.
185
186
 
186
187
  Local state directories are owner-only. Task state, context telemetry, trace,
@@ -0,0 +1 @@
1
+ export function validBenchmarkCandidateProvenance(value: unknown): boolean;
@@ -0,0 +1 @@
1
+ export function benchmarkCandidateProvenance(root: string): Record<string, unknown>;
@@ -0,0 +1,4 @@
1
+ export type BenchmarkLedgerBinding = { schemaVersion: 1; algorithm: string; digest: string; records: number; bytes: number };
2
+ export function inspectBenchmarkLedger(file: string): { binding: BenchmarkLedgerBinding; records: unknown[]; raw: Buffer };
3
+ export function assertBenchmarkLedgerBinding(expected: unknown, observed: unknown, label?: string): BenchmarkLedgerBinding;
4
+ export function validateBenchmarkLedgerPrefix(records: unknown[], order: unknown[], completedRecord: (record: unknown) => boolean): Set<string>;
@@ -0,0 +1 @@
1
+ export function completedBenchmarkRecord(record: unknown): boolean;
@@ -0,0 +1 @@
1
+ export function benchmarkGitEnvironment(): NodeJS.ProcessEnv;
@@ -3,7 +3,7 @@ import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { containsSensitiveText } from "../security/sensitive-data.js";
5
5
  import { resolveProjectProfileDocument } from "./project-profile.js";
6
- import { CORE_RUNTIME_INTEGRITY_FILES } from "./runtime-integrity.js";
6
+ import { discoverRuntimeIntegrityFiles } from "./runtime-integrity.js";
7
7
 
8
8
  const API_VERSION = "piagent/v1";
9
9
  const CORE_API_VERSION = 1;
@@ -798,7 +798,7 @@ function buildCoreIntegrity(root) {
798
798
  "packages/piagent-core/capabilities/project-profile.js",
799
799
  "packages/piagent-core/security/sensitive-data.js",
800
800
  "packages/piagent-core/extensions/piagent-guard.ts",
801
- ...CORE_RUNTIME_INTEGRITY_FILES,
801
+ ...discoverRuntimeIntegrityFiles(root),
802
802
  // context-engine.js decides which repository content enters the model
803
803
  // context and records the resulting telemetry, so it is part of the
804
804
  // runtime trust boundary enforced by the profile lock.
@@ -148,12 +148,21 @@ function lexicalAncestors(target) {
148
148
  return ancestors;
149
149
  }
150
150
 
151
- function metadataSignature(targets) {
151
+ // The directories above every target, sorted, derived once per snapshot. The
152
+ // set is a pure function of the target list, and a cached entry's target list
153
+ // cannot change while the entry lives, so deriving it per call was repeating
154
+ // work that could not produce a different answer -- and at 296 pinned files it
155
+ // was the single most expensive part of a cache hit, more than every `lstat`
156
+ // this function performs put together.
157
+ function ancestorPaths(targets) {
158
+ return [...new Set(targets.flatMap((target) => lexicalAncestors(target.path)))].sort(compare);
159
+ }
160
+
161
+ function metadataSignature(targets, ancestors) {
152
162
  if (!targets) return undefined;
153
163
  const records = [];
154
- const ancestors = new Set(targets.flatMap((target) => lexicalAncestors(target.path)));
155
164
  try {
156
- for (const ancestor of [...ancestors].sort(compare)) {
165
+ for (const ancestor of ancestors ?? ancestorPaths(targets)) {
157
166
  const stat = fs.lstatSync(ancestor, { bigint: true });
158
167
  const symbolic = stat.isSymbolicLink();
159
168
  const identity = symbolic ? statIdentity(stat, true) : ancestorIdentity(stat);
@@ -194,13 +203,14 @@ function cacheIdentity(lockDocument, options = {}) {
194
203
  }
195
204
 
196
205
  function snapshotTargets(targets) {
197
- const signature = metadataSignature(targets);
198
- return signature ? { signature, targets } : undefined;
206
+ const ancestors = ancestorPaths(targets);
207
+ const signature = metadataSignature(targets, ancestors);
208
+ return signature ? { signature, targets, ancestors } : undefined;
199
209
  }
200
210
 
201
211
  function stableSnapshot(snapshot) {
202
212
  if (!snapshot) return false;
203
- const current = metadataSignature(snapshot.targets);
213
+ const current = metadataSignature(snapshot.targets, snapshot.ancestors);
204
214
  return Boolean(current && current === snapshot.signature);
205
215
  }
206
216
 
@@ -209,7 +219,7 @@ export function verifyCapabilityLockCached(cache, root, profilePath, lockPath, l
209
219
  const identity = cacheIdentity(lockDocument, options);
210
220
  const cached = options.forceFull === true ? undefined : cache?.get(key);
211
221
  if (cached?.identity === identity) {
212
- const signature = metadataSignature(cached.targets);
222
+ const signature = metadataSignature(cached.targets, cached.ancestors);
213
223
  if (signature && signature === cached.signature) return { ...cached.verification, cacheStatus: "hit" };
214
224
  }
215
225
  cache?.delete(key);
@@ -1,3 +1,6 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
1
4
  export const CORE_RUNTIME_INTEGRITY_FILES = Object.freeze([
2
5
  "packages/piagent-core/runtime/context/adaptive-planner.ts",
3
6
  "packages/piagent-core/runtime/context/retrieval-route-policy.ts",
@@ -31,7 +34,53 @@ export const CORE_RUNTIME_INTEGRITY_FILES = Object.freeze([
31
34
  "packages/piagent-core/runtime/hooks/session-start-hook.ts",
32
35
  "packages/piagent-core/runtime/hooks/tool-call-hook.ts",
33
36
  "packages/piagent-core/runtime/hooks/tool-result-hook.ts",
37
+ "packages/piagent-core/runtime/hooks/tool-result-metadata.ts",
34
38
  "packages/piagent-core/runtime/input/chat-images.ts",
39
+ "packages/piagent-core/runtime/inspection/activity-event-adapter.ts",
40
+ "packages/piagent-core/runtime/inspection/approval-broker.ts",
41
+ "packages/piagent-core/runtime/inspection/criteria-links.ts",
42
+ "packages/piagent-core/runtime/inspection/commit-summary-projection.ts",
43
+ "packages/piagent-core/runtime/inspection/diff-projection.ts",
44
+ "packages/piagent-core/runtime/inspection/git-numstat-adapter.ts",
45
+ "packages/piagent-core/runtime/inspection/git-filter-safety.ts",
46
+ "packages/piagent-core/runtime/inspection/git-status-adapter.ts",
47
+ "packages/piagent-core/runtime/inspection/git-tree-adapter.ts",
48
+ "packages/piagent-core/runtime/inspection/mcp-control.ts",
49
+ "packages/piagent-core/runtime/inspection/mutation-provenance-contract.ts",
50
+ "packages/piagent-core/runtime/inspection/mutation-provenance-recorder.ts",
51
+ "packages/piagent-core/runtime/inspection/mutation-provenance-store.ts",
52
+ "packages/piagent-core/runtime/inspection/project-runtime-inspection.ts",
53
+ "packages/piagent-core/runtime/inspection/review-state-contract.ts",
54
+ "packages/piagent-core/runtime/inspection/review-state-projection.ts",
55
+ "packages/piagent-core/runtime/inspection/review-state-store.ts",
56
+ "packages/piagent-core/runtime/inspection/runtime-event-store.ts",
57
+ "packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts",
58
+ "packages/piagent-core/runtime/inspection/zero-turn-conformance.ts",
59
+ "packages/piagent-core/runtime/inspection/source-evidence-contract.ts",
60
+ "packages/piagent-core/runtime/inspection/source-evidence-store.ts",
61
+ "packages/piagent-core/runtime/inspection/source-inspection-plan.ts",
62
+ "packages/piagent-core/runtime/inspection/source-mutation-projection.ts",
63
+ "packages/piagent-core/runtime/inspection/source-mutation-store.ts",
64
+ "packages/piagent-core/runtime/inspection/source-revert-projection.ts",
65
+ "packages/piagent-core/runtime/inspection/source-handoff-store.ts",
66
+ "packages/piagent-core/runtime/inspection/source-open-target.ts",
67
+ "packages/piagent-core/runtime/inspection/task-run-index.ts",
68
+ "packages/piagent-core/runtime/inspection/task-recovery-timeline.ts",
69
+ "packages/piagent-core/runtime/inspection/task-compaction-history.ts",
70
+ "packages/piagent-core/runtime/inspection/context-telemetry-inspection.ts",
71
+ "packages/piagent-core/runtime/inspection/task-handoff-history.ts",
72
+ "packages/piagent-core/runtime/inspection/task-subagent-tree.ts",
73
+ "packages/piagent-core/runtime/inspection/task-baseline-start-capture.ts",
74
+ "packages/piagent-core/runtime/inspection/task-control-journal.ts",
75
+ "packages/piagent-core/runtime/inspection/task-source-projection.ts",
76
+ "packages/piagent-core/runtime/inspection/task-provenance-projection.ts",
77
+ "packages/piagent-core/runtime/inspection/verifier-snapshot-contract.ts",
78
+ "packages/piagent-core/runtime/inspection/verifier-snapshot-store.ts",
79
+ "packages/piagent-core/runtime/inspection/webui-snapshot.ts",
80
+ "packages/piagent-core/runtime/inspection/text-diff.ts",
81
+ "packages/piagent-core/runtime/inspection/source-change-projection.ts",
82
+ "packages/piagent-core/runtime/inspection/workspace-file-reader.ts",
83
+ "packages/piagent-core/runtime/inspection/workspace-source-projection.ts",
35
84
  "packages/piagent-core/runtime/model/capabilities.ts",
36
85
  "packages/piagent-core/runtime/model/authenticated-catalog.ts",
37
86
  "packages/piagent-core/runtime/model/model-route-policy.ts",
@@ -42,6 +91,10 @@ export const CORE_RUNTIME_INTEGRITY_FILES = Object.freeze([
42
91
  "packages/piagent-core/runtime/model/snapshot-telemetry.ts",
43
92
  "packages/piagent-core/runtime/policy/authority-manifest.ts",
44
93
  "packages/piagent-core/runtime/policy/authority-resume-policy.ts",
94
+ "packages/piagent-core/runtime/policy/source-index-transaction.ts",
95
+ "packages/piagent-core/runtime/policy/source-mutation-guard-binding.ts",
96
+ "packages/piagent-core/runtime/policy/source-mutation-guard.ts",
97
+ "packages/piagent-core/runtime/policy/source-worktree-transaction.ts",
45
98
  "packages/piagent-core/runtime/policy/task-authority-runtime.ts",
46
99
  "packages/piagent-core/runtime/orchestration/role-policy.ts",
47
100
  "packages/piagent-core/runtime/orchestration/role-binder.ts",
@@ -106,3 +159,140 @@ export const CORE_RUNTIME_INTEGRITY_FILES = Object.freeze([
106
159
  "scripts/register-typescript-loader.mjs",
107
160
  "scripts/typescript-loader.mjs"
108
161
  ]);
162
+
163
+ const EXECUTABLE_SOURCE = /\.(?:[cm]?js|ts|json|sh)$/;
164
+ const IMPORT_SPECIFIER = /(?:\bimport\s*(?:type\s+)?(?:[^"'`]*?\s+from\s*)?|\bexport\s+(?:type\s+)?[^"'`]*?\s+from\s*)["']([^"']+)["']/g;
165
+ const DYNAMIC_IMPORT = /\bimport\(\s*["']([^"']+)["']\s*\)/g;
166
+ const RUNTIME_LITERAL = /["']((?:packages|scripts)\/[A-Za-z0-9_./-]+\.(?:[cm]?js|ts|json|sh))["']/g;
167
+ // A shell entrypoint reaches a sibling program through the directory it computed
168
+ // for itself -- `"$SCRIPT_DIR/pi-usage-history.mjs"` -- so the repository-relative
169
+ // literal the scanner above looks for never appears in the source. `piagent-usage`
170
+ // is a pinned command that ran a 567-line unpinned program this way.
171
+ const SHELL_SIBLING = /\$(?:\{)?(?:SCRIPT_DIR|ROOT|REPO_ROOT|PLATFORM_ROOT)(?:\})?\/([A-Za-z0-9_./-]+\.(?:[cm]?js|ts|json|sh))/g;
172
+ const MAX_INTEGRITY_FILES = 5_000;
173
+
174
+ function normalizedRelative(root, absolute) {
175
+ const relative = path.relative(root, absolute);
176
+ if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) return undefined;
177
+ return relative.split(path.sep).join("/");
178
+ }
179
+
180
+ // A served bundle is more than its scripts: the document names which script runs,
181
+ // so pinning the JavaScript while leaving the HTML free would leave the choice of
182
+ // program unpinned.
183
+ const SERVED_BUNDLE_ASSET = /\.(?:[cm]?js|css|html|json|svg|woff2)$/;
184
+
185
+ function bundleFilesBelow(root, relativeDirectory) {
186
+ return executableFilesBelow(root, relativeDirectory, SERVED_BUNDLE_ASSET);
187
+ }
188
+
189
+ function executableFilesBelow(root, relativeDirectory, accept = EXECUTABLE_SOURCE) {
190
+ const directory = path.join(root, relativeDirectory);
191
+ if (!fs.existsSync(directory)) return [];
192
+ const files = [];
193
+ const visit = (absolute) => {
194
+ const entries = fs.readdirSync(absolute, { withFileTypes: true });
195
+ for (const entry of entries) {
196
+ const target = path.join(absolute, entry.name), stat = fs.lstatSync(target);
197
+ if (stat.isSymbolicLink()) throw new Error(`runtime-integrity-symlink:${normalizedRelative(root, target) ?? "outside-root"}`);
198
+ if (stat.isDirectory()) visit(target);
199
+ else if (stat.isFile() && accept.test(entry.name)) files.push(normalizedRelative(root, target));
200
+ }
201
+ };
202
+ visit(directory);
203
+ return files.filter(Boolean);
204
+ }
205
+
206
+ function localImportTarget(root, importer, specifier) {
207
+ if (!specifier.startsWith(".")) return undefined;
208
+ const base = path.resolve(path.dirname(path.join(root, importer)), specifier);
209
+ // TypeScript sources import a sibling module by its emitted name, so `./x.js`
210
+ // is how a `.ts` file refers to `x.ts`. Without that rewrite the specifier
211
+ // resolves to nothing and the reference is dropped in silence -- a module
212
+ // that decides what the guard enforces would then sit outside the lock while
213
+ // this list still claimed to cover the whole import graph.
214
+ const rewritten = base.endsWith(".js") ? [`${base.slice(0, -3)}.ts`] : [];
215
+ const candidates = [base, ...rewritten, `${base}.ts`, `${base}.js`, `${base}.mjs`, path.join(base, "index.ts"), path.join(base, "index.js")];
216
+ for (const candidate of candidates) {
217
+ const relative = normalizedRelative(root, candidate);
218
+ if (!relative || !fs.existsSync(candidate)) continue;
219
+ const stat = fs.lstatSync(candidate);
220
+ if (stat.isSymbolicLink()) throw new Error(`runtime-integrity-symlink:${relative}`);
221
+ if (stat.isFile() && EXECUTABLE_SOURCE.test(candidate)) return relative;
222
+ }
223
+ return undefined;
224
+ }
225
+
226
+ function sourceReferences(root, relativeFile) {
227
+ // Shell entrypoints are scanned too. They were skipped here, so a pinned
228
+ // command could execute an unpinned program and the lock reported a complete
229
+ // graph while missing it.
230
+ const shell = relativeFile.endsWith(".sh");
231
+ if (!shell && !/\.(?:[cm]?js|ts)$/.test(relativeFile)) return [];
232
+ const source = fs.readFileSync(path.join(root, relativeFile), "utf8"), references = new Set();
233
+ if (shell) {
234
+ const directory = path.posix.dirname(relativeFile);
235
+ for (const pattern of [RUNTIME_LITERAL, SHELL_SIBLING]) {
236
+ pattern.lastIndex = 0;
237
+ for (let match = pattern.exec(source); match; match = pattern.exec(source)) {
238
+ const candidate = pattern === SHELL_SIBLING ? path.posix.join(directory, match[1]) : match[1];
239
+ const absolute = path.join(root, candidate), relative = normalizedRelative(root, absolute);
240
+ if (relative && fs.existsSync(absolute) && fs.lstatSync(absolute).isFile()) references.add(relative);
241
+ }
242
+ }
243
+ return [...references];
244
+ }
245
+ for (const pattern of [IMPORT_SPECIFIER, DYNAMIC_IMPORT]) {
246
+ pattern.lastIndex = 0;
247
+ for (let match = pattern.exec(source); match; match = pattern.exec(source)) {
248
+ const target = localImportTarget(root, relativeFile, match[1]);
249
+ if (target) references.add(target);
250
+ }
251
+ }
252
+ RUNTIME_LITERAL.lastIndex = 0;
253
+ for (let match = RUNTIME_LITERAL.exec(source); match; match = RUNTIME_LITERAL.exec(source)) {
254
+ const target = path.join(root, match[1]), relative = normalizedRelative(root, target);
255
+ if (relative && fs.existsSync(target) && fs.lstatSync(target).isFile()) references.add(relative);
256
+ }
257
+ return [...references];
258
+ }
259
+
260
+ export function discoverRuntimeIntegrityFiles(root) {
261
+ const packageDocument = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
262
+ const declaredExtensions = Array.isArray(packageDocument.pi?.extensions) ? packageDocument.pi.extensions : [];
263
+ const declaredBins = packageDocument.bin && typeof packageDocument.bin === "object" ? Object.values(packageDocument.bin) : [];
264
+ const declaredEntrypoints = Array.isArray(packageDocument.piagent?.runtimeIntegrityEntrypoints)
265
+ ? packageDocument.piagent.runtimeIntegrityEntrypoints : [];
266
+ const seeds = new Set([
267
+ ...CORE_RUNTIME_INTEGRITY_FILES,
268
+ "packages/piagent-core/extensions/piagent-guard.ts",
269
+ ...executableFilesBelow(root, "packages/piagent-core/runtime"),
270
+ // The browser bundle the WebUI serves. The published package ships the built
271
+ // assets and not the sources they came from, so on an installed platform
272
+ // this code cannot be regenerated or cross-checked against anything -- and it
273
+ // runs inside the origin that holds the session cookie and the CSRF token,
274
+ // with the authority to drive session commands, source mutation and provider
275
+ // auth. The server that serves it was pinned; what it serves was not.
276
+ //
277
+ // The tree is absent in a source checkout until the workspace is built, and
278
+ // absence is not a failure here: a lock recorded with these entries still
279
+ // fails verification if they later disappear.
280
+ ...bundleFilesBelow(root, "packages/piagent-webui/dist/client"),
281
+ ...declaredExtensions,
282
+ ...declaredBins,
283
+ ...declaredEntrypoints
284
+ ].filter((entry) => typeof entry === "string" && !path.isAbsolute(entry)));
285
+ const files = new Set(), pending = [...seeds];
286
+ while (pending.length) {
287
+ if (files.size >= MAX_INTEGRITY_FILES) throw new Error("runtime-integrity-file-limit");
288
+ const relative = pending.pop();
289
+ if (files.has(relative)) continue;
290
+ const absolute = path.join(root, relative), contained = normalizedRelative(root, absolute);
291
+ if (!contained || !fs.existsSync(absolute)) continue;
292
+ const stat = fs.lstatSync(absolute);
293
+ if (stat.isSymbolicLink() || !stat.isFile()) throw new Error(`runtime-integrity-file-unsafe:${relative}`);
294
+ files.add(contained);
295
+ for (const reference of sourceReferences(root, contained)) if (!files.has(reference)) pending.push(reference);
296
+ }
297
+ return [...files].sort((left, right) => left.localeCompare(right, "en"));
298
+ }