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.
- package/.agents/skills/harness-debate-plan/SKILL.md +1 -1
- package/.agents/skills/harness-decisions/SKILL.md +2 -3
- package/.agents/skills/harness-governor/SKILL.md +6 -5
- package/.agents/skills/harness-orchestration/SKILL.md +4 -4
- package/.agents/skills/harness-review/SKILL.md +7 -7
- package/.agents/skills/harness-sentrux-setup/SKILL.md +4 -3
- package/.agents/skills/harness-steer/SKILL.md +1 -1
- package/.agents/skills/sentrux/SKILL.md +9 -9
- package/.pi/PACKAGING.md +4 -4
- package/.pi/SYSTEM.md +54 -120
- package/.pi/agents/harness/incident-recorder.md +0 -1
- package/.pi/agents/harness/planning/decompose.md +1 -3
- package/.pi/agents/harness/planning/execution-plan-author.md +0 -2
- package/.pi/agents/harness/planning/hypothesis-validator.md +0 -2
- package/.pi/agents/harness/planning/hypothesis.md +0 -2
- package/.pi/agents/harness/planning/implementation-researcher.md +0 -2
- package/.pi/agents/harness/planning/plan-adversary.md +0 -2
- package/.pi/agents/harness/planning/plan-evaluator.md +1 -3
- package/.pi/agents/harness/planning/planning-context.md +0 -2
- package/.pi/agents/harness/planning/review-integrator.md +0 -2
- package/.pi/agents/harness/planning/sprint-contract-auditor.md +0 -2
- package/.pi/agents/harness/planning/stack-researcher.md +0 -2
- package/.pi/agents/harness/{adversary.md → reviewing/adversary.md} +0 -2
- package/.pi/agents/harness/{evaluator.md → reviewing/evaluator.md} +0 -2
- package/.pi/agents/harness/{tie-breaker.md → reviewing/tie-breaker.md} +0 -2
- package/.pi/agents/harness/{executor.md → running/executor.md} +0 -2
- package/.pi/agents/harness/sentrux-bootstrap.md +0 -1
- package/.pi/agents/harness/sentrux-steward.md +0 -2
- package/.pi/agents/harness/trace-librarian.md +0 -1
- package/.pi/extensions/00-harness-project-control.ts +133 -0
- package/.pi/extensions/00-posthog-network-bootstrap.ts +1 -1
- package/.pi/extensions/agt-kill-switch.ts +57 -0
- package/.pi/extensions/agt-prompt-guard.ts +32 -0
- package/.pi/extensions/budget-guard.ts +2 -0
- package/.pi/extensions/custom-footer.ts +46 -145
- package/.pi/extensions/custom-header.ts +1 -1
- package/.pi/extensions/custom-system-prompt.ts +1 -1
- package/.pi/extensions/debate-orchestrator.ts +7 -5
- package/.pi/extensions/harness-ask-user.ts +8 -8
- package/.pi/extensions/harness-debate-tools.ts +27 -43
- package/.pi/extensions/harness-lens.ts +94 -0
- package/.pi/extensions/harness-live-widget.ts +33 -2
- package/.pi/extensions/harness-plan-approval.ts +12 -12
- package/.pi/extensions/harness-run-context.ts +1214 -852
- package/.pi/extensions/harness-subagent-governance.ts +8 -0
- package/.pi/extensions/harness-subagent-submit.ts +36 -164
- package/.pi/extensions/harness-subagents.ts +4 -4
- package/.pi/extensions/harness-telemetry.ts +3 -1
- package/.pi/extensions/harness-web-tools.ts +3 -3
- package/.pi/extensions/observation-bus.ts +2 -0
- package/.pi/extensions/policy-gate.ts +27 -5
- package/.pi/extensions/review-integrity.ts +91 -10
- package/.pi/extensions/sentrux-rules-sync.ts +3 -1
- package/.pi/extensions/subagent-governance.ts +92 -0
- package/.pi/extensions/test-diff-integrity.ts +1 -0
- package/.pi/extensions/trace-recorder.ts +3 -1
- package/.pi/extensions/{ultimate-pi-vcc.ts → vcc-compaction.ts} +1 -1
- package/.pi/harness/README.md +6 -2
- package/.pi/harness/agents.manifest.json +38 -49
- package/.pi/harness/agents.policy.yaml +275 -0
- package/.pi/harness/corpus/graphify-kb-updater.config.json +55 -0
- package/.pi/harness/docs/adrs/0006-sentrux-dual-layer.md +2 -1
- package/.pi/harness/docs/adrs/0030-inhouse-vcc-compaction.md +1 -1
- package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +1 -1
- package/.pi/harness/docs/adrs/0044-harness-steer-loop.md +3 -2
- package/.pi/harness/docs/adrs/0045-harness-lens-minimal-contract.md +49 -0
- package/.pi/harness/docs/adrs/0045-phase-scoped-agent-directories.md +33 -0
- package/.pi/harness/docs/adrs/0046-agt-policy-engine.md +51 -0
- package/.pi/harness/docs/adrs/0047-agt-layered-security.md +39 -0
- package/.pi/harness/docs/adrs/0048-tool-call-hook-order.md +25 -0
- package/.pi/harness/docs/adrs/0049-agents-policy-manifest.md +36 -0
- package/.pi/harness/docs/adrs/README.md +6 -0
- package/.pi/harness/docs/graphify-kb-updater-runbook.md +11 -5
- package/.pi/harness/docs/practice-map.md +2 -2
- package/.pi/harness/evolution/README.md +1 -2
- package/.pi/harness/examples/agents.policy.project.yaml +19 -0
- package/.pi/harness/examples/policies/custom-deny-bash.yaml +9 -0
- package/.pi/harness/policies/bash-denylists.yaml +5 -0
- package/.pi/harness/policies/defaults.yaml +51 -0
- package/.pi/harness/policies/orchestrator.yaml +18 -0
- package/.pi/harness/policies/phases.yaml +10 -0
- package/.pi/harness/policies/roles.yaml +5 -0
- package/.pi/harness/policies/web-guard.yaml +5 -0
- package/.pi/harness/policies/workflow-sequences.yaml +9 -0
- package/.pi/harness/sentrux/architecture.manifest.json +26 -4
- package/.pi/harness/specs/harness-spawn-context.schema.json +1 -1
- package/.pi/harness/specs/observation.schema.json +2 -1
- package/.pi/lib/agents-policy.d.mts +70 -0
- package/.pi/lib/agents-policy.mjs +325 -0
- package/.pi/lib/agents-policy.ts +19 -0
- package/.pi/lib/agt/audit-run-sink.ts +52 -0
- package/.pi/lib/agt/build-evaluation-context.ts +285 -0
- package/.pi/lib/agt/config.ts +28 -0
- package/.pi/lib/agt/delegation.ts +69 -0
- package/.pi/lib/agt/evaluate-policy.ts +56 -0
- package/.pi/lib/agt/identity-registry.ts +41 -0
- package/.pi/lib/agt/index.ts +55 -0
- package/.pi/lib/agt/kill-switch-state.ts +11 -0
- package/.pi/lib/agt/legacy-evaluate.ts +101 -0
- package/.pi/lib/agt/policy-engine.ts +154 -0
- package/.pi/lib/agt/rings.ts +21 -0
- package/.pi/lib/agt/sre-hooks.ts +45 -0
- package/.pi/lib/agt/trust-run-store.ts +26 -0
- package/.pi/lib/agt/workflow-history.ts +29 -0
- package/.pi/lib/agt-governance-active.ts +14 -0
- package/.pi/lib/agt-tool-guard.ts +78 -0
- package/.pi/lib/ask-user/dialog.ts +314 -0
- package/.pi/{extensions/lib → lib}/debate-bus-core.ts +10 -10
- package/.pi/{extensions/lib → lib}/debate-bus-state.ts +1 -1
- package/.pi/{extensions/lib → lib}/extension-load-guard.ts +21 -0
- package/.pi/lib/harness-agt-tool-guard.ts +5 -0
- package/.pi/{extensions/lib → lib}/harness-artifact-gate.ts +6 -16
- package/.pi/lib/harness-debate-core-deps.ts +14 -0
- package/.pi/lib/harness-debate-workflow-deps.ts +43 -0
- package/.pi/lib/harness-lens/.gitattributes +1 -0
- package/.pi/lib/harness-lens/clients/edit-autopatch.ts +88 -0
- package/.pi/lib/harness-lens/clients/file-kinds.ts +380 -0
- package/.pi/lib/harness-lens/clients/file-time.ts +215 -0
- package/.pi/lib/harness-lens/clients/file-utils.ts +484 -0
- package/.pi/lib/harness-lens/clients/format-service.ts +276 -0
- package/.pi/lib/harness-lens/clients/formatters.ts +1000 -0
- package/.pi/lib/harness-lens/clients/git-guard.ts +31 -0
- package/.pi/lib/harness-lens/clients/indent-retarget.ts +90 -0
- package/.pi/lib/harness-lens/clients/installer/index.ts +2368 -0
- package/.pi/lib/harness-lens/clients/latency-logger.ts +80 -0
- package/.pi/lib/harness-lens/clients/lens-config.ts +43 -0
- package/.pi/lib/harness-lens/clients/lens-events.ts +164 -0
- package/.pi/lib/harness-lens/clients/lsp/aggregation.ts +91 -0
- package/.pi/lib/harness-lens/clients/lsp/client.ts +1466 -0
- package/.pi/lib/harness-lens/clients/lsp/config.ts +216 -0
- package/.pi/lib/harness-lens/clients/lsp/edits.ts +297 -0
- package/.pi/lib/harness-lens/clients/lsp/index.ts +1355 -0
- package/.pi/lib/harness-lens/clients/lsp/interactive-install.ts +424 -0
- package/.pi/lib/harness-lens/clients/lsp/language.ts +223 -0
- package/.pi/lib/harness-lens/clients/lsp/launch.ts +939 -0
- package/.pi/lib/harness-lens/clients/lsp/lsp-index.ts +11 -0
- package/.pi/lib/harness-lens/clients/lsp/path-utils.ts +12 -0
- package/.pi/lib/harness-lens/clients/lsp/server-strategies.ts +81 -0
- package/.pi/lib/harness-lens/clients/lsp/server.ts +1971 -0
- package/.pi/lib/harness-lens/clients/path-utils.ts +182 -0
- package/.pi/lib/harness-lens/clients/pipeline.ts +360 -0
- package/.pi/lib/harness-lens/clients/project-profile.ts +117 -0
- package/.pi/lib/harness-lens/clients/runtime-agent-end.ts +112 -0
- package/.pi/lib/harness-lens/clients/runtime-config.ts +33 -0
- package/.pi/lib/harness-lens/clients/runtime-coordinator.ts +186 -0
- package/.pi/lib/harness-lens/clients/runtime-tool-result.ts +171 -0
- package/.pi/lib/harness-lens/clients/safe-spawn.ts +339 -0
- package/.pi/lib/harness-lens/clients/secrets-scanner.ts +214 -0
- package/.pi/lib/harness-lens/clients/tool-policy.ts +2072 -0
- package/.pi/lib/harness-lens/clients/types.ts +59 -0
- package/.pi/lib/harness-lens/clients/widget-state.ts +283 -0
- package/.pi/lib/harness-lens/index.ts +532 -0
- package/.pi/lib/harness-lens/tools/lsp-diagnostics.ts +706 -0
- package/.pi/lib/harness-lens/tools/lsp-navigation.ts +1246 -0
- package/.pi/{extensions/lib → lib}/harness-posthog.ts +3 -0
- package/.pi/lib/harness-project-config.ts +91 -0
- package/.pi/lib/harness-run-context-responses.ts +9 -0
- package/.pi/lib/harness-run-context.ts +1 -3
- package/.pi/{extensions/lib/spawn-policy.ts → lib/harness-spawn-policy.ts} +4 -3
- package/.pi/{extensions/lib → lib}/harness-spawn-topology.ts +5 -28
- package/.pi/lib/harness-subagent-auth.ts +51 -0
- package/.pi/{extensions/lib → lib}/harness-subagent-precheck.ts +13 -10
- package/.pi/{extensions/lib → lib}/harness-subagent-submit-pipeline.ts +3 -3
- package/.pi/lib/harness-subagent-submit-register.ts +163 -0
- package/.pi/{extensions/lib → lib}/harness-subagent-submit-registry.ts +1 -55
- package/.pi/{extensions/lib → lib}/harness-subagents-bridge.ts +53 -14
- package/.pi/{extensions/lib → lib}/harness-subprocess-bootstrap.ts +1 -1
- package/.pi/lib/harness-ui-state.ts +27 -12
- package/.pi/{extensions/lib → lib}/plan-approval/create-plan.ts +2 -2
- package/.pi/{extensions/lib → lib}/plan-approval/format-plan.ts +2 -2
- package/.pi/{extensions/lib → lib}/plan-approval/plan-review.ts +162 -201
- package/.pi/{extensions/lib → lib}/plan-approval/render.ts +1 -1
- package/.pi/{extensions/lib → lib}/plan-approval/resolve-disk.ts +2 -2
- package/.pi/{extensions/lib → lib}/plan-approval/types.ts +1 -1
- package/.pi/{extensions/lib → lib}/plan-approval/validate.ts +3 -3
- package/.pi/{extensions/lib → lib}/plan-approval-readiness.ts +3 -52
- package/.pi/{extensions/lib → lib}/plan-debate-envelope.ts +1 -1
- package/.pi/{extensions/lib → lib}/plan-debate-gate.ts +1 -1
- package/.pi/{extensions/lib → lib}/plan-debate-lane.ts +1 -4
- package/.pi/{extensions/lib → lib}/plan-messenger.ts +1 -1
- package/.pi/prompts/harness-auto.md +2 -2
- package/.pi/prompts/harness-plan.md +4 -6
- package/.pi/prompts/harness-review.md +9 -9
- package/.pi/prompts/harness-run.md +7 -7
- package/.pi/prompts/harness-setup.md +42 -68
- package/.pi/prompts/harness-steer.md +2 -2
- package/.pi/scripts/README.md +3 -5
- package/.pi/scripts/generate-agents-policy-yaml.mjs +148 -0
- package/.pi/scripts/graphify-kb-updater.mjs +48 -8
- package/.pi/scripts/harness-agents-manifest.mjs +61 -4
- package/.pi/scripts/harness-agt-doctor.ts +36 -0
- package/.pi/scripts/harness-cli-verify.sh +9 -2
- package/.pi/scripts/harness-project-toggle.mjs +129 -0
- package/.pi/scripts/harness-sentrux-cli.mjs +142 -0
- package/.pi/scripts/harness-verify.mjs +113 -39
- package/.pi/scripts/harness-web-policy-guard.mjs +2 -2
- package/.pi/scripts/validate-plan-dag.mjs +65 -74
- package/.pi/scripts/vendor-pi-vcc-settings.stub.ts +2 -2
- package/.pi/scripts/vendor-sync-pi-vcc.sh +1 -1
- package/.pi/skills/architecture/broker-domain/SKILL.md +65 -0
- package/.pi/skills/architecture/cqrs/SKILL.md +63 -0
- package/.pi/skills/architecture/event-driven/SKILL.md +60 -0
- package/.pi/skills/architecture/hexagonal-ports-adapters/SKILL.md +66 -0
- package/.pi/skills/architecture/layered/SKILL.md +68 -0
- package/.pi/skills/architecture/microkernel/SKILL.md +62 -0
- package/.pi/skills/architecture/microservices/SKILL.md +64 -0
- package/.pi/skills/architecture/modular-monolith/SKILL.md +65 -0
- package/.pi/skills/architecture/orchestration-driven-soa/SKILL.md +61 -0
- package/.pi/skills/architecture/pipeline/SKILL.md +63 -0
- package/.pi/skills/architecture/service-based/SKILL.md +64 -0
- package/.pi/skills/architecture/service-mesh/SKILL.md +60 -0
- package/.pi/skills/architecture/space-based/SKILL.md +60 -0
- package/.pi/skills/ast-grep/SKILL.md +40 -321
- package/.pi/skills/delivery/debugging-discipline/SKILL.md +36 -0
- package/.pi/skills/delivery/documentation-update/SKILL.md +33 -0
- package/.pi/skills/delivery/requirements-to-implementation/SKILL.md +34 -0
- package/.pi/skills/delivery/risk-based-verification/SKILL.md +43 -0
- package/.pi/skills/delivery/tradeoff-analysis/SKILL.md +34 -0
- package/.pi/skills/engineering/api-contract-design/SKILL.md +38 -0
- package/.pi/skills/engineering/cohesion-coupling/SKILL.md +43 -0
- package/.pi/skills/engineering/complexity-control/SKILL.md +31 -0
- package/.pi/skills/engineering/defensive-programming/SKILL.md +38 -0
- package/.pi/skills/engineering/dependency-management/SKILL.md +29 -0
- package/.pi/skills/engineering/domain-modeling/SKILL.md +32 -0
- package/.pi/skills/engineering/error-handling/SKILL.md +37 -0
- package/.pi/skills/engineering/legacy-code-seams/SKILL.md +35 -0
- package/.pi/skills/engineering/naming-and-intent/SKILL.md +29 -0
- package/.pi/skills/engineering/refactoring-safe-evolution/SKILL.md +35 -0
- package/.pi/skills/engineering/routine-function-design/SKILL.md +34 -0
- package/.pi/skills/engineering/small-change-discipline/SKILL.md +35 -0
- package/.pi/skills/lsp-navigation/SKILL.md +89 -0
- package/.pi/skills/quality/code-review-self-check/SKILL.md +35 -0
- package/.pi/skills/quality/privacy-data-handling/SKILL.md +26 -0
- package/.pi/skills/quality/security-review/SKILL.md +34 -0
- package/.pi/skills/quality/test-strategy/SKILL.md +33 -0
- package/.pi/skills/quality/testability-design/SKILL.md +33 -0
- package/.pi/skills/systems/concurrency-safety/SKILL.md +32 -0
- package/.pi/skills/systems/data-modeling-migrations/SKILL.md +31 -0
- package/.pi/skills/systems/observability-instrumentation/SKILL.md +32 -0
- package/.pi/skills/systems/performance-measurement/SKILL.md +35 -0
- package/.pi/skills/systems/reliability-design/SKILL.md +32 -0
- package/.sentrux/rules.toml +20 -4
- package/AGENTS.md +5 -0
- package/CHANGELOG.md +26 -0
- package/README.md +85 -58
- package/THIRD_PARTY_NOTICES.md +12 -21
- package/package.json +15 -7
- package/vendor/pi-subagents/src/agents.ts +45 -1
- package/vendor/pi-subagents/src/subagents.ts +866 -811
- package/vendor/pi-vcc/src/core/brief.ts +68 -99
- package/vendor/pi-vcc/src/core/settings.ts +2 -2
- package/.agents/skills/caveman/SKILL.md +0 -67
- package/.pi/agents/harness/meta-optimizer.md +0 -36
- package/.pi/agents/harness/planning/scout-graphify.md +0 -39
- package/.pi/agents/harness/planning/scout-semantic.md +0 -41
- package/.pi/agents/harness/planning/scout-structure.md +0 -37
- package/.pi/extensions/lib/ask-user/dialog.ts +0 -260
- package/.pi/extensions/lib/harness-subagent-auth.ts +0 -209
- package/.pi/extensions/lib/harness-subagent-policy.ts +0 -236
- package/.pi/extensions/pi-model-router-harness.ts +0 -42
- package/.pi/harness/evolution/meta-optimizer.mjs +0 -99
- package/.pi/harness/specs/router-tuning-proposal.schema.json +0 -114
- package/.pi/model-router.example.json +0 -36
- package/.pi/prompts/harness-critic.md +0 -10
- package/.pi/prompts/harness-eval.md +0 -10
- package/.pi/prompts/harness-router-tune.md +0 -52
- package/.pi/scripts/harness-generate-model-router.mjs +0 -327
- package/.pi/scripts/harness-model-router-routing.test.mjs +0 -97
- package/.pi/scripts/harness-sync-model-router.mjs +0 -97
- package/.pi/scripts/vendor-sync-pi-model-router.sh +0 -47
- package/vendor/pi-model-router/.prettierignore +0 -4
- package/vendor/pi-model-router/.prettierrc +0 -5
- package/vendor/pi-model-router/AGENTS.md +0 -39
- package/vendor/pi-model-router/LICENSE +0 -21
- package/vendor/pi-model-router/README.md +0 -99
- package/vendor/pi-model-router/UPSTREAM_PIN.md +0 -10
- package/vendor/pi-model-router/docs/ARCHITECTURE.md +0 -54
- package/vendor/pi-model-router/extensions/commands.ts +0 -720
- package/vendor/pi-model-router/extensions/config.ts +0 -348
- package/vendor/pi-model-router/extensions/constants.ts +0 -1
- package/vendor/pi-model-router/extensions/index.ts +0 -478
- package/vendor/pi-model-router/extensions/provider.ts +0 -580
- package/vendor/pi-model-router/extensions/routing.ts +0 -564
- package/vendor/pi-model-router/extensions/state.ts +0 -52
- package/vendor/pi-model-router/extensions/types.ts +0 -95
- package/vendor/pi-model-router/extensions/ui.ts +0 -144
- package/vendor/pi-model-router/model-router.example.json +0 -48
- package/vendor/pi-model-router/package.json +0 -48
- package/vendor/pi-model-router/tsconfig.json +0 -16
- /package/.pi/{prompts → harness/docs}/planning-rubrics.md +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/fallback.ts +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/render.ts +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/schema.ts +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/types.ts +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/validate-core.mjs +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/validate.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-cocoindex-refresh.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-paths.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-spawn-budget.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-vcc-settings.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-web/run-cli.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-approval/dialog.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-approval/schema.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-eligibility.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-focus.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-id.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-lanes.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-round-status.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-write-guard.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-review-gate.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-review-integrator-rules.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-scope-guard.ts +0 -0
- /package/.pi/{extensions/lib → lib}/posthog-client.ts +0 -0
- /package/.pi/{extensions/lib → lib}/posthog-node.d.ts +0 -0
|
@@ -24,6 +24,9 @@ export type HarnessPostHogEventName =
|
|
|
24
24
|
| "harness_eval_verdict"
|
|
25
25
|
| "harness_sentrux_signal"
|
|
26
26
|
| "harness_observation"
|
|
27
|
+
| "harness_lens_analysis_complete"
|
|
28
|
+
| "harness_lens_findings"
|
|
29
|
+
| "harness_lens_turn_findings"
|
|
27
30
|
| "harness_subagent_spawned"
|
|
28
31
|
| "harness_subagent_completed"
|
|
29
32
|
| "harness_subagent_result_wait"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-project harness enable/disable — `.pi/harness/project.json`.
|
|
3
|
+
* Default: enabled when the file is missing (backward compatible).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { dirname, join } from "node:path";
|
|
8
|
+
|
|
9
|
+
export const HARNESS_PROJECT_CONFIG_BASENAME = "project.json";
|
|
10
|
+
|
|
11
|
+
export interface HarnessProjectConfig {
|
|
12
|
+
schema_version: "1.0.0";
|
|
13
|
+
enabled: boolean;
|
|
14
|
+
updated_at?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function harnessProjectConfigPath(projectRoot: string): string {
|
|
18
|
+
return join(projectRoot, ".pi", "harness", HARNESS_PROJECT_CONFIG_BASENAME);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function envOverrideEnabled(): boolean | null {
|
|
22
|
+
const raw = process.env.HARNESS_ENABLED?.trim().toLowerCase();
|
|
23
|
+
if (!raw) return null;
|
|
24
|
+
if (raw === "0" || raw === "false" || raw === "no") return false;
|
|
25
|
+
if (raw === "1" || raw === "true" || raw === "yes") return true;
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function readHarnessProjectConfig(
|
|
30
|
+
projectRoot: string = process.cwd(),
|
|
31
|
+
): HarnessProjectConfig {
|
|
32
|
+
const fromEnv = envOverrideEnabled();
|
|
33
|
+
if (fromEnv !== null) {
|
|
34
|
+
return { schema_version: "1.0.0", enabled: fromEnv };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const path = harnessProjectConfigPath(projectRoot);
|
|
38
|
+
if (!existsSync(path)) {
|
|
39
|
+
return { schema_version: "1.0.0", enabled: true };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const raw = JSON.parse(
|
|
44
|
+
readFileSync(path, "utf8"),
|
|
45
|
+
) as Partial<HarnessProjectConfig>;
|
|
46
|
+
if (typeof raw.enabled === "boolean") {
|
|
47
|
+
return {
|
|
48
|
+
schema_version: "1.0.0",
|
|
49
|
+
enabled: raw.enabled,
|
|
50
|
+
updated_at: raw.updated_at,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
} catch {
|
|
54
|
+
// corrupt file — treat as enabled so operators are not locked out
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { schema_version: "1.0.0", enabled: true };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function isHarnessProjectEnabled(projectRoot?: string): boolean {
|
|
61
|
+
return readHarnessProjectConfig(projectRoot ?? process.cwd()).enabled;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function writeHarnessProjectEnabled(
|
|
65
|
+
projectRoot: string,
|
|
66
|
+
enabled: boolean,
|
|
67
|
+
): HarnessProjectConfig {
|
|
68
|
+
const path = harnessProjectConfigPath(projectRoot);
|
|
69
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
70
|
+
const config: HarnessProjectConfig = {
|
|
71
|
+
schema_version: "1.0.0",
|
|
72
|
+
enabled,
|
|
73
|
+
updated_at: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
writeFileSync(path, `${JSON.stringify(config, null, "\t")}\n`, "utf8");
|
|
76
|
+
return config;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Slash commands that stay available while governance is disabled. */
|
|
80
|
+
export const HARNESS_ALWAYS_ALLOWED_COMMANDS = new Set([
|
|
81
|
+
"harness-enable",
|
|
82
|
+
"harness-disable",
|
|
83
|
+
"harness-enabled-status",
|
|
84
|
+
"harness-setup",
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
export function isHarnessWorkflowCommand(command: string): boolean {
|
|
88
|
+
if (!command.startsWith("harness-")) return false;
|
|
89
|
+
if (HARNESS_ALWAYS_ALLOWED_COMMANDS.has(command)) return false;
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
@@ -101,7 +101,6 @@ const HARNESS_COMMANDS = new Set([
|
|
|
101
101
|
"harness-drift-proceed",
|
|
102
102
|
"harness-policy-status",
|
|
103
103
|
"harness-trace-last",
|
|
104
|
-
"harness-router-tune",
|
|
105
104
|
"harness-budget-status",
|
|
106
105
|
]);
|
|
107
106
|
|
|
@@ -213,7 +212,6 @@ export const HARNESS_COMMAND_PHASE: Record<string, HarnessPhase> = {
|
|
|
213
212
|
"harness-run-status": "plan",
|
|
214
213
|
"harness-use-run": "plan",
|
|
215
214
|
"harness-policy-status": "merge",
|
|
216
|
-
"harness-router-tune": "plan",
|
|
217
215
|
"harness-budget-status": "plan",
|
|
218
216
|
"harness-setup": "execute",
|
|
219
217
|
};
|
|
@@ -1763,7 +1761,7 @@ export function nextStepAfterOutcome(input: {
|
|
|
1763
1761
|
return "/harness-run-status";
|
|
1764
1762
|
}
|
|
1765
1763
|
|
|
1766
|
-
/** Read executor handoff artifact written by harness/executor submit pipeline. */
|
|
1764
|
+
/** Read executor handoff artifact written by harness/running/executor submit pipeline. */
|
|
1767
1765
|
export async function readExecutorHandoffFromRun(
|
|
1768
1766
|
runId: string,
|
|
1769
1767
|
projectRoot: string,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Subagent tool policy — block nested orchestration tools (defense in depth).
|
|
3
|
+
* Shared by AGT evaluation context and extensions (lives under .pi/lib, not extensions).
|
|
3
4
|
*/
|
|
4
5
|
|
|
5
6
|
export const SUBAGENT_BLOCKED_TOOLS = new Set([
|
|
@@ -11,9 +12,9 @@ export const SUBAGENT_BLOCKED_TOOLS = new Set([
|
|
|
11
12
|
]);
|
|
12
13
|
|
|
13
14
|
const ASK_USER_ALLOWED_AGENT_TYPES = new Set([
|
|
14
|
-
"harness/evaluator",
|
|
15
|
-
"harness/adversary",
|
|
16
|
-
"harness/tie-breaker",
|
|
15
|
+
"harness/reviewing/evaluator",
|
|
16
|
+
"harness/reviewing/adversary",
|
|
17
|
+
"harness/reviewing/tie-breaker",
|
|
17
18
|
]);
|
|
18
19
|
|
|
19
20
|
export interface ToolCallDecision {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { constants } from "node:fs";
|
|
6
6
|
import { access } from "node:fs/promises";
|
|
7
7
|
import { join } from "node:path";
|
|
8
|
-
import type { HarnessPhase } from "
|
|
8
|
+
import type { HarnessPhase } from "./harness-run-context.js";
|
|
9
9
|
|
|
10
10
|
export interface SpawnTopologyResult {
|
|
11
11
|
ok: boolean;
|
|
@@ -23,13 +23,6 @@ const DEBATE_LANE_AGENTS = new Set([
|
|
|
23
23
|
"harness/planning/review-integrator",
|
|
24
24
|
]);
|
|
25
25
|
|
|
26
|
-
/** @deprecated Legacy tool-tied scouts — prefer parent tools + planning-context.yaml (ADR 0041). */
|
|
27
|
-
const LEGACY_SCOUT_AGENTS = new Set([
|
|
28
|
-
"harness/planning/scout-graphify",
|
|
29
|
-
"harness/planning/scout-structure",
|
|
30
|
-
"harness/planning/scout-semantic",
|
|
31
|
-
]);
|
|
32
|
-
|
|
33
26
|
const PLANNING_CONTEXT_AGENT = "harness/planning/planning-context";
|
|
34
27
|
|
|
35
28
|
const PARALLEL_RESEARCH_AGENTS = new Set([
|
|
@@ -42,7 +35,7 @@ function countInSet(names: string[], allowed: Set<string>): number {
|
|
|
42
35
|
}
|
|
43
36
|
|
|
44
37
|
function isReconnaissanceAgent(name: string): boolean {
|
|
45
|
-
return
|
|
38
|
+
return name === PLANNING_CONTEXT_AGENT;
|
|
46
39
|
}
|
|
47
40
|
|
|
48
41
|
async function decompositionReady(
|
|
@@ -103,28 +96,12 @@ export async function validateHarnessSpawnTopology(
|
|
|
103
96
|
};
|
|
104
97
|
}
|
|
105
98
|
|
|
106
|
-
const legacyScouts = countInSet(names, LEGACY_SCOUT_AGENTS);
|
|
107
99
|
const planningContext = names.filter(
|
|
108
100
|
(n) => n === PLANNING_CONTEXT_AGENT,
|
|
109
101
|
).length;
|
|
110
102
|
const research = countInSet(names, PARALLEL_RESEARCH_AGENTS);
|
|
111
|
-
const recon =
|
|
103
|
+
const recon = planningContext;
|
|
112
104
|
|
|
113
|
-
if (legacyScouts > 0 && planningContext > 0) {
|
|
114
|
-
return {
|
|
115
|
-
ok: false,
|
|
116
|
-
message:
|
|
117
|
-
"Do not mix legacy scout-* subagents with planning-context in one batch. " +
|
|
118
|
-
"Prefer parent tool use + planning-context.yaml, or a single planning-context subagent.",
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
if (legacyScouts > 3) {
|
|
122
|
-
return {
|
|
123
|
-
ok: false,
|
|
124
|
-
message:
|
|
125
|
-
"At most 3 legacy planning scouts per parallel batch (deprecated — use planning-context).",
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
105
|
if (planningContext > 1) {
|
|
129
106
|
return {
|
|
130
107
|
ok: false,
|
|
@@ -149,7 +126,7 @@ export async function validateHarnessSpawnTopology(
|
|
|
149
126
|
ok: false,
|
|
150
127
|
message:
|
|
151
128
|
"Parallel batches may include only one independent group: " +
|
|
152
|
-
"research (≤2 lanes), optional
|
|
129
|
+
"research (≤2 lanes), optional single planning-context, " +
|
|
153
130
|
"or a single sequential lane agent.",
|
|
154
131
|
};
|
|
155
132
|
}
|
|
@@ -175,7 +152,7 @@ export async function validateHarnessSpawnTopology(
|
|
|
175
152
|
}
|
|
176
153
|
|
|
177
154
|
if (phase === "plan") {
|
|
178
|
-
const mutating = names.filter((n) => n.startsWith("harness/
|
|
155
|
+
const mutating = names.filter((n) => n.startsWith("harness/running/"));
|
|
179
156
|
if (mutating.length > 0) {
|
|
180
157
|
return {
|
|
181
158
|
ok: false,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve concrete LLM credentials for harness subagent subprocesses.
|
|
3
|
+
*
|
|
4
|
+
* Harness subprocesses run with `--no-extensions`, so auth forwarding only uses
|
|
5
|
+
* concrete provider/model references from the parent session or agent config.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { AgentConfig } from "../../vendor/pi-subagents/src/agents.js";
|
|
9
|
+
|
|
10
|
+
const SENTINEL_API_KEYS = new Set(["<authenticated>"]);
|
|
11
|
+
|
|
12
|
+
export function isUsableApiKey(key: string | undefined): key is string {
|
|
13
|
+
return Boolean(key && !SENTINEL_API_KEYS.has(key));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function parseModelRef(
|
|
17
|
+
ref: string,
|
|
18
|
+
): { provider: string; modelId: string } | null {
|
|
19
|
+
const slash = ref.indexOf("/");
|
|
20
|
+
if (slash <= 0) return null;
|
|
21
|
+
const provider = ref.slice(0, slash).trim();
|
|
22
|
+
const modelId = ref.slice(slash + 1).trim();
|
|
23
|
+
if (!provider || !modelId || provider === "router") return null;
|
|
24
|
+
return { provider, modelId };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ConcreteSubagentModel {
|
|
28
|
+
modelRef: string;
|
|
29
|
+
provider: string;
|
|
30
|
+
modelId: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function resolveConcreteSubagentModel(
|
|
34
|
+
_parentCwd: string,
|
|
35
|
+
parentModel: { provider: string; id: string } | undefined,
|
|
36
|
+
agent: AgentConfig,
|
|
37
|
+
_taskSnippet?: string,
|
|
38
|
+
): ConcreteSubagentModel | undefined {
|
|
39
|
+
if (agent.model) {
|
|
40
|
+
const parsed = parseModelRef(agent.model);
|
|
41
|
+
if (parsed) {
|
|
42
|
+
return { modelRef: agent.model, ...parsed };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!parentModel || parentModel.provider === "router") return undefined;
|
|
47
|
+
const modelRef = `${parentModel.provider}/${parentModel.id}`;
|
|
48
|
+
const parsed = parseModelRef(modelRef);
|
|
49
|
+
if (!parsed) return undefined;
|
|
50
|
+
return { modelRef, ...parsed };
|
|
51
|
+
}
|
|
@@ -5,13 +5,11 @@
|
|
|
5
5
|
import {
|
|
6
6
|
type AgentConfig,
|
|
7
7
|
agentAllowsMutatingTools,
|
|
8
|
-
} from "
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from "../../lib/harness-run-context.js";
|
|
8
|
+
} from "../../vendor/pi-subagents/src/agents.js";
|
|
9
|
+
import { getAgentKind } from "./agents-policy.mjs";
|
|
10
|
+
import { getHarnessPackageRoot } from "./harness-paths.js";
|
|
11
|
+
import { type HarnessPhase, inferHarnessPhase } from "./harness-run-context.js";
|
|
13
12
|
import { validateHarnessSpawnTopology } from "./harness-spawn-topology.js";
|
|
14
|
-
import { classifyHarnessAgent } from "./harness-subagent-policy.js";
|
|
15
13
|
|
|
16
14
|
export interface SubagentTaskRef {
|
|
17
15
|
agent: string;
|
|
@@ -64,7 +62,7 @@ export async function precheckHarnessSubagentSpawn(
|
|
|
64
62
|
const cfg = resolveAgent(agents, n);
|
|
65
63
|
return cfg
|
|
66
64
|
? agentAllowsMutatingTools(cfg)
|
|
67
|
-
: n.startsWith("harness/
|
|
65
|
+
: n.startsWith("harness/running/");
|
|
68
66
|
});
|
|
69
67
|
|
|
70
68
|
if (phase === "plan" && mutating.length > 0) {
|
|
@@ -78,8 +76,8 @@ export async function precheckHarnessSubagentSpawn(
|
|
|
78
76
|
|
|
79
77
|
const parallelEvalAdversary =
|
|
80
78
|
(params.tasks?.length ?? 0) === 2 &&
|
|
81
|
-
params.tasks?.some((t) => t.agent === "harness/evaluator") &&
|
|
82
|
-
params.tasks?.some((t) => t.agent === "harness/adversary") &&
|
|
79
|
+
params.tasks?.some((t) => t.agent === "harness/reviewing/evaluator") &&
|
|
80
|
+
params.tasks?.some((t) => t.agent === "harness/reviewing/adversary") &&
|
|
83
81
|
phase === "evaluate";
|
|
84
82
|
|
|
85
83
|
if (
|
|
@@ -105,9 +103,14 @@ export async function precheckHarnessSubagentSpawn(
|
|
|
105
103
|
return topology;
|
|
106
104
|
}
|
|
107
105
|
|
|
106
|
+
const packageRoot = getHarnessPackageRoot(
|
|
107
|
+
// @ts-expect-error pi extensions run as ESM
|
|
108
|
+
import.meta.url,
|
|
109
|
+
);
|
|
110
|
+
const projectRoot = opts?.projectRoot ?? process.cwd();
|
|
108
111
|
for (const name of names) {
|
|
109
112
|
if (!name.startsWith("harness/")) continue;
|
|
110
|
-
|
|
113
|
+
getAgentKind(packageRoot, projectRoot, name);
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
return { ok: true };
|
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
import { mkdir, readFile } from "node:fs/promises";
|
|
6
6
|
import { dirname, join, resolve } from "node:path";
|
|
7
|
-
import { validateAgainstHarnessSchema } from "
|
|
8
|
-
import { resolveGuardedRunDir } from "
|
|
9
|
-
import { writeYamlFile } from "../../lib/harness-yaml.js";
|
|
7
|
+
import { validateAgainstHarnessSchema } from "./harness-schema-validate.js";
|
|
8
|
+
import { resolveGuardedRunDir } from "./harness-subagent-submit-path.js";
|
|
10
9
|
import {
|
|
11
10
|
resolveArtifactRelPath,
|
|
12
11
|
type SubmitToolSpec,
|
|
13
12
|
} from "./harness-subagent-submit-registry.js";
|
|
13
|
+
import { writeYamlFile } from "./harness-yaml.js";
|
|
14
14
|
import {
|
|
15
15
|
type ApplyDebateLaneResult,
|
|
16
16
|
applyDebateLaneFromDoc,
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { Type } from "@sinclair/typebox";
|
|
4
|
+
import { allowsAgentTool } from "./agents-policy.mjs";
|
|
5
|
+
import { resolveGuardedRunDir } from "./harness-subagent-submit-path.js";
|
|
6
|
+
import {
|
|
7
|
+
executeSubmitPipeline,
|
|
8
|
+
loadSubmitDocument,
|
|
9
|
+
} from "./harness-subagent-submit-pipeline.js";
|
|
10
|
+
import { SUBMIT_TOOL_SPECS } from "./harness-subagent-submit-registry.js";
|
|
11
|
+
|
|
12
|
+
const DocumentSchema = Type.Object(
|
|
13
|
+
{
|
|
14
|
+
document: Type.Optional(
|
|
15
|
+
Type.Record(Type.String(), Type.Unknown(), {
|
|
16
|
+
description:
|
|
17
|
+
"Artifact fields (deprecated when source_path is set; ADR 0043)",
|
|
18
|
+
}),
|
|
19
|
+
),
|
|
20
|
+
source_path: Type.Optional(
|
|
21
|
+
Type.String({
|
|
22
|
+
description:
|
|
23
|
+
"Relative path under run dir, e.g. artifacts/.draft/decomposition.yaml",
|
|
24
|
+
}),
|
|
25
|
+
),
|
|
26
|
+
},
|
|
27
|
+
{ additionalProperties: false },
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export function resolveHarnessSubmitRunContext(packageRoot: string): {
|
|
31
|
+
projectRoot: string;
|
|
32
|
+
specsDir: string;
|
|
33
|
+
runId: string;
|
|
34
|
+
runDirEnv?: string;
|
|
35
|
+
agentId: string;
|
|
36
|
+
} {
|
|
37
|
+
const projectRoot = process.env.HARNESS_PKG_ROOT?.trim() || packageRoot;
|
|
38
|
+
const specsDir = join(projectRoot, ".pi", "harness", "specs");
|
|
39
|
+
const runId = process.env.HARNESS_RUN_ID?.trim() ?? "";
|
|
40
|
+
const runDirEnv = process.env.HARNESS_RUN_DIR?.trim();
|
|
41
|
+
const agentId = process.env.HARNESS_AGENT_ID?.trim() ?? "";
|
|
42
|
+
return { projectRoot, specsDir, runId, runDirEnv, agentId };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function isSubprocessHarnessSubmit(): boolean {
|
|
46
|
+
return (
|
|
47
|
+
process.env.PI_HARNESS_SUBPROCESS === "1" &&
|
|
48
|
+
Boolean(process.env.HARNESS_RUN_ID?.trim())
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function registerHarnessSubagentSubmitTools(
|
|
53
|
+
pi: ExtensionAPI,
|
|
54
|
+
packageRoot: string,
|
|
55
|
+
): void {
|
|
56
|
+
for (const spec of SUBMIT_TOOL_SPECS) {
|
|
57
|
+
pi.registerTool({
|
|
58
|
+
name: spec.toolName,
|
|
59
|
+
label: spec.toolName.replace(/^submit_/, "Submit "),
|
|
60
|
+
description: `Terminal harness artifact submit (${spec.toolName}). Call once with the full schema document before ending the turn.`,
|
|
61
|
+
parameters: DocumentSchema,
|
|
62
|
+
async execute(_id, params, _signal, _onUpdate, _ctx) {
|
|
63
|
+
if (!isSubprocessHarnessSubmit()) {
|
|
64
|
+
return {
|
|
65
|
+
content: [
|
|
66
|
+
{
|
|
67
|
+
type: "text",
|
|
68
|
+
text: "submit tools require PI_HARNESS_SUBPROCESS and HARNESS_RUN_ID",
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
details: {},
|
|
72
|
+
isError: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const { projectRoot, specsDir, runId, runDirEnv, agentId } =
|
|
76
|
+
resolveHarnessSubmitRunContext(packageRoot);
|
|
77
|
+
if (
|
|
78
|
+
!allowsAgentTool({
|
|
79
|
+
packageRoot,
|
|
80
|
+
projectRoot,
|
|
81
|
+
agentId,
|
|
82
|
+
toolName: spec.toolName,
|
|
83
|
+
toolInput: params as Record<string, unknown>,
|
|
84
|
+
isSubprocess: true,
|
|
85
|
+
})
|
|
86
|
+
) {
|
|
87
|
+
return {
|
|
88
|
+
content: [
|
|
89
|
+
{
|
|
90
|
+
type: "text",
|
|
91
|
+
text: `${spec.toolName} is not allowed for agent ${agentId} (agents.policy.yaml)`,
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
details: { agentId, tool: spec.toolName },
|
|
95
|
+
isError: true,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const runResolved = await resolveGuardedRunDir({
|
|
99
|
+
projectRoot,
|
|
100
|
+
runId,
|
|
101
|
+
runDirEnv,
|
|
102
|
+
});
|
|
103
|
+
if (!runResolved.ok) {
|
|
104
|
+
return {
|
|
105
|
+
content: [{ type: "text", text: runResolved.error }],
|
|
106
|
+
details: {},
|
|
107
|
+
isError: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const loaded = await loadSubmitDocument({
|
|
111
|
+
projectRoot,
|
|
112
|
+
runDir: runResolved.runDir,
|
|
113
|
+
document: (params as { document?: Record<string, unknown> }).document,
|
|
114
|
+
source_path: (params as { source_path?: string }).source_path,
|
|
115
|
+
});
|
|
116
|
+
if (!loaded.ok) {
|
|
117
|
+
return {
|
|
118
|
+
content: [
|
|
119
|
+
{
|
|
120
|
+
type: "text",
|
|
121
|
+
text: `Validation failed:\n${loaded.validation_errors.join("\n")}`,
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
isError: true,
|
|
125
|
+
details: loaded,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const result = await executeSubmitPipeline({
|
|
129
|
+
projectRoot,
|
|
130
|
+
specsDir,
|
|
131
|
+
spec,
|
|
132
|
+
agentId,
|
|
133
|
+
document: loaded.document,
|
|
134
|
+
runId,
|
|
135
|
+
runDirEnv,
|
|
136
|
+
});
|
|
137
|
+
if (!result.ok) {
|
|
138
|
+
return {
|
|
139
|
+
content: [
|
|
140
|
+
{
|
|
141
|
+
type: "text",
|
|
142
|
+
text: `Validation failed:\n${(result.validation_errors ?? []).join("\n")}`,
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
isError: true,
|
|
146
|
+
details: result,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const lines = [`ok: wrote ${result.artifact_path}`];
|
|
150
|
+
if (result.lane_result?.messenger_posted) {
|
|
151
|
+
lines.push("messenger updated");
|
|
152
|
+
}
|
|
153
|
+
if (result.human_required) {
|
|
154
|
+
lines.push("human_required: parent must call ask_user");
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
158
|
+
details: result as unknown,
|
|
159
|
+
};
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Registry: submit tool name →
|
|
2
|
+
* Registry: submit tool name → schema, artifact path (allowlists live in agents.policy.yaml).
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { DebateLaneKind } from "./plan-debate-lane.js";
|
|
6
6
|
|
|
7
7
|
export interface SubmitToolSpec {
|
|
8
8
|
toolName: string;
|
|
9
|
-
agents: readonly string[];
|
|
10
9
|
schemaFile: string;
|
|
11
10
|
artifactPath: string | ((doc: Record<string, unknown>) => string);
|
|
12
11
|
debateLane?: DebateLaneKind;
|
|
@@ -24,144 +23,91 @@ function roundPath(prefix: string, doc: Record<string, unknown>): string {
|
|
|
24
23
|
export const SUBMIT_TOOL_SPECS: readonly SubmitToolSpec[] = [
|
|
25
24
|
{
|
|
26
25
|
toolName: "submit_planning_context",
|
|
27
|
-
agents: ["harness/planning/planning-context"],
|
|
28
26
|
schemaFile: "plan-planning-context.schema.json",
|
|
29
27
|
artifactPath: "artifacts/planning-context.yaml",
|
|
30
28
|
},
|
|
31
|
-
{
|
|
32
|
-
toolName: "submit_scout_findings",
|
|
33
|
-
agents: [
|
|
34
|
-
"harness/planning/scout-graphify",
|
|
35
|
-
"harness/planning/scout-structure",
|
|
36
|
-
"harness/planning/scout-semantic",
|
|
37
|
-
],
|
|
38
|
-
schemaFile: "plan-scout-findings.schema.json",
|
|
39
|
-
artifactPath: (doc) => {
|
|
40
|
-
const lane =
|
|
41
|
-
typeof doc.lane === "string"
|
|
42
|
-
? doc.lane
|
|
43
|
-
: typeof doc.scout_lane === "string"
|
|
44
|
-
? doc.scout_lane
|
|
45
|
-
: "graphify";
|
|
46
|
-
return `artifacts/scout-${lane}.yaml`;
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
29
|
{
|
|
50
30
|
toolName: "submit_decomposition_brief",
|
|
51
|
-
agents: ["harness/planning/decompose", "harness/planning/plan-synthesizer"],
|
|
52
31
|
schemaFile: "plan-decomposition-brief.schema.json",
|
|
53
32
|
artifactPath: "artifacts/decomposition.yaml",
|
|
54
33
|
},
|
|
55
34
|
{
|
|
56
35
|
toolName: "submit_hypothesis_brief",
|
|
57
|
-
agents: [
|
|
58
|
-
"harness/planning/hypothesis",
|
|
59
|
-
"harness/planning/plan-synthesizer",
|
|
60
|
-
],
|
|
61
36
|
schemaFile: "plan-hypothesis-brief.schema.json",
|
|
62
37
|
artifactPath: "artifacts/hypothesis.yaml",
|
|
63
38
|
},
|
|
64
39
|
{
|
|
65
40
|
toolName: "submit_implementation_research",
|
|
66
|
-
agents: ["harness/planning/implementation-researcher"],
|
|
67
41
|
schemaFile: "plan-implementation-research-brief.schema.json",
|
|
68
42
|
artifactPath: "artifacts/implementation-research.yaml",
|
|
69
43
|
},
|
|
70
44
|
{
|
|
71
45
|
toolName: "submit_stack_brief",
|
|
72
|
-
agents: ["harness/planning/stack-researcher"],
|
|
73
46
|
schemaFile: "plan-stack-brief.schema.json",
|
|
74
47
|
artifactPath: "artifacts/stack.yaml",
|
|
75
48
|
},
|
|
76
49
|
{
|
|
77
50
|
toolName: "submit_execution_plan_brief",
|
|
78
|
-
agents: [
|
|
79
|
-
"harness/planning/execution-plan-author",
|
|
80
|
-
"harness/planning/plan-synthesizer",
|
|
81
|
-
],
|
|
82
51
|
schemaFile: "plan-execution-plan-brief.schema.json",
|
|
83
52
|
artifactPath: "artifacts/execution-plan-draft.yaml",
|
|
84
53
|
},
|
|
85
54
|
{
|
|
86
55
|
toolName: "submit_hypothesis_validation",
|
|
87
|
-
agents: ["harness/planning/hypothesis-validator"],
|
|
88
56
|
schemaFile: "plan-hypothesis-eval.schema.json",
|
|
89
57
|
artifactPath: (doc) => roundPath("hypothesis-validation", doc),
|
|
90
58
|
debateLane: "hypothesis-validation",
|
|
91
59
|
},
|
|
92
60
|
{
|
|
93
61
|
toolName: "submit_validation_turn",
|
|
94
|
-
agents: ["harness/planning/plan-evaluator"],
|
|
95
62
|
schemaFile: "plan-validation-turn.schema.json",
|
|
96
63
|
artifactPath: (doc) => roundPath("validation-turn", doc),
|
|
97
64
|
debateLane: "validation-turn",
|
|
98
65
|
},
|
|
99
66
|
{
|
|
100
67
|
toolName: "submit_adversary_brief",
|
|
101
|
-
agents: ["harness/planning/plan-adversary"],
|
|
102
68
|
schemaFile: "plan-adversary-brief.schema.json",
|
|
103
69
|
artifactPath: (doc) => roundPath("adversary-brief", doc),
|
|
104
70
|
debateLane: "adversary-brief",
|
|
105
71
|
},
|
|
106
72
|
{
|
|
107
73
|
toolName: "submit_sprint_audit",
|
|
108
|
-
agents: ["harness/planning/sprint-contract-auditor"],
|
|
109
74
|
schemaFile: "plan-sprint-audit-turn.schema.json",
|
|
110
75
|
artifactPath: (doc) => roundPath("sprint-audit", doc),
|
|
111
76
|
debateLane: "sprint-audit",
|
|
112
77
|
},
|
|
113
78
|
{
|
|
114
79
|
toolName: "submit_review_round_draft",
|
|
115
|
-
agents: ["harness/planning/review-integrator"],
|
|
116
80
|
schemaFile: "plan-review-round-draft.schema.json",
|
|
117
81
|
artifactPath: (doc) => roundPath("review-round-draft", doc),
|
|
118
82
|
},
|
|
119
83
|
{
|
|
120
84
|
toolName: "submit_executor_handoff",
|
|
121
|
-
agents: ["harness/executor"],
|
|
122
85
|
schemaFile: "harness-executor-handoff.schema.json",
|
|
123
86
|
artifactPath: "handoff/executor-summary.yaml",
|
|
124
87
|
},
|
|
125
88
|
{
|
|
126
89
|
toolName: "submit_eval_verdict",
|
|
127
|
-
agents: ["harness/evaluator"],
|
|
128
90
|
schemaFile: "eval-verdict.schema.json",
|
|
129
91
|
artifactPath: "artifacts/eval-verdict.yaml",
|
|
130
92
|
},
|
|
131
93
|
{
|
|
132
94
|
toolName: "submit_adversary_report",
|
|
133
|
-
agents: ["harness/adversary"],
|
|
134
95
|
schemaFile: "adversary-report.schema.json",
|
|
135
96
|
artifactPath: "artifacts/adversary-report.yaml",
|
|
136
97
|
},
|
|
137
98
|
{
|
|
138
99
|
toolName: "submit_human_required",
|
|
139
|
-
agents: ["harness/planning/decompose", "harness/planning/hypothesis"],
|
|
140
100
|
schemaFile: "harness-human-required.schema.json",
|
|
141
101
|
artifactPath: "artifacts/human-required.yaml",
|
|
142
102
|
humanRequired: true,
|
|
143
103
|
},
|
|
144
104
|
{
|
|
145
105
|
toolName: "submit_sentrux_manifest_proposal",
|
|
146
|
-
agents: ["harness/sentrux-steward"],
|
|
147
106
|
schemaFile: "sentrux-manifest-proposal.schema.json",
|
|
148
107
|
artifactPath: "artifacts/sentrux-manifest-proposal.yaml",
|
|
149
108
|
},
|
|
150
109
|
] as const;
|
|
151
110
|
|
|
152
|
-
export const SUBMIT_TOOLS_BY_AGENT: Readonly<
|
|
153
|
-
Record<string, ReadonlySet<string>>
|
|
154
|
-
> = (() => {
|
|
155
|
-
const map = new Map<string, Set<string>>();
|
|
156
|
-
for (const spec of SUBMIT_TOOL_SPECS) {
|
|
157
|
-
for (const agent of spec.agents) {
|
|
158
|
-
if (!map.has(agent)) map.set(agent, new Set());
|
|
159
|
-
map.get(agent)?.add(spec.toolName);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return Object.fromEntries(map.entries());
|
|
163
|
-
})();
|
|
164
|
-
|
|
165
111
|
export function specForSubmitTool(
|
|
166
112
|
toolName: string,
|
|
167
113
|
): SubmitToolSpec | undefined {
|