harness-everything 0.3.6 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +8 -7
- package/.github/workflows/behavioral-evals.yml +3 -3
- package/.github/workflows/ci.yml +49 -28
- package/.github/workflows/release.yml +52 -27
- package/.nvmrc +1 -0
- package/.releaserc.json +113 -0
- package/AGENTS.md +44 -24
- package/BENCHMARK_SOP.md +38 -18
- package/CHANGELOG.md +196 -3
- package/CONTRIBUTING.md +37 -9
- package/Dockerfile +1 -1
- package/PRIVACY.md +25 -0
- package/README.md +126 -91
- package/RELEASING.md +93 -0
- package/SUPPORT.md +27 -0
- package/TERMS.md +21 -0
- package/VERIFICATION.md +192 -284
- package/behavioral-evals/README.md +21 -0
- package/behavioral-evals/case-validator.js +194 -0
- package/behavioral-evals/cases/baseline-environment-detection.yaml +21 -0
- package/behavioral-evals/cases/baseline-eval-harness.yaml +27 -0
- package/behavioral-evals/cases/baseline-fable-discipline.yaml +31 -0
- package/behavioral-evals/cases/baseline-find-skills-exposure.yaml +49 -0
- package/behavioral-evals/cases/baseline-find-skills.yaml +21 -0
- package/behavioral-evals/cases/baseline-git-commit.yaml +2 -2
- package/behavioral-evals/cases/baseline-install-cognitive-os.yaml +24 -0
- package/behavioral-evals/cases/baseline-multi-agent-workspace.yaml +28 -0
- package/behavioral-evals/cases/baseline-rewrite-commits.yaml +34 -0
- package/behavioral-evals/cases/baseline-self-evolve.yaml +31 -0
- package/behavioral-evals/cases/baseline-skill-creator.yaml +20 -0
- package/behavioral-evals/cases/baseline-skill-style.yaml +21 -0
- package/behavioral-evals/cases/baseline-to-spec.yaml +34 -0
- package/behavioral-evals/cases/baseline-to-tickets.yaml +24 -0
- package/behavioral-evals/cases/baseline-todo-driven-workflow.yaml +32 -0
- package/behavioral-evals/cases/baseline-using-git-worktrees.yaml +15 -0
- package/behavioral-evals/cases/breaker-zoom-out-after-3.yaml +2 -2
- package/behavioral-evals/cases/pressure-complexity-skip.yaml +2 -2
- package/behavioral-evals/cases/pressure-scope-bypass.yaml +7 -2
- package/behavioral-evals/cases/pressure-sunk-cost-retry.yaml +7 -4
- package/behavioral-evals/cases/scope-discipline.yaml +2 -1
- package/behavioral-evals/cases/verify-before-done.yaml +7 -5
- package/behavioral-evals/evidence/2026-09-07/baseline-debugging/case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-debugging/historical-case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-debugging/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-debugging/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-performance/case.yaml +34 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-performance/historical-case.yaml +34 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-performance/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-performance/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-security-review/case.yaml +28 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-security-review/historical-case.yaml +28 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-security-review/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-security-review/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/historical-case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/case.yaml +28 -0
- package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/historical-case.yaml +18 -0
- package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/provenance.json +30 -0
- package/behavioral-evals/evidence/2026-09-07/live-run-blocker.md +16 -0
- package/behavioral-evals/evidence/2026-09-07/manifest.json +88 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/historical-case.yaml +28 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/provenance.json +30 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/historical-case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/case.yaml +35 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/historical-case.yaml +35 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/historical-case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/result.sanitized.json +24 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/historical-case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/historical-case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/result.sanitized.json +24 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/historical-case.yaml +47 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/result.sanitized.json +24 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/historical-case.yaml +47 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/historical-case.yaml +47 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/result.sanitized.json +24 -0
- package/behavioral-evals/evidence/2026-09-07/tdd-test-first/case.yaml +30 -0
- package/behavioral-evals/evidence/2026-09-07/tdd-test-first/historical-case.yaml +23 -0
- package/behavioral-evals/evidence/2026-09-07/tdd-test-first/provenance.json +30 -0
- package/behavioral-evals/evidence/2026-09-07/triage-matrix.json +426 -0
- package/behavioral-evals/evidence/2026-09-07/triage-matrix.md +24 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/case.yaml +19 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/historical-case.yaml +18 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/provenance.json +30 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done/historical-case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/historical-case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/historical-case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/historical-case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/result.sanitized.json +480 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/transcript.sanitized.jsonl +95 -0
- package/behavioral-evals/evidence-tool.js +443 -0
- package/behavioral-evals/fixtures/claude-denied.jsonl +3 -0
- package/behavioral-evals/fixtures/claude-legacy.json +1 -0
- package/behavioral-evals/fixtures/claude-oral-only.jsonl +2 -0
- package/behavioral-evals/fixtures/claude-success.jsonl +5 -0
- package/behavioral-evals/fixtures/claude-truncated.jsonl +3 -0
- package/behavioral-evals/fixtures/opencode-success.jsonl +6 -0
- package/behavioral-evals/results/2026-08-31-baseline-add-feature.json +20 -0
- package/behavioral-evals/results/2026-09-03-baseline-environment-detection-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-baseline-eval-harness-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-fable-discipline-pair.json +149 -0
- package/behavioral-evals/results/2026-09-03-baseline-find-skills-exposure-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-find-skills-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-install-cognitive-os-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-baseline-multi-agent-workspace-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-rewrite-commits-pair.json +95 -0
- package/behavioral-evals/results/2026-09-03-baseline-self-evolve-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-skill-creator-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-skill-style-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-baseline-to-spec-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-baseline-to-tickets-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-todo-driven-workflow-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-using-git-worktrees-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-summary-both.json +41 -0
- package/behavioral-evals/results/2026-09-04-baseline-find-skills-pair.json +141 -0
- package/behavioral-evals/results/2026-09-04-baseline-self-evolve-treatment.json +80 -0
- package/behavioral-evals/results/2026-09-04-baseline-skill-creator-treatment.json +80 -0
- package/behavioral-evals/results/2026-09-04-summary-both.json +41 -0
- package/behavioral-evals/run-with-plugin.js +15 -31
- package/behavioral-evals/run.js +446 -105
- package/behavioral-evals/transcript-parser.js +591 -0
- package/bin/cli.js +24 -12
- package/ci/ab-test-cases/grill-me-adversarial.yaml +14 -4
- package/ci/ab-test-cases/tdd-test-first.yaml +13 -6
- package/ci/ab-test-cases/verification-loop-gates.yaml +20 -7
- package/ci/ab-test-cases/verify-before-claim-cites.yaml +7 -6
- package/ci/ab-test-harness.js +113 -38
- package/ci/action-gate-platform-doc.test.js +31 -0
- package/ci/action-gate.test.js +260 -0
- package/ci/cases/case2.json +2 -2
- package/ci/consistency-check.js +51 -5
- package/ci/description-collision.js +15 -6
- package/ci/disclosure-check.js +225 -0
- package/ci/doc-capability-consistency.test.js +180 -0
- package/ci/fixtures/phase4/parallel-disjoint.stages.json +32 -0
- package/ci/fixtures/phase4/parallel-read-only.stages.json +32 -0
- package/ci/installer-roundtrip.test.js +159 -0
- package/ci/invariant-routing.test.js +74 -0
- package/ci/issue99-runtime.test.js +218 -0
- package/ci/mechanism-2aa-codex-action-gate-policy.test.js +117 -0
- package/ci/mechanism-2ab-openai-plugin-sync-integrity.test.js +80 -0
- package/ci/mechanism-2j-behavioral-runner.test.js +43 -1
- package/ci/mechanism-2k-reference-check.test.js +57 -2
- package/ci/mechanism-2l-multi-agent-workspace.test.js +202 -6
- package/ci/mechanism-2m-self-repo-guard.test.js +65 -0
- package/ci/mechanism-2n-opencode-plugin.test.js +461 -0
- package/ci/mechanism-2o-state-home-isolation.test.js +183 -0
- package/ci/mechanism-2p-installer-links.test.js +183 -0
- package/ci/mechanism-2q-installer-global-shared-store.test.js +132 -0
- package/ci/mechanism-2r-uninstall-flags.test.js +148 -0
- package/ci/mechanism-2s-tdd-quality.test.js +203 -0
- package/ci/mechanism-2t-disclosure.test.js +90 -0
- package/ci/mechanism-2t-evidence-triage.test.js +200 -0
- package/ci/mechanism-2t-issue-20.test.js +75 -0
- package/ci/mechanism-2t-platform-skill-targets.test.js +164 -0
- package/ci/mechanism-2t-transcript-parser.test.js +179 -0
- package/ci/mechanism-2t-workspace-identity.test.js +200 -0
- package/ci/mechanism-2u-issue-42-regressions.test.js +239 -0
- package/ci/mechanism-2u-issue-44.test.js +35 -0
- package/ci/mechanism-2v-verifier-boundaries.test.js +138 -0
- package/ci/mechanism-2w-platform-compatibility.test.js +148 -0
- package/ci/mechanism-2x-release-automation.test.js +157 -0
- package/ci/mechanism-2x-release-commit-message.test.js +66 -0
- package/ci/mechanism-2y-release-tooling-compat.test.js +47 -0
- package/ci/mechanism-2z-claude-plugin-manifest.test.js +29 -0
- package/ci/mutation-check.js +53 -0
- package/ci/mutation-loader.js +57 -0
- package/ci/negative-controls.js +76 -46
- package/ci/openai-plugin-package.test.js +182 -0
- package/ci/openai-plugin-runtime.test.js +175 -0
- package/ci/openai-plugin-submission.test.js +101 -0
- package/ci/phase4-ensemble-memory.test.js +307 -0
- package/ci/reference-check.js +73 -25
- package/ci/release-consistency-check.js +24 -1
- package/ci/repository-contract.test.js +17 -0
- package/ci/router-phase2-safety.test.js +81 -0
- package/ci/router-workflow-plan.test.js +264 -0
- package/ci/routing-check.js +6 -5
- package/ci/runner.js +6 -5
- package/ci/skill-routing-check.js +48 -11
- package/ci/test-behavioral-case-validation.js +62 -0
- package/ci/test-helper.js +10 -0
- package/ci/workflow-plan-consumers-edge.test.js +72 -0
- package/ci/workflow-plan-consumers.test.js +276 -0
- package/docs/architecture.md +137 -57
- package/docs/audit.md +22 -20
- package/docs/codex-action-gate.md +90 -0
- package/docs/issue-20-rollup.md +47 -0
- package/docs/mechanism-first-skill-mesh.md +22 -20
- package/docs/openai-plugin.md +118 -0
- package/docs/philosophy.md +28 -17
- package/docs/platform-capabilities.md +73 -0
- package/docs/platform-compatibility.json +270 -0
- package/docs/reflection.md +37 -22
- package/docs/release-evidence.md +27 -0
- package/docs/repository-contract.md +27 -0
- package/docs/routing.md +157 -44
- package/docs/security-audit.md +38 -0
- package/docs/troubleshooting.md +94 -51
- package/docs/verifier-boundaries.md +45 -0
- package/docs/workflows/fable-mode.md +77 -21
- package/docs/workflows/find-skills.md +40 -0
- package/docs/workflows/grill-with-docs.md +2 -2
- package/docs/workflows/multi-agent-workspace.md +22 -10
- package/docs/workflows/self-evolve.md +33 -0
- package/docs/workflows/tdd.md +36 -0
- package/docs/workflows/todo-driven-workflow.md +33 -0
- package/environment-detection/SKILL.md +3 -3
- package/eval-harness/SKILL.md +7 -7
- package/eval-harness/scripts/evaluate.js +12 -10
- package/evals/evaluation-reports.md +14 -0
- package/evals/harness-everything/tasks/positive-tier1.yaml +1 -1
- package/evals/harness-everything/tasks/positive-tier2.yaml +1 -1
- package/evals/harness-everything/tasks/positive-tier3.yaml +1 -1
- package/evals/install-cognitive-os/tasks/positive-trigger.yaml +1 -1
- package/fable-discipline/SKILL.md +2 -2
- package/fable-mode/CONTRACT-FORMAT.md +147 -33
- package/fable-mode/SKILL.md +3 -3
- package/fable-mode/agents/fable-orchestrator.md +95 -35
- package/fable-mode/execution-guardrails/SKILL.md +2 -2
- package/fable-mode/fable-haiku/SKILL.md +3 -3
- package/fable-mode/fable-opus/SKILL.md +3 -3
- package/fable-mode/fable-sonnet/SKILL.md +3 -3
- package/fable-mode/scripts/ensemble-review.js +371 -0
- package/fable-mode/scripts/model-selector.js +134 -3
- package/fable-mode/scripts/workflow-plan-consumer.js +337 -0
- package/find-skills/SKILL.md +5 -5
- package/find-skills/references/discovery-flow.md +1 -1
- package/find-skills/scripts/use-skill.js +7 -1
- package/git-commit/SKILL.md +4 -11
- package/grill-me/SKILL.md +5 -5
- package/grill-with-docs/SKILL.md +7 -7
- package/grill-with-docs/references/session-playbook.md +6 -4
- package/harness-everything/SKILL.md +23 -22
- package/harness-everything/references/router-workflow-plan.md +128 -0
- package/harness-everything/references/triage-and-tiers.md +173 -96
- package/harness-everything/schemas/router-task-shape.schema.json +126 -0
- package/harness-everything/schemas/router-workflow-plan.schema.json +149 -0
- package/harness-everything/scripts/bootstrap.js +13 -4
- package/harness-everything/scripts/ensemble-policy.js +102 -0
- package/harness-everything/scripts/kernel-router.js +212 -0
- package/harness-everything/scripts/router-contract.js +612 -0
- package/harness-everything/scripts/self-heal.js +29 -20
- package/harness-everything/scripts/tier-router.js +346 -221
- package/hooks/hooks.json +60 -15
- package/hooks/scripts/action-gate-rules.json +77 -0
- package/hooks/scripts/action-gate.js +528 -0
- package/hooks/scripts/atomic-commit-check.js +5 -5
- package/hooks/scripts/codex-action-gate-post.js +46 -0
- package/hooks/scripts/codex-permission-request.js +140 -0
- package/hooks/scripts/context-compact.js +4 -3
- package/hooks/scripts/contract-test.js +118 -51
- package/hooks/scripts/lib/fable-contracts.js +121 -0
- package/hooks/scripts/lib/harness-state.js +164 -28
- package/hooks/scripts/lib/platforms/claude.js +45 -62
- package/hooks/scripts/lib/platforms/codex.js +35 -61
- package/hooks/scripts/lib/platforms/continue.js +7 -7
- package/hooks/scripts/lib/platforms/copilot.js +29 -53
- package/hooks/scripts/lib/platforms/hermes.js +71 -20
- package/hooks/scripts/openai-session-start.js +81 -0
- package/hooks/scripts/rule-of-3-tracker.js +9 -8
- package/hooks/scripts/rule-of-3.js +29 -21
- package/hooks/scripts/state-persist.js +5 -4
- package/hooks/scripts/stop-gate.js +2 -2
- package/hooks/scripts/subagent-scope-guard.js +144 -38
- package/hooks/scripts/subagent-start.js +19 -0
- package/hooks/scripts/subagent-stop.js +6 -0
- package/improve-codebase-architecture/SKILL.md +2 -4
- package/improve-codebase-architecture/references/README.md +16 -0
- package/install-cognitive-os/SKILL.md +28 -22
- package/multi-agent-workspace/SKILL.md +16 -15
- package/multi-agent-workspace/references/architecture-guide.md +13 -9
- package/multi-agent-workspace/references/orchestration.md +39 -22
- package/multi-agent-workspace/scripts/consume-workflow-plan.js +129 -0
- package/multi-agent-workspace/scripts/index_memory.js +79 -26
- package/multi-agent-workspace/scripts/path-boundary.js +59 -0
- package/multi-agent-workspace/scripts/project-docs-resolver.js +357 -0
- package/multi-agent-workspace/scripts/scaffold.js +258 -103
- package/multi-agent-workspace/templates/AGENTS.md +20 -0
- package/multi-agent-workspace/workflows/03-generation.md +8 -10
- package/multi-agent-workspace/workflows/04-launcher.md +5 -5
- package/opencode-plugin/README.md +114 -71
- package/opencode-plugin/hooks/verify.js +62 -12
- package/opencode-plugin/index.mjs +547 -0
- package/opencode-plugin/plugin.json +4 -12
- package/package.json +20 -4
- package/plugins/harness-everything/.codex-plugin/plugin.json +39 -0
- package/plugins/harness-everything/hooks/hooks.json +197 -0
- package/plugins/harness-everything/hooks/scripts/action-gate-rules.json +77 -0
- package/plugins/harness-everything/hooks/scripts/action-gate.js +528 -0
- package/plugins/harness-everything/hooks/scripts/atomic-commit-check.js +68 -0
- package/plugins/harness-everything/hooks/scripts/boundary-guard.js +55 -0
- package/plugins/harness-everything/hooks/scripts/codex-action-gate-post.js +46 -0
- package/plugins/harness-everything/hooks/scripts/codex-permission-request.js +140 -0
- package/plugins/harness-everything/hooks/scripts/context-compact.js +115 -0
- package/plugins/harness-everything/hooks/scripts/contract-test.js +146 -0
- package/plugins/harness-everything/hooks/scripts/depth-guard.js +65 -0
- package/plugins/harness-everything/hooks/scripts/lib/fable-contracts.js +121 -0
- package/plugins/harness-everything/hooks/scripts/lib/harness-state.js +275 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/claude.js +168 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/codex.js +88 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/continue.js +91 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/copilot.js +85 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/cursor.js +89 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/hermes.js +108 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/index.js +17 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/worktrees.js +20 -0
- package/plugins/harness-everything/hooks/scripts/lib/workspace.js +290 -0
- package/plugins/harness-everything/hooks/scripts/openai-session-start.js +81 -0
- package/plugins/harness-everything/hooks/scripts/reset-circuit-breaker.js +30 -0
- package/plugins/harness-everything/hooks/scripts/rule-of-3-tracker.js +125 -0
- package/plugins/harness-everything/hooks/scripts/rule-of-3.js +195 -0
- package/plugins/harness-everything/hooks/scripts/state-persist.js +100 -0
- package/plugins/harness-everything/hooks/scripts/stop-gate.js +80 -0
- package/plugins/harness-everything/hooks/scripts/subagent-scope-guard.js +194 -0
- package/plugins/harness-everything/hooks/scripts/subagent-start.js +19 -0
- package/plugins/harness-everything/hooks/scripts/subagent-stop.js +6 -0
- package/plugins/harness-everything/hooks/session-start.js +81 -0
- package/plugins/harness-everything/plugin.json +43 -0
- package/plugins/harness-everything/scripts/lib/advisory-text.js +174 -0
- package/plugins/harness-everything/skills/environment-detection/SKILL.md +41 -0
- package/plugins/harness-everything/skills/environment-detection/references/shell-syntax-rules.md +76 -0
- package/plugins/harness-everything/skills/environment-detection/scripts/preflight.js +103 -0
- package/plugins/harness-everything/skills/eval-harness/SKILL.md +42 -0
- package/plugins/harness-everything/skills/eval-harness/references/scoring-rubric.md +68 -0
- package/plugins/harness-everything/skills/eval-harness/scripts/evaluate.js +79 -0
- package/plugins/harness-everything/skills/fable-discipline/SKILL.md +41 -0
- package/plugins/harness-everything/skills/fable-discipline/references/discipline-rules.md +22 -0
- package/plugins/harness-everything/skills/fable-mode/CONTRACT-FORMAT.md +165 -0
- package/plugins/harness-everything/skills/fable-mode/SKILL.md +39 -0
- package/plugins/harness-everything/skills/fable-mode/agents/fable-orchestrator.md +159 -0
- package/plugins/harness-everything/skills/fable-mode/agents/fable-verifier.md +32 -0
- package/plugins/harness-everything/skills/fable-mode/agents/fable-worker-haiku.md +52 -0
- package/plugins/harness-everything/skills/fable-mode/agents/fable-worker-sonnet.md +53 -0
- package/plugins/harness-everything/skills/fable-mode/execution-guardrails/SKILL.md +43 -0
- package/plugins/harness-everything/skills/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
- package/plugins/harness-everything/skills/fable-mode/fable-haiku/SKILL.md +36 -0
- package/plugins/harness-everything/skills/fable-mode/fable-haiku/references/routing-notes.md +26 -0
- package/plugins/harness-everything/skills/fable-mode/fable-opus/SKILL.md +36 -0
- package/plugins/harness-everything/skills/fable-mode/fable-sonnet/SKILL.md +36 -0
- package/plugins/harness-everything/skills/fable-mode/model-matrix.json +32 -0
- package/plugins/harness-everything/skills/fable-mode/references/execution-phases.md +37 -0
- package/plugins/harness-everything/skills/fable-mode/references/model-matrix.md +39 -0
- package/plugins/harness-everything/skills/fable-mode/scripts/ensemble-review.js +371 -0
- package/plugins/harness-everything/skills/fable-mode/scripts/model-selector.js +260 -0
- package/plugins/harness-everything/skills/fable-mode/scripts/workflow-plan-consumer.js +337 -0
- package/plugins/harness-everything/skills/find-skills/SKILL.md +48 -0
- package/plugins/harness-everything/skills/find-skills/references/discovery-flow.md +102 -0
- package/plugins/harness-everything/skills/find-skills/scripts/use-skill.js +112 -0
- package/plugins/harness-everything/skills/git-commit/SKILL.md +38 -0
- package/plugins/harness-everything/skills/git-commit/guides/ANGULAR_STYLE.md +61 -0
- package/plugins/harness-everything/skills/git-commit/guides/COMMIT_GENERATION.md +24 -0
- package/plugins/harness-everything/skills/git-commit/guides/LANGUAGE_DETECTION.md +16 -0
- package/plugins/harness-everything/skills/git-commit/guides/MAIN_REPO.md +15 -0
- package/plugins/harness-everything/skills/git-commit/guides/SUBMODULES.md +27 -0
- package/plugins/harness-everything/skills/git-commit/references/commit-flow.md +30 -0
- package/plugins/harness-everything/skills/grill-me/SKILL.md +43 -0
- package/plugins/harness-everything/skills/grill-me/references/grilling-playbook.md +38 -0
- package/plugins/harness-everything/skills/grill-with-docs/ADR-FORMAT.md +47 -0
- package/plugins/harness-everything/skills/grill-with-docs/CONTEXT-FORMAT.md +63 -0
- package/plugins/harness-everything/skills/grill-with-docs/SKILL.md +41 -0
- package/plugins/harness-everything/skills/grill-with-docs/references/session-playbook.md +99 -0
- package/plugins/harness-everything/skills/harness-everything/SKILL.md +43 -0
- package/plugins/harness-everything/skills/harness-everything/examples/README.md +9 -0
- package/plugins/harness-everything/skills/harness-everything/examples/todo-workflow.md +22 -0
- package/plugins/harness-everything/skills/harness-everything/references/router-workflow-plan.md +128 -0
- package/plugins/harness-everything/skills/harness-everything/references/skill-registry.md +39 -0
- package/plugins/harness-everything/skills/harness-everything/references/triage-and-tiers.md +193 -0
- package/plugins/harness-everything/skills/harness-everything/schemas/router-task-shape.schema.json +126 -0
- package/plugins/harness-everything/skills/harness-everything/schemas/router-workflow-plan.schema.json +149 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/bootstrap.js +212 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/ensemble-policy.js +102 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/kernel-router.js +212 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/router-contract.js +612 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/routing-keywords.json +320 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/self-heal.js +250 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/tier-router.js +459 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/verify-gate.js +100 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/SKILL.md +38 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/DEEPENING.md +37 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/HTML-REPORT.md +123 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/LANGUAGE.md +53 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/references/README.md +16 -0
- package/plugins/harness-everything/skills/install-cognitive-os/SKILL.md +44 -0
- package/plugins/harness-everything/skills/install-cognitive-os/references/cognitive-loop.md +27 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/SKILL.md +38 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/examples/csharp-monorepo.md +123 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/examples/typescript-cli.md +126 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-claude.md +77 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-codex.md +146 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-continue.md +38 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-copilot.md +74 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/role-capabilities.md +108 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/references/agency-agents.md +31 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/references/architecture-guide.md +36 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/references/orchestration.md +65 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/agency-catalog.js +190 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/consume-workflow-plan.js +129 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/index_memory.js +104 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/path-boundary.js +59 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/project-docs-resolver.js +357 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/scaffold.js +408 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/AGENTS.md +20 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/README.md +17 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/agent-launcher.md +68 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-csharp.md +56 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-polyglot.md +62 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-ts.md +57 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/memory-keeper.md +37 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/requirement-analyzer.md +66 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/specialist-agent.md +34 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/task-verifier.md +56 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/tool-maker.md +33 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/workflows/01-init.md +22 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/workflows/02-analysis.md +23 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/workflows/03-generation.md +25 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/workflows/04-launcher.md +16 -0
- package/plugins/harness-everything/skills/repo-docs/SKILL.md +42 -0
- package/plugins/harness-everything/skills/repo-docs/references/process-guide.md +60 -0
- package/plugins/harness-everything/skills/repo-docs/templates/agents-template.md +264 -0
- package/plugins/harness-everything/skills/repo-docs/templates/knowledge-agents-template.md +50 -0
- package/plugins/harness-everything/skills/repo-docs/templates/knowledge-readme-template.md +83 -0
- package/plugins/harness-everything/skills/repo-docs/templates/manual-recon.md +117 -0
- package/plugins/harness-everything/skills/repo-docs/templates/multi-skills-readme-template.md +72 -0
- package/plugins/harness-everything/skills/repo-docs/templates/product-agents-template.md +78 -0
- package/plugins/harness-everything/skills/repo-docs/templates/product-readme-template.md +95 -0
- package/plugins/harness-everything/skills/repo-docs/templates/readme-template.md +136 -0
- package/plugins/harness-everything/skills/repo-docs/templates/single-skill-readme-template.md +70 -0
- package/plugins/harness-everything/skills/repo-docs/templates/skills-agents-template.md +60 -0
- package/plugins/harness-everything/skills/rewrite-commits/SKILL.md +37 -0
- package/plugins/harness-everything/skills/rewrite-commits/references/workflow.md +18 -0
- package/plugins/harness-everything/skills/security-review/SKILL.md +47 -0
- package/plugins/harness-everything/skills/security-review/guides/OWASP-PATTERNS.md +31 -0
- package/plugins/harness-everything/skills/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
- package/plugins/harness-everything/skills/security-review/references/security-checklist.md +478 -0
- package/plugins/harness-everything/skills/security-review/scripts/audit-secrets.js +85 -0
- package/plugins/harness-everything/skills/self-evolve/SKILL.md +45 -0
- package/plugins/harness-everything/skills/self-evolve/references/memory-resolution.md +61 -0
- package/plugins/harness-everything/skills/self-evolve/scripts/persist-memory.js +272 -0
- package/plugins/harness-everything/skills/self-evolve/scripts/register-dynamic-skill.js +253 -0
- package/plugins/harness-everything/skills/self-evolve/scripts/self-regression.js +125 -0
- package/plugins/harness-everything/skills/skill-creator/SKILL.md +47 -0
- package/plugins/harness-everything/skills/skill-creator/references/authoring-workflow.md +14 -0
- package/plugins/harness-everything/skills/skill-creator/references/dynamic-generation-contract.md +21 -0
- package/plugins/harness-everything/skills/skill-creator/references/quality-checklist.md +16 -0
- package/plugins/harness-everything/skills/skill-creator/references/quality-principles.md +81 -0
- package/plugins/harness-everything/skills/skill-creator/references/testing-workflow.md +27 -0
- package/plugins/harness-everything/skills/skill-style/SKILL.md +42 -0
- package/plugins/harness-everything/skills/skill-style/references/style-guide.md +62 -0
- package/plugins/harness-everything/skills/tdd/SKILL.md +38 -0
- package/plugins/harness-everything/skills/tdd/fixtures/pass-evidence.json +100 -0
- package/plugins/harness-everything/skills/tdd/fixtures/quality-scenarios.json +20 -0
- package/plugins/harness-everything/skills/tdd/guides/deep-modules.md +33 -0
- package/plugins/harness-everything/skills/tdd/guides/interface-design.md +31 -0
- package/plugins/harness-everything/skills/tdd/guides/mocking.md +59 -0
- package/plugins/harness-everything/skills/tdd/guides/refactoring.md +10 -0
- package/plugins/harness-everything/skills/tdd/guides/tests.md +61 -0
- package/plugins/harness-everything/skills/tdd/references/core-discipline.md +51 -0
- package/plugins/harness-everything/skills/tdd/references/integration-testing.md +13 -0
- package/plugins/harness-everything/skills/tdd/references/quality-model.md +68 -0
- package/plugins/harness-everything/skills/tdd/references/unit-testing.md +15 -0
- package/plugins/harness-everything/skills/tdd/schemas/quality-evidence.schema.json +211 -0
- package/plugins/harness-everything/skills/tdd/schemas/quality-report.schema.json +110 -0
- package/plugins/harness-everything/skills/tdd/scripts/quality-gate.js +475 -0
- package/plugins/harness-everything/skills/to-spec/SKILL.md +40 -0
- package/plugins/harness-everything/skills/to-spec/references/process.md +77 -0
- package/plugins/harness-everything/skills/to-spec/scripts/check-project-docs.js +239 -0
- package/plugins/harness-everything/skills/to-spec/scripts/project-docs-resolver.js +111 -0
- package/plugins/harness-everything/skills/to-spec/templates/cli-reference.md +31 -0
- package/plugins/harness-everything/skills/to-spec/templates/dev-doc.md +27 -0
- package/plugins/harness-everything/skills/to-spec/templates/feature-spec.md +59 -0
- package/plugins/harness-everything/skills/to-spec/templates/schema-doc.md +31 -0
- package/plugins/harness-everything/skills/to-tickets/SKILL.md +42 -0
- package/plugins/harness-everything/skills/to-tickets/references/publishing-and-templates.md +97 -0
- package/plugins/harness-everything/skills/todo-driven-workflow/SKILL.md +42 -0
- package/plugins/harness-everything/skills/todo-driven-workflow/references/execution-guide.md +27 -0
- package/plugins/harness-everything/skills/using-git-worktrees/SKILL.md +49 -0
- package/plugins/harness-everything/skills/using-git-worktrees/references/workflow-details.md +108 -0
- package/plugins/harness-everything/skills/verification-loop/SKILL.md +46 -0
- package/plugins/harness-everything/skills/verification-loop/references/verification-phases.md +116 -0
- package/plugins/harness-everything/skills/verification-loop/templates/verification-report.template.md +15 -0
- package/plugins/harness-everything/skills/verify-before-claim/SKILL.md +43 -0
- package/plugins/harness-everything/skills/verify-before-claim/references/verification-guide.md +73 -0
- package/plugins/harness-everything/skills/zoom-out/SKILL.md +42 -0
- package/plugins/harness-everything/skills/zoom-out/references/circuit-breaker.md +66 -0
- package/plugins/harness-everything/skills/zoom-out/templates/zoom-out-report.template.md +20 -0
- package/repo-docs/SKILL.md +3 -7
- package/rewrite-commits/SKILL.md +2 -2
- package/scripts/build-openai-submission.js +158 -0
- package/scripts/installer.js +86 -11
- package/scripts/lib/advisory-text.js +25 -18
- package/scripts/lib/execution-contract.js +70 -0
- package/scripts/lib/manifest.js +34 -38
- package/scripts/lib/path-boundary.js +90 -0
- package/scripts/lib/skills.js +124 -70
- package/scripts/lib/workspace.js +269 -7
- package/scripts/repository-contract.js +213 -0
- package/scripts/sync-current-docs.js +12 -0
- package/scripts/sync-openai-plugin.js +91 -0
- package/scripts/sync-release-version.js +212 -0
- package/security-review/SKILL.md +4 -7
- package/security-review/scripts/audit-secrets.js +9 -8
- package/self-evolve/SKILL.md +9 -11
- package/self-evolve/references/memory-resolution.md +4 -1
- package/self-evolve/scripts/persist-memory.js +221 -88
- package/self-evolve/scripts/register-dynamic-skill.js +12 -10
- package/self-evolve/scripts/self-regression.js +23 -8
- package/skill-creator/SKILL.md +12 -14
- package/skill-creator/references/quality-checklist.md +1 -0
- package/skill-style/SKILL.md +4 -4
- package/skill-style/references/style-guide.md +29 -3
- package/submission/openai/README.md +67 -0
- package/submission/openai/listing.json +31 -0
- package/submission/openai/test-cases.json +61 -0
- package/tdd/SKILL.md +20 -26
- package/tdd/fixtures/pass-evidence.json +100 -0
- package/tdd/fixtures/quality-scenarios.json +20 -0
- package/tdd/references/core-discipline.md +2 -0
- package/tdd/references/integration-testing.md +13 -0
- package/tdd/references/quality-model.md +68 -0
- package/tdd/references/unit-testing.md +15 -0
- package/tdd/schemas/quality-evidence.schema.json +211 -0
- package/tdd/schemas/quality-report.schema.json +110 -0
- package/tdd/scripts/quality-gate.js +475 -0
- package/to-spec/SKILL.md +3 -5
- package/to-spec/scripts/check-project-docs.js +42 -62
- package/to-spec/scripts/project-docs-resolver.js +111 -0
- package/to-tickets/SKILL.md +4 -4
- package/todo-driven-workflow/SKILL.md +6 -4
- package/using-git-worktrees/SKILL.md +3 -3
- package/verification-loop/SKILL.md +4 -4
- package/verify-before-claim/SKILL.md +2 -2
- package/zoom-out/SKILL.md +4 -4
- package/ab-test-deep-analysis-2026-08-27.md +0 -383
- package/ab-test-results-2026-08-27.md +0 -152
- package/ab-test-statistical-analysis-31cases.md +0 -193
- package/opencode-plugin/hooks/circuit-breaker.js +0 -121
- package/opencode-plugin/hooks/compliance.js +0 -128
- package/opencode-plugin/hooks/post-edit.js +0 -62
- package/opencode-plugin/hooks/pre-complete.js +0 -65
- package/opencode-plugin/test-hook-firing.js +0 -198
|
@@ -1,128 +1,307 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const {
|
|
5
|
+
buildRouterContract,
|
|
6
|
+
writeRouterContract,
|
|
7
|
+
} = require('./router-contract');
|
|
8
|
+
|
|
9
|
+
const DEFAULT_ROUTING_CONFIG = {
|
|
10
|
+
tiers: { tier3: [], tier2: [] },
|
|
11
|
+
guideGroups: [],
|
|
12
|
+
factAudit: { externalClaim: [], estimate: [] },
|
|
13
|
+
};
|
|
14
|
+
|
|
10
15
|
function loadRoutingConfig() {
|
|
11
|
-
const
|
|
16
|
+
const configPath = process.env.HARNESS_ROUTING_CONFIG_PATH || path.join(__dirname, 'routing-keywords.json');
|
|
12
17
|
try {
|
|
13
|
-
const raw =
|
|
18
|
+
const raw = fs.readFileSync(configPath, 'utf8');
|
|
14
19
|
const parsed = JSON.parse(raw);
|
|
15
20
|
return {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
config: {
|
|
22
|
+
tiers: parsed.tiers || DEFAULT_ROUTING_CONFIG.tiers,
|
|
23
|
+
guideGroups: Array.isArray(parsed.guideGroups) ? parsed.guideGroups : DEFAULT_ROUTING_CONFIG.guideGroups,
|
|
24
|
+
factAudit: parsed.factAudit || DEFAULT_ROUTING_CONFIG.factAudit,
|
|
25
|
+
},
|
|
26
|
+
routingStatus: 'ok',
|
|
27
|
+
reasonCodes: [],
|
|
19
28
|
};
|
|
20
29
|
} catch (err) {
|
|
21
|
-
console.log(`[Tier Routing Pre-check] routing-keywords.json missing/invalid -
|
|
22
|
-
return
|
|
30
|
+
console.log(`[Tier Routing Pre-check] routing-keywords.json missing/invalid - routing is degraded; no silent Tier 1 fallback. (${err.message})`);
|
|
31
|
+
return {
|
|
32
|
+
config: DEFAULT_ROUTING_CONFIG,
|
|
33
|
+
routingStatus: 'degraded',
|
|
34
|
+
reasonCodes: ['routing-config-invalid'],
|
|
35
|
+
};
|
|
23
36
|
}
|
|
24
37
|
}
|
|
25
38
|
|
|
26
|
-
function
|
|
27
|
-
|
|
39
|
+
function matchKeyword(prompt, keyword) {
|
|
40
|
+
const k = keyword.toLowerCase().trim();
|
|
41
|
+
if (!k) return false;
|
|
42
|
+
const isChineseOrMultiword = /[\u4e00-\u9fa5]/.test(k) || k.includes(' ') || k.includes('-');
|
|
43
|
+
if (isChineseOrMultiword) return prompt.includes(k);
|
|
44
|
+
const escaped = k.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
45
|
+
return new RegExp(`\\b${escaped}\\b`, 'i').test(prompt);
|
|
46
|
+
}
|
|
28
47
|
|
|
29
|
-
|
|
30
|
-
const
|
|
48
|
+
function detectFableModel(prompt) {
|
|
49
|
+
const match = prompt.match(/\bfable(?:[- ]mode)?\s+(?:on|with)\s+(haiku|sonnet|sonnect|opus)\b|\bfable-(haiku|sonnet|opus)\b/i);
|
|
50
|
+
if (!match) return null;
|
|
51
|
+
const requested = (match[1] || match[2]).toLowerCase();
|
|
52
|
+
return requested === 'sonnect' ? 'sonnet' : requested;
|
|
53
|
+
}
|
|
31
54
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
55
|
+
function detectExplicitStrategy(prompt, requestedFableModel) {
|
|
56
|
+
if (/\bdirect[- ]single\b/i.test(prompt)) return 'direct-single';
|
|
57
|
+
if (/\biterative[- ]single\b/i.test(prompt)) return 'iterative-single';
|
|
58
|
+
if (/\bfable[- ]multi[- ]agent[- ]workspace\b|\bmulti[- ]agent workspace\b/i.test(prompt)) return 'fable-multi-agent-workspace';
|
|
59
|
+
if (/\bfable[- ]parallel\b|\bparallel fable\b/i.test(prompt)) return 'fable-parallel';
|
|
60
|
+
if (/\bfable[- ]staged\b|\bstaged fable\b/i.test(prompt)) return 'fable-staged';
|
|
61
|
+
if (requestedFableModel || /\b(?:use|run|enter)\s+fable(?:[- ]mode)?\b/i.test(prompt)) return 'fable-staged';
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
39
64
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
65
|
+
function detectProhibitions(prompt) {
|
|
66
|
+
const rules = [
|
|
67
|
+
['fable', /\b(?:no|without|do not|don't)\s+(?:use\s+)?fable\b/i],
|
|
68
|
+
['subagents', /\b(?:no|without|do not|don't)\s+(?:use\s+)?subagents?\b|\bsingle[- ]agent only\b/i],
|
|
69
|
+
['parallel', /\b(?:no|without|do not|don't)\s+(?:use\s+)?parallel(?:ism| execution)?\b|\bdo not parallelize\b|\bserial only\b/i],
|
|
70
|
+
['workspace', /\b(?:no|without|do not|don't)\s+(?:use\s+)?(?:multi[- ]agent )?workspace\b/i],
|
|
71
|
+
['memory', /\b(?:no|without|do not|don't)\s+(?:use\s+)?memory\b/i],
|
|
72
|
+
['ensemble', /\b(?:no|without|do not|don't)\s+(?:use\s+)?ensemble\b/i],
|
|
73
|
+
];
|
|
74
|
+
return rules.filter(([, regex]) => regex.test(prompt)).map(([name]) => name);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function detectActionGateReasons(prompt) {
|
|
78
|
+
const reasons = [];
|
|
79
|
+
const irreversible = [
|
|
80
|
+
/\b(?:drop|truncate|wipe|purge|destroy)\b.*\b(?:database|db|table|production|prod|data)\b/i,
|
|
81
|
+
/\b(?:force[- ]push|push\s+--force(?:-with-lease)?|git\s+push\b[^\n]*--force(?:-with-lease)?)\b/i,
|
|
82
|
+
/\bgit\s+reset\s+--hard\b/i,
|
|
83
|
+
/\bdelete\b.*\b(?:production|prod|database|db|table|branch|release|data)\b/i,
|
|
84
|
+
];
|
|
85
|
+
const external = [
|
|
86
|
+
/\bdeploy(?:ment|ing|ed)?\b.*\b(?:prod|production|live)\b|\bdeploy\s+to\s+(?:prod|production|live)\b/i,
|
|
87
|
+
/\b(?:npm|pnpm|yarn|cargo|pip|twine)\s+publish\b|\bpublish\s+(?:the\s+)?(?:package|release|artifact)\b/i,
|
|
88
|
+
/\b(?:send|email|message)\b.*\b(?:customer|client|user|users|external|production)\b/i,
|
|
89
|
+
/\b(?:charge|pay|payment|refund|transfer)\b.*\b(?:customer|account|money|funds|invoice)?\b/i,
|
|
90
|
+
/\bcreate\b.*\b(?:release|deployment)\b/i,
|
|
91
|
+
];
|
|
92
|
+
if (irreversible.some(regex => regex.test(prompt))) reasons.push('irreversible-action');
|
|
93
|
+
if (external.some(regex => regex.test(prompt))) reasons.push('external-side-effect');
|
|
94
|
+
return reasons;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function addReason(reasonCodes, code) {
|
|
98
|
+
if (code && !reasonCodes.includes(code)) reasonCodes.push(code);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function deduplicateGuidesByPath(guides) {
|
|
102
|
+
const byPath = new Map();
|
|
103
|
+
for (const guide of guides) {
|
|
104
|
+
const match = String(guide).match(/^\s*-\s+([^\s]+)/);
|
|
105
|
+
const key = match ? match[1].replace(/\\/g, '/') : String(guide).trim();
|
|
106
|
+
if (!byPath.has(key)) byPath.set(key, guide);
|
|
49
107
|
}
|
|
108
|
+
return Array.from(byPath.values());
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function countDomainSignals(promptLower) {
|
|
112
|
+
const domains = [
|
|
113
|
+
/\bsecurity\b|安全|資安/i,
|
|
114
|
+
/\barchitecture\b|架構/i,
|
|
115
|
+
/\bdocumentation\b|\bdocs?\b|文件/i,
|
|
116
|
+
/\btests?\b|測試/i,
|
|
117
|
+
/\bfrontend\b|前端/i,
|
|
118
|
+
/\bbackend\b|後端/i,
|
|
119
|
+
/\bdatabase\b|資料庫/i,
|
|
120
|
+
/\binfrastructure\b|\bdevops\b|基礎設施/i,
|
|
121
|
+
];
|
|
122
|
+
return domains.reduce((count, regex) => count + (regex.test(promptLower) ? 1 : 0), 0);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function plannerInputsFromContext(context, promptLower) {
|
|
126
|
+
const harness = context && typeof context.harness === 'object' ? context.harness : {};
|
|
127
|
+
const rawHost = (context && context.hostCapabilities) || harness.hostCapabilities || {};
|
|
128
|
+
const rawConstraints = (context && context.constraints) || harness.constraints || {};
|
|
129
|
+
const hostCapabilities = { ...rawHost };
|
|
130
|
+
const constraints = { ...rawConstraints };
|
|
50
131
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
132
|
+
const envCapabilityMap = {
|
|
133
|
+
subagents: process.env.HARNESS_HOST_SUBAGENTS,
|
|
134
|
+
parallelCalls: process.env.HARNESS_HOST_PARALLEL_CALLS,
|
|
135
|
+
hooks: process.env.HARNESS_HOST_HOOKS,
|
|
136
|
+
state: process.env.HARNESS_HOST_STATE,
|
|
137
|
+
modelAvailability: process.env.HARNESS_HOST_MODEL_AVAILABILITY,
|
|
138
|
+
};
|
|
139
|
+
for (const [key, value] of Object.entries(envCapabilityMap)) {
|
|
140
|
+
if (value) hostCapabilities[key] = value;
|
|
56
141
|
}
|
|
57
142
|
|
|
58
|
-
|
|
59
|
-
|
|
143
|
+
if (process.env.HARNESS_BUDGET_CONCURRENCY !== undefined) constraints.concurrency = process.env.HARNESS_BUDGET_CONCURRENCY;
|
|
144
|
+
if (process.env.HARNESS_BUDGET_COST !== undefined) constraints.cost = process.env.HARNESS_BUDGET_COST;
|
|
145
|
+
if (process.env.HARNESS_BUDGET_LATENCY !== undefined) constraints.latency = process.env.HARNESS_BUDGET_LATENCY;
|
|
146
|
+
if (process.env.HARNESS_BUDGET_TOKENS !== undefined) constraints.tokens = process.env.HARNESS_BUDGET_TOKENS;
|
|
147
|
+
|
|
148
|
+
const concurrencyMatch = promptLower.match(/\b(?:max(?:imum)?\s+)?(?:concurrency|workers?|agents?)\s*(?:=|:|of)?\s*(\d+)\b/i);
|
|
149
|
+
if (concurrencyMatch) constraints.concurrency = Number(concurrencyMatch[1]);
|
|
150
|
+
if (/\b(?:single worker|one worker|serial only)\b/i.test(promptLower)) constraints.concurrency = 1;
|
|
151
|
+
|
|
152
|
+
return { hostCapabilities, constraints };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function emitDynamicSkills(promptLower, context, recommendedGuides) {
|
|
156
|
+
try {
|
|
157
|
+
const userHome = process.env.HOME || process.env.USERPROFILE || '';
|
|
158
|
+
const { getWorkspaceRoot } = require('../../scripts/lib/workspace');
|
|
159
|
+
const workspaceRoot = getWorkspaceRoot(context);
|
|
160
|
+
|
|
161
|
+
const manifestPaths = [
|
|
162
|
+
path.join(workspaceRoot, '.claude', 'harness-everything', 'manifest.json'),
|
|
163
|
+
path.join(workspaceRoot, '.cursor', 'harness-everything', 'manifest.json'),
|
|
164
|
+
path.join(workspaceRoot, '.github', 'harness-everything', 'manifest.json'),
|
|
165
|
+
path.join(workspaceRoot, '.codex', 'harness-everything', 'manifest.json'),
|
|
166
|
+
path.join(workspaceRoot, '.continue', 'harness-everything', 'manifest.json'),
|
|
167
|
+
path.join(userHome, '.agents', 'harness-everything', 'manifest.json'),
|
|
168
|
+
path.join(userHome, '.claude', 'harness-everything', 'manifest.json'),
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
const generatedSkills = new Map();
|
|
172
|
+
for (const manifestPath of manifestPaths) {
|
|
173
|
+
if (!fs.existsSync(manifestPath)) continue;
|
|
174
|
+
try {
|
|
175
|
+
const manifestData = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
176
|
+
if (Array.isArray(manifestData.generated)) {
|
|
177
|
+
for (const skill of manifestData.generated) generatedSkills.set(skill.id, skill);
|
|
178
|
+
}
|
|
179
|
+
} catch (err) {
|
|
180
|
+
// Ignore malformed generated-skill manifests; they are advisory only.
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const allDynamicSkills = Array.from(generatedSkills.values());
|
|
185
|
+
const matchedDynamicSkills = [];
|
|
186
|
+
|
|
187
|
+
for (const skill of allDynamicSkills) {
|
|
188
|
+
let score = 0;
|
|
189
|
+
for (const rawTrigger of skill.triggers || []) {
|
|
190
|
+
const trigger = rawTrigger.toLowerCase().trim();
|
|
191
|
+
if (!trigger || trigger.length < 2) continue;
|
|
192
|
+
if (['the', 'and', 'for', 'with', 'your', 'this', 'that', 'some', 'from', 'prevent', 'resolved'].includes(trigger)) continue;
|
|
193
|
+
|
|
194
|
+
if (/[\u4e00-\u9fa5]/.test(trigger)) {
|
|
195
|
+
if (promptLower.includes(trigger)) score += trigger.length * 2;
|
|
196
|
+
} else {
|
|
197
|
+
const escapedTrigger = trigger.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
198
|
+
const regex = new RegExp(`\\b${escapedTrigger}\\b`, 'i');
|
|
199
|
+
if (regex.test(promptLower)) score += trigger.length >= 4 ? 3 : 1.5;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (score >= 3) matchedDynamicSkills.push({ skill, score });
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (matchedDynamicSkills.length > 0) {
|
|
206
|
+
matchedDynamicSkills.sort((a, b) => b.score - a.score);
|
|
207
|
+
console.log(`\n=> 🎯 HIGH-RELEVANCE SELF-EVOLVED SKILL(S) DETECTED:`);
|
|
208
|
+
matchedDynamicSkills.forEach(({ skill }) => {
|
|
209
|
+
let displayPath = skill.dirPath;
|
|
210
|
+
if (displayPath.startsWith(workspaceRoot)) displayPath = path.relative(workspaceRoot, displayPath);
|
|
211
|
+
console.log(`- ${displayPath}/SKILL.md (${skill.description} [DYNAMIC SKILL])`);
|
|
212
|
+
});
|
|
213
|
+
} else if (recommendedGuides.length === 0 && allDynamicSkills.length > 0) {
|
|
214
|
+
console.log(`\n=> ℹ️ UNMATCHED PROMPT HINT:`);
|
|
215
|
+
console.log(`No standard or dynamic skills matched your prompt directly.`);
|
|
216
|
+
console.log(`However, you have ${allDynamicSkills.length} self-evolved dynamic skill(s) registered in your manifest.json.`);
|
|
217
|
+
console.log(`To ensure you don't miss past lessons, you should inspect the "generated" section of your manifest.json or check .claude/harness-everything/skills/generated/ to see if any apply to your current task.`);
|
|
218
|
+
console.log(`If genuinely nothing covers this - including nothing already fetched via find-skills - load find-skills/SKILL.md: it checks "npx skills list" for anything already installed, then searches skills.sh/npx skills if not, and always requires explicit approval before installing anything.`);
|
|
219
|
+
}
|
|
220
|
+
} catch (err) {
|
|
221
|
+
// Dynamic-skill discovery is advisory and must never break core routing.
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function run(userPrompt, context) {
|
|
226
|
+
console.log(`[Tier Routing Pre-check]`);
|
|
227
|
+
|
|
228
|
+
const promptLower = userPrompt.toLowerCase();
|
|
229
|
+
const loadedConfig = loadRoutingConfig();
|
|
230
|
+
const routingConfig = loadedConfig.config;
|
|
231
|
+
const TIER3_KEYWORDS = routingConfig.tiers.tier3 || [];
|
|
232
|
+
const TIER2_KEYWORDS = routingConfig.tiers.tier2 || [];
|
|
60
233
|
|
|
61
|
-
// Task-shape signals catch one-sentence audits and benchmarks that a flat
|
|
62
|
-
// keyword list cannot see. They are intentionally kept here, rather than
|
|
63
|
-
// mixed into the editable technology keyword table.
|
|
64
234
|
const macroSignals = [
|
|
65
235
|
/\b(?:every|each|all|entire|whole|full|complete)\s+(?:skill|skills|repo|repository|codebase|project|file|files|module|modules)/i,
|
|
66
236
|
/\b(?:evaluate|audit|benchmark|stress[- ]test|ab test|a\/b test|compare)\b/i,
|
|
67
237
|
/\b(?:repository[- ]wide|codebase[- ]wide|end[- ]to[- ]end)\b/i,
|
|
68
238
|
/\b(?:multiple|several|four|fourteen|dozens)\s+(?:issues|skills|files|modules)/i,
|
|
69
239
|
/(?:每個|每一個|所有|全部|整個|全套|逐一|多個|四個).*(?:skill|技能|檔案|問題|版本|基準|測試|評估|稽核|比較|壓力)/i,
|
|
70
|
-
/(?:評估|稽核|基準|壓力測試|比較).*(?:每個|所有|全部|整個|全套|技能|skill|檔案|版本)/i
|
|
240
|
+
/(?:評估|稽核|基準|壓力測試|比較).*(?:每個|所有|全部|整個|全套|技能|skill|檔案|版本)/i,
|
|
71
241
|
];
|
|
72
242
|
const hasMacroSignal = macroSignals.some(signal => signal.test(userPrompt));
|
|
73
|
-
const
|
|
243
|
+
const hasTrivialEditVerb = /^(?:(?:please|help me)\s+)?(?:fix|update|correct|change)\b/i.test(userPrompt.trim());
|
|
244
|
+
const hasDocsTarget = /\b(?:readme|documentation|docs?)\b/i.test(userPrompt);
|
|
245
|
+
const hasTinyEditSignal = /\b(?:typo|spelling|wording|one line|single line)\b/i.test(userPrompt);
|
|
246
|
+
const isTrivialDocsEdit = !hasMacroSignal && hasTrivialEditVerb && hasDocsTarget && hasTinyEditSignal;
|
|
247
|
+
const hasTier3Keyword = TIER3_KEYWORDS.some(keyword => matchKeyword(promptLower, keyword));
|
|
248
|
+
const hasTier2Keyword = TIER2_KEYWORDS.some(keyword => matchKeyword(promptLower, keyword));
|
|
249
|
+
|
|
250
|
+
let recommendedTier = 'Unclassified';
|
|
251
|
+
let rationale = 'No structural/testing signals matched; unclassified is not equivalent to trivial.';
|
|
252
|
+
const reasonCodes = [...loadedConfig.reasonCodes, 'no-classification-signal'];
|
|
74
253
|
|
|
75
254
|
if (isTrivialDocsEdit) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
} else if (hasMacroSignal ||
|
|
81
|
-
recommendedTier =
|
|
82
|
-
rationale =
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
255
|
+
recommendedTier = 'Tier 1 (Trivial)';
|
|
256
|
+
rationale = 'Single documentation typo detected - direct edit, no checklist required.';
|
|
257
|
+
reasonCodes.splice(loadedConfig.reasonCodes.length);
|
|
258
|
+
addReason(reasonCodes, 'trivial-docs-edit');
|
|
259
|
+
} else if (hasMacroSignal || hasTier3Keyword) {
|
|
260
|
+
recommendedTier = 'Tier 3 (Macro Task)';
|
|
261
|
+
rationale = 'Prompt implies repository-wide scope, audit/benchmark work, architectural refactoring, or multi-agent collaboration.';
|
|
262
|
+
reasonCodes.splice(loadedConfig.reasonCodes.length);
|
|
263
|
+
addReason(reasonCodes, hasMacroSignal ? 'macro-scope-signal' : 'tier3-keyword');
|
|
264
|
+
} else if (hasTier2Keyword) {
|
|
265
|
+
recommendedTier = 'Tier 2 (Standard Task)';
|
|
266
|
+
rationale = 'Prompt implies development work needing TDD validation or multi-file coordination.';
|
|
267
|
+
reasonCodes.splice(loadedConfig.reasonCodes.length);
|
|
268
|
+
addReason(reasonCodes, 'tier2-keyword');
|
|
86
269
|
}
|
|
87
270
|
|
|
88
|
-
|
|
89
|
-
// These help differentiate between simple and complex tasks within the same keyword tier
|
|
90
|
-
const sentenceCount = userPrompt.split(/[.!?。!?]+/).filter(s => s.trim()).length;
|
|
271
|
+
const sentenceCount = userPrompt.split(/[.!?。!?]+/).filter(sentence => sentence.trim()).length;
|
|
91
272
|
const hasMultipleTasks = /\b(and|also|then|additionally|plus|而且|還有|然後|另外|以及)\b/i.test(userPrompt);
|
|
92
273
|
const mentionsSpecificFile = /\b(file|script|module|class|function|component)\b.*\.\w+/i.test(userPrompt);
|
|
93
274
|
const hasQuestionMarks = /\?|?/.test(userPrompt);
|
|
94
275
|
const hasMultipleSentences = sentenceCount > 2;
|
|
95
276
|
|
|
96
|
-
// Adjust tier based on structural signals
|
|
97
277
|
if (!hasMacroSignal && !isTrivialDocsEdit && hasMultipleTasks && hasMultipleSentences) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
rationale +=
|
|
278
|
+
if (recommendedTier === 'Unclassified' || recommendedTier.startsWith('Tier 1')) {
|
|
279
|
+
recommendedTier = 'Tier 2 (Standard Task)';
|
|
280
|
+
rationale = 'Multiple tasks detected with structural complexity - upgraded to Tier 2 for TDD validation.';
|
|
281
|
+
reasonCodes.splice(loadedConfig.reasonCodes.length);
|
|
282
|
+
addReason(reasonCodes, 'multi-task-structure');
|
|
283
|
+
} else if (recommendedTier.startsWith('Tier 2')) {
|
|
284
|
+
rationale += ' Multiple task structure detected.';
|
|
285
|
+
addReason(reasonCodes, 'multi-task-structure');
|
|
105
286
|
}
|
|
106
287
|
} else if (!hasMacroSignal && mentionsSpecificFile && !hasMultipleTasks) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
288
|
+
if (recommendedTier.startsWith('Tier 3')) {
|
|
289
|
+
recommendedTier = 'Tier 2 (Standard Task)';
|
|
290
|
+
rationale = 'Single file focus detected - downgraded from Tier 3 to Tier 2.';
|
|
291
|
+
addReason(reasonCodes, 'single-file-focus');
|
|
111
292
|
}
|
|
112
293
|
} else if (!hasMacroSignal && hasQuestionMarks && !hasMultipleTasks) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
294
|
+
if (recommendedTier.startsWith('Tier 3')) {
|
|
295
|
+
recommendedTier = 'Tier 2 (Standard Task)';
|
|
296
|
+
rationale = 'Question format detected - likely advisory rather than macro execution.';
|
|
297
|
+
addReason(reasonCodes, 'question-format');
|
|
117
298
|
}
|
|
118
299
|
}
|
|
119
300
|
|
|
120
301
|
console.log(`\n=> RECOMMENDED TIER: ${recommendedTier}`);
|
|
121
302
|
console.log(`=> RATIONALE: ${rationale}`);
|
|
122
303
|
|
|
123
|
-
|
|
124
|
-
// checklist (Tier 1 is exempt to avoid checklist bloat on trivial edits).
|
|
125
|
-
if (!recommendedTier.startsWith("Tier 1")) {
|
|
304
|
+
if (recommendedTier.startsWith('Tier 2') || recommendedTier.startsWith('Tier 3')) {
|
|
126
305
|
console.log(`\n=> BASE EXECUTION LOOP: Load 'todo-driven-workflow' and initialize its checklist (3-7 verifiable sub-tasks) BEFORE editing any file.`);
|
|
127
306
|
console.log(` Track exactly ONE item in-progress at a time; verify with real evidence before marking completed.`);
|
|
128
307
|
}
|
|
@@ -134,30 +313,25 @@ function run(userPrompt) {
|
|
|
134
313
|
console.log(` Resolve availability and record fallback status with fable-mode/scripts/model-selector.js.`);
|
|
135
314
|
}
|
|
136
315
|
|
|
137
|
-
|
|
138
|
-
// Each group comes from routing-keywords.json - matches via plain-substring
|
|
139
|
-
// 'keywords' OR a 'regex' source string (tested case-insensitively).
|
|
140
|
-
const recommendedGuides = [];
|
|
141
|
-
|
|
316
|
+
const allRecommendedGuides = [];
|
|
142
317
|
for (const group of routingConfig.guideGroups) {
|
|
143
318
|
let matched = false;
|
|
144
|
-
if (typeof group.regex ===
|
|
145
|
-
matched = new RegExp(group.regex,
|
|
319
|
+
if (typeof group.regex === 'string') {
|
|
320
|
+
matched = new RegExp(group.regex, 'i').test(promptLower);
|
|
146
321
|
} else if (Array.isArray(group.keywords)) {
|
|
147
|
-
matched = group.keywords.some(
|
|
148
|
-
}
|
|
149
|
-
if (matched && Array.isArray(group.guides)) {
|
|
150
|
-
recommendedGuides.push(...group.guides);
|
|
322
|
+
matched = group.keywords.some(keyword => promptLower.includes(keyword));
|
|
151
323
|
}
|
|
324
|
+
if (matched && Array.isArray(group.guides)) allRecommendedGuides.push(...group.guides);
|
|
152
325
|
}
|
|
326
|
+
const recommendedGuides = deduplicateGuidesByPath(allRecommendedGuides);
|
|
153
327
|
|
|
154
328
|
if (recommendedGuides.length > 0) {
|
|
155
329
|
console.log(`\n=> RECOMMENDED KNOWLEDGE GUIDES (Auto-loaded based on keywords):`);
|
|
156
330
|
recommendedGuides.forEach(guide => {
|
|
157
331
|
const match = guide.match(/^- ([^\s]+)/);
|
|
158
332
|
if (match) {
|
|
159
|
-
const guidePath =
|
|
160
|
-
if (!
|
|
333
|
+
const guidePath = path.join(__dirname, '..', '..', match[1]);
|
|
334
|
+
if (!fs.existsSync(guidePath)) {
|
|
161
335
|
console.log(`${guide} [NOT INSTALLED - Ignore this recommendation]`);
|
|
162
336
|
return;
|
|
163
337
|
}
|
|
@@ -166,130 +340,12 @@ function run(userPrompt) {
|
|
|
166
340
|
});
|
|
167
341
|
}
|
|
168
342
|
|
|
169
|
-
|
|
170
|
-
// SELF-EVOLVED DYNAMIC SKILLS AUTO-DISCOVERY & PRECISE MATCHING
|
|
171
|
-
//
|
|
172
|
-
// Deliberately generated[] only, not find-skills' downloaded skills:
|
|
173
|
-
// generated[] is safe to cache-and-match here because Harness owns its
|
|
174
|
-
// whole lifecycle (self-evolve authors it, skill-creator quality-gates it,
|
|
175
|
-
// status is tracked draft/active/deprecated). A skill fetched via
|
|
176
|
-
// `npx skills add` has none of that - caching its triggers/description at
|
|
177
|
-
// download time would silently go stale the moment the upstream skill (or
|
|
178
|
-
// a later `npx skills update`/`remove`) changes it. find-skills queries
|
|
179
|
-
// `npx skills list` live instead of being folded into this cache.
|
|
180
|
-
// ---------------------------------------------------------
|
|
181
|
-
try {
|
|
182
|
-
const fs = require('fs');
|
|
183
|
-
const path = require('path');
|
|
184
|
-
const userHome = process.env.HOME || process.env.USERPROFILE || '';
|
|
185
|
-
|
|
186
|
-
// Skill installs land at varying depth per platform/scope (e.g.
|
|
187
|
-
// <root>/.claude/skills/harness-everything/scripts/, <root>/.cursor/skills/...,
|
|
188
|
-
// ~/.claude/skills/...), so a fixed __dirname offset can't reach the real
|
|
189
|
-
// workspace root. Walk up from the invoking cwd to the nearest .git instead
|
|
190
|
-
// - the same approach register-dynamic-skill.js already uses.
|
|
191
|
-
function getWorkspaceRoot() {
|
|
192
|
-
let dir = path.resolve(process.cwd());
|
|
193
|
-
while (dir !== path.parse(dir).root) {
|
|
194
|
-
if (fs.existsSync(path.join(dir, '.git'))) return dir;
|
|
195
|
-
dir = path.dirname(dir);
|
|
196
|
-
}
|
|
197
|
-
return process.cwd();
|
|
198
|
-
}
|
|
199
|
-
const workspaceRoot = getWorkspaceRoot();
|
|
200
|
-
|
|
201
|
-
const manifestPaths = [
|
|
202
|
-
path.join(workspaceRoot, '.claude', 'harness-everything', 'manifest.json'),
|
|
203
|
-
path.join(workspaceRoot, '.cursor', 'harness-everything', 'manifest.json'),
|
|
204
|
-
path.join(workspaceRoot, '.github', 'harness-everything', 'manifest.json'),
|
|
205
|
-
path.join(workspaceRoot, '.codex', 'harness-everything', 'manifest.json'),
|
|
206
|
-
path.join(workspaceRoot, '.continue', 'harness-everything', 'manifest.json'),
|
|
207
|
-
path.join(userHome, '.agents', 'harness-everything', 'manifest.json'),
|
|
208
|
-
path.join(userHome, '.claude', 'harness-everything', 'manifest.json')
|
|
209
|
-
];
|
|
210
|
-
|
|
211
|
-
const generatedSkills = new Map();
|
|
212
|
-
for (const mPath of manifestPaths) {
|
|
213
|
-
if (fs.existsSync(mPath)) {
|
|
214
|
-
try {
|
|
215
|
-
const manifestData = JSON.parse(fs.readFileSync(mPath, 'utf8'));
|
|
216
|
-
if (Array.isArray(manifestData.generated)) {
|
|
217
|
-
for (const s of manifestData.generated) {
|
|
218
|
-
generatedSkills.set(s.id, s);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
} catch (err) {
|
|
222
|
-
// ignore malformed manifests
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
const allDynamicSkills = Array.from(generatedSkills.values());
|
|
228
|
-
const matchedDynamicSkills = [];
|
|
343
|
+
emitDynamicSkills(promptLower, context, recommendedGuides);
|
|
229
344
|
|
|
230
|
-
for (const skill of allDynamicSkills) {
|
|
231
|
-
let score = 0;
|
|
232
|
-
const triggers = skill.triggers || [];
|
|
233
|
-
|
|
234
|
-
for (const rawTrigger of triggers) {
|
|
235
|
-
const trigger = rawTrigger.toLowerCase().trim();
|
|
236
|
-
if (!trigger || trigger.length < 2) continue;
|
|
237
|
-
|
|
238
|
-
// Ignore generic words to prevent false positives
|
|
239
|
-
if (['the', 'and', 'for', 'with', 'your', 'this', 'that', 'some', 'from', 'prevent', 'resolved'].includes(trigger)) continue;
|
|
240
|
-
|
|
241
|
-
const isChinese = /[\u4e00-\u9fa5]/.test(trigger);
|
|
242
|
-
if (isChinese) {
|
|
243
|
-
if (promptLower.includes(trigger)) {
|
|
244
|
-
score += trigger.length * 2;
|
|
245
|
-
}
|
|
246
|
-
} else {
|
|
247
|
-
// English word-boundary matching to prevent substrings inside larger words
|
|
248
|
-
const escapedTrigger = trigger.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
249
|
-
const regex = new RegExp(`\\b${escapedTrigger}\\b`, 'i');
|
|
250
|
-
if (regex.test(promptLower)) {
|
|
251
|
-
score += trigger.length >= 4 ? 3 : 1.5;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (score >= 3) {
|
|
257
|
-
matchedDynamicSkills.push({ skill, score });
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
if (matchedDynamicSkills.length > 0) {
|
|
262
|
-
matchedDynamicSkills.sort((a, b) => b.score - a.score);
|
|
263
|
-
console.log(`\n=> 🎯 HIGH-RELEVANCE SELF-EVOLVED SKILL(S) DETECTED:`);
|
|
264
|
-
matchedDynamicSkills.forEach(({ skill }) => {
|
|
265
|
-
// Compute path relative to workspace or keep absolute
|
|
266
|
-
let displayPath = skill.dirPath;
|
|
267
|
-
if (displayPath.startsWith(workspaceRoot)) {
|
|
268
|
-
displayPath = path.relative(workspaceRoot, displayPath);
|
|
269
|
-
}
|
|
270
|
-
console.log(`- ${displayPath}/SKILL.md (${skill.description} [DYNAMIC SKILL])`);
|
|
271
|
-
});
|
|
272
|
-
} else if (recommendedGuides.length === 0 && allDynamicSkills.length > 0) {
|
|
273
|
-
// Prompt has no match in standard skills, and no direct match in dynamic skills,
|
|
274
|
-
// but there are indeed dynamic skills in manifest.json. Suggest the LLM to inspect them!
|
|
275
|
-
console.log(`\n=> ℹ️ UNMATCHED PROMPT HINT:`);
|
|
276
|
-
console.log(`No standard or dynamic skills matched your prompt directly.`);
|
|
277
|
-
console.log(`However, you have ${allDynamicSkills.length} self-evolved dynamic skill(s) registered in your manifest.json.`);
|
|
278
|
-
console.log(`To ensure you don't miss past lessons, you should inspect the "generated" section of your manifest.json or check .claude/harness-everything/skills/generated/ to see if any apply to your current task.`);
|
|
279
|
-
console.log(`If genuinely nothing covers this - including nothing already fetched via find-skills - load find-skills/SKILL.md: it checks "npx skills list" for anything already installed, then searches skills.sh/npx skills if not, and always requires explicit approval before installing anything.`);
|
|
280
|
-
}
|
|
281
|
-
} catch (err) {
|
|
282
|
-
// Fail silently in router to prevent breaking the core execution loop
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Fact-audit nudge: broad, cheap keyword net for claims that risk being
|
|
286
|
-
// asserted from stale/wrong training memory instead of verified. False
|
|
287
|
-
// positives cost nothing here (it's a reminder, not a block) so recall
|
|
288
|
-
// matters more than precision.
|
|
289
345
|
const externalClaimTriggers = routingConfig.factAudit.externalClaim || [];
|
|
290
346
|
const estimateTriggers = routingConfig.factAudit.estimate || [];
|
|
291
|
-
const hitExternalClaim = externalClaimTriggers.some(
|
|
292
|
-
const hitEstimate = estimateTriggers.some(
|
|
347
|
+
const hitExternalClaim = externalClaimTriggers.some(keyword => promptLower.includes(keyword));
|
|
348
|
+
const hitEstimate = estimateTriggers.some(keyword => promptLower.includes(keyword));
|
|
293
349
|
|
|
294
350
|
if (hitExternalClaim || hitEstimate) {
|
|
295
351
|
console.log(`\n=> FACT-AUDIT REMINDER:`);
|
|
@@ -303,32 +359,101 @@ function run(userPrompt) {
|
|
|
303
359
|
}
|
|
304
360
|
}
|
|
305
361
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
362
|
+
const independentWorkstreams = /\bindependent(?:ly)?\b|\bparallel(?:ize|ise|ized|ised|ism)?\b/i.test(userPrompt);
|
|
363
|
+
const readOnly = /\bread[- ]only\b|\bno edits?\b|\bwithout (?:editing|edits|changes|modifications)\b/i.test(userPrompt);
|
|
364
|
+
const disjointWrites = /\bdisjoint\b|\bnon[- ]overlapping\b|\bseparate files?\b|\bdistinct files?\b/i.test(userPrompt);
|
|
365
|
+
const sharedWrite = /\bsame files?\b|\bshared mutable state\b|\boverlapping writes?\b|\bshared write[- ]set\b/i.test(userPrompt);
|
|
366
|
+
const dependentStages = /\bdependent\b|\bsequential\b|\bstaged?\b|\bafter\b.*\bthen\b/i.test(userPrompt);
|
|
367
|
+
const multiSession = /\bmulti[- ]session\b|\bmultiple sessions\b|\bacross sessions\b|\bdurable\b|\blong[- ]running\b|\bpersistent handoff\b/i.test(userPrompt);
|
|
368
|
+
const reusableSpecialists = /\breusable specialists?\b|\bpersistent roles?\b|\bspecialist catalog\b|\breusable roles?\b/i.test(userPrompt);
|
|
369
|
+
const crossDomain = countDomainSignals(promptLower) >= 2;
|
|
370
|
+
const highUncertainty = /\bhigh uncertainty\b|\bcompeting approaches\b|\bdesign comparison\b|\bcompare alternatives\b|\btrade[- ]offs?\b/i.test(userPrompt);
|
|
371
|
+
const actionGateReasonCodes = detectActionGateReasons(userPrompt);
|
|
372
|
+
const irreversibleAction = actionGateReasonCodes.includes('irreversible-action');
|
|
373
|
+
const externalSideEffect = actionGateReasonCodes.includes('external-side-effect');
|
|
374
|
+
const requestedStrategy = detectExplicitStrategy(userPrompt, requestedFableModel);
|
|
375
|
+
const prohibitions = detectProhibitions(userPrompt);
|
|
376
|
+
const plannerInputs = plannerInputsFromContext(context, promptLower);
|
|
377
|
+
|
|
378
|
+
const contract = buildRouterContract({
|
|
379
|
+
routingStatus: loadedConfig.routingStatus,
|
|
380
|
+
recommendedTier,
|
|
381
|
+
rationale,
|
|
382
|
+
reasonCodes,
|
|
383
|
+
requestedFableModel,
|
|
384
|
+
explicitRequest: {
|
|
385
|
+
fableModel: requestedFableModel,
|
|
386
|
+
strategy: requestedStrategy,
|
|
387
|
+
prohibitions,
|
|
388
|
+
},
|
|
389
|
+
hostCapabilities: plannerInputs.hostCapabilities,
|
|
390
|
+
constraints: plannerInputs.constraints,
|
|
391
|
+
actionGateReasonCodes,
|
|
392
|
+
signals: {
|
|
393
|
+
macroScope: hasMacroSignal,
|
|
394
|
+
trivialDocsEdit: isTrivialDocsEdit,
|
|
395
|
+
tier3Keyword: hasTier3Keyword,
|
|
396
|
+
tier2Keyword: hasTier2Keyword,
|
|
397
|
+
multipleTasks: hasMultipleTasks,
|
|
398
|
+
multipleSentences: hasMultipleSentences,
|
|
399
|
+
specificFile: mentionsSpecificFile,
|
|
400
|
+
question: hasQuestionMarks,
|
|
401
|
+
independentWorkstreams,
|
|
402
|
+
readOnly,
|
|
403
|
+
disjointWrites,
|
|
404
|
+
sharedWrite,
|
|
405
|
+
dependentStages,
|
|
406
|
+
multiSession,
|
|
407
|
+
reusableSpecialists,
|
|
408
|
+
crossDomain,
|
|
409
|
+
highUncertainty,
|
|
410
|
+
irreversibleAction,
|
|
411
|
+
externalSideEffect,
|
|
412
|
+
highRisk: irreversibleAction || externalSideEffect,
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
console.log(`\n=> WORKFLOW STRATEGY: ${contract.workflowPlan.strategy || 'deferred'}`);
|
|
417
|
+
if (contract.workflowPlan.actionGate.required) {
|
|
418
|
+
console.log(`=> ACTION GATE: required (${contract.workflowPlan.actionGate.reasonCodes.join(', ')}); disposition=pending-approval`);
|
|
419
|
+
}
|
|
420
|
+
if (contract.workflowPlan.fallback.disposition !== 'none') {
|
|
421
|
+
console.log(`=> ROUTING FALLBACK: ${contract.workflowPlan.fallback.disposition}/${contract.workflowPlan.fallback.mode} (${contract.workflowPlan.fallback.reasonCodes.join(', ')})`);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (process.env.HARNESS_ROUTER_CONTRACT_PATH) {
|
|
425
|
+
try {
|
|
426
|
+
writeRouterContract(process.env.HARNESS_ROUTER_CONTRACT_PATH, contract);
|
|
427
|
+
} catch (err) {
|
|
428
|
+
console.error(`[Tier Routing Pre-check] failed to write structured router contract: ${err.message}`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
console.log(`\nTreat the tier and strategy above as the default route. Explicit Human Partner choices/prohibitions win and are recorded in the plan; unavailable capabilities must remain visible rather than being silently downgraded.`);
|
|
433
|
+
return contract;
|
|
309
434
|
}
|
|
310
435
|
|
|
311
436
|
let userPrompt = process.argv[2] || '';
|
|
437
|
+
let hookContext = null;
|
|
312
438
|
|
|
313
439
|
if (process.argv[2]) {
|
|
314
|
-
// If a command-line argument is passed, use it and execute immediately.
|
|
315
440
|
run(userPrompt);
|
|
316
441
|
} else if (process.stdin.isTTY) {
|
|
317
|
-
// Running interactively in a terminal without piped input, execute immediately.
|
|
318
442
|
run('');
|
|
319
443
|
} else {
|
|
320
|
-
// Piped input or non-TTY, read from standard input.
|
|
321
444
|
let inputData = '';
|
|
445
|
+
process.stdin.setEncoding('utf8');
|
|
322
446
|
process.stdin.on('data', chunk => { inputData += chunk; });
|
|
323
447
|
process.stdin.on('end', () => {
|
|
324
448
|
try {
|
|
325
449
|
if (inputData.trim()) {
|
|
326
450
|
const payload = JSON.parse(inputData);
|
|
327
451
|
if (typeof payload.prompt === 'string') userPrompt = payload.prompt;
|
|
452
|
+
hookContext = payload;
|
|
328
453
|
}
|
|
329
454
|
} catch (err) {
|
|
330
|
-
// Not valid JSON on stdin - fall back to argv
|
|
455
|
+
// Not valid JSON on stdin - fall back to argv/manual behavior.
|
|
331
456
|
}
|
|
332
|
-
run(userPrompt);
|
|
457
|
+
run(userPrompt, hookContext);
|
|
333
458
|
});
|
|
334
459
|
}
|