ultimate-pi 0.18.0 → 0.19.0

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 (314) hide show
  1. package/.agents/skills/harness-debate-plan/SKILL.md +1 -1
  2. package/.agents/skills/harness-decisions/SKILL.md +2 -3
  3. package/.agents/skills/harness-governor/SKILL.md +6 -5
  4. package/.agents/skills/harness-orchestration/SKILL.md +4 -4
  5. package/.agents/skills/harness-review/SKILL.md +7 -7
  6. package/.agents/skills/harness-sentrux-setup/SKILL.md +4 -3
  7. package/.agents/skills/harness-steer/SKILL.md +1 -1
  8. package/.agents/skills/sentrux/SKILL.md +9 -9
  9. package/.pi/PACKAGING.md +4 -4
  10. package/.pi/SYSTEM.md +54 -120
  11. package/.pi/agents/harness/incident-recorder.md +0 -1
  12. package/.pi/agents/harness/planning/decompose.md +1 -3
  13. package/.pi/agents/harness/planning/execution-plan-author.md +0 -2
  14. package/.pi/agents/harness/planning/hypothesis-validator.md +0 -2
  15. package/.pi/agents/harness/planning/hypothesis.md +0 -2
  16. package/.pi/agents/harness/planning/implementation-researcher.md +0 -2
  17. package/.pi/agents/harness/planning/plan-adversary.md +0 -2
  18. package/.pi/agents/harness/planning/plan-evaluator.md +1 -3
  19. package/.pi/agents/harness/planning/planning-context.md +0 -2
  20. package/.pi/agents/harness/planning/review-integrator.md +0 -2
  21. package/.pi/agents/harness/planning/sprint-contract-auditor.md +0 -2
  22. package/.pi/agents/harness/planning/stack-researcher.md +0 -2
  23. package/.pi/agents/harness/{adversary.md → reviewing/adversary.md} +0 -2
  24. package/.pi/agents/harness/{evaluator.md → reviewing/evaluator.md} +0 -2
  25. package/.pi/agents/harness/{tie-breaker.md → reviewing/tie-breaker.md} +0 -2
  26. package/.pi/agents/harness/{executor.md → running/executor.md} +0 -2
  27. package/.pi/agents/harness/sentrux-bootstrap.md +0 -1
  28. package/.pi/agents/harness/sentrux-steward.md +0 -2
  29. package/.pi/agents/harness/trace-librarian.md +0 -1
  30. package/.pi/extensions/00-harness-project-control.ts +133 -0
  31. package/.pi/extensions/00-posthog-network-bootstrap.ts +1 -1
  32. package/.pi/extensions/agt-kill-switch.ts +57 -0
  33. package/.pi/extensions/agt-prompt-guard.ts +32 -0
  34. package/.pi/extensions/budget-guard.ts +2 -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 +7 -5
  39. package/.pi/extensions/harness-ask-user.ts +8 -8
  40. package/.pi/extensions/harness-debate-tools.ts +27 -43
  41. package/.pi/extensions/harness-lens.ts +94 -0
  42. package/.pi/extensions/harness-live-widget.ts +33 -2
  43. package/.pi/extensions/harness-plan-approval.ts +12 -12
  44. package/.pi/extensions/harness-run-context.ts +1214 -852
  45. package/.pi/extensions/harness-subagent-governance.ts +8 -0
  46. package/.pi/extensions/harness-subagent-submit.ts +36 -164
  47. package/.pi/extensions/harness-subagents.ts +4 -4
  48. package/.pi/extensions/harness-telemetry.ts +3 -1
  49. package/.pi/extensions/harness-web-tools.ts +3 -3
  50. package/.pi/extensions/observation-bus.ts +2 -0
  51. package/.pi/extensions/policy-gate.ts +27 -5
  52. package/.pi/extensions/review-integrity.ts +91 -10
  53. package/.pi/extensions/sentrux-rules-sync.ts +3 -1
  54. package/.pi/extensions/subagent-governance.ts +92 -0
  55. package/.pi/extensions/test-diff-integrity.ts +1 -0
  56. package/.pi/extensions/trace-recorder.ts +3 -1
  57. package/.pi/extensions/{ultimate-pi-vcc.ts → vcc-compaction.ts} +1 -1
  58. package/.pi/harness/README.md +6 -2
  59. package/.pi/harness/agents.manifest.json +38 -49
  60. package/.pi/harness/agents.policy.yaml +275 -0
  61. package/.pi/harness/corpus/graphify-kb-updater.config.json +55 -0
  62. package/.pi/harness/docs/adrs/0006-sentrux-dual-layer.md +2 -1
  63. package/.pi/harness/docs/adrs/0030-inhouse-vcc-compaction.md +1 -1
  64. package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +1 -1
  65. package/.pi/harness/docs/adrs/0044-harness-steer-loop.md +3 -2
  66. package/.pi/harness/docs/adrs/0045-harness-lens-minimal-contract.md +49 -0
  67. package/.pi/harness/docs/adrs/0045-phase-scoped-agent-directories.md +33 -0
  68. package/.pi/harness/docs/adrs/0046-agt-policy-engine.md +51 -0
  69. package/.pi/harness/docs/adrs/0047-agt-layered-security.md +39 -0
  70. package/.pi/harness/docs/adrs/0048-tool-call-hook-order.md +25 -0
  71. package/.pi/harness/docs/adrs/0049-agents-policy-manifest.md +36 -0
  72. package/.pi/harness/docs/adrs/README.md +6 -0
  73. package/.pi/harness/docs/graphify-kb-updater-runbook.md +11 -5
  74. package/.pi/harness/docs/practice-map.md +2 -2
  75. package/.pi/harness/evolution/README.md +1 -2
  76. package/.pi/harness/examples/agents.policy.project.yaml +19 -0
  77. package/.pi/harness/examples/policies/custom-deny-bash.yaml +9 -0
  78. package/.pi/harness/policies/bash-denylists.yaml +5 -0
  79. package/.pi/harness/policies/defaults.yaml +51 -0
  80. package/.pi/harness/policies/orchestrator.yaml +18 -0
  81. package/.pi/harness/policies/phases.yaml +10 -0
  82. package/.pi/harness/policies/roles.yaml +5 -0
  83. package/.pi/harness/policies/web-guard.yaml +5 -0
  84. package/.pi/harness/policies/workflow-sequences.yaml +9 -0
  85. package/.pi/harness/sentrux/architecture.manifest.json +26 -4
  86. package/.pi/harness/specs/harness-spawn-context.schema.json +1 -1
  87. package/.pi/harness/specs/observation.schema.json +2 -1
  88. package/.pi/lib/agents-policy.d.mts +70 -0
  89. package/.pi/lib/agents-policy.mjs +325 -0
  90. package/.pi/lib/agents-policy.ts +19 -0
  91. package/.pi/lib/agt/audit-run-sink.ts +52 -0
  92. package/.pi/lib/agt/build-evaluation-context.ts +285 -0
  93. package/.pi/lib/agt/config.ts +28 -0
  94. package/.pi/lib/agt/delegation.ts +69 -0
  95. package/.pi/lib/agt/evaluate-policy.ts +56 -0
  96. package/.pi/lib/agt/identity-registry.ts +41 -0
  97. package/.pi/lib/agt/index.ts +55 -0
  98. package/.pi/lib/agt/kill-switch-state.ts +11 -0
  99. package/.pi/lib/agt/legacy-evaluate.ts +101 -0
  100. package/.pi/lib/agt/policy-engine.ts +154 -0
  101. package/.pi/lib/agt/rings.ts +21 -0
  102. package/.pi/lib/agt/sre-hooks.ts +45 -0
  103. package/.pi/lib/agt/trust-run-store.ts +26 -0
  104. package/.pi/lib/agt/workflow-history.ts +29 -0
  105. package/.pi/lib/agt-governance-active.ts +14 -0
  106. package/.pi/lib/agt-tool-guard.ts +78 -0
  107. package/.pi/lib/ask-user/dialog.ts +314 -0
  108. package/.pi/{extensions/lib → lib}/debate-bus-core.ts +10 -10
  109. package/.pi/{extensions/lib → lib}/debate-bus-state.ts +1 -1
  110. package/.pi/{extensions/lib → lib}/extension-load-guard.ts +21 -0
  111. package/.pi/lib/harness-agt-tool-guard.ts +5 -0
  112. package/.pi/{extensions/lib → lib}/harness-artifact-gate.ts +6 -16
  113. package/.pi/lib/harness-debate-core-deps.ts +14 -0
  114. package/.pi/lib/harness-debate-workflow-deps.ts +43 -0
  115. package/.pi/lib/harness-lens/.gitattributes +1 -0
  116. package/.pi/lib/harness-lens/clients/edit-autopatch.ts +88 -0
  117. package/.pi/lib/harness-lens/clients/file-kinds.ts +380 -0
  118. package/.pi/lib/harness-lens/clients/file-time.ts +215 -0
  119. package/.pi/lib/harness-lens/clients/file-utils.ts +484 -0
  120. package/.pi/lib/harness-lens/clients/format-service.ts +276 -0
  121. package/.pi/lib/harness-lens/clients/formatters.ts +1000 -0
  122. package/.pi/lib/harness-lens/clients/git-guard.ts +31 -0
  123. package/.pi/lib/harness-lens/clients/indent-retarget.ts +90 -0
  124. package/.pi/lib/harness-lens/clients/installer/index.ts +2368 -0
  125. package/.pi/lib/harness-lens/clients/latency-logger.ts +80 -0
  126. package/.pi/lib/harness-lens/clients/lens-config.ts +43 -0
  127. package/.pi/lib/harness-lens/clients/lens-events.ts +164 -0
  128. package/.pi/lib/harness-lens/clients/lsp/aggregation.ts +91 -0
  129. package/.pi/lib/harness-lens/clients/lsp/client.ts +1466 -0
  130. package/.pi/lib/harness-lens/clients/lsp/config.ts +216 -0
  131. package/.pi/lib/harness-lens/clients/lsp/edits.ts +297 -0
  132. package/.pi/lib/harness-lens/clients/lsp/index.ts +1355 -0
  133. package/.pi/lib/harness-lens/clients/lsp/interactive-install.ts +424 -0
  134. package/.pi/lib/harness-lens/clients/lsp/language.ts +223 -0
  135. package/.pi/lib/harness-lens/clients/lsp/launch.ts +939 -0
  136. package/.pi/lib/harness-lens/clients/lsp/lsp-index.ts +11 -0
  137. package/.pi/lib/harness-lens/clients/lsp/path-utils.ts +12 -0
  138. package/.pi/lib/harness-lens/clients/lsp/server-strategies.ts +81 -0
  139. package/.pi/lib/harness-lens/clients/lsp/server.ts +1971 -0
  140. package/.pi/lib/harness-lens/clients/path-utils.ts +182 -0
  141. package/.pi/lib/harness-lens/clients/pipeline.ts +360 -0
  142. package/.pi/lib/harness-lens/clients/project-profile.ts +117 -0
  143. package/.pi/lib/harness-lens/clients/runtime-agent-end.ts +112 -0
  144. package/.pi/lib/harness-lens/clients/runtime-config.ts +33 -0
  145. package/.pi/lib/harness-lens/clients/runtime-coordinator.ts +186 -0
  146. package/.pi/lib/harness-lens/clients/runtime-tool-result.ts +171 -0
  147. package/.pi/lib/harness-lens/clients/safe-spawn.ts +339 -0
  148. package/.pi/lib/harness-lens/clients/secrets-scanner.ts +214 -0
  149. package/.pi/lib/harness-lens/clients/tool-policy.ts +2072 -0
  150. package/.pi/lib/harness-lens/clients/types.ts +59 -0
  151. package/.pi/lib/harness-lens/clients/widget-state.ts +283 -0
  152. package/.pi/lib/harness-lens/index.ts +532 -0
  153. package/.pi/lib/harness-lens/tools/lsp-diagnostics.ts +706 -0
  154. package/.pi/lib/harness-lens/tools/lsp-navigation.ts +1246 -0
  155. package/.pi/{extensions/lib → lib}/harness-posthog.ts +3 -0
  156. package/.pi/lib/harness-project-config.ts +91 -0
  157. package/.pi/lib/harness-run-context-responses.ts +9 -0
  158. package/.pi/lib/harness-run-context.ts +1 -3
  159. package/.pi/{extensions/lib/spawn-policy.ts → lib/harness-spawn-policy.ts} +4 -3
  160. package/.pi/{extensions/lib → lib}/harness-spawn-topology.ts +5 -28
  161. package/.pi/lib/harness-subagent-auth.ts +51 -0
  162. package/.pi/{extensions/lib → lib}/harness-subagent-precheck.ts +13 -10
  163. package/.pi/{extensions/lib → lib}/harness-subagent-submit-pipeline.ts +3 -3
  164. package/.pi/lib/harness-subagent-submit-register.ts +163 -0
  165. package/.pi/{extensions/lib → lib}/harness-subagent-submit-registry.ts +1 -55
  166. package/.pi/{extensions/lib → lib}/harness-subagents-bridge.ts +53 -14
  167. package/.pi/{extensions/lib → lib}/harness-subprocess-bootstrap.ts +1 -1
  168. package/.pi/lib/harness-ui-state.ts +27 -12
  169. package/.pi/{extensions/lib → lib}/plan-approval/create-plan.ts +2 -2
  170. package/.pi/{extensions/lib → lib}/plan-approval/format-plan.ts +2 -2
  171. package/.pi/{extensions/lib → lib}/plan-approval/plan-review.ts +162 -201
  172. package/.pi/{extensions/lib → lib}/plan-approval/render.ts +1 -1
  173. package/.pi/{extensions/lib → lib}/plan-approval/resolve-disk.ts +2 -2
  174. package/.pi/{extensions/lib → lib}/plan-approval/types.ts +1 -1
  175. package/.pi/{extensions/lib → lib}/plan-approval/validate.ts +3 -3
  176. package/.pi/{extensions/lib → lib}/plan-approval-readiness.ts +3 -52
  177. package/.pi/{extensions/lib → lib}/plan-debate-envelope.ts +1 -1
  178. package/.pi/{extensions/lib → lib}/plan-debate-gate.ts +1 -1
  179. package/.pi/{extensions/lib → lib}/plan-debate-lane.ts +1 -4
  180. package/.pi/{extensions/lib → lib}/plan-messenger.ts +1 -1
  181. package/.pi/prompts/harness-auto.md +2 -2
  182. package/.pi/prompts/harness-plan.md +4 -6
  183. package/.pi/prompts/harness-review.md +9 -9
  184. package/.pi/prompts/harness-run.md +7 -7
  185. package/.pi/prompts/harness-setup.md +42 -68
  186. package/.pi/prompts/harness-steer.md +2 -2
  187. package/.pi/scripts/README.md +3 -5
  188. package/.pi/scripts/generate-agents-policy-yaml.mjs +148 -0
  189. package/.pi/scripts/graphify-kb-updater.mjs +48 -8
  190. package/.pi/scripts/harness-agents-manifest.mjs +61 -4
  191. package/.pi/scripts/harness-agt-doctor.ts +36 -0
  192. package/.pi/scripts/harness-cli-verify.sh +9 -2
  193. package/.pi/scripts/harness-project-toggle.mjs +129 -0
  194. package/.pi/scripts/harness-sentrux-cli.mjs +142 -0
  195. package/.pi/scripts/harness-verify.mjs +113 -39
  196. package/.pi/scripts/harness-web-policy-guard.mjs +2 -2
  197. package/.pi/scripts/validate-plan-dag.mjs +65 -74
  198. package/.pi/scripts/vendor-pi-vcc-settings.stub.ts +2 -2
  199. package/.pi/scripts/vendor-sync-pi-vcc.sh +1 -1
  200. package/.pi/skills/architecture/broker-domain/SKILL.md +65 -0
  201. package/.pi/skills/architecture/cqrs/SKILL.md +63 -0
  202. package/.pi/skills/architecture/event-driven/SKILL.md +60 -0
  203. package/.pi/skills/architecture/hexagonal-ports-adapters/SKILL.md +66 -0
  204. package/.pi/skills/architecture/layered/SKILL.md +68 -0
  205. package/.pi/skills/architecture/microkernel/SKILL.md +62 -0
  206. package/.pi/skills/architecture/microservices/SKILL.md +64 -0
  207. package/.pi/skills/architecture/modular-monolith/SKILL.md +65 -0
  208. package/.pi/skills/architecture/orchestration-driven-soa/SKILL.md +61 -0
  209. package/.pi/skills/architecture/pipeline/SKILL.md +63 -0
  210. package/.pi/skills/architecture/service-based/SKILL.md +64 -0
  211. package/.pi/skills/architecture/service-mesh/SKILL.md +60 -0
  212. package/.pi/skills/architecture/space-based/SKILL.md +60 -0
  213. package/.pi/skills/ast-grep/SKILL.md +40 -321
  214. package/.pi/skills/delivery/debugging-discipline/SKILL.md +36 -0
  215. package/.pi/skills/delivery/documentation-update/SKILL.md +33 -0
  216. package/.pi/skills/delivery/requirements-to-implementation/SKILL.md +34 -0
  217. package/.pi/skills/delivery/risk-based-verification/SKILL.md +43 -0
  218. package/.pi/skills/delivery/tradeoff-analysis/SKILL.md +34 -0
  219. package/.pi/skills/engineering/api-contract-design/SKILL.md +38 -0
  220. package/.pi/skills/engineering/cohesion-coupling/SKILL.md +43 -0
  221. package/.pi/skills/engineering/complexity-control/SKILL.md +31 -0
  222. package/.pi/skills/engineering/defensive-programming/SKILL.md +38 -0
  223. package/.pi/skills/engineering/dependency-management/SKILL.md +29 -0
  224. package/.pi/skills/engineering/domain-modeling/SKILL.md +32 -0
  225. package/.pi/skills/engineering/error-handling/SKILL.md +37 -0
  226. package/.pi/skills/engineering/legacy-code-seams/SKILL.md +35 -0
  227. package/.pi/skills/engineering/naming-and-intent/SKILL.md +29 -0
  228. package/.pi/skills/engineering/refactoring-safe-evolution/SKILL.md +35 -0
  229. package/.pi/skills/engineering/routine-function-design/SKILL.md +34 -0
  230. package/.pi/skills/engineering/small-change-discipline/SKILL.md +35 -0
  231. package/.pi/skills/lsp-navigation/SKILL.md +89 -0
  232. package/.pi/skills/quality/code-review-self-check/SKILL.md +35 -0
  233. package/.pi/skills/quality/privacy-data-handling/SKILL.md +26 -0
  234. package/.pi/skills/quality/security-review/SKILL.md +34 -0
  235. package/.pi/skills/quality/test-strategy/SKILL.md +33 -0
  236. package/.pi/skills/quality/testability-design/SKILL.md +33 -0
  237. package/.pi/skills/systems/concurrency-safety/SKILL.md +32 -0
  238. package/.pi/skills/systems/data-modeling-migrations/SKILL.md +31 -0
  239. package/.pi/skills/systems/observability-instrumentation/SKILL.md +32 -0
  240. package/.pi/skills/systems/performance-measurement/SKILL.md +35 -0
  241. package/.pi/skills/systems/reliability-design/SKILL.md +32 -0
  242. package/.sentrux/rules.toml +20 -4
  243. package/AGENTS.md +5 -0
  244. package/CHANGELOG.md +26 -0
  245. package/README.md +85 -58
  246. package/THIRD_PARTY_NOTICES.md +12 -21
  247. package/package.json +15 -7
  248. package/vendor/pi-subagents/src/agents.ts +45 -1
  249. package/vendor/pi-subagents/src/subagents.ts +866 -811
  250. package/vendor/pi-vcc/src/core/brief.ts +68 -99
  251. package/vendor/pi-vcc/src/core/settings.ts +2 -2
  252. package/.agents/skills/caveman/SKILL.md +0 -67
  253. package/.pi/agents/harness/meta-optimizer.md +0 -36
  254. package/.pi/agents/harness/planning/scout-graphify.md +0 -39
  255. package/.pi/agents/harness/planning/scout-semantic.md +0 -41
  256. package/.pi/agents/harness/planning/scout-structure.md +0 -37
  257. package/.pi/extensions/lib/ask-user/dialog.ts +0 -260
  258. package/.pi/extensions/lib/harness-subagent-auth.ts +0 -209
  259. package/.pi/extensions/lib/harness-subagent-policy.ts +0 -236
  260. package/.pi/extensions/pi-model-router-harness.ts +0 -42
  261. package/.pi/harness/evolution/meta-optimizer.mjs +0 -99
  262. package/.pi/harness/specs/router-tuning-proposal.schema.json +0 -114
  263. package/.pi/model-router.example.json +0 -36
  264. package/.pi/prompts/harness-critic.md +0 -10
  265. package/.pi/prompts/harness-eval.md +0 -10
  266. package/.pi/prompts/harness-router-tune.md +0 -52
  267. package/.pi/scripts/harness-generate-model-router.mjs +0 -327
  268. package/.pi/scripts/harness-model-router-routing.test.mjs +0 -97
  269. package/.pi/scripts/harness-sync-model-router.mjs +0 -97
  270. package/.pi/scripts/vendor-sync-pi-model-router.sh +0 -47
  271. package/vendor/pi-model-router/.prettierignore +0 -4
  272. package/vendor/pi-model-router/.prettierrc +0 -5
  273. package/vendor/pi-model-router/AGENTS.md +0 -39
  274. package/vendor/pi-model-router/LICENSE +0 -21
  275. package/vendor/pi-model-router/README.md +0 -99
  276. package/vendor/pi-model-router/UPSTREAM_PIN.md +0 -10
  277. package/vendor/pi-model-router/docs/ARCHITECTURE.md +0 -54
  278. package/vendor/pi-model-router/extensions/commands.ts +0 -720
  279. package/vendor/pi-model-router/extensions/config.ts +0 -348
  280. package/vendor/pi-model-router/extensions/constants.ts +0 -1
  281. package/vendor/pi-model-router/extensions/index.ts +0 -478
  282. package/vendor/pi-model-router/extensions/provider.ts +0 -580
  283. package/vendor/pi-model-router/extensions/routing.ts +0 -564
  284. package/vendor/pi-model-router/extensions/state.ts +0 -52
  285. package/vendor/pi-model-router/extensions/types.ts +0 -95
  286. package/vendor/pi-model-router/extensions/ui.ts +0 -144
  287. package/vendor/pi-model-router/model-router.example.json +0 -48
  288. package/vendor/pi-model-router/package.json +0 -48
  289. package/vendor/pi-model-router/tsconfig.json +0 -16
  290. /package/.pi/{prompts → harness/docs}/planning-rubrics.md +0 -0
  291. /package/.pi/{extensions/lib → lib}/ask-user/fallback.ts +0 -0
  292. /package/.pi/{extensions/lib → lib}/ask-user/render.ts +0 -0
  293. /package/.pi/{extensions/lib → lib}/ask-user/schema.ts +0 -0
  294. /package/.pi/{extensions/lib → lib}/ask-user/types.ts +0 -0
  295. /package/.pi/{extensions/lib → lib}/ask-user/validate-core.mjs +0 -0
  296. /package/.pi/{extensions/lib → lib}/ask-user/validate.ts +0 -0
  297. /package/.pi/{extensions/lib → lib}/harness-cocoindex-refresh.ts +0 -0
  298. /package/.pi/{extensions/lib → lib}/harness-paths.ts +0 -0
  299. /package/.pi/{extensions/lib → lib}/harness-spawn-budget.ts +0 -0
  300. /package/.pi/{extensions/lib → lib}/harness-vcc-settings.ts +0 -0
  301. /package/.pi/{extensions/lib → lib}/harness-web/run-cli.ts +0 -0
  302. /package/.pi/{extensions/lib → lib}/plan-approval/dialog.ts +0 -0
  303. /package/.pi/{extensions/lib → lib}/plan-approval/schema.ts +0 -0
  304. /package/.pi/{extensions/lib → lib}/plan-debate-eligibility.ts +0 -0
  305. /package/.pi/{extensions/lib → lib}/plan-debate-focus.ts +0 -0
  306. /package/.pi/{extensions/lib → lib}/plan-debate-id.ts +0 -0
  307. /package/.pi/{extensions/lib → lib}/plan-debate-lanes.ts +0 -0
  308. /package/.pi/{extensions/lib → lib}/plan-debate-round-status.ts +0 -0
  309. /package/.pi/{extensions/lib → lib}/plan-debate-write-guard.ts +0 -0
  310. /package/.pi/{extensions/lib → lib}/plan-review-gate.ts +0 -0
  311. /package/.pi/{extensions/lib → lib}/plan-review-integrator-rules.ts +0 -0
  312. /package/.pi/{extensions/lib → lib}/plan-scope-guard.ts +0 -0
  313. /package/.pi/{extensions/lib → lib}/posthog-client.ts +0 -0
  314. /package/.pi/{extensions/lib → lib}/posthog-node.d.ts +0 -0
@@ -0,0 +1,69 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { getOrCreateParentIdentity } from "./identity-registry.js";
4
+
5
+ const ROLE_CAPABILITIES: Record<string, string[]> = {
6
+ planner: ["harness.read", "harness.submit.plan"],
7
+ executor: ["harness.read", "harness.write", "harness.submit.run"],
8
+ evaluator: ["harness.read", "harness.submit.review"],
9
+ adversary: ["harness.read", "harness.submit.review"],
10
+ tie_breaker: ["harness.read", "harness.submit.review"],
11
+ meta: ["harness.read"],
12
+ trace: ["harness.read"],
13
+ incident: ["harness.read"],
14
+ other: ["harness.read"],
15
+ };
16
+
17
+ export function capabilitiesForHarnessAgent(
18
+ agentId: string,
19
+ kind: string,
20
+ ): string[] {
21
+ if (agentId.startsWith("harness/planning/")) {
22
+ return ROLE_CAPABILITIES.planner ?? ["harness.read"];
23
+ }
24
+ return ROLE_CAPABILITIES[kind] ?? ROLE_CAPABILITIES.other;
25
+ }
26
+
27
+ export interface DelegationBundle {
28
+ agentDid: string;
29
+ delegationCeiling: number;
30
+ identityPath: string;
31
+ }
32
+
33
+ export function mintSubagentDelegation(input: {
34
+ runId: string;
35
+ runDir: string;
36
+ agentId: string;
37
+ agentKind: string;
38
+ trustCeiling?: number;
39
+ }): DelegationBundle {
40
+ const parent = getOrCreateParentIdentity(input.runId, input.runDir);
41
+ const caps = capabilitiesForHarnessAgent(input.agentId, input.agentKind);
42
+ const safeId = input.agentId.replace(/\//g, "_");
43
+ const agentDir = join(input.runDir, "agents", safeId);
44
+ mkdirSync(agentDir, { recursive: true });
45
+
46
+ const child = parent.delegate(`harness-${safeId}`, caps, {
47
+ description: `Harness subagent ${input.agentId}`,
48
+ });
49
+ writeFileSync(
50
+ join(agentDir, "identity.json"),
51
+ JSON.stringify(child.toJSON(), null, 2),
52
+ );
53
+
54
+ const ceiling = input.trustCeiling ?? 1;
55
+ return {
56
+ agentDid: child.did,
57
+ delegationCeiling: ceiling,
58
+ identityPath: join(agentDir, "identity.json"),
59
+ };
60
+ }
61
+
62
+ export function delegationEnvFromBundle(
63
+ bundle: DelegationBundle,
64
+ ): Record<string, string> {
65
+ return {
66
+ HARNESS_AGENT_DID: bundle.agentDid,
67
+ HARNESS_DELEGATION_CEILING: String(bundle.delegationCeiling),
68
+ };
69
+ }
@@ -0,0 +1,56 @@
1
+ import type { PolicyDecisionResult } from "@microsoft/agent-governance-sdk";
2
+ import type { BuildEvaluationContextInput } from "./build-evaluation-context.js";
3
+ import { buildHarnessAgtEvaluationContext } from "./build-evaluation-context.js";
4
+ import { isHarnessAgtPolicyEnabled } from "./config.js";
5
+ import { evaluateLegacyHarnessToolPolicy } from "./legacy-evaluate.js";
6
+ import { getAgtPolicyEngine } from "./policy-engine.js";
7
+
8
+ export interface HarnessPolicyEvaluation {
9
+ allowed: boolean;
10
+ reason: string;
11
+ source: "agt" | "legacy";
12
+ agt?: PolicyDecisionResult;
13
+ }
14
+
15
+ export async function evaluateHarnessToolPolicy(
16
+ packageRoot: string,
17
+ input: BuildEvaluationContextInput,
18
+ ): Promise<HarnessPolicyEvaluation> {
19
+ if (!isHarnessAgtPolicyEnabled()) {
20
+ const legacy = await evaluateLegacyHarnessToolPolicy(input);
21
+ return {
22
+ allowed: legacy.allowed,
23
+ reason: legacy.reason,
24
+ source: "legacy",
25
+ };
26
+ }
27
+
28
+ try {
29
+ const context = await buildHarnessAgtEvaluationContext(input);
30
+ const engine = getAgtPolicyEngine(packageRoot, input.projectRoot);
31
+ const agentDid = String(context.agent_did ?? context.harness_agent_id);
32
+ const result = engine.evaluatePolicy(agentDid, context);
33
+ if (!result.allowed) {
34
+ return {
35
+ allowed: false,
36
+ reason:
37
+ result.reason ??
38
+ `agt-policy: denied by ${result.policyName ?? "policy"}/${result.matchedRule ?? "rule"}`,
39
+ source: "agt",
40
+ agt: result,
41
+ };
42
+ }
43
+ return {
44
+ allowed: true,
45
+ reason: result.reason ?? "allow",
46
+ source: "agt",
47
+ agt: result,
48
+ };
49
+ } catch (err) {
50
+ return {
51
+ allowed: false,
52
+ reason: `agt-policy: evaluation failed (fail-closed): ${String(err)}`,
53
+ source: "agt",
54
+ };
55
+ }
56
+ }
@@ -0,0 +1,41 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { AgentIdentity } from "@microsoft/agent-governance-sdk";
4
+
5
+ const runRoots = new Map<string, AgentIdentity>();
6
+
7
+ export function getOrCreateParentIdentity(
8
+ runId: string,
9
+ runDir: string,
10
+ ): AgentIdentity {
11
+ const cached = runRoots.get(runId);
12
+ if (cached) return cached;
13
+
14
+ const agentsDir = join(runDir, "agents", "_parent");
15
+ const identityPath = join(agentsDir, "identity.json");
16
+ mkdirSync(agentsDir, { recursive: true });
17
+
18
+ if (existsSync(identityPath)) {
19
+ const json = JSON.parse(readFileSync(identityPath, "utf-8"));
20
+ const restored = AgentIdentity.fromJSON(json);
21
+ runRoots.set(runId, restored);
22
+ return restored;
23
+ }
24
+
25
+ const identity = AgentIdentity.generate(`harness-parent-${runId}`, [
26
+ "harness.orchestrate",
27
+ "harness.delegate",
28
+ "harness.plan",
29
+ "harness.execute",
30
+ ]);
31
+ writeFileSync(identityPath, JSON.stringify(identity.toJSON(), null, 2));
32
+ runRoots.set(runId, identity);
33
+ return identity;
34
+ }
35
+
36
+ export function loadChildIdentity(agentDir: string): AgentIdentity | null {
37
+ const identityPath = join(agentDir, "identity.json");
38
+ if (!existsSync(identityPath)) return null;
39
+ const json = JSON.parse(readFileSync(identityPath, "utf-8"));
40
+ return AgentIdentity.fromJSON(json);
41
+ }
@@ -0,0 +1,55 @@
1
+ export {
2
+ appendPolicyAuditEvent,
3
+ verifyRunAuditChain,
4
+ } from "./audit-run-sink.js";
5
+ export type {
6
+ BuildEvaluationContextInput,
7
+ HarnessAgtContext,
8
+ } from "./build-evaluation-context.js";
9
+ export {
10
+ buildHarnessAgtEvaluationContext,
11
+ buildHarnessAgtEvaluationContextFromRun,
12
+ } from "./build-evaluation-context.js";
13
+ export {
14
+ isHarnessAgtPolicyEnabled,
15
+ resolveHarnessPackageRootFromEnv,
16
+ resolveHarnessPoliciesDir,
17
+ } from "./config.js";
18
+ export {
19
+ capabilitiesForHarnessAgent,
20
+ delegationEnvFromBundle,
21
+ mintSubagentDelegation,
22
+ } from "./delegation.js";
23
+ export type { HarnessPolicyEvaluation } from "./evaluate-policy.js";
24
+ export { evaluateHarnessToolPolicy } from "./evaluate-policy.js";
25
+ export {
26
+ getOrCreateParentIdentity,
27
+ loadChildIdentity,
28
+ } from "./identity-registry.js";
29
+ export { evaluateLegacyHarnessToolPolicy } from "./legacy-evaluate.js";
30
+ export {
31
+ createAgtPolicyEngine,
32
+ createHarnessPolicyEngine,
33
+ doctorHarnessPolicies,
34
+ getAgtPolicyEngine,
35
+ getHarnessPolicyEngine,
36
+ HarnessPolicyLoadError,
37
+ resetHarnessPolicyEngineCache,
38
+ } from "./policy-engine.js";
39
+ export { createRingEnforcer, ringForHarnessAgentKind } from "./rings.js";
40
+ export {
41
+ getHarnessGovernanceMetrics,
42
+ isSreEnforceEnabled,
43
+ recordSpawnAttempt,
44
+ spawnCircuitOpen,
45
+ } from "./sre-hooks.js";
46
+ export {
47
+ getTrustManagerForRun,
48
+ recordPolicyAllow,
49
+ recordPolicyDeny,
50
+ trustScoreForAgent,
51
+ } from "./trust-run-store.js";
52
+ export {
53
+ workflowBlocked,
54
+ workflowFlagsFromEntries,
55
+ } from "./workflow-history.js";
@@ -0,0 +1,11 @@
1
+ const denyCounts = new Map<string, number>();
2
+
3
+ export function recordHarnessPolicyDeny(sessionId: string): number {
4
+ const n = (denyCounts.get(sessionId) ?? 0) + 1;
5
+ denyCounts.set(sessionId, n);
6
+ return n;
7
+ }
8
+
9
+ export function resetHarnessPolicyDenyCount(sessionId: string): void {
10
+ denyCounts.delete(sessionId);
11
+ }
@@ -0,0 +1,101 @@
1
+ import { allowsAgentTool } from "../agents-policy.mjs";
2
+ import { evaluateContextModeMutation } from "../harness-context-mode-policy.js";
3
+ import {
4
+ extractWritePathFromToolInput,
5
+ getLatestRunContext,
6
+ isPlanPhaseAllowedMutation,
7
+ } from "../harness-run-context.js";
8
+ import { evaluateSubagentToolCall } from "../harness-spawn-policy.js";
9
+ import type { BuildEvaluationContextInput } from "./build-evaluation-context.js";
10
+ import {
11
+ buildHarnessAgtEvaluationContext,
12
+ type HarnessAgtContext,
13
+ harnessSessionToolDenyReason,
14
+ } from "./build-evaluation-context.js";
15
+
16
+ /** Combined legacy path for HARNESS_AGT_POLICY=0 parity tests. */
17
+ export async function evaluateLegacyHarnessToolPolicy(
18
+ input: BuildEvaluationContextInput,
19
+ ): Promise<{ allowed: boolean; reason: string; context?: HarnessAgtContext }> {
20
+ const { toolName, toolInput, policyState, entries, projectRoot, sessionId } =
21
+ input;
22
+ const agentId =
23
+ process.env.PI_HARNESS_SUBPROCESS === "1"
24
+ ? (process.env.HARNESS_AGENT_ID?.trim() ?? "harness/unknown")
25
+ : "parent-orchestrator";
26
+ const isSubprocess = process.env.PI_HARNESS_SUBPROCESS === "1";
27
+ const isParent = agentId === "parent-orchestrator";
28
+
29
+ const spawn = evaluateSubagentToolCall(toolName, agentId);
30
+ if (spawn.action === "block") {
31
+ return { allowed: false, reason: spawn.reason ?? "spawn policy" };
32
+ }
33
+
34
+ if (
35
+ !allowsAgentTool({
36
+ packageRoot: input.packageRoot,
37
+ projectRoot,
38
+ agentId,
39
+ toolName,
40
+ toolInput,
41
+ isSubprocess,
42
+ isParentOrchestrator: isParent,
43
+ })
44
+ ) {
45
+ return {
46
+ allowed: false,
47
+ reason: `agents-policy: ${toolName} not allowed for ${agentId}`,
48
+ };
49
+ }
50
+
51
+ const runCtx = getLatestRunContext(entries);
52
+ const phase = policyState.phase;
53
+ const bashCommand =
54
+ toolName === "bash" ? String(toolInput.command ?? "") : "";
55
+
56
+ if (toolName === "write" || toolName === "edit") {
57
+ const planMutation = await isPlanPhaseAllowedMutation(
58
+ toolName,
59
+ toolInput,
60
+ phase,
61
+ runCtx,
62
+ projectRoot,
63
+ {
64
+ aborted: policyState.aborted,
65
+ entries,
66
+ ownerSessionId: runCtx?.owner_pi_session_id,
67
+ currentSessionId: sessionId,
68
+ },
69
+ );
70
+ if (!planMutation.allowed) {
71
+ return {
72
+ allowed: false,
73
+ reason: planMutation.reason ?? "plan phase mutation blocked",
74
+ };
75
+ }
76
+ }
77
+
78
+ const ctxMode = evaluateContextModeMutation(toolName, toolInput, phase, {
79
+ aborted: policyState.aborted,
80
+ budgetBypass: policyState.budgetBypass,
81
+ readOnlyAgent: false,
82
+ });
83
+ if (ctxMode.blocked) {
84
+ return { allowed: false, reason: ctxMode.reason };
85
+ }
86
+
87
+ const sessionDeny = harnessSessionToolDenyReason({
88
+ toolName,
89
+ toolInput,
90
+ phase,
91
+ agentId,
92
+ entries,
93
+ aborted: policyState.aborted,
94
+ });
95
+ if (sessionDeny) {
96
+ return { allowed: false, reason: sessionDeny };
97
+ }
98
+
99
+ const context = await buildHarnessAgtEvaluationContext(input);
100
+ return { allowed: true, reason: "legacy allow", context };
101
+ }
@@ -0,0 +1,154 @@
1
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import {
4
+ ConflictResolutionStrategy,
5
+ PolicyEngine,
6
+ } from "@microsoft/agent-governance-sdk";
7
+ import {
8
+ resolveHarnessPoliciesDir,
9
+ resolveProjectPoliciesDir,
10
+ } from "./config.js";
11
+
12
+ const PACKAGE_POLICY_FILES = [
13
+ "defaults.yaml",
14
+ "phases.yaml",
15
+ "roles.yaml",
16
+ "orchestrator.yaml",
17
+ "bash-denylists.yaml",
18
+ "web-guard.yaml",
19
+ "workflow-sequences.yaml",
20
+ ] as const;
21
+
22
+ let cachedEngine: PolicyEngine | null = null;
23
+ let cachedKey: string | null = null;
24
+
25
+ export class HarnessPolicyLoadError extends Error {
26
+ constructor(message: string) {
27
+ super(message);
28
+ this.name = "HarnessPolicyLoadError";
29
+ }
30
+ }
31
+
32
+ function loadYamlFile(engine: PolicyEngine, path: string): void {
33
+ let raw: string;
34
+ try {
35
+ raw = readFileSync(path, "utf-8");
36
+ } catch (err) {
37
+ throw new HarnessPolicyLoadError(
38
+ `Missing or unreadable policy file: ${path} (${String(err)})`,
39
+ );
40
+ }
41
+ engine.loadYaml(raw);
42
+ }
43
+
44
+ function loadProjectPolicyDir(
45
+ engine: PolicyEngine,
46
+ projectRoot: string,
47
+ ): string[] {
48
+ const dir = resolveProjectPoliciesDir(projectRoot);
49
+ const loaded: string[] = [];
50
+ if (!existsSync(dir)) return loaded;
51
+ const names = readdirSync(dir)
52
+ .filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"))
53
+ .sort();
54
+ for (const name of names) {
55
+ loadYamlFile(engine, join(dir, name));
56
+ loaded.push(name);
57
+ }
58
+ return loaded;
59
+ }
60
+
61
+ export interface CreateAgtPolicyEngineInput {
62
+ packageRoot: string;
63
+ projectRoot: string;
64
+ }
65
+
66
+ export function createAgtPolicyEngine(
67
+ input: CreateAgtPolicyEngineInput,
68
+ ): PolicyEngine {
69
+ const engine = new PolicyEngine([], ConflictResolutionStrategy.DenyOverrides);
70
+ const dir = resolveHarnessPoliciesDir(input.packageRoot);
71
+ for (const file of PACKAGE_POLICY_FILES) {
72
+ loadYamlFile(engine, join(dir, file));
73
+ }
74
+ loadProjectPolicyDir(engine, input.projectRoot);
75
+ return engine;
76
+ }
77
+
78
+ /** @deprecated Use createAgtPolicyEngine */
79
+ export function createHarnessPolicyEngine(packageRoot: string): PolicyEngine {
80
+ return createAgtPolicyEngine({
81
+ packageRoot,
82
+ projectRoot: process.cwd(),
83
+ });
84
+ }
85
+
86
+ export function getAgtPolicyEngine(
87
+ packageRoot: string,
88
+ projectRoot: string,
89
+ ): PolicyEngine {
90
+ const key = `${packageRoot}\0${projectRoot}`;
91
+ if (cachedEngine && cachedKey === key) return cachedEngine;
92
+ cachedEngine = createAgtPolicyEngine({ packageRoot, projectRoot });
93
+ cachedKey = key;
94
+ return cachedEngine;
95
+ }
96
+
97
+ export function getHarnessPolicyEngine(packageRoot: string): PolicyEngine {
98
+ return getAgtPolicyEngine(packageRoot, process.cwd());
99
+ }
100
+
101
+ export function resetHarnessPolicyEngineCache(): void {
102
+ cachedEngine = null;
103
+ cachedKey = null;
104
+ }
105
+
106
+ /** Doctor: policies dir exists and all expected YAML files present. */
107
+ export function doctorHarnessPolicies(
108
+ packageRoot: string,
109
+ projectRoot = process.cwd(),
110
+ ): {
111
+ ok: boolean;
112
+ errors: string[];
113
+ policyDir: string;
114
+ loaded: string[];
115
+ projectLoaded: string[];
116
+ } {
117
+ const errors: string[] = [];
118
+ const policyDir = resolveHarnessPoliciesDir(packageRoot);
119
+ if (!existsSync(policyDir)) {
120
+ errors.push(`policy directory missing: ${policyDir}`);
121
+ }
122
+ const loaded: string[] = [];
123
+ for (const file of PACKAGE_POLICY_FILES) {
124
+ const path = join(policyDir, file);
125
+ if (!existsSync(path)) {
126
+ errors.push(`missing policy file: ${path}`);
127
+ continue;
128
+ }
129
+ loaded.push(file);
130
+ }
131
+ let projectLoaded: string[] = [];
132
+ try {
133
+ const names = readdirSync(policyDir).filter((f) => f.endsWith(".yaml"));
134
+ if (names.length === 0) {
135
+ errors.push(`no YAML policies in ${policyDir}`);
136
+ }
137
+ } catch (err) {
138
+ errors.push(`cannot read policy dir: ${String(err)}`);
139
+ }
140
+ if (errors.length === 0) {
141
+ try {
142
+ createAgtPolicyEngine({ packageRoot, projectRoot });
143
+ const projDir = resolveProjectPoliciesDir(projectRoot);
144
+ if (existsSync(projDir)) {
145
+ projectLoaded = readdirSync(projDir).filter(
146
+ (f) => f.endsWith(".yaml") || f.endsWith(".yml"),
147
+ );
148
+ }
149
+ } catch (err) {
150
+ errors.push(`PolicyEngine load failed: ${String(err)}`);
151
+ }
152
+ }
153
+ return { ok: errors.length === 0, errors, policyDir, loaded, projectLoaded };
154
+ }
@@ -0,0 +1,21 @@
1
+ import { ExecutionRing, RingEnforcer } from "@microsoft/agent-governance-sdk";
2
+
3
+ const KIND_RING: Record<string, ExecutionRing> = {
4
+ planner: ExecutionRing.Ring0,
5
+ executor: ExecutionRing.Ring2,
6
+ evaluator: ExecutionRing.Ring0,
7
+ adversary: ExecutionRing.Ring3,
8
+ tie_breaker: ExecutionRing.Ring0,
9
+ meta: ExecutionRing.Ring0,
10
+ trace: ExecutionRing.Ring0,
11
+ incident: ExecutionRing.Ring0,
12
+ other: ExecutionRing.Ring3,
13
+ };
14
+
15
+ export function ringForHarnessAgentKind(kind: string): ExecutionRing {
16
+ return KIND_RING[kind] ?? ExecutionRing.Ring3;
17
+ }
18
+
19
+ export function createRingEnforcer(): RingEnforcer {
20
+ return new RingEnforcer();
21
+ }
@@ -0,0 +1,45 @@
1
+ import {
2
+ CircuitBreaker,
3
+ GovernanceMetrics,
4
+ } from "@microsoft/agent-governance-sdk";
5
+
6
+ let metrics: GovernanceMetrics | null = null;
7
+ const breakers = new Map<string, CircuitBreaker>();
8
+
9
+ export function getHarnessGovernanceMetrics(): GovernanceMetrics {
10
+ if (!metrics) {
11
+ metrics = new GovernanceMetrics();
12
+ }
13
+ return metrics;
14
+ }
15
+
16
+ export function getSpawnCircuitBreaker(runId: string): CircuitBreaker {
17
+ let cb = breakers.get(runId);
18
+ if (!cb) {
19
+ cb = new CircuitBreaker(5, 60_000);
20
+ breakers.set(runId, cb);
21
+ }
22
+ return cb;
23
+ }
24
+
25
+ export function isSreEnforceEnabled(): boolean {
26
+ return process.env.HARNESS_AGT_SRE_ENFORCE === "1";
27
+ }
28
+
29
+ export function recordSpawnAttempt(runId: string, ok: boolean): void {
30
+ const cb = getSpawnCircuitBreaker(runId);
31
+ if (ok) {
32
+ cb.onSuccess();
33
+ } else {
34
+ cb.onFailure();
35
+ }
36
+ getHarnessGovernanceMetrics().recordPolicyDecision(ok ? "allow" : "deny", 0, {
37
+ run_id: runId,
38
+ kind: "harness_spawn",
39
+ });
40
+ }
41
+
42
+ export function spawnCircuitOpen(runId: string): boolean {
43
+ if (!isSreEnforceEnabled()) return false;
44
+ return !getSpawnCircuitBreaker(runId).canExecute();
45
+ }
@@ -0,0 +1,26 @@
1
+ import { TrustManager } from "@microsoft/agent-governance-sdk";
2
+
3
+ const stores = new Map<string, TrustManager>();
4
+
5
+ export function getTrustManagerForRun(runId: string): TrustManager {
6
+ let tm = stores.get(runId);
7
+ if (!tm) {
8
+ tm = new TrustManager({ initialScore: 0.85, decayFactor: 0.98 });
9
+ stores.set(runId, tm);
10
+ }
11
+ return tm;
12
+ }
13
+
14
+ export function recordPolicyDeny(runId: string, agentDid: string): void {
15
+ const tm = getTrustManagerForRun(runId);
16
+ tm.recordFailure(agentDid, 0.08);
17
+ }
18
+
19
+ export function recordPolicyAllow(runId: string, agentDid: string): void {
20
+ const tm = getTrustManagerForRun(runId);
21
+ tm.recordSuccess(agentDid, 0.02);
22
+ }
23
+
24
+ export function trustScoreForAgent(runId: string, agentDid: string): number {
25
+ return getTrustManagerForRun(runId).getTrustScore(agentDid).overall;
26
+ }
@@ -0,0 +1,29 @@
1
+ /** Lightweight workflow flags from session custom entries (observation-bus parity). */
2
+
3
+ type EntryLike = {
4
+ type?: string;
5
+ customType?: string;
6
+ data?: { kind?: string; flags?: string[] };
7
+ };
8
+
9
+ export function workflowFlagsFromEntries(entries: unknown[]): Set<string> {
10
+ const flags = new Set<string>();
11
+ for (const raw of entries) {
12
+ const entry = raw as EntryLike;
13
+ if (entry.type !== "custom") continue;
14
+ if (entry.customType !== "harness-observation") continue;
15
+ const data = entry.data;
16
+ if (!data?.flags) continue;
17
+ for (const f of data.flags) {
18
+ if (typeof f === "string") flags.add(f);
19
+ }
20
+ }
21
+ return flags;
22
+ }
23
+
24
+ export function workflowBlocked(
25
+ flags: Set<string>,
26
+ requiredPrior: string,
27
+ ): boolean {
28
+ return !flags.has(requiredPrior);
29
+ }
@@ -0,0 +1,14 @@
1
+ import { existsSync } from "node:fs";
2
+ import { isAgtGovernanceActive as hasProjectAgtFiles } from "./agents-policy.mjs";
3
+ import { isHarnessProjectEnabled } from "./harness-project-config.js";
4
+
5
+ /** Subprocess AGT + merged policies when harness is on or project declares policy files. */
6
+ export function isAgtGovernanceActive(projectRoot?: string): boolean {
7
+ const root = projectRoot ?? process.cwd();
8
+ if (isHarnessProjectEnabled(root)) return true;
9
+ return hasProjectAgtFiles(root);
10
+ }
11
+
12
+ export function projectHasPolicyDir(projectRoot: string): boolean {
13
+ return hasProjectAgtFiles(projectRoot);
14
+ }