ultimate-pi 0.18.1 → 0.19.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 (325) hide show
  1. package/.agents/skills/harness-debate-plan/SKILL.md +1 -1
  2. package/.agents/skills/harness-decisions/SKILL.md +1 -2
  3. package/.agents/skills/harness-governor/SKILL.md +6 -5
  4. package/.agents/skills/web-retrieval/SKILL.md +163 -0
  5. package/.agents/skills/wiki-autoresearch/SKILL.md +6 -6
  6. package/.pi/PACKAGING.md +4 -4
  7. package/.pi/SYSTEM.md +75 -123
  8. package/.pi/agents/harness/incident-recorder.md +0 -1
  9. package/.pi/agents/harness/planning/decompose.md +0 -2
  10. package/.pi/agents/harness/planning/execution-plan-author.md +0 -2
  11. package/.pi/agents/harness/planning/hypothesis-validator.md +0 -2
  12. package/.pi/agents/harness/planning/hypothesis.md +0 -2
  13. package/.pi/agents/harness/planning/implementation-researcher.md +1 -3
  14. package/.pi/agents/harness/planning/plan-adversary.md +0 -2
  15. package/.pi/agents/harness/planning/plan-evaluator.md +1 -3
  16. package/.pi/agents/harness/planning/planning-context.md +0 -2
  17. package/.pi/agents/harness/planning/review-integrator.md +0 -2
  18. package/.pi/agents/harness/planning/sprint-contract-auditor.md +0 -2
  19. package/.pi/agents/harness/planning/stack-researcher.md +5 -3
  20. package/.pi/agents/harness/reviewing/adversary.md +0 -2
  21. package/.pi/agents/harness/reviewing/evaluator.md +0 -2
  22. package/.pi/agents/harness/reviewing/tie-breaker.md +0 -2
  23. package/.pi/agents/harness/running/executor.md +0 -2
  24. package/.pi/agents/harness/sentrux-bootstrap.md +0 -1
  25. package/.pi/agents/harness/sentrux-steward.md +0 -2
  26. package/.pi/agents/harness/trace-librarian.md +0 -1
  27. package/.pi/agents/harness/web-retrieval/web-answerer.md +35 -0
  28. package/.pi/agents/harness/web-retrieval/web-criteria-verifier.md +28 -0
  29. package/.pi/agents/harness/web-retrieval/web-gap-analyzer.md +31 -0
  30. package/.pi/agents/harness/web-retrieval/web-query-expander-fast.md +34 -0
  31. package/.pi/agents/harness/web-retrieval/web-query-expander.md +60 -0
  32. package/.pi/agents/harness/web-retrieval/web-summarizer.md +18 -0
  33. package/.pi/extensions/agt-kill-switch.ts +57 -0
  34. package/.pi/extensions/agt-prompt-guard.ts +32 -0
  35. package/.pi/extensions/custom-footer.ts +46 -145
  36. package/.pi/extensions/custom-header.ts +1 -1
  37. package/.pi/extensions/custom-system-prompt.ts +1 -1
  38. package/.pi/extensions/debate-orchestrator.ts +6 -6
  39. package/.pi/extensions/harness-ask-user.ts +7 -7
  40. package/.pi/extensions/harness-debate-tools.ts +26 -42
  41. package/.pi/extensions/harness-lens.ts +94 -0
  42. package/.pi/extensions/harness-plan-approval.ts +11 -11
  43. package/.pi/extensions/harness-run-context.ts +1070 -876
  44. package/.pi/extensions/harness-subagent-governance.ts +8 -0
  45. package/.pi/extensions/harness-subagent-submit.ts +34 -163
  46. package/.pi/extensions/harness-subagents.ts +3 -3
  47. package/.pi/extensions/harness-telemetry.ts +2 -2
  48. package/.pi/extensions/harness-web-guard.ts +2 -1
  49. package/.pi/extensions/harness-web-tools.ts +691 -53
  50. package/.pi/extensions/policy-gate.ts +25 -5
  51. package/.pi/extensions/sentrux-rules-sync.ts +1 -1
  52. package/.pi/extensions/subagent-governance.ts +92 -0
  53. package/.pi/extensions/trace-recorder.ts +1 -1
  54. package/.pi/extensions/{ultimate-pi-vcc.ts → vcc-compaction.ts} +1 -1
  55. package/.pi/harness/README.md +6 -2
  56. package/.pi/harness/agents.manifest.json +46 -25
  57. package/.pi/harness/agents.policy.yaml +309 -0
  58. package/.pi/harness/docs/adrs/0030-inhouse-vcc-compaction.md +1 -1
  59. package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +1 -1
  60. package/.pi/harness/docs/adrs/0045-harness-lens-minimal-contract.md +49 -0
  61. package/.pi/harness/docs/adrs/0046-agt-policy-engine.md +51 -0
  62. package/.pi/harness/docs/adrs/0047-agt-layered-security.md +39 -0
  63. package/.pi/harness/docs/adrs/0048-tool-call-hook-order.md +25 -0
  64. package/.pi/harness/docs/adrs/0049-agents-policy-manifest.md +36 -0
  65. package/.pi/harness/docs/adrs/0050-agentic-web-retrieval-stack.md +46 -0
  66. package/.pi/harness/docs/adrs/README.md +5 -0
  67. package/.pi/harness/docs/harness-web-search.md +97 -0
  68. package/.pi/harness/env.harness.template +9 -1
  69. package/.pi/harness/evolution/README.md +1 -2
  70. package/.pi/harness/examples/agents.policy.project.yaml +19 -0
  71. package/.pi/harness/examples/policies/custom-deny-bash.yaml +9 -0
  72. package/.pi/harness/examples/web-heuristic-angles.project.yaml +22 -0
  73. package/.pi/harness/policies/bash-denylists.yaml +5 -0
  74. package/.pi/harness/policies/defaults.yaml +51 -0
  75. package/.pi/harness/policies/orchestrator.yaml +18 -0
  76. package/.pi/harness/policies/phases.yaml +10 -0
  77. package/.pi/harness/policies/roles.yaml +5 -0
  78. package/.pi/harness/policies/web-guard.yaml +5 -0
  79. package/.pi/harness/policies/workflow-sequences.yaml +9 -0
  80. package/.pi/harness/sentrux/architecture.manifest.json +26 -4
  81. package/.pi/harness/specs/observation.schema.json +2 -1
  82. package/.pi/harness/web-heuristic-angles.json +278 -0
  83. package/.pi/harness/web-heuristic-angles.yaml +182 -0
  84. package/.pi/lib/agents-policy.d.mts +70 -0
  85. package/.pi/lib/agents-policy.mjs +331 -0
  86. package/.pi/lib/agents-policy.ts +19 -0
  87. package/.pi/lib/agt/audit-run-sink.ts +52 -0
  88. package/.pi/lib/agt/build-evaluation-context.ts +285 -0
  89. package/.pi/lib/agt/config.ts +28 -0
  90. package/.pi/lib/agt/delegation.ts +69 -0
  91. package/.pi/lib/agt/evaluate-policy.ts +56 -0
  92. package/.pi/lib/agt/identity-registry.ts +41 -0
  93. package/.pi/lib/agt/index.ts +55 -0
  94. package/.pi/lib/agt/kill-switch-state.ts +11 -0
  95. package/.pi/lib/agt/legacy-evaluate.ts +101 -0
  96. package/.pi/lib/agt/policy-engine.ts +154 -0
  97. package/.pi/lib/agt/rings.ts +21 -0
  98. package/.pi/lib/agt/sre-hooks.ts +45 -0
  99. package/.pi/lib/agt/trust-run-store.ts +26 -0
  100. package/.pi/lib/agt/workflow-history.ts +29 -0
  101. package/.pi/lib/agt-governance-active.ts +14 -0
  102. package/.pi/lib/agt-tool-guard.ts +78 -0
  103. package/.pi/lib/ask-user/dialog.ts +314 -0
  104. package/.pi/{extensions/lib → lib}/debate-bus-core.ts +10 -10
  105. package/.pi/{extensions/lib → lib}/debate-bus-state.ts +1 -1
  106. package/.pi/{extensions/lib → lib}/extension-load-guard.ts +13 -2
  107. package/.pi/lib/harness-agt-tool-guard.ts +5 -0
  108. package/.pi/{extensions/lib → lib}/harness-artifact-gate.ts +1 -1
  109. package/.pi/lib/harness-debate-core-deps.ts +14 -0
  110. package/.pi/lib/harness-debate-workflow-deps.ts +43 -0
  111. package/.pi/lib/harness-lens/.gitattributes +1 -0
  112. package/.pi/lib/harness-lens/clients/edit-autopatch.ts +88 -0
  113. package/.pi/lib/harness-lens/clients/file-kinds.ts +380 -0
  114. package/.pi/lib/harness-lens/clients/file-time.ts +215 -0
  115. package/.pi/lib/harness-lens/clients/file-utils.ts +484 -0
  116. package/.pi/lib/harness-lens/clients/format-service.ts +276 -0
  117. package/.pi/lib/harness-lens/clients/formatters.ts +1000 -0
  118. package/.pi/lib/harness-lens/clients/git-guard.ts +31 -0
  119. package/.pi/lib/harness-lens/clients/indent-retarget.ts +90 -0
  120. package/.pi/lib/harness-lens/clients/installer/index.ts +2368 -0
  121. package/.pi/lib/harness-lens/clients/latency-logger.ts +80 -0
  122. package/.pi/lib/harness-lens/clients/lens-config.ts +43 -0
  123. package/.pi/lib/harness-lens/clients/lens-events.ts +164 -0
  124. package/.pi/lib/harness-lens/clients/lsp/aggregation.ts +91 -0
  125. package/.pi/lib/harness-lens/clients/lsp/client.ts +1466 -0
  126. package/.pi/lib/harness-lens/clients/lsp/config.ts +216 -0
  127. package/.pi/lib/harness-lens/clients/lsp/edits.ts +297 -0
  128. package/.pi/lib/harness-lens/clients/lsp/index.ts +1355 -0
  129. package/.pi/lib/harness-lens/clients/lsp/interactive-install.ts +424 -0
  130. package/.pi/lib/harness-lens/clients/lsp/language.ts +223 -0
  131. package/.pi/lib/harness-lens/clients/lsp/launch.ts +939 -0
  132. package/.pi/lib/harness-lens/clients/lsp/lsp-index.ts +11 -0
  133. package/.pi/lib/harness-lens/clients/lsp/path-utils.ts +12 -0
  134. package/.pi/lib/harness-lens/clients/lsp/server-strategies.ts +81 -0
  135. package/.pi/lib/harness-lens/clients/lsp/server.ts +1971 -0
  136. package/.pi/lib/harness-lens/clients/path-utils.ts +182 -0
  137. package/.pi/lib/harness-lens/clients/pipeline.ts +360 -0
  138. package/.pi/lib/harness-lens/clients/project-profile.ts +117 -0
  139. package/.pi/lib/harness-lens/clients/runtime-agent-end.ts +112 -0
  140. package/.pi/lib/harness-lens/clients/runtime-config.ts +33 -0
  141. package/.pi/lib/harness-lens/clients/runtime-coordinator.ts +186 -0
  142. package/.pi/lib/harness-lens/clients/runtime-tool-result.ts +171 -0
  143. package/.pi/lib/harness-lens/clients/safe-spawn.ts +339 -0
  144. package/.pi/lib/harness-lens/clients/secrets-scanner.ts +214 -0
  145. package/.pi/lib/harness-lens/clients/tool-policy.ts +2072 -0
  146. package/.pi/lib/harness-lens/clients/types.ts +59 -0
  147. package/.pi/lib/harness-lens/clients/widget-state.ts +283 -0
  148. package/.pi/lib/harness-lens/index.ts +532 -0
  149. package/.pi/lib/harness-lens/tools/lsp-diagnostics.ts +706 -0
  150. package/.pi/lib/harness-lens/tools/lsp-navigation.ts +1246 -0
  151. package/.pi/{extensions/lib → lib}/harness-posthog.ts +3 -0
  152. package/.pi/lib/harness-run-context-responses.ts +9 -0
  153. package/.pi/lib/harness-run-context.ts +0 -2
  154. package/.pi/{extensions/lib/spawn-policy.ts → lib/harness-spawn-policy.ts} +1 -0
  155. package/.pi/{extensions/lib → lib}/harness-spawn-topology.ts +1 -1
  156. package/.pi/lib/harness-subagent-auth.ts +81 -0
  157. package/.pi/{extensions/lib → lib}/harness-subagent-precheck.ts +10 -7
  158. package/.pi/{extensions/lib → lib}/harness-subagent-submit-pipeline.ts +3 -3
  159. package/.pi/lib/harness-subagent-submit-register.ts +163 -0
  160. package/.pi/{extensions/lib → lib}/harness-subagent-submit-registry.ts +1 -37
  161. package/.pi/{extensions/lib → lib}/harness-subagents-bridge.ts +74 -14
  162. package/.pi/{extensions/lib → lib}/harness-subprocess-bootstrap.ts +1 -1
  163. package/.pi/lib/harness-web/artifacts.ts +200 -0
  164. package/.pi/lib/harness-web/cache.ts +369 -0
  165. package/.pi/{extensions/lib → lib}/harness-web/run-cli.ts +42 -2
  166. package/.pi/{extensions/lib → lib}/plan-approval/create-plan.ts +2 -2
  167. package/.pi/{extensions/lib → lib}/plan-approval/format-plan.ts +2 -2
  168. package/.pi/{extensions/lib → lib}/plan-approval/plan-review.ts +162 -201
  169. package/.pi/{extensions/lib → lib}/plan-approval/render.ts +1 -1
  170. package/.pi/{extensions/lib → lib}/plan-approval/resolve-disk.ts +2 -2
  171. package/.pi/{extensions/lib → lib}/plan-approval/types.ts +1 -1
  172. package/.pi/{extensions/lib → lib}/plan-approval/validate.ts +3 -3
  173. package/.pi/{extensions/lib → lib}/plan-debate-envelope.ts +1 -1
  174. package/.pi/{extensions/lib → lib}/plan-debate-gate.ts +1 -1
  175. package/.pi/{extensions/lib → lib}/plan-debate-lane.ts +1 -4
  176. package/.pi/{extensions/lib → lib}/plan-messenger.ts +1 -1
  177. package/.pi/prompts/harness-plan.md +2 -1
  178. package/.pi/prompts/harness-setup.md +40 -65
  179. package/.pi/scripts/README.md +2 -5
  180. package/.pi/scripts/gen-web-heuristic-angles-json.mjs +24 -0
  181. package/.pi/scripts/generate-agents-policy-yaml.mjs +148 -0
  182. package/.pi/scripts/harness-agents-manifest.mjs +60 -3
  183. package/.pi/scripts/harness-agt-doctor.ts +36 -0
  184. package/.pi/scripts/harness-cli-verify.sh +14 -2
  185. package/.pi/scripts/harness-verify.mjs +191 -39
  186. package/.pi/scripts/harness-web-policy-guard.mjs +3 -3
  187. package/.pi/scripts/harness-web.py +218 -15
  188. package/.pi/scripts/harness_web/deep_search.py +55 -0
  189. package/.pi/scripts/harness_web/evidence_bundle.py +47 -0
  190. package/.pi/scripts/harness_web/find_similar.py +88 -0
  191. package/.pi/scripts/harness_web/heuristic_angles_shipped.py +85 -0
  192. package/.pi/scripts/harness_web/heuristic_config.py +251 -0
  193. package/.pi/scripts/harness_web/highlights.py +47 -0
  194. package/.pi/scripts/harness_web/multi_search.py +59 -0
  195. package/.pi/scripts/harness_web/output.py +24 -0
  196. package/.pi/scripts/harness_web/query_angles.py +116 -0
  197. package/.pi/scripts/harness_web/rank.py +163 -0
  198. package/.pi/scripts/harness_web/scrape.py +30 -0
  199. package/.pi/scripts/tests/test_harness_web_heuristic_config.py +132 -0
  200. package/.pi/scripts/tests/test_harness_web_query_angles.py +45 -0
  201. package/.pi/scripts/tests/test_harness_web_rank.py +56 -0
  202. package/.pi/scripts/validate-plan-dag.mjs +65 -74
  203. package/.pi/scripts/vendor-pi-vcc-settings.stub.ts +2 -2
  204. package/.pi/scripts/vendor-sync-pi-vcc.sh +1 -1
  205. package/.pi/skills/architecture/broker-domain/SKILL.md +65 -0
  206. package/.pi/skills/architecture/cqrs/SKILL.md +63 -0
  207. package/.pi/skills/architecture/event-driven/SKILL.md +60 -0
  208. package/.pi/skills/architecture/hexagonal-ports-adapters/SKILL.md +66 -0
  209. package/.pi/skills/architecture/layered/SKILL.md +68 -0
  210. package/.pi/skills/architecture/microkernel/SKILL.md +62 -0
  211. package/.pi/skills/architecture/microservices/SKILL.md +64 -0
  212. package/.pi/skills/architecture/modular-monolith/SKILL.md +65 -0
  213. package/.pi/skills/architecture/orchestration-driven-soa/SKILL.md +61 -0
  214. package/.pi/skills/architecture/pipeline/SKILL.md +63 -0
  215. package/.pi/skills/architecture/service-based/SKILL.md +64 -0
  216. package/.pi/skills/architecture/service-mesh/SKILL.md +60 -0
  217. package/.pi/skills/architecture/space-based/SKILL.md +60 -0
  218. package/.pi/skills/ast-grep/SKILL.md +40 -321
  219. package/.pi/skills/delivery/debugging-discipline/SKILL.md +36 -0
  220. package/.pi/skills/delivery/documentation-update/SKILL.md +33 -0
  221. package/.pi/skills/delivery/requirements-to-implementation/SKILL.md +34 -0
  222. package/.pi/skills/delivery/risk-based-verification/SKILL.md +43 -0
  223. package/.pi/skills/delivery/tradeoff-analysis/SKILL.md +34 -0
  224. package/.pi/skills/engineering/api-contract-design/SKILL.md +38 -0
  225. package/.pi/skills/engineering/cohesion-coupling/SKILL.md +43 -0
  226. package/.pi/skills/engineering/complexity-control/SKILL.md +31 -0
  227. package/.pi/skills/engineering/defensive-programming/SKILL.md +38 -0
  228. package/.pi/skills/engineering/dependency-management/SKILL.md +29 -0
  229. package/.pi/skills/engineering/domain-modeling/SKILL.md +32 -0
  230. package/.pi/skills/engineering/error-handling/SKILL.md +37 -0
  231. package/.pi/skills/engineering/legacy-code-seams/SKILL.md +35 -0
  232. package/.pi/skills/engineering/naming-and-intent/SKILL.md +29 -0
  233. package/.pi/skills/engineering/refactoring-safe-evolution/SKILL.md +35 -0
  234. package/.pi/skills/engineering/routine-function-design/SKILL.md +34 -0
  235. package/.pi/skills/engineering/small-change-discipline/SKILL.md +35 -0
  236. package/.pi/skills/lsp-navigation/SKILL.md +89 -0
  237. package/.pi/skills/quality/code-review-self-check/SKILL.md +35 -0
  238. package/.pi/skills/quality/privacy-data-handling/SKILL.md +26 -0
  239. package/.pi/skills/quality/security-review/SKILL.md +34 -0
  240. package/.pi/skills/quality/test-strategy/SKILL.md +33 -0
  241. package/.pi/skills/quality/testability-design/SKILL.md +33 -0
  242. package/.pi/skills/systems/concurrency-safety/SKILL.md +32 -0
  243. package/.pi/skills/systems/data-modeling-migrations/SKILL.md +31 -0
  244. package/.pi/skills/systems/observability-instrumentation/SKILL.md +32 -0
  245. package/.pi/skills/systems/performance-measurement/SKILL.md +35 -0
  246. package/.pi/skills/systems/reliability-design/SKILL.md +32 -0
  247. package/.sentrux/rules.toml +20 -4
  248. package/AGENTS.md +7 -2
  249. package/CHANGELOG.md +20 -0
  250. package/README.md +3 -12
  251. package/THIRD_PARTY_NOTICES.md +12 -21
  252. package/package.json +17 -7
  253. package/vendor/pi-subagents/src/agents.ts +45 -1
  254. package/vendor/pi-subagents/src/subagents.ts +866 -811
  255. package/vendor/pi-vcc/src/core/brief.ts +68 -99
  256. package/vendor/pi-vcc/src/core/settings.ts +2 -2
  257. package/.agents/skills/caveman/SKILL.md +0 -67
  258. package/.agents/skills/scrapling-web/SKILL.md +0 -98
  259. package/.pi/agents/harness/meta-optimizer.md +0 -36
  260. package/.pi/extensions/00-posthog-network-bootstrap.ts +0 -11
  261. package/.pi/extensions/lib/ask-user/dialog.ts +0 -260
  262. package/.pi/extensions/lib/harness-subagent-auth.ts +0 -207
  263. package/.pi/extensions/lib/harness-subagent-policy.ts +0 -236
  264. package/.pi/extensions/pi-model-router-harness.ts +0 -42
  265. package/.pi/harness/evolution/meta-optimizer.mjs +0 -99
  266. package/.pi/harness/specs/router-tuning-proposal.schema.json +0 -114
  267. package/.pi/model-router.example.json +0 -36
  268. package/.pi/prompts/harness-critic.md +0 -10
  269. package/.pi/prompts/harness-eval.md +0 -10
  270. package/.pi/prompts/harness-router-tune.md +0 -52
  271. package/.pi/scripts/harness-generate-model-router.mjs +0 -327
  272. package/.pi/scripts/harness-model-router-routing.test.mjs +0 -97
  273. package/.pi/scripts/harness-sync-model-router.mjs +0 -97
  274. package/.pi/scripts/harness_web/__pycache__/__init__.cpython-314.pyc +0 -0
  275. package/.pi/scripts/harness_web/__pycache__/config.cpython-314.pyc +0 -0
  276. package/.pi/scripts/harness_web/__pycache__/output.cpython-314.pyc +0 -0
  277. package/.pi/scripts/harness_web/__pycache__/scrape.cpython-314.pyc +0 -0
  278. package/.pi/scripts/harness_web/__pycache__/search.cpython-314.pyc +0 -0
  279. package/.pi/scripts/harness_web/__pycache__/search_ddg.cpython-314.pyc +0 -0
  280. package/.pi/scripts/harness_web/__pycache__/search_searxng.cpython-314.pyc +0 -0
  281. package/.pi/scripts/vendor-sync-pi-model-router.sh +0 -47
  282. package/vendor/pi-model-router/.prettierignore +0 -4
  283. package/vendor/pi-model-router/.prettierrc +0 -5
  284. package/vendor/pi-model-router/AGENTS.md +0 -39
  285. package/vendor/pi-model-router/LICENSE +0 -21
  286. package/vendor/pi-model-router/README.md +0 -99
  287. package/vendor/pi-model-router/UPSTREAM_PIN.md +0 -10
  288. package/vendor/pi-model-router/docs/ARCHITECTURE.md +0 -54
  289. package/vendor/pi-model-router/extensions/commands.ts +0 -720
  290. package/vendor/pi-model-router/extensions/config.ts +0 -348
  291. package/vendor/pi-model-router/extensions/constants.ts +0 -1
  292. package/vendor/pi-model-router/extensions/index.ts +0 -478
  293. package/vendor/pi-model-router/extensions/provider.ts +0 -580
  294. package/vendor/pi-model-router/extensions/routing.ts +0 -564
  295. package/vendor/pi-model-router/extensions/state.ts +0 -52
  296. package/vendor/pi-model-router/extensions/types.ts +0 -95
  297. package/vendor/pi-model-router/extensions/ui.ts +0 -144
  298. package/vendor/pi-model-router/model-router.example.json +0 -48
  299. package/vendor/pi-model-router/package.json +0 -48
  300. package/vendor/pi-model-router/tsconfig.json +0 -16
  301. /package/.pi/{prompts → harness/docs}/planning-rubrics.md +0 -0
  302. /package/.pi/{extensions/lib → lib}/ask-user/fallback.ts +0 -0
  303. /package/.pi/{extensions/lib → lib}/ask-user/render.ts +0 -0
  304. /package/.pi/{extensions/lib → lib}/ask-user/schema.ts +0 -0
  305. /package/.pi/{extensions/lib → lib}/ask-user/types.ts +0 -0
  306. /package/.pi/{extensions/lib → lib}/ask-user/validate-core.mjs +0 -0
  307. /package/.pi/{extensions/lib → lib}/ask-user/validate.ts +0 -0
  308. /package/.pi/{extensions/lib → lib}/harness-cocoindex-refresh.ts +0 -0
  309. /package/.pi/{extensions/lib → lib}/harness-paths.ts +0 -0
  310. /package/.pi/{extensions/lib → lib}/harness-spawn-budget.ts +0 -0
  311. /package/.pi/{extensions/lib → lib}/harness-vcc-settings.ts +0 -0
  312. /package/.pi/{extensions/lib → lib}/plan-approval/dialog.ts +0 -0
  313. /package/.pi/{extensions/lib → lib}/plan-approval/schema.ts +0 -0
  314. /package/.pi/{extensions/lib → lib}/plan-approval-readiness.ts +0 -0
  315. /package/.pi/{extensions/lib → lib}/plan-debate-eligibility.ts +0 -0
  316. /package/.pi/{extensions/lib → lib}/plan-debate-focus.ts +0 -0
  317. /package/.pi/{extensions/lib → lib}/plan-debate-id.ts +0 -0
  318. /package/.pi/{extensions/lib → lib}/plan-debate-lanes.ts +0 -0
  319. /package/.pi/{extensions/lib → lib}/plan-debate-round-status.ts +0 -0
  320. /package/.pi/{extensions/lib → lib}/plan-debate-write-guard.ts +0 -0
  321. /package/.pi/{extensions/lib → lib}/plan-review-gate.ts +0 -0
  322. /package/.pi/{extensions/lib → lib}/plan-review-integrator-rules.ts +0 -0
  323. /package/.pi/{extensions/lib → lib}/plan-scope-guard.ts +0 -0
  324. /package/.pi/{extensions/lib → lib}/posthog-client.ts +0 -0
  325. /package/.pi/{extensions/lib → lib}/posthog-node.d.ts +0 -0
@@ -0,0 +1,331 @@
1
+ /**
2
+ * agents.policy.yaml loader — package + project merge (SSOT for agent tools).
3
+ */
4
+
5
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
6
+ import { join, dirname } from "node:path";
7
+ import { parse as parseYaml } from "yaml";
8
+
9
+ const BUILTIN_DENY_TOOLS = new Set([
10
+ "subagent",
11
+ "Agent",
12
+ "get_subagent_result",
13
+ "steer_subagent",
14
+ "blackboard",
15
+ ]);
16
+
17
+ const PLANNING_BASH_DENY_PATTERNS = [
18
+ /\bgraphify\s+update\b/i,
19
+ /\bgraphify\s+extract\b/i,
20
+ /\bgraphify\s+install\b/i,
21
+ /\bccc\s+(index|init|reset|daemon)\b/i,
22
+ /\bccc\s+search\b.*--refresh/i,
23
+ /\bpip\s+install\b/i,
24
+ /\buv\s+tool\s+install\b/i,
25
+ /\bnpm\s+install\b/i,
26
+ ];
27
+
28
+ const PLANNING_ARTIFACT_JSON_WRITE = /artifacts\/[^\s'"`;]+\.json\b/i;
29
+
30
+ const MUTATING_TOOLS = new Set(["write", "edit"]);
31
+
32
+ const cache = new Map();
33
+
34
+ export function packageAgentsPolicyPath(packageRoot) {
35
+ return join(packageRoot, ".pi", "harness", "agents.policy.yaml");
36
+ }
37
+
38
+ export function projectAgentsPolicyPath(projectRoot) {
39
+ return join(projectRoot, ".pi", "agents.policy.yaml");
40
+ }
41
+
42
+ export function projectPoliciesDir(projectRoot) {
43
+ return join(projectRoot, ".pi", "policies");
44
+ }
45
+
46
+ function readYamlFile(path) {
47
+ if (!existsSync(path)) return null;
48
+ try {
49
+ return parseYaml(readFileSync(path, "utf8"));
50
+ } catch {
51
+ return null;
52
+ }
53
+ }
54
+
55
+ function normalizeKindEntry(raw) {
56
+ if (!raw || typeof raw !== "object") return null;
57
+ const tools = Array.isArray(raw.tools) ? raw.tools.map(String) : [];
58
+ return {
59
+ tools,
60
+ extensions: raw.extensions === false ? false : Boolean(raw.extensions),
61
+ readOnly: raw.read_only === true,
62
+ maxTurns:
63
+ typeof raw.max_turns === "number" && raw.max_turns > 0
64
+ ? raw.max_turns
65
+ : undefined,
66
+ thinking:
67
+ typeof raw.thinking === "string" && raw.thinking.trim()
68
+ ? raw.thinking.trim()
69
+ : undefined,
70
+ model:
71
+ typeof raw.model === "string" && raw.model.trim() ? raw.model.trim() : undefined,
72
+ };
73
+ }
74
+
75
+ function normalizeAgentEntry(raw) {
76
+ if (!raw || typeof raw !== "object") return {};
77
+ const toolsAdd = Array.isArray(raw.tools_add)
78
+ ? raw.tools_add.map(String)
79
+ : Array.isArray(raw.tools)
80
+ ? raw.tools.map(String)
81
+ : [];
82
+ return {
83
+ kind: typeof raw.kind === "string" ? raw.kind.trim() : undefined,
84
+ toolsAdd,
85
+ toolsDeny: Array.isArray(raw.tools_deny)
86
+ ? raw.tools_deny.map(String)
87
+ : [],
88
+ submitTool:
89
+ typeof raw.submit_tool === "string" ? raw.submit_tool.trim() : undefined,
90
+ extensions:
91
+ raw.extensions === false
92
+ ? false
93
+ : raw.extensions === true
94
+ ? true
95
+ : undefined,
96
+ maxTurns:
97
+ typeof raw.max_turns === "number" && raw.max_turns > 0
98
+ ? raw.max_turns
99
+ : undefined,
100
+ thinking:
101
+ typeof raw.thinking === "string" && raw.thinking.trim()
102
+ ? raw.thinking.trim()
103
+ : undefined,
104
+ model:
105
+ typeof raw.model === "string" && raw.model.trim() ? raw.model.trim() : undefined,
106
+ };
107
+ }
108
+
109
+ export function loadAgentsPolicyMerged(packageRoot, projectRoot) {
110
+ const key = `${packageRoot}\0${projectRoot}`;
111
+ if (cache.has(key)) return cache.get(key);
112
+
113
+ const pkgDoc = readYamlFile(packageAgentsPolicyPath(packageRoot)) ?? {};
114
+ const projDoc = readYamlFile(projectAgentsPolicyPath(projectRoot)) ?? {};
115
+
116
+ const kinds = new Map();
117
+ for (const [name, raw] of Object.entries(pkgDoc.kinds ?? {})) {
118
+ const k = normalizeKindEntry(raw);
119
+ if (k) kinds.set(name, k);
120
+ }
121
+ for (const [name, raw] of Object.entries(projDoc.kinds ?? {})) {
122
+ const k = normalizeKindEntry(raw);
123
+ if (k) kinds.set(name, k);
124
+ }
125
+
126
+ const agents = new Map();
127
+ for (const [id, raw] of Object.entries(pkgDoc.agents ?? {})) {
128
+ agents.set(id, normalizeAgentEntry(raw));
129
+ }
130
+ for (const [id, raw] of Object.entries(projDoc.agents ?? {})) {
131
+ const prev = agents.get(id) ?? {};
132
+ const next = normalizeAgentEntry(raw);
133
+ agents.set(id, {
134
+ ...prev,
135
+ ...next,
136
+ toolsAdd: [...new Set([...(prev.toolsAdd ?? []), ...(next.toolsAdd ?? [])])],
137
+ toolsDeny: [...new Set([...(prev.toolsDeny ?? []), ...(next.toolsDeny ?? [])])],
138
+ });
139
+ }
140
+
141
+ const merged = {
142
+ schemaVersion: String(pkgDoc.apiVersion ?? projDoc.apiVersion ?? "harness.toolkit/v1"),
143
+ kinds,
144
+ agents,
145
+ defaults: normalizeAgentEntry(projDoc.defaults ?? pkgDoc.defaults ?? {}),
146
+ };
147
+ cache.set(key, merged);
148
+ return merged;
149
+ }
150
+
151
+ export function resolveEffectiveTools(agentId, merged) {
152
+ const entry = merged.agents.get(agentId) ?? merged.defaults;
153
+ const kindName = entry.kind ?? "other";
154
+ const kind = merged.kinds.get(kindName) ?? merged.kinds.get("other") ?? {
155
+ tools: ["read", "grep", "find", "ls"],
156
+ extensions: false,
157
+ readOnly: true,
158
+ };
159
+
160
+ const base = new Set(kind.tools);
161
+ for (const t of entry.toolsAdd ?? []) base.add(t);
162
+ for (const t of entry.toolsDeny ?? []) base.delete(t);
163
+ for (const t of BUILTIN_DENY_TOOLS) base.delete(t);
164
+
165
+ return {
166
+ kind: kindName,
167
+ effectiveTools: [...base],
168
+ extensionsOff: entry.extensions === true ? false : entry.extensions === false ? true : !kind.extensions,
169
+ readOnly: kind.readOnly,
170
+ maxTurns: entry.maxTurns ?? kind.maxTurns,
171
+ thinking: entry.thinking ?? kind.thinking,
172
+ model: entry.model ?? kind.model,
173
+ submitTool: entry.submitTool,
174
+ };
175
+ }
176
+
177
+ export function getAgentPolicySpec(packageRoot, projectRoot, agentId) {
178
+ const merged = loadAgentsPolicyMerged(packageRoot, projectRoot);
179
+ if (!merged.agents.has(agentId) && !merged.defaults?.kind) {
180
+ return null;
181
+ }
182
+ return resolveEffectiveTools(agentId, merged);
183
+ }
184
+
185
+ export function getAgentKind(packageRoot, projectRoot, agentId) {
186
+ const spec = getAgentPolicySpec(packageRoot, projectRoot, agentId);
187
+ if (spec) return spec.kind;
188
+ if (agentId.startsWith("harness/planning/")) return "planner";
189
+ if (agentId === "harness/running/executor") return "executor";
190
+ if (agentId === "harness/reviewing/evaluator") return "evaluator";
191
+ if (agentId === "harness/reviewing/adversary") return "adversary";
192
+ if (agentId === "harness/reviewing/tie-breaker") return "tie_breaker";
193
+ if (agentId === "harness/meta-optimizer") return "meta";
194
+ if (agentId === "harness/trace-librarian") return "trace";
195
+ if (agentId === "harness/incident-recorder") return "incident";
196
+ return "other";
197
+ }
198
+
199
+ export function isHarnessPlanningAgent(agentId) {
200
+ return agentId.startsWith("harness/planning/");
201
+ }
202
+
203
+ export function harnessSubagentPhaseHint(packageRoot, projectRoot, agentId) {
204
+ if (isHarnessPlanningAgent(agentId)) return "plan";
205
+ const kind = getAgentKind(packageRoot, projectRoot, agentId);
206
+ switch (kind) {
207
+ case "planner":
208
+ return "plan";
209
+ case "executor":
210
+ return "execute";
211
+ case "evaluator":
212
+ return "evaluate";
213
+ case "adversary":
214
+ return "adversary";
215
+ default:
216
+ return null;
217
+ }
218
+ }
219
+
220
+ function isMutatingBash(command) {
221
+ if (!command) return false;
222
+ return /\b(rm\s+-rf|git\s+(push|commit|reset|checkout|merge|rebase)|npm\s+run|make\b|docker\s+)/i.test(
223
+ command,
224
+ );
225
+ }
226
+
227
+ /**
228
+ * Manifest allowlist + subprocess constraints (replaces harness-subagent-policy.ts).
229
+ */
230
+ export function allowsAgentTool(input) {
231
+ const {
232
+ packageRoot,
233
+ projectRoot,
234
+ agentId,
235
+ toolName,
236
+ toolInput = {},
237
+ isSubprocess = false,
238
+ isParentOrchestrator = false,
239
+ } = input;
240
+
241
+ if (isParentOrchestrator) {
242
+ if (toolName.startsWith("submit_")) return false;
243
+ return true;
244
+ }
245
+
246
+ const spec = getAgentPolicySpec(packageRoot, projectRoot, agentId);
247
+ if (!spec) return false;
248
+
249
+ if (!spec.effectiveTools.includes(toolName)) return false;
250
+
251
+ if (toolName.startsWith("submit_")) {
252
+ if (!isSubprocess) return false;
253
+ if (toolName === "submit_human_required" && agentId === "harness/running/executor") {
254
+ return false;
255
+ }
256
+ }
257
+
258
+ if (MUTATING_TOOLS.has(toolName) && spec.readOnly) return false;
259
+
260
+ if (toolName === "ctx_batch_execute" && spec.readOnly) {
261
+ const commands = toolInput.commands;
262
+ if (Array.isArray(commands)) {
263
+ for (const c of commands) {
264
+ const cmd =
265
+ typeof c === "string"
266
+ ? c
267
+ : String(c?.command ?? c?.code ?? "");
268
+ if (cmd && isMutatingBash(cmd)) return false;
269
+ }
270
+ }
271
+ }
272
+
273
+ if (toolName === "ctx_execute" && spec.readOnly) {
274
+ const code = String(toolInput.code ?? toolInput.command ?? "");
275
+ if (code && isMutatingBash(code)) return false;
276
+ }
277
+
278
+ if (toolName === "bash" && spec.readOnly) {
279
+ const command = String(toolInput.command ?? "");
280
+ if (command && isMutatingBash(command)) return false;
281
+ if (
282
+ isHarnessPlanningAgent(agentId) &&
283
+ command &&
284
+ PLANNING_ARTIFACT_JSON_WRITE.test(command)
285
+ ) {
286
+ return false;
287
+ }
288
+ if (
289
+ isHarnessPlanningAgent(agentId) &&
290
+ command &&
291
+ PLANNING_BASH_DENY_PATTERNS.some((p) => p.test(command))
292
+ ) {
293
+ return false;
294
+ }
295
+ }
296
+
297
+ return true;
298
+ }
299
+
300
+ export function applyAgentPolicyToConfig(agent, packageRoot, projectRoot) {
301
+ const spec = getAgentPolicySpec(packageRoot, projectRoot, agent.name);
302
+ if (!spec) return agent;
303
+ return {
304
+ ...agent,
305
+ tools: spec.effectiveTools.length > 0 ? spec.effectiveTools : undefined,
306
+ extensionsOff: spec.extensionsOff,
307
+ maxTurns: spec.maxTurns ?? agent.maxTurns,
308
+ thinking: spec.thinking ?? agent.thinking,
309
+ model: spec.model ?? agent.model,
310
+ };
311
+ }
312
+
313
+ export function findProjectRootFromAgentsDir(projectAgentsDir) {
314
+ if (!projectAgentsDir) return process.cwd();
315
+ const piDir = dirname(projectAgentsDir);
316
+ if (piDir.endsWith("/.pi") || piDir.endsWith("\\.pi")) {
317
+ return dirname(piDir);
318
+ }
319
+ return process.cwd();
320
+ }
321
+
322
+ export function isAgtGovernanceActive(projectRoot) {
323
+ if (existsSync(projectAgentsPolicyPath(projectRoot))) return true;
324
+ const polDir = projectPoliciesDir(projectRoot);
325
+ if (!existsSync(polDir)) return false;
326
+ try {
327
+ return readdirSync(polDir).some((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
328
+ } catch {
329
+ return false;
330
+ }
331
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * agents.policy.yaml — TypeScript surface (implementation in agents-policy.mjs).
3
+ */
4
+
5
+ export {
6
+ allowsAgentTool,
7
+ applyAgentPolicyToConfig,
8
+ findProjectRootFromAgentsDir,
9
+ getAgentKind,
10
+ getAgentPolicySpec,
11
+ harnessSubagentPhaseHint,
12
+ isAgtGovernanceActive,
13
+ isHarnessPlanningAgent,
14
+ loadAgentsPolicyMerged,
15
+ packageAgentsPolicyPath,
16
+ projectAgentsPolicyPath,
17
+ projectPoliciesDir,
18
+ resolveEffectiveTools,
19
+ } from "./agents-policy.mjs";
@@ -0,0 +1,52 @@
1
+ import { appendFileSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { AuditLogger } from "@microsoft/agent-governance-sdk";
4
+
5
+ const loggers = new Map<string, AuditLogger>();
6
+
7
+ export function getAuditLoggerForRun(runDir: string): AuditLogger {
8
+ const key = runDir;
9
+ let logger = loggers.get(key);
10
+ if (!logger) {
11
+ logger = new AuditLogger();
12
+ loggers.set(key, logger);
13
+ }
14
+ return logger;
15
+ }
16
+
17
+ export function appendPolicyAuditEvent(input: {
18
+ runDir: string;
19
+ runId: string;
20
+ toolName: string;
21
+ allowed: boolean;
22
+ reason: string;
23
+ agentDid: string;
24
+ phase: string;
25
+ }): void {
26
+ const logger = getAuditLoggerForRun(input.runDir);
27
+ logger.log({
28
+ action: `tool.${input.toolName}:${input.phase}:${input.reason}`,
29
+ agentId: input.agentDid,
30
+ decision: input.allowed ? "allow" : "deny",
31
+ });
32
+ const auditPath = join(input.runDir, "agt-audit.jsonl");
33
+ mkdirSync(input.runDir, { recursive: true });
34
+ appendFileSync(
35
+ auditPath,
36
+ `${JSON.stringify({
37
+ ts: new Date().toISOString(),
38
+ run_id: input.runId,
39
+ tool: input.toolName,
40
+ allowed: input.allowed,
41
+ reason: input.reason,
42
+ agent_did: input.agentDid,
43
+ phase: input.phase,
44
+ })}\n`,
45
+ );
46
+ }
47
+
48
+ export function verifyRunAuditChain(runDir: string): boolean {
49
+ const logger = loggers.get(runDir);
50
+ if (!logger) return true;
51
+ return logger.verify();
52
+ }
@@ -0,0 +1,285 @@
1
+ import {
2
+ allowsAgentTool,
3
+ getAgentKind,
4
+ isHarnessPlanningAgent,
5
+ } from "../agents-policy.mjs";
6
+ import {
7
+ evaluateContextModeMutation,
8
+ isMutatingBash,
9
+ } from "../harness-context-mode-policy.js";
10
+ import {
11
+ extractWritePathFromToolInput,
12
+ getLatestRunContext,
13
+ type HarnessPhase,
14
+ type HarnessRunContext,
15
+ isHarnessAutoSession,
16
+ isPlanPhaseAllowedMutation,
17
+ } from "../harness-run-context.js";
18
+ import { evaluateSubagentToolCall } from "../harness-spawn-policy.js";
19
+
20
+ export interface BuildEvaluationContextInput {
21
+ toolName: string;
22
+ toolInput: Record<string, unknown>;
23
+ packageRoot: string;
24
+ projectRoot: string;
25
+ sessionId: string;
26
+ entries: unknown[];
27
+ policyState: {
28
+ phase: HarnessPhase;
29
+ approvedPlan: boolean;
30
+ planId: string | null;
31
+ aborted: boolean;
32
+ budgetBypass: boolean;
33
+ };
34
+ agentDid?: string;
35
+ }
36
+
37
+ export type HarnessAgtContext = Record<string, unknown>;
38
+
39
+ const PLANNING_BASH_DENY_PATTERNS = [
40
+ /\bgraphify\s+update\b/i,
41
+ /\bgraphify\s+extract\b/i,
42
+ /\bgraphify\s+install\b/i,
43
+ /\bccc\s+(index|init|reset|daemon)\b/i,
44
+ /\bccc\s+search\b.*--refresh/i,
45
+ /\bpip\s+install\b/i,
46
+ /\buv\s+tool\s+install\b/i,
47
+ /\bnpm\s+install\b/i,
48
+ /\bnpm\s+install\b.*cocoindex/i,
49
+ /\buv\s+tool\s+install\b.*cocoindex/i,
50
+ ];
51
+
52
+ const PLANNING_ARTIFACT_JSON_WRITE = /artifacts\/[^\s'"`;]+\.json\b/i;
53
+
54
+ const WEB_BLOCK_PATTERNS: Array<{ re: RegExp }> = [
55
+ { re: /\bfirecrawl\b/i },
56
+ { re: /\b(?:curl|wget)\b[^\n|;&]*\s+https?:\/\//i },
57
+ { re: /\bscrapling\s+(?:fetch|extract)\b/i },
58
+ ];
59
+
60
+ const WEB_ALLOW_PATTERNS = [
61
+ /harness-web\.py\b/i,
62
+ /harness-cli-verify\.sh\b/i,
63
+ /\bgraphify\b/i,
64
+ /\bctx7\b/i,
65
+ /\bcontext7\b/i,
66
+ /\bgit\b/i,
67
+ /harness-searxng-bootstrap/i,
68
+ ];
69
+
70
+ function resolveAgentId(): string {
71
+ if (process.env.PI_HARNESS_SUBPROCESS === "1") {
72
+ return process.env.HARNESS_AGENT_ID?.trim() || "harness/unknown";
73
+ }
74
+ return "parent-orchestrator";
75
+ }
76
+
77
+ export function bashWebBlocked(command: string): boolean {
78
+ if (!command) return false;
79
+ if (WEB_ALLOW_PATTERNS.some((re) => re.test(command))) return false;
80
+ return WEB_BLOCK_PATTERNS.some(({ re }) => re.test(command));
81
+ }
82
+
83
+ /** Shared session-scoped deny reasons for legacy parity and AGT context flags. */
84
+ export function harnessSessionToolDenyReason(input: {
85
+ toolName: string;
86
+ toolInput: Record<string, unknown>;
87
+ phase: HarnessPhase;
88
+ agentId: string;
89
+ entries: unknown[];
90
+ aborted: boolean;
91
+ }): string | null {
92
+ if (!isHarnessAutoSession(input.entries)) return null;
93
+ const bashCommand =
94
+ input.toolName === "bash" ? String(input.toolInput.command ?? "") : "";
95
+ if (
96
+ input.aborted &&
97
+ ((bashCommand && isMutatingBash(bashCommand)) ||
98
+ input.toolName === "write" ||
99
+ input.toolName === "edit")
100
+ ) {
101
+ return "harness-abort lock";
102
+ }
103
+ if (
104
+ bashCommand &&
105
+ isMutatingBash(bashCommand) &&
106
+ !input.aborted &&
107
+ input.phase !== "execute" &&
108
+ input.phase !== "merge"
109
+ ) {
110
+ return "mutating bash blocked outside execute/merge";
111
+ }
112
+ if (bashCommand && bashWebBlocked(bashCommand)) {
113
+ return "web/bash curl blocked (use harness web_search / web_fetch)";
114
+ }
115
+ return null;
116
+ }
117
+
118
+ function bashPlanningDenied(command: string, agentType: string): boolean {
119
+ if (!command || !isHarnessPlanningAgent(agentType)) return false;
120
+ return PLANNING_BASH_DENY_PATTERNS.some((p) => p.test(command));
121
+ }
122
+
123
+ function bashPlanningJsonDenied(command: string, agentType: string): boolean {
124
+ if (!command || !isHarnessPlanningAgent(agentType)) return false;
125
+ return PLANNING_ARTIFACT_JSON_WRITE.test(command);
126
+ }
127
+
128
+ function harnessSessionActive(entries: unknown[]): boolean {
129
+ return isHarnessAutoSession(entries);
130
+ }
131
+
132
+ export async function buildHarnessAgtEvaluationContext(
133
+ input: BuildEvaluationContextInput,
134
+ ): Promise<HarnessAgtContext> {
135
+ const agentId = resolveAgentId();
136
+ const isSubprocess = process.env.PI_HARNESS_SUBPROCESS === "1";
137
+ const isParentOrchestrator = agentId === "parent-orchestrator";
138
+ const agentKind = getAgentKind(input.packageRoot, input.projectRoot, agentId);
139
+ const runCtx = getLatestRunContext(input.entries);
140
+ const phase = input.policyState.phase;
141
+ const bashCommand =
142
+ input.toolName === "bash" ? String(input.toolInput.command ?? "") : "";
143
+ const sessionActive = harnessSessionActive(input.entries);
144
+
145
+ const MUTATING_FILE_TOOLS = new Set(["write", "edit"]);
146
+ const planMutation =
147
+ sessionActive && MUTATING_FILE_TOOLS.has(input.toolName)
148
+ ? await isPlanPhaseAllowedMutation(
149
+ input.toolName,
150
+ input.toolInput,
151
+ phase,
152
+ runCtx,
153
+ input.projectRoot,
154
+ {
155
+ aborted: input.policyState.aborted,
156
+ entries: input.entries,
157
+ ownerSessionId: runCtx?.owner_pi_session_id,
158
+ currentSessionId: input.sessionId,
159
+ },
160
+ )
161
+ : { allowed: true };
162
+
163
+ const ctxMode = sessionActive
164
+ ? evaluateContextModeMutation(input.toolName, input.toolInput, phase, {
165
+ aborted: input.policyState.aborted,
166
+ budgetBypass: input.policyState.budgetBypass,
167
+ readOnlyAgent:
168
+ agentKind === "planner" ||
169
+ agentKind === "evaluator" ||
170
+ agentKind === "adversary" ||
171
+ agentKind === "tie_breaker",
172
+ })
173
+ : { blocked: false, reason: "" };
174
+
175
+ const spawnDecision = evaluateSubagentToolCall(input.toolName, agentId);
176
+
177
+ const toolAllowed = allowsAgentTool({
178
+ packageRoot: input.packageRoot,
179
+ projectRoot: input.projectRoot,
180
+ agentId,
181
+ toolName: input.toolName,
182
+ toolInput: input.toolInput,
183
+ isSubprocess,
184
+ isParentOrchestrator,
185
+ });
186
+
187
+ let evalPlanPacketBlock = false;
188
+ if (
189
+ sessionActive &&
190
+ runCtx?.plan_packet_path &&
191
+ (phase === "evaluate" || phase === "adversary") &&
192
+ (input.toolName === "write" || input.toolName === "edit")
193
+ ) {
194
+ const target = String(
195
+ input.toolInput.path ?? input.toolInput.filePath ?? "",
196
+ );
197
+ if (target.includes("plan-packet.yaml")) {
198
+ evalPlanPacketBlock = true;
199
+ }
200
+ }
201
+
202
+ const writePath =
203
+ input.toolName === "write" || input.toolName === "edit"
204
+ ? extractWritePathFromToolInput(input.toolInput)
205
+ : null;
206
+
207
+ const mutatingBashPhaseBlock =
208
+ sessionActive &&
209
+ Boolean(bashCommand && isMutatingBash(bashCommand)) &&
210
+ !input.policyState.aborted &&
211
+ phase !== "execute" &&
212
+ phase !== "merge";
213
+
214
+ const abortMutatingBlock =
215
+ sessionActive &&
216
+ input.policyState.aborted &&
217
+ ((bashCommand && isMutatingBash(bashCommand)) ||
218
+ input.toolName === "write" ||
219
+ input.toolName === "edit");
220
+
221
+ return {
222
+ tool_name: input.toolName,
223
+ harness_phase: phase,
224
+ harness_agent_id: agentId,
225
+ harness_agent_kind: agentKind,
226
+ is_subprocess: isSubprocess,
227
+ is_parent_orchestrator: isParentOrchestrator,
228
+ harness_session_active: sessionActive,
229
+ is_harness_agent: agentId.startsWith("harness/"),
230
+ approved_plan: input.policyState.approvedPlan,
231
+ plan_ready: Boolean(runCtx?.plan_ready),
232
+ aborted: input.policyState.aborted,
233
+ budget_bypass: input.policyState.budgetBypass,
234
+ run_id: runCtx?.run_id ?? process.env.HARNESS_RUN_ID ?? "",
235
+ plan_id: input.policyState.planId ?? runCtx?.plan_id ?? "",
236
+ plan_mutation_allowed: planMutation.allowed,
237
+ plan_mutation_block: sessionActive && !planMutation.allowed,
238
+ context_mode_block: ctxMode.blocked,
239
+ tool_allowed: toolAllowed,
240
+ spawn_policy_block: spawnDecision.action === "block",
241
+ is_mutating_bash: bashCommand ? isMutatingBash(bashCommand) : false,
242
+ is_mutating_write_tool:
243
+ input.toolName === "write" || input.toolName === "edit",
244
+ bash_web_block: sessionActive && bashWebBlocked(bashCommand),
245
+ bash_planning_deny:
246
+ sessionActive && bashPlanningDenied(bashCommand, agentId),
247
+ bash_planning_json_block:
248
+ sessionActive && bashPlanningJsonDenied(bashCommand, agentId),
249
+ eval_plan_packet_write_block: evalPlanPacketBlock,
250
+ is_submit_tool: input.toolName.startsWith("submit_"),
251
+ is_planning_agent: isHarnessPlanningAgent(agentId),
252
+ is_read_only_kind:
253
+ agentKind === "planner" ||
254
+ agentKind === "evaluator" ||
255
+ agentKind === "adversary" ||
256
+ agentKind === "tie_breaker" ||
257
+ agentKind === "trace" ||
258
+ agentKind === "incident" ||
259
+ agentKind === "meta",
260
+ is_executor_kind: agentKind === "executor",
261
+ trust_score: Number(process.env.HARNESS_TRUST_SCORE ?? "1"),
262
+ delegation_ceiling: Number(process.env.HARNESS_DELEGATION_CEILING ?? "1"),
263
+ agent_did: input.agentDid ?? process.env.HARNESS_AGENT_DID ?? agentId,
264
+ write_path: writePath ?? "",
265
+ mutating_bash_phase_block: mutatingBashPhaseBlock,
266
+ abort_mutating_block: abortMutatingBlock,
267
+ };
268
+ }
269
+
270
+ export async function buildHarnessAgtEvaluationContextFromRun(
271
+ input: Omit<BuildEvaluationContextInput, "policyState"> & {
272
+ policyState?: BuildEvaluationContextInput["policyState"];
273
+ },
274
+ ): Promise<HarnessAgtContext> {
275
+ const policyState = input.policyState ?? {
276
+ phase: (process.env.HARNESS_SUBAGENT_PHASE_HINT as HarnessPhase) ?? "plan",
277
+ approvedPlan: true,
278
+ planId: null,
279
+ aborted: false,
280
+ budgetBypass: false,
281
+ };
282
+ return buildHarnessAgtEvaluationContext({ ...input, policyState });
283
+ }
284
+
285
+ export type { HarnessRunContext };