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.
- package/.agents/skills/harness-debate-plan/SKILL.md +1 -1
- package/.agents/skills/harness-decisions/SKILL.md +1 -2
- package/.agents/skills/harness-governor/SKILL.md +6 -5
- package/.agents/skills/web-retrieval/SKILL.md +163 -0
- package/.agents/skills/wiki-autoresearch/SKILL.md +6 -6
- package/.pi/PACKAGING.md +4 -4
- package/.pi/SYSTEM.md +75 -123
- package/.pi/agents/harness/incident-recorder.md +0 -1
- package/.pi/agents/harness/planning/decompose.md +0 -2
- 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 +1 -3
- 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 +5 -3
- package/.pi/agents/harness/reviewing/adversary.md +0 -2
- package/.pi/agents/harness/reviewing/evaluator.md +0 -2
- package/.pi/agents/harness/reviewing/tie-breaker.md +0 -2
- package/.pi/agents/harness/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/agents/harness/web-retrieval/web-answerer.md +35 -0
- package/.pi/agents/harness/web-retrieval/web-criteria-verifier.md +28 -0
- package/.pi/agents/harness/web-retrieval/web-gap-analyzer.md +31 -0
- package/.pi/agents/harness/web-retrieval/web-query-expander-fast.md +34 -0
- package/.pi/agents/harness/web-retrieval/web-query-expander.md +60 -0
- package/.pi/agents/harness/web-retrieval/web-summarizer.md +18 -0
- package/.pi/extensions/agt-kill-switch.ts +57 -0
- package/.pi/extensions/agt-prompt-guard.ts +32 -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 +6 -6
- package/.pi/extensions/harness-ask-user.ts +7 -7
- package/.pi/extensions/harness-debate-tools.ts +26 -42
- package/.pi/extensions/harness-lens.ts +94 -0
- package/.pi/extensions/harness-plan-approval.ts +11 -11
- package/.pi/extensions/harness-run-context.ts +1070 -876
- package/.pi/extensions/harness-subagent-governance.ts +8 -0
- package/.pi/extensions/harness-subagent-submit.ts +34 -163
- package/.pi/extensions/harness-subagents.ts +3 -3
- package/.pi/extensions/harness-telemetry.ts +2 -2
- package/.pi/extensions/harness-web-guard.ts +2 -1
- package/.pi/extensions/harness-web-tools.ts +691 -53
- package/.pi/extensions/policy-gate.ts +25 -5
- package/.pi/extensions/sentrux-rules-sync.ts +1 -1
- package/.pi/extensions/subagent-governance.ts +92 -0
- package/.pi/extensions/trace-recorder.ts +1 -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 +46 -25
- package/.pi/harness/agents.policy.yaml +309 -0
- 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/0045-harness-lens-minimal-contract.md +49 -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/0050-agentic-web-retrieval-stack.md +46 -0
- package/.pi/harness/docs/adrs/README.md +5 -0
- package/.pi/harness/docs/harness-web-search.md +97 -0
- package/.pi/harness/env.harness.template +9 -1
- 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/examples/web-heuristic-angles.project.yaml +22 -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/observation.schema.json +2 -1
- package/.pi/harness/web-heuristic-angles.json +278 -0
- package/.pi/harness/web-heuristic-angles.yaml +182 -0
- package/.pi/lib/agents-policy.d.mts +70 -0
- package/.pi/lib/agents-policy.mjs +331 -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 +13 -2
- package/.pi/lib/harness-agt-tool-guard.ts +5 -0
- package/.pi/{extensions/lib → lib}/harness-artifact-gate.ts +1 -1
- 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-run-context-responses.ts +9 -0
- package/.pi/lib/harness-run-context.ts +0 -2
- package/.pi/{extensions/lib/spawn-policy.ts → lib/harness-spawn-policy.ts} +1 -0
- package/.pi/{extensions/lib → lib}/harness-spawn-topology.ts +1 -1
- package/.pi/lib/harness-subagent-auth.ts +81 -0
- package/.pi/{extensions/lib → lib}/harness-subagent-precheck.ts +10 -7
- 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 -37
- package/.pi/{extensions/lib → lib}/harness-subagents-bridge.ts +74 -14
- package/.pi/{extensions/lib → lib}/harness-subprocess-bootstrap.ts +1 -1
- package/.pi/lib/harness-web/artifacts.ts +200 -0
- package/.pi/lib/harness-web/cache.ts +369 -0
- package/.pi/{extensions/lib → lib}/harness-web/run-cli.ts +42 -2
- 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-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-plan.md +2 -1
- package/.pi/prompts/harness-setup.md +40 -65
- package/.pi/scripts/README.md +2 -5
- package/.pi/scripts/gen-web-heuristic-angles-json.mjs +24 -0
- package/.pi/scripts/generate-agents-policy-yaml.mjs +148 -0
- package/.pi/scripts/harness-agents-manifest.mjs +60 -3
- package/.pi/scripts/harness-agt-doctor.ts +36 -0
- package/.pi/scripts/harness-cli-verify.sh +14 -2
- package/.pi/scripts/harness-verify.mjs +191 -39
- package/.pi/scripts/harness-web-policy-guard.mjs +3 -3
- package/.pi/scripts/harness-web.py +218 -15
- package/.pi/scripts/harness_web/deep_search.py +55 -0
- package/.pi/scripts/harness_web/evidence_bundle.py +47 -0
- package/.pi/scripts/harness_web/find_similar.py +88 -0
- package/.pi/scripts/harness_web/heuristic_angles_shipped.py +85 -0
- package/.pi/scripts/harness_web/heuristic_config.py +251 -0
- package/.pi/scripts/harness_web/highlights.py +47 -0
- package/.pi/scripts/harness_web/multi_search.py +59 -0
- package/.pi/scripts/harness_web/output.py +24 -0
- package/.pi/scripts/harness_web/query_angles.py +116 -0
- package/.pi/scripts/harness_web/rank.py +163 -0
- package/.pi/scripts/harness_web/scrape.py +30 -0
- package/.pi/scripts/tests/test_harness_web_heuristic_config.py +132 -0
- package/.pi/scripts/tests/test_harness_web_query_angles.py +45 -0
- package/.pi/scripts/tests/test_harness_web_rank.py +56 -0
- 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 +7 -2
- package/CHANGELOG.md +20 -0
- package/README.md +3 -12
- package/THIRD_PARTY_NOTICES.md +12 -21
- package/package.json +17 -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/.agents/skills/scrapling-web/SKILL.md +0 -98
- package/.pi/agents/harness/meta-optimizer.md +0 -36
- package/.pi/extensions/00-posthog-network-bootstrap.ts +0 -11
- package/.pi/extensions/lib/ask-user/dialog.ts +0 -260
- package/.pi/extensions/lib/harness-subagent-auth.ts +0 -207
- 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/harness_web/__pycache__/__init__.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/config.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/output.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/scrape.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/search.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/search_ddg.cpython-314.pyc +0 -0
- package/.pi/scripts/harness_web/__pycache__/search_searxng.cpython-314.pyc +0 -0
- 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}/plan-approval/dialog.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-approval/schema.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-approval-readiness.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
|
@@ -14,7 +14,6 @@ Bootstraps the complete ultimate-pi agentic harness: Graphify knowledge graph, C
|
|
|
14
14
|
| Pitfall | Correct approach |
|
|
15
15
|
|---------|------------------|
|
|
16
16
|
| `UP_PKG="$(pwd)"` in an **external** repo | Wrong — scripts live in the npm package. Resolve via `harness-resolve-up-pkg.mjs` (see Step 0). |
|
|
17
|
-
| Provider detection from `OPENAI_*` / `ANTHROPIC_*` env only | Wrong for pi users — keys live in `~/.pi/agent/auth.json`. Use `harness-generate-model-router.mjs` (Pi `ModelRegistry.getAvailable()`). |
|
|
18
17
|
| Re-running 2.1–2.8 manually after CLI verify | Wasteful — trust `harness-cli-verify.sh` output; only fix reported ✗ lines. |
|
|
19
18
|
| Overwriting `AGENTS.md` after graphify | Graphify appends a section — **merge**, do not replace (Step 4.3). |
|
|
20
19
|
| `sentrux-rules-sync` without project manifest | Use **`harness-sentrux-bootstrap.mjs`** (Step 4.2) — seeds manifest + idempotent rules sync. |
|
|
@@ -141,6 +140,8 @@ python3 "$UP_PKG/.pi/scripts/harness-web.py" scrape "https://example.com" -o .we
|
|
|
141
140
|
|
|
142
141
|
After pi loads extensions, agents should smoke **`web_search`** once (not `UP_PKG` / `import scrapling` preflight). Example intent: query `ultimate-pi harness`, `limit` 2.
|
|
143
142
|
|
|
143
|
+
**WRS subagent models (optional):** set env vars to any Pi `provider/model-id` — `HARNESS_WEB_FAST_MODEL`, `HARNESS_WEB_EXPANDER_MODEL`, `HARNESS_WEB_QUALITY_MODEL` (see **web-retrieval** skill). Add to `.env` via `harness-sync-env.mjs` or export in shell.
|
|
144
|
+
|
|
144
145
|
- **`--skip-tools`:** skip Step 2 (includes Scrapling verify).
|
|
145
146
|
- On Linux/WSL, if stealth scrape fails, install browser libs from `harness-cli-verify.sh` output or use `--fast` for static targets.
|
|
146
147
|
|
|
@@ -154,9 +155,9 @@ bash "$UP_PKG/.pi/scripts/harness-cli-verify.sh"
|
|
|
154
155
|
# Reinstall everything: bash "$UP_PKG/.pi/scripts/harness-cli-verify.sh" --force
|
|
155
156
|
```
|
|
156
157
|
|
|
157
|
-
**Required (script must exit 0):** scrapling + harness-web smoke, ctx7,
|
|
158
|
+
**Required (script must exit 0):** scrapling + harness-web smoke, ctx7, ast-grep (`sg`), sentrux (when harness manifest present).
|
|
158
159
|
|
|
159
|
-
**Warnings allowed:** gh (if not authenticated), agent-browser (if OS libs need manual `sudo apt-get install`), cocoindex-code (empty corpus on tiny repos; first `[full]` install downloads local embedding model).
|
|
160
|
+
**Warnings allowed:** biome (optional; skipped for non-JS/TS repos or if install fails), gh (if not authenticated), agent-browser (if OS libs need manual `sudo apt-get install`), cocoindex-code (empty corpus on tiny repos; first `[full]` install downloads local embedding model).
|
|
160
161
|
|
|
161
162
|
If the script reports **agent-browser shared library errors** on Linux/WSL, run the fix it prints, then re-verify:
|
|
162
163
|
|
|
@@ -189,7 +190,7 @@ python3 "$UP_PKG/.pi/scripts/harness-web.py" search "query" -o .web/search.json
|
|
|
189
190
|
python3 "$UP_PKG/.pi/scripts/harness-web.py" scrape "https://example.com" -o .web/page.md --fast
|
|
190
191
|
```
|
|
191
192
|
|
|
192
|
-
See `.agents/skills/
|
|
193
|
+
See `.agents/skills/web-retrieval/SKILL.md` (install + env).
|
|
193
194
|
|
|
194
195
|
### 2.2 — ctx7 (Context7 Library Docs + Skills Management)
|
|
195
196
|
|
|
@@ -251,21 +252,21 @@ ccc status
|
|
|
251
252
|
|
|
252
253
|
Verify: `ccc doctor` and `ccc search --limit 3 "export function"` (no `--refresh`).
|
|
253
254
|
|
|
254
|
-
### 2.5 — biome (
|
|
255
|
+
### 2.5 — biome (Optional, JS/TS-focused lint + format)
|
|
255
256
|
|
|
256
|
-
|
|
257
|
-
if ! command -v biome &>/dev/null || [ "$FORCE" = "true" ]; then
|
|
258
|
-
npm install -g @biomejs/biome
|
|
259
|
-
fi
|
|
260
|
-
```
|
|
257
|
+
Biome is **not a hard requirement** for harness setup. Install/use it when the target project is JS/TS (for example, has `package.json` or already uses `biome.json`). For other stacks, skip and use the repo's native formatter/linter.
|
|
261
258
|
|
|
262
|
-
Check if project already has biome config:
|
|
263
259
|
```bash
|
|
264
|
-
|
|
260
|
+
if [ -f package.json ] || [ -f biome.json ]; then
|
|
261
|
+
if ! command -v biome &>/dev/null || [ "$FORCE" = "true" ]; then
|
|
262
|
+
npm install -g @biomejs/biome
|
|
263
|
+
fi
|
|
264
|
+
biome --version
|
|
265
|
+
else
|
|
266
|
+
echo "Skipping biome (non-JS/TS repo; optional tool)"
|
|
267
|
+
fi
|
|
265
268
|
```
|
|
266
269
|
|
|
267
|
-
Verify: `biome --version`
|
|
268
|
-
|
|
269
270
|
### 2.6 — ast-grep (AST-Aware Structural Code Search)
|
|
270
271
|
|
|
271
272
|
```bash
|
|
@@ -327,7 +328,14 @@ sentrux plugin add-standard 2>/dev/null || echo "Plugins already installed or fa
|
|
|
327
328
|
|
|
328
329
|
## Step 3 — Pi Extension Packages
|
|
329
330
|
|
|
330
|
-
Bundled extensions load from the installed `ultimate-pi` package.
|
|
331
|
+
Bundled extensions load from the installed `ultimate-pi` package. The harness lens wrapper at `.pi/extensions/harness-lens.ts` loads `.pi/extensions/lib/harness-lens/` for edit autopatch, secrets blocking, deferred format, and LSP tools. Structural search uses shell `sg` (installed globally by setup); architecture gates use Sentrux. See [ADR 0045](.pi/harness/docs/adrs/0045-harness-lens-minimal-contract.md).
|
|
332
|
+
|
|
333
|
+
Harness lens findings are **complementary** to Sentrux:
|
|
334
|
+
|
|
335
|
+
- **Harness lens:** fast edit-time and turn-time code feedback; standalone lens widgets/health telemetry are disabled, and findings flow through the harness PostHog telemetry layer.
|
|
336
|
+
- **Sentrux:** architecture-quality signal and gate (`.sentrux/rules.toml`, `sentrux-signal.yaml`, harness review/evaluate inputs).
|
|
337
|
+
|
|
338
|
+
Do not treat harness lens as a replacement for Sentrux. If a future lens change adds architecture-boundary gating that duplicates Sentrux, keep Sentrux authoritative and disable/remove the overlapping lens path.
|
|
331
339
|
|
|
332
340
|
Optionally install the companion lockfile used in development:
|
|
333
341
|
|
|
@@ -341,51 +349,19 @@ else
|
|
|
341
349
|
fi
|
|
342
350
|
```
|
|
343
351
|
|
|
344
|
-
Merge extension entries from `$UP_PKG/.pi/settings.example.json` into this project's `.pi/settings.json` `packages` array (add any missing `npm:…` entries; keep existing user packages).
|
|
352
|
+
Merge extension entries from `$UP_PKG/.pi/settings.example.json` into this project's `.pi/settings.json` `packages` array (add any missing `npm:…` entries; keep existing user packages).
|
|
345
353
|
|
|
346
354
|
Verify each package:
|
|
347
355
|
|
|
348
356
|
| Package | Purpose | Phase |
|
|
349
357
|
|---------|---------|-------|
|
|
350
358
|
| `@posthog/pi` | Analytics event capture | F0 |
|
|
351
|
-
| `
|
|
359
|
+
| `context-mode` | Context runtime and MCP context-saving tools | F0 |
|
|
352
360
|
| `harness-subagents` (bundled extension) | L4 `subagent` tool, subprocess spawns, package agents | P16 |
|
|
353
361
|
| Vendored `pi-vcc` (`vendor/pi-vcc`, `.pi/extensions/ultimate-pi-vcc.ts`) | VCC compaction / `vcc_recall` — env-only: `HARNESS_VCC_COMPACTION` (default on), `HARNESS_VCC_DEBUG` | Shipped |
|
|
354
|
-
| `pi-
|
|
355
|
-
|
|
356
|
-
## Step 3.5 — Model Router Configuration (Dynamic)
|
|
357
|
-
|
|
358
|
-
`.pi/model-router.json` is **user-specific** (gitignored). Generate from **Pi authenticated providers** (`~/.pi/agent/auth.json`, OAuth, env) — **not** env-var guessing alone.
|
|
359
|
-
|
|
360
|
-
Pi API (see `packages/coding-agent` docs / SDK example `02-custom-model.ts`):
|
|
361
|
-
|
|
362
|
-
- `AuthStorage.create()` → credentials store
|
|
363
|
-
- `ModelRegistry.create(authStorage)` → registry
|
|
364
|
-
- `await modelRegistry.getAvailable()` → models with working auth (same as interactive pi)
|
|
365
|
-
|
|
366
|
-
```bash
|
|
367
|
-
# Verify vendored extension source ships with ultimate-pi
|
|
368
|
-
ls "$UP_PKG/vendor/pi-model-router/extensions/index.ts" 2>/dev/null \
|
|
369
|
-
&& echo "✓ vendored pi-model-router" \
|
|
370
|
-
|| echo "✗ missing vendor/pi-model-router"
|
|
371
|
-
|
|
372
|
-
# Generate from Pi registry (skips if .pi/model-router.json exists; --force to regenerate)
|
|
373
|
-
node "$UP_PKG/.pi/scripts/harness-generate-model-router.mjs"
|
|
374
|
-
# Preview only: node "$UP_PKG/.pi/scripts/harness-generate-model-router.mjs" --dry-run
|
|
375
|
-
|
|
376
|
-
# Merge router defaults after config exists (never adds npm packages — router is vendored)
|
|
377
|
-
node "$UP_PKG/.pi/scripts/harness-sync-model-router.mjs"
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
If generation prints "No authenticated Pi providers": warn in report — user should run **`/login`** in pi (or `pi login`) then re-run Step 3.5. Do **not** infer providers from `OPENAI_API_KEY` alone; pi sessions often use `opencode-go` via auth.json without those env vars.
|
|
381
|
-
|
|
382
|
-
Do NOT block setup. If no config is written, `harness-sync-model-router.mjs` clears a premature `defaultProvider: "router"` in `.pi/settings.json`.
|
|
383
|
-
|
|
384
|
-
**Router onboarding** — The vendored extension starts only after `.pi/model-router.json` appears. Running the script above prepares that file plus optional Pi defaults (**`router` / `auto`**, or whatever `defaultProfile` is) via `harness-sync-model-router.mjs` when `defaultProvider` was unset—then **`/reload`**. Generated profiles use **one model SKU per profile**; high/medium/low tiers differ in **thinking** only. Subagents resolve their subprocess model from the **agent system prompt** complexity (same lock rules).
|
|
385
|
-
|
|
386
|
-
Manual override: **`/router profile auto`** or **`/router profile opencode-go`** anytime after reload if they changed defaults.
|
|
362
|
+
| Harness lens (`.pi/extensions/harness-lens.ts` → `.pi/extensions/lib/harness-lens/index.ts`) | Edit autopatch, secrets block, deferred format, LSP tools; PostHog lens telemetry; Sentrux remains architecture gate; `sg` is shell-only | F0 |
|
|
387
363
|
|
|
388
|
-
## Step 3.
|
|
364
|
+
## Step 3.5 — Harness agents (package-resolved)
|
|
389
365
|
|
|
390
366
|
`harness-subagents` loads agents from the installed **`ultimate-pi`** package (`$UP_PKG/.pi/agents/**`) with namespaced ids (`harness/running/executor`, `harness/reviewing/evaluator`, `pi-pi/agent-expert`). **Do not copy** agents into the project unless you want a deliberate override.
|
|
391
367
|
|
|
@@ -500,10 +476,9 @@ Ensure `.gitignore` contains harness runtime entries (see repo root `.gitignore`
|
|
|
500
476
|
!.pi/harness/incidents/README.md
|
|
501
477
|
.pi/harness/debates/*
|
|
502
478
|
!.pi/harness/debates/README.md
|
|
503
|
-
.pi/harness/router/proposals/*
|
|
504
479
|
|
|
505
|
-
#
|
|
506
|
-
.pi/
|
|
480
|
+
# Harness lens runtime config/cache and local diagnostics state
|
|
481
|
+
.pi/harness/.lens/
|
|
507
482
|
|
|
508
483
|
# sentrux baselines and local meta (rules.toml is committed)
|
|
509
484
|
.sentrux/*
|
|
@@ -564,7 +539,7 @@ Created: $(date +%Y-%m-%d)
|
|
|
564
539
|
- .pi/harness/specs/ → Harness contracts and schema docs
|
|
565
540
|
- .pi/harness/incidents/ → Incident and override records
|
|
566
541
|
- `.agents/skills/` (npm package) → Harness skills (no copy into `.pi/skills/` needed)
|
|
567
|
-
- `.pi/agents/` → Optional per-repo agent overrides (package agents load automatically — see Step 3.
|
|
542
|
+
- `.pi/agents/` → Optional per-repo agent overrides (package agents load automatically — see Step 3.5)
|
|
568
543
|
|
|
569
544
|
## Graphify-First Workflow
|
|
570
545
|
|
|
@@ -580,7 +555,7 @@ Created: $(date +%Y-%m-%d)
|
|
|
580
555
|
- Decisions and incidents in `.pi/harness/` with structured artifacts
|
|
581
556
|
- `GRAPHIFY_VIZ_NODE_LIMIT=200000 graphify update .` after significant code changes
|
|
582
557
|
- ast-grep (`sg`) is the default code search tool — use `sg -p 'pattern'` for structural search, never grep for code
|
|
583
|
-
-
|
|
558
|
+
- Use shell `sg` for structural search; project-specific ast-grep rule dirs are optional in the **target repo**, not a harness template default
|
|
584
559
|
```
|
|
585
560
|
|
|
586
561
|
## Step 5 — Verification
|
|
@@ -627,10 +602,11 @@ print(f'✓ knowledge graph built ({n} nodes)' if n else '✗ graph.json has 0 n
|
|
|
627
602
|
" 2>/dev/null || echo "✗ no graph built yet"
|
|
628
603
|
graphify hook status 2>/dev/null && echo "✓ graphify git hooks installed" || echo "✗ graphify git hooks not installed"
|
|
629
604
|
|
|
630
|
-
#
|
|
631
|
-
ls "$UP_PKG
|
|
632
|
-
&& echo "✓
|
|
633
|
-
ls
|
|
605
|
+
# harness lens extension
|
|
606
|
+
ls "$UP_PKG/.pi/extensions/harness-lens.ts" 2>/dev/null \
|
|
607
|
+
&& echo "✓ harness lens wrapper" || echo "✗ harness lens wrapper missing"
|
|
608
|
+
ls "$UP_PKG/.pi/extensions/lib/harness-lens/index.ts" 2>/dev/null \
|
|
609
|
+
&& echo "✓ harness lens upstream pin" || echo "✗ harness lens upstream pin missing"
|
|
634
610
|
|
|
635
611
|
# raw folder for graphify sources
|
|
636
612
|
ls -d ./raw 2>/dev/null && echo "✓ ./raw directory exists" || echo "! ./raw directory missing"
|
|
@@ -672,13 +648,13 @@ Output summary table:
|
|
|
672
648
|
| ctx7 | ✓/✗ | Login: yes/no |
|
|
673
649
|
| agent-browser | ✓/✗ | Config: .pi/harness/browser.json |
|
|
674
650
|
| cocoindex-code | ✓/✗ | `ccc status`; index auto-refreshed before harness scouts |
|
|
675
|
-
| biome |
|
|
651
|
+
| biome | ✓/✗/skip | Optional; JS/TS-focused (skip on non-JS/TS stacks) |
|
|
676
652
|
| ast-grep | ✓/✗ | AST-aware code search (`sg`)
|
|
677
653
|
| gh CLI | ✓/✗ | Auth: yes/no |
|
|
678
654
|
| sentrux | ✓/✗ | CLI + plugins; rules via Step 4.2 bootstrap |
|
|
679
655
|
| Sentrux rules.toml | ✓/✗ | `.sentrux/rules.toml` synced from manifest |
|
|
680
|
-
| pi extensions | ✓/✗ |
|
|
681
|
-
|
|
|
656
|
+
| pi extensions | ✓/✗ | bundled extensions + harness lens wrapper |
|
|
657
|
+
| harness lens | ✓/✗ | `.pi/extensions/harness-lens.ts`; PostHog owns lens telemetry; complements Sentrux architecture signal |
|
|
682
658
|
| `.env` | ✓/✗/ask | Created / keys appended / user declined |
|
|
683
659
|
|
|
684
660
|
| .gitignore | ✓/✗ | entries added (incl. `.env`) |
|
|
@@ -728,11 +704,10 @@ Next steps:
|
|
|
728
704
|
| gh not installed | Show GitHub CLI install link. Skip label creation. |
|
|
729
705
|
| pi packages install fail | Show error output. Check npm permissions. |
|
|
730
706
|
| graph already exists | Report node count. Refresh with `graphify update .` unless user passed `--force`. |
|
|
731
|
-
| biome.json missing |
|
|
707
|
+
| biome.json missing | No action required. Biome is optional; use project-native tooling. |
|
|
732
708
|
| settings.json not writable | Warn. Settings won't persist across sessions. |
|
|
733
709
|
| No internet | Block for tool installs. Continue for graphify-only steps if `--skip-tools`. |
|
|
734
710
|
| sentrux install fails | Show install script output. Fallback: download from https://github.com/sentrux/sentrux/releases/latest |
|
|
735
|
-
| No model-router.json / "No authenticated Pi providers" | Run `/login` in pi, then `node "$UP_PKG/.pi/scripts/harness-generate-model-router.mjs" --force` |
|
|
736
711
|
| UP_PKG not found | `pi install npm:ultimate-pi` or `npm i -g ultimate-pi`; verify with `node "$UP_PKG/.pi/scripts/harness-resolve-up-pkg.mjs"` |
|
|
737
712
|
| No `.env` at project root | `ask_user` create vs skip; on create: `harness-sync-env.mjs --create-missing` |
|
|
738
713
|
|
package/.pi/scripts/README.md
CHANGED
|
@@ -14,7 +14,7 @@ UP_PKG="$(node -p "require('path').dirname(require.resolve('ultimate-pi/package.
|
|
|
14
14
|
|
|
15
15
|
**Developing this repo** (clone of `ultimate-pi`): from the repo root, `UP_PKG="$(pwd)"` (or the same `require.resolve` after `npm install`).
|
|
16
16
|
|
|
17
|
-
From **Typescript extensions**, use `resolveHarnessScript()` / `getHarnessPackageRoot()` in `.pi/
|
|
17
|
+
From **Typescript extensions**, use `resolveHarnessScript()` / `getHarnessPackageRoot()` in `.pi/lib/harness-paths.ts`.
|
|
18
18
|
|
|
19
19
|
## Invocations (from the consuming project root)
|
|
20
20
|
|
|
@@ -29,11 +29,8 @@ From **Typescript extensions**, use `resolveHarnessScript()` / `getHarnessPackag
|
|
|
29
29
|
| Sentrux rules drift check (CI) | `node "$UP_PKG/.pi/scripts/sentrux-rules-sync.mjs" --check` |
|
|
30
30
|
| Sentrux run/review check or gate (root-resolving) | `node "$UP_PKG/.pi/scripts/harness-sentrux-cli.mjs" check` / `gate [--save]` |
|
|
31
31
|
| Resolve package root (`UP_PKG`) | `node "$UP_PKG/.pi/scripts/harness-resolve-up-pkg.mjs"` |
|
|
32
|
-
| Model-router config (Pi auth) | `node "$UP_PKG/.pi/scripts/harness-generate-model-router.mjs"` |
|
|
33
32
|
| Project `.env` (append-only) | `node "$UP_PKG/.pi/scripts/harness-sync-env.mjs"` (`--create-missing` after user confirms) |
|
|
34
|
-
|
|
|
35
|
-
| Vendor router sync (this repo only) | `bash .pi/scripts/vendor-sync-pi-model-router.sh` or `npm run vendor:sync-router` |
|
|
36
|
-
| Meta-optimizer (JSONL proposals) | `node "$UP_PKG/.pi/harness/evolution/meta-optimizer.mjs"` |
|
|
33
|
+
| Harness lens extension | `.pi/extensions/harness-lens.ts` → `.pi/lib/harness-lens/index.ts` (loaded by `.pi/extensions`; PostHog owns lens telemetry) |
|
|
37
34
|
|
|
38
35
|
Pass `--force` to shell scripts that support it (e.g. `harness-graphify-bootstrap.sh --force`, `harness-cli-verify.sh --force`).
|
|
39
36
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/** Regenerate .pi/harness/web-heuristic-angles.json from shipped Python defaults. */
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import { writeFileSync } from "node:fs";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "..", "harness");
|
|
9
|
+
const out = join(root, "web-heuristic-angles.json");
|
|
10
|
+
const py = join(dirname(fileURLToPath(import.meta.url)), "harness_web", "heuristic_angles_shipped.py");
|
|
11
|
+
const json = execFileSync(
|
|
12
|
+
"python3",
|
|
13
|
+
[
|
|
14
|
+
"-c",
|
|
15
|
+
`import json, importlib.util
|
|
16
|
+
spec = importlib.util.spec_from_file_location("shipped", ${JSON.stringify(py)})
|
|
17
|
+
mod = importlib.util.module_from_spec(spec)
|
|
18
|
+
spec.loader.exec_module(mod)
|
|
19
|
+
print(json.dumps(mod.SHIPPED_HEURISTIC_ANGLES, indent=2))`,
|
|
20
|
+
],
|
|
21
|
+
{ encoding: "utf-8" },
|
|
22
|
+
);
|
|
23
|
+
writeFileSync(out, `${json}\n`, "utf-8");
|
|
24
|
+
console.log(`wrote ${out}`);
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Generate .pi/harness/agents.policy.yaml from harness agent .md frontmatter + submit registry.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
7
|
+
import { join, dirname } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { parse as parseYaml } from "yaml";
|
|
10
|
+
import { walkAgentsDir } from "../lib/harness-agent-discovery.mjs";
|
|
11
|
+
|
|
12
|
+
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
13
|
+
const AGENTS_DIR = join(ROOT, ".pi", "agents");
|
|
14
|
+
const OUT = join(ROOT, ".pi", "harness", "agents.policy.yaml");
|
|
15
|
+
|
|
16
|
+
const SUBMIT_BY_AGENT = {
|
|
17
|
+
"harness/planning/planning-context": ["submit_planning_context"],
|
|
18
|
+
"harness/planning/decompose": ["submit_decomposition_brief", "submit_human_required"],
|
|
19
|
+
"harness/planning/hypothesis": ["submit_hypothesis_brief"],
|
|
20
|
+
"harness/planning/hypothesis-validator": ["submit_hypothesis_validation"],
|
|
21
|
+
"harness/planning/plan-evaluator": ["submit_validation_turn"],
|
|
22
|
+
"harness/planning/plan-adversary": ["submit_adversary_brief"],
|
|
23
|
+
"harness/planning/sprint-contract-auditor": ["submit_sprint_audit"],
|
|
24
|
+
"harness/planning/review-integrator": ["submit_review_round_draft"],
|
|
25
|
+
"harness/planning/implementation-researcher": ["submit_implementation_research"],
|
|
26
|
+
"harness/planning/stack-researcher": ["submit_stack_brief"],
|
|
27
|
+
"harness/planning/execution-plan-author": ["submit_execution_plan_brief"],
|
|
28
|
+
"harness/running/executor": ["submit_executor_handoff"],
|
|
29
|
+
"harness/reviewing/evaluator": ["submit_eval_verdict"],
|
|
30
|
+
"harness/reviewing/adversary": ["submit_adversary_report"],
|
|
31
|
+
"harness/reviewing/tie-breaker": ["submit_human_required"],
|
|
32
|
+
"harness/trace-librarian": ["submit_human_required"],
|
|
33
|
+
"harness/incident-recorder": ["submit_human_required"],
|
|
34
|
+
"harness/sentrux-steward": ["submit_sentrux_manifest_proposal"],
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
function parseFrontmatter(content) {
|
|
38
|
+
const m = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
39
|
+
if (!m) return {};
|
|
40
|
+
return parseYaml(m[1]) ?? {};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function kindFor(id) {
|
|
44
|
+
if (id.startsWith("harness/planning/")) return "planner";
|
|
45
|
+
if (id === "harness/running/executor") return "executor";
|
|
46
|
+
if (id === "harness/reviewing/evaluator") return "evaluator";
|
|
47
|
+
if (id === "harness/reviewing/adversary") return "adversary";
|
|
48
|
+
if (id === "harness/reviewing/tie-breaker") return "tie_breaker";
|
|
49
|
+
if (id === "harness/trace-librarian") return "trace";
|
|
50
|
+
if (id === "harness/incident-recorder") return "incident";
|
|
51
|
+
if (id === "harness/sentrux-steward" || id === "harness/sentrux-bootstrap")
|
|
52
|
+
return "planner";
|
|
53
|
+
return "other";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const KIND_BASE = {
|
|
57
|
+
planner: ["read", "grep", "find", "ls"],
|
|
58
|
+
executor: ["read", "write", "edit", "bash", "grep", "find", "ls"],
|
|
59
|
+
evaluator: ["read", "grep", "find", "ls"],
|
|
60
|
+
adversary: ["read", "grep", "find", "ls"],
|
|
61
|
+
tie_breaker: ["read", "grep", "find", "ls"],
|
|
62
|
+
trace: ["read", "grep", "find", "ls"],
|
|
63
|
+
incident: ["read", "grep", "find", "ls"],
|
|
64
|
+
other: ["read", "grep", "find", "ls"],
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function csvTools(fm) {
|
|
68
|
+
const raw = fm.tools;
|
|
69
|
+
if (!raw) return [];
|
|
70
|
+
return String(raw)
|
|
71
|
+
.split(",")
|
|
72
|
+
.map((t) => t.trim())
|
|
73
|
+
.filter(Boolean);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function main() {
|
|
77
|
+
const files = new Map();
|
|
78
|
+
walkAgentsDir(AGENTS_DIR, "package", files);
|
|
79
|
+
|
|
80
|
+
const kinds = {
|
|
81
|
+
planner: { tools: KIND_BASE.planner, extensions: false, read_only: true },
|
|
82
|
+
executor: { tools: KIND_BASE.executor, extensions: true, read_only: false },
|
|
83
|
+
evaluator: { tools: KIND_BASE.evaluator, extensions: false, read_only: true },
|
|
84
|
+
adversary: { tools: KIND_BASE.adversary, extensions: false, read_only: true },
|
|
85
|
+
tie_breaker: {
|
|
86
|
+
tools: KIND_BASE.tie_breaker,
|
|
87
|
+
extensions: false,
|
|
88
|
+
read_only: true,
|
|
89
|
+
},
|
|
90
|
+
trace: { tools: KIND_BASE.trace, extensions: false, read_only: true },
|
|
91
|
+
incident: { tools: KIND_BASE.incident, extensions: false, read_only: true },
|
|
92
|
+
other: { tools: KIND_BASE.other, extensions: false, read_only: true },
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const agents = {};
|
|
96
|
+
|
|
97
|
+
for (const [id, file] of files) {
|
|
98
|
+
if (!id.startsWith("harness/")) continue;
|
|
99
|
+
const fm = parseFrontmatter(file.content);
|
|
100
|
+
const kind = kindFor(id);
|
|
101
|
+
const base = new Set(KIND_BASE[kind] ?? KIND_BASE.other);
|
|
102
|
+
const fromFm = csvTools(fm);
|
|
103
|
+
const submit = SUBMIT_BY_AGENT[id] ?? [];
|
|
104
|
+
const toolsAdd = [...new Set([...fromFm, ...submit])].filter(
|
|
105
|
+
(t) => !base.has(t),
|
|
106
|
+
);
|
|
107
|
+
const entry = { kind };
|
|
108
|
+
if (toolsAdd.length > 0) entry.tools_add = toolsAdd;
|
|
109
|
+
if (fm.extensions === false) entry.extensions = false;
|
|
110
|
+
if (fm.extensions === true) entry.extensions = true;
|
|
111
|
+
if (typeof fm.max_turns === "number") entry.max_turns = fm.max_turns;
|
|
112
|
+
if (typeof fm.thinking === "string") entry.thinking = fm.thinking;
|
|
113
|
+
if (submit.length === 1) entry.submit_tool = submit[0];
|
|
114
|
+
agents[id] = entry;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// plan-synthesizer: parent-only, minimal policy for spawn if ever used
|
|
118
|
+
agents["harness/planning/plan-synthesizer"] = {
|
|
119
|
+
kind: "planner",
|
|
120
|
+
tools_add: [
|
|
121
|
+
"submit_decomposition_brief",
|
|
122
|
+
"submit_hypothesis_brief",
|
|
123
|
+
"submit_execution_plan_brief",
|
|
124
|
+
],
|
|
125
|
+
extensions: false,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const doc = {
|
|
129
|
+
apiVersion: "harness.toolkit/v1",
|
|
130
|
+
kinds,
|
|
131
|
+
agents,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const yaml = [
|
|
135
|
+
"# Generated/maintained SSOT for harness agent tools (see ADR 0049).",
|
|
136
|
+
"# Regenerate hints: node .pi/scripts/generate-agents-policy-yaml.mjs",
|
|
137
|
+
"",
|
|
138
|
+
];
|
|
139
|
+
const { stringify } = await import("yaml");
|
|
140
|
+
yaml.push(stringify(doc));
|
|
141
|
+
await writeFile(OUT, yaml.join("\n"), "utf8");
|
|
142
|
+
console.log(`Wrote ${OUT} (${Object.keys(agents).length} harness agents)`);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
main().catch((err) => {
|
|
146
|
+
console.error(err);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
});
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* node .pi/scripts/harness-agents-manifest.mjs --check
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
10
11
|
import { readFile, writeFile } from "node:fs/promises";
|
|
11
12
|
import { join, dirname } from "node:path";
|
|
12
13
|
import { fileURLToPath } from "node:url";
|
|
@@ -15,6 +16,10 @@ import {
|
|
|
15
16
|
sha256Content,
|
|
16
17
|
walkAgentsDir,
|
|
17
18
|
} from "../lib/harness-agent-discovery.mjs";
|
|
19
|
+
import {
|
|
20
|
+
loadAgentsPolicyMerged,
|
|
21
|
+
packageAgentsPolicyPath,
|
|
22
|
+
} from "../lib/agents-policy.mjs";
|
|
18
23
|
|
|
19
24
|
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
20
25
|
const MANIFEST_PATH = join(ROOT, ".pi", "harness", "agents.manifest.json");
|
|
@@ -27,7 +32,7 @@ async function readPackageMeta() {
|
|
|
27
32
|
return { name: pkg.name ?? "ultimate-pi", version: pkg.version ?? "0.0.0" };
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
function buildManifest(packageFiles, packageName, packageVersion) {
|
|
35
|
+
async function buildManifest(packageFiles, packageName, packageVersion) {
|
|
31
36
|
const agents = {};
|
|
32
37
|
for (const f of packageFiles.values()) {
|
|
33
38
|
agents[f.id] = {
|
|
@@ -35,11 +40,17 @@ function buildManifest(packageFiles, packageName, packageVersion) {
|
|
|
35
40
|
sha256: sha256Content(f.content),
|
|
36
41
|
};
|
|
37
42
|
}
|
|
43
|
+
const policyPath = packageAgentsPolicyPath(ROOT);
|
|
44
|
+
let policy_sha256;
|
|
45
|
+
if (existsSync(policyPath)) {
|
|
46
|
+
policy_sha256 = sha256Content(await readFile(policyPath, "utf-8"));
|
|
47
|
+
}
|
|
38
48
|
return {
|
|
39
49
|
schema_version: "1.0.0",
|
|
40
50
|
package: packageName,
|
|
41
51
|
package_version: packageVersion,
|
|
42
52
|
generated_at: new Date().toISOString(),
|
|
53
|
+
...(policy_sha256 ? { policy_sha256 } : {}),
|
|
43
54
|
agents,
|
|
44
55
|
};
|
|
45
56
|
}
|
|
@@ -68,6 +79,37 @@ function getDriftReport(manifest, packageFiles) {
|
|
|
68
79
|
return { ok: items.length === 0, items };
|
|
69
80
|
}
|
|
70
81
|
|
|
82
|
+
function frontmatterHasToolLists(content) {
|
|
83
|
+
const m = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
84
|
+
if (!m) return false;
|
|
85
|
+
return /^tools:/m.test(m[1]) || /^disallowed_tools:/m.test(m[1]);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function verifyAgentsPolicy(packageFiles) {
|
|
89
|
+
const items = [];
|
|
90
|
+
const policyPath = packageAgentsPolicyPath(ROOT);
|
|
91
|
+
if (!existsSync(policyPath)) {
|
|
92
|
+
return { ok: false, items: [{ id: "*", kind: "missing_agents_policy_yaml" }] };
|
|
93
|
+
}
|
|
94
|
+
const merged = loadAgentsPolicyMerged(ROOT, ROOT);
|
|
95
|
+
for (const [id, file] of packageFiles) {
|
|
96
|
+
if (!id.startsWith("harness/")) continue;
|
|
97
|
+
if (frontmatterHasToolLists(file.content)) {
|
|
98
|
+
items.push({ id, kind: "frontmatter_tools" });
|
|
99
|
+
}
|
|
100
|
+
if (!merged.agents.has(id)) {
|
|
101
|
+
items.push({ id, kind: "missing_policy_entry" });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
for (const id of merged.agents.keys()) {
|
|
105
|
+
if (!id.startsWith("harness/")) continue;
|
|
106
|
+
if (!packageFiles.has(id)) {
|
|
107
|
+
items.push({ id, kind: "orphan_policy_entry" });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return { ok: items.length === 0, items };
|
|
111
|
+
}
|
|
112
|
+
|
|
71
113
|
async function loadPackageFiles() {
|
|
72
114
|
const files = new Map();
|
|
73
115
|
walkAgentsDir(PACKAGE_AGENTS, "package", files);
|
|
@@ -81,7 +123,7 @@ async function main() {
|
|
|
81
123
|
const mode = process.argv.includes("--check") ? "check" : "write";
|
|
82
124
|
const { name, version } = await readPackageMeta();
|
|
83
125
|
const packageFiles = await loadPackageFiles();
|
|
84
|
-
const built = buildManifest(packageFiles, name, version);
|
|
126
|
+
const built = await buildManifest(packageFiles, name, version);
|
|
85
127
|
|
|
86
128
|
if (mode === "write") {
|
|
87
129
|
await writeFile(MANIFEST_PATH, `${JSON.stringify(built, null, "\t")}\n`, "utf-8");
|
|
@@ -107,6 +149,19 @@ async function main() {
|
|
|
107
149
|
process.exit(1);
|
|
108
150
|
}
|
|
109
151
|
|
|
152
|
+
const policyCheck = verifyAgentsPolicy(packageFiles);
|
|
153
|
+
if (!policyCheck.ok) {
|
|
154
|
+
for (const item of policyCheck.items) {
|
|
155
|
+
console.error(`policy: ${item.id} (${item.kind})`);
|
|
156
|
+
}
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (built.policy_sha256 && onDisk.policy_sha256 !== built.policy_sha256) {
|
|
161
|
+
console.error("policy_sha256 mismatch — regenerate manifest with --write");
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
|
|
110
165
|
if (onDisk.package_version !== version) {
|
|
111
166
|
console.error(
|
|
112
167
|
`package_version mismatch: manifest=${onDisk.package_version} package=${version}`,
|
|
@@ -114,7 +169,9 @@ async function main() {
|
|
|
114
169
|
process.exit(1);
|
|
115
170
|
}
|
|
116
171
|
|
|
117
|
-
console.log(
|
|
172
|
+
console.log(
|
|
173
|
+
`agents.manifest.json OK (${Object.keys(built.agents).length} agents, policy aligned)`,
|
|
174
|
+
);
|
|
118
175
|
}
|
|
119
176
|
|
|
120
177
|
main().catch((err) => {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env npx tsx
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { doctorHarnessPolicies } from "../lib/agt/policy-engine.js";
|
|
6
|
+
|
|
7
|
+
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
8
|
+
const doc = doctorHarnessPolicies(ROOT);
|
|
9
|
+
if (!doc.ok) {
|
|
10
|
+
console.error("AGT policy doctor failed:");
|
|
11
|
+
for (const e of doc.errors) console.error(` - ${e}`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const pkg = JSON.parse(readFileSync(join(ROOT, "package.json"), "utf-8")) as {
|
|
15
|
+
files?: string[];
|
|
16
|
+
};
|
|
17
|
+
const files = pkg.files ?? [];
|
|
18
|
+
if (
|
|
19
|
+
!files.some(
|
|
20
|
+
(f: string) =>
|
|
21
|
+
f === ".pi/harness/policies" || f.startsWith(".pi/harness/policies/"),
|
|
22
|
+
)
|
|
23
|
+
) {
|
|
24
|
+
console.error("package.json files[] missing .pi/harness/policies");
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
if (
|
|
28
|
+
!files.includes(".pi/lib") &&
|
|
29
|
+
!files.some((f) => f.startsWith(".pi/lib/"))
|
|
30
|
+
) {
|
|
31
|
+
console.error("package.json files[] missing .pi/lib (ships .pi/lib/agt)");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
console.log(
|
|
35
|
+
`AGT doctor OK (${doc.loaded.length} policies at ${doc.policyDir})`,
|
|
36
|
+
);
|
|
@@ -214,6 +214,11 @@ verify_scrapling() {
|
|
|
214
214
|
else
|
|
215
215
|
fail "harness-web search smoke failed (ddg_html)"
|
|
216
216
|
fi
|
|
217
|
+
if python3 "$_hw" search-deep "ultimate-pi harness" --expand-heuristic -o .web/verify-search-deep.json --limit 3 2>/dev/null | grep -q wrote; then
|
|
218
|
+
pass "harness-web search-deep smoke (heuristic angles)"
|
|
219
|
+
else
|
|
220
|
+
fail "harness-web search-deep smoke failed"
|
|
221
|
+
fi
|
|
217
222
|
if python3 "$_hw" scrape "https://example.com" -o .web/verify-page.md --fast 2>/dev/null | grep -q wrote; then
|
|
218
223
|
pass "harness-web scrape --fast smoke"
|
|
219
224
|
else
|
|
@@ -262,11 +267,18 @@ verify_cocoindex() {
|
|
|
262
267
|
|
|
263
268
|
verify_biome() {
|
|
264
269
|
log "[biome]"
|
|
265
|
-
|
|
270
|
+
if [ ! -f "${ROOT}/package.json" ] && [ ! -f "${ROOT}/biome.json" ]; then
|
|
271
|
+
warn "biome skipped (non-JS/TS repo detected; optional tool)"
|
|
272
|
+
return
|
|
273
|
+
fi
|
|
274
|
+
npm_global_install "@biomejs/biome" "biome" || {
|
|
275
|
+
warn "biome npm install failed (optional — use your stack's formatter/linter)"
|
|
276
|
+
return
|
|
277
|
+
}
|
|
266
278
|
if biome --version &>/dev/null; then
|
|
267
279
|
pass "biome $(biome --version 2>/dev/null | head -1)"
|
|
268
280
|
else
|
|
269
|
-
|
|
281
|
+
warn "biome --version failed (optional — use your stack's formatter/linter)"
|
|
270
282
|
fi
|
|
271
283
|
}
|
|
272
284
|
|