harness-everything 0.2.1 → 0.3.6
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/.claude-plugin/marketplace.json +27 -0
- package/.claude-plugin/plugin.json +51 -0
- package/.gitattributes +1 -0
- package/.github/workflows/behavioral-evals.yml +36 -0
- package/.github/workflows/ci.yml +117 -0
- package/.github/workflows/release.yml +45 -0
- package/.husky/commit-msg +1 -0
- package/.waza.yaml +22 -0
- package/AGENTS.md +60 -2
- package/BENCHMARK_SOP.md +62 -62
- package/CHANGELOG.md +297 -114
- package/CODE_OF_CONDUCT.md +24 -0
- package/CONTRIBUTING.md +47 -0
- package/Dockerfile +18 -18
- package/LICENSE +201 -201
- package/README.md +279 -197
- package/SECURITY.md +33 -0
- package/VERIFICATION.md +394 -347
- package/ab-test-deep-analysis-2026-08-27.md +383 -0
- package/ab-test-results-2026-08-27.md +152 -0
- package/ab-test-statistical-analysis-31cases.md +193 -0
- package/behavioral-evals/README.md +85 -0
- package/behavioral-evals/analyze-plugin-results.js +110 -0
- package/behavioral-evals/cases/baseline-add-feature.yaml +34 -0
- package/behavioral-evals/cases/baseline-api-design.yaml +32 -0
- package/behavioral-evals/cases/baseline-debugging.yaml +31 -0
- package/behavioral-evals/cases/baseline-dependency.yaml +24 -0
- package/behavioral-evals/cases/baseline-documentation.yaml +34 -0
- package/behavioral-evals/cases/baseline-error-handling.yaml +31 -0
- package/behavioral-evals/cases/baseline-git-commit.yaml +33 -0
- package/behavioral-evals/cases/baseline-performance-monitoring.yaml +28 -0
- package/behavioral-evals/cases/baseline-performance.yaml +34 -0
- package/behavioral-evals/cases/baseline-refactor-with-tests.yaml +35 -0
- package/behavioral-evals/cases/baseline-refactor.yaml +27 -0
- package/behavioral-evals/cases/baseline-security-review.yaml +28 -0
- package/behavioral-evals/cases/baseline-simple-bugfix.yaml +33 -0
- package/behavioral-evals/cases/baseline-tdd-workflow.yaml +28 -0
- package/behavioral-evals/cases/breaker-zoom-out-after-3.yaml +50 -0
- package/behavioral-evals/cases/pressure-budget-skip-review.yaml +27 -0
- package/behavioral-evals/cases/pressure-bypass-review.yaml +27 -0
- package/behavioral-evals/cases/pressure-complexity-skip.yaml +37 -0
- package/behavioral-evals/cases/pressure-expert-skip-testing.yaml +31 -0
- package/behavioral-evals/cases/pressure-fatigue-skip.yaml +33 -0
- package/behavioral-evals/cases/pressure-management-skip-all.yaml +28 -0
- package/behavioral-evals/cases/pressure-scope-bypass.yaml +28 -0
- package/behavioral-evals/cases/pressure-skip-docs.yaml +50 -0
- package/behavioral-evals/cases/pressure-skip-error-handling.yaml +35 -0
- package/behavioral-evals/cases/pressure-skip-security.yaml +32 -0
- package/behavioral-evals/cases/pressure-skip-tests.yaml +27 -0
- package/behavioral-evals/cases/pressure-skip-verification.yaml +43 -0
- package/behavioral-evals/cases/pressure-social-skip-review.yaml +28 -0
- package/behavioral-evals/cases/pressure-sunk-cost-retry.yaml +47 -0
- package/behavioral-evals/cases/scope-discipline.yaml +32 -0
- package/behavioral-evals/cases/tier1-no-overplan.yaml +26 -0
- package/behavioral-evals/cases/verify-before-done.yaml +31 -0
- package/behavioral-evals/results/.gitkeep +0 -0
- package/behavioral-evals/results/2026-08-23-breaker-zoom-out-after-3.json +20 -0
- package/behavioral-evals/results/2026-08-23-pressure-skip-verification.json +20 -0
- package/behavioral-evals/results/2026-08-23-pressure-sunk-cost-retry.json +20 -0
- package/behavioral-evals/results/2026-08-23-scope-discipline.json +16 -0
- package/behavioral-evals/results/2026-08-23-tier1-no-overplan.json +20 -0
- package/behavioral-evals/results/2026-08-23-verify-before-done.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-add-feature.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-api-design.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-debugging.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-dependency.json +16 -0
- package/behavioral-evals/results/2026-08-27-baseline-documentation.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-error-handling.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-git-commit.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-performance-monitoring.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-performance.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-refactor-with-tests.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-refactor.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-security-review.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-simple-bugfix.json +20 -0
- package/behavioral-evals/results/2026-08-27-baseline-tdd-workflow.json +24 -0
- package/behavioral-evals/results/2026-08-27-breaker-zoom-out-after-3.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-budget-skip-review.json +16 -0
- package/behavioral-evals/results/2026-08-27-pressure-bypass-review.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-complexity-skip.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-expert-skip-testing.json +16 -0
- package/behavioral-evals/results/2026-08-27-pressure-fatigue-skip.json +16 -0
- package/behavioral-evals/results/2026-08-27-pressure-management-skip-all.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-skip-docs.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-skip-error-handling.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-skip-security.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-skip-tests.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-skip-verification.json +24 -0
- package/behavioral-evals/results/2026-08-27-pressure-social-skip-review.json +20 -0
- package/behavioral-evals/results/2026-08-27-pressure-sunk-cost-retry.json +24 -0
- package/behavioral-evals/results/2026-08-27-scope-discipline.json +16 -0
- package/behavioral-evals/results/2026-08-27-tier1-no-overplan.json +20 -0
- package/behavioral-evals/results/2026-08-27-verify-before-done.json +20 -0
- package/behavioral-evals/results/run-20260827-115509.log +287 -0
- package/behavioral-evals/run-with-plugin.js +316 -0
- package/behavioral-evals/run.js +587 -0
- package/benchmarks/README.md +63 -0
- package/benchmarks/ab-test-2026-08-26/results.json +55 -0
- package/benchmarks/results/logs/.gitkeep +0 -0
- package/benchmarks/results/logs/test-a-harness.md +31 -0
- package/benchmarks/results/logs/test-a-vanilla.md +28 -0
- package/benchmarks/results/logs/test-b-micro-loop-harness.md +48 -0
- package/benchmarks/results/logs/test-b-micro-loop-vanilla.md +36 -0
- package/benchmarks/results/logs/test-c-attention-loss-harness.md +40 -0
- package/benchmarks/results/logs/test-c-attention-loss-vanilla.md +63 -0
- package/benchmarks/results/logs/test-d-knowledge-boundary-harness.md +24 -0
- package/benchmarks/results/logs/test-d-knowledge-boundary-vanilla.md +29 -0
- package/benchmarks/results/logs/test-e-shell-awareness-harness.md +20 -0
- package/benchmarks/results/logs/test-e-shell-awareness-vanilla.md +20 -0
- package/benchmarks/results/logs/test-f-fact-audit-harness.md +16 -0
- package/benchmarks/results/logs/test-f-fact-audit-vanilla.md +16 -0
- package/benchmarks/results/results.json +158 -0
- package/benchmarks/run.js +220 -0
- package/benchmarks/schema.json +44 -0
- package/bin/cli.js +152 -97
- package/ci/ab-test-cases/grill-me-adversarial.yaml +18 -0
- package/ci/ab-test-cases/tdd-test-first.yaml +23 -0
- package/ci/ab-test-cases/verification-loop-gates.yaml +25 -0
- package/ci/ab-test-cases/verify-before-claim-cites.yaml +18 -0
- package/ci/ab-test-harness.js +410 -0
- package/{eval-framework → ci}/cases/case1.json +5 -5
- package/ci/cases/case10-small-feature.json +5 -0
- package/ci/cases/case11-readme-typo-update.json +5 -0
- package/ci/cases/case12-chinese-macro-audit.json +5 -0
- package/{eval-framework → ci}/cases/case2.json +5 -5
- package/{eval-framework → ci}/cases/case3.json +5 -5
- package/{eval-framework → ci}/cases/case4-zh-tier2.json +5 -5
- package/{eval-framework → ci}/cases/case5-zh-tier3.json +5 -5
- package/ci/cases/case6-macro-skill-audit.json +5 -0
- package/ci/cases/case7-macro-reference-audit.json +5 -0
- package/ci/cases/case8-controlled-ab-benchmark.json +5 -0
- package/ci/cases/case9-four-issue-audit.json +5 -0
- package/ci/consistency-check.js +347 -0
- package/ci/description-collision.js +109 -0
- package/ci/fable-mode-test.js +120 -0
- package/ci/fixtures/agency-agents/divisions.json +6 -0
- package/ci/fixtures/agency-agents/engineering/code-reviewer.md +11 -0
- package/ci/fixtures/agency-agents/testing/reality-checker.md +11 -0
- package/ci/fixtures/bad-frontmatter-colon/SKILL.md +16 -0
- package/ci/fixtures/duplicate-description/skill-a/SKILL.md +16 -0
- package/ci/fixtures/duplicate-description/skill-b/SKILL.md +16 -0
- package/ci/mechanism-2a-rule-of-3.test.js +46 -0
- package/ci/mechanism-2b-boundary-guard.test.js +16 -0
- package/ci/mechanism-2c-state-persist.test.js +29 -0
- package/ci/mechanism-2d-fact-audit.test.js +18 -0
- package/ci/mechanism-2e-scope-guard.test.js +24 -0
- package/ci/mechanism-2f-stop-gate.test.js +23 -0
- package/ci/mechanism-2g-platform-ignore.test.js +88 -0
- package/ci/mechanism-2h-installer-manifest.test.js +147 -0
- package/ci/mechanism-2i-crlf-frontmatter.test.js +145 -0
- package/ci/mechanism-2i-install-verification.test.js +34 -0
- package/ci/mechanism-2j-behavioral-runner.test.js +20 -0
- package/ci/mechanism-2k-reference-check.test.js +20 -0
- package/ci/mechanism-2l-multi-agent-workspace.test.js +105 -0
- package/ci/mechanism-test.js +71 -0
- package/ci/negative-controls.js +84 -0
- package/ci/reference-check.js +112 -0
- package/ci/release-consistency-check.js +123 -0
- package/ci/routing-check.js +90 -0
- package/{eval-framework → ci}/runner.js +56 -56
- package/ci/skill-routing-check.js +98 -0
- package/ci/test-helper.js +104 -0
- package/ci/test-negative-controls.js +148 -0
- package/commitlint.config.js +25 -0
- package/docker-verify.sh +266 -266
- package/docs/architecture.md +99 -95
- package/docs/audit.md +53 -0
- package/docs/mechanism-first-skill-mesh.md +163 -0
- package/docs/philosophy.md +47 -45
- package/docs/reflection.md +48 -34
- package/docs/routing.md +58 -45
- package/docs/troubleshooting.md +284 -0
- package/docs/workflows/environment-detection.md +63 -63
- package/docs/workflows/eval-harness.md +64 -57
- package/docs/workflows/fable-discipline.md +59 -59
- package/docs/workflows/fable-mode.md +12 -15
- package/docs/workflows/find-skills.md +36 -0
- package/docs/workflows/git-commit.md +71 -62
- package/docs/workflows/grill-me.md +62 -62
- package/docs/workflows/grill-with-docs.md +69 -62
- package/docs/workflows/harness-everything.md +95 -92
- package/docs/workflows/improve-codebase-architecture.md +68 -60
- package/docs/workflows/install-cognitive-os.md +60 -60
- package/docs/workflows/multi-agent-workspace.md +42 -0
- package/docs/workflows/repo-docs.md +64 -59
- package/docs/workflows/rewrite-commits.md +60 -60
- package/docs/workflows/security-review.md +77 -58
- package/docs/workflows/self-evolve.md +42 -59
- package/docs/workflows/skill-creator.md +80 -75
- package/docs/workflows/skill-style.md +64 -64
- package/docs/workflows/tdd.md +7 -4
- package/docs/workflows/to-spec.md +83 -0
- package/docs/workflows/to-tickets.md +80 -0
- package/docs/workflows/todo-driven-workflow.md +28 -30
- package/docs/workflows/using-git-worktrees.md +67 -63
- package/docs/workflows/verification-loop.md +71 -69
- package/docs/workflows/verify-before-claim.md +64 -60
- package/docs/workflows/zoom-out.md +74 -62
- package/environment-detection/SKILL.md +41 -77
- package/environment-detection/references/shell-syntax-rules.md +76 -0
- package/environment-detection/scripts/preflight.js +103 -93
- package/eval-framework/fixtures/bad-frontmatter-colon/SKILL.md +14 -0
- package/eval-framework/fixtures/duplicate-desc-skill-a/SKILL.md +14 -0
- package/eval-framework/fixtures/duplicate-desc-skill-b/SKILL.md +14 -0
- package/eval-framework/fixtures/missing-delimiter/SKILL.md +13 -0
- package/eval-framework/fixtures/over-budget-skill/SKILL.md +36 -0
- package/eval-harness/SKILL.md +42 -59
- package/eval-harness/references/scoring-rubric.md +68 -0
- package/eval-harness/scripts/evaluate.js +77 -61
- package/evals/environment-detection/eval.yaml +26 -0
- package/evals/environment-detection/tasks/negative-trigger.yaml +16 -0
- package/evals/environment-detection/tasks/positive-trigger.yaml +15 -0
- package/evals/eval-harness/eval.yaml +26 -0
- package/evals/eval-harness/tasks/negative-trigger.yaml +16 -0
- package/evals/eval-harness/tasks/positive-trigger.yaml +15 -0
- package/evals/fable-discipline/eval.yaml +26 -0
- package/evals/fable-discipline/tasks/negative-trigger.yaml +16 -0
- package/evals/fable-discipline/tasks/positive-trigger.yaml +15 -0
- package/evals/fable-mode/eval.yaml +26 -0
- package/evals/fable-mode/tasks/negative-tier2-no-model.yaml +18 -0
- package/evals/fable-mode/tasks/negative-trigger.yaml +16 -0
- package/evals/fable-mode/tasks/positive-haiku-mode.yaml +16 -0
- package/evals/fable-mode/tasks/positive-opus-mode.yaml +16 -0
- package/evals/fable-mode/tasks/positive-sonnet-mode.yaml +16 -0
- package/evals/fable-mode/tasks/positive-trigger.yaml +15 -0
- package/evals/find-skills/eval.yaml +26 -0
- package/evals/find-skills/tasks/negative-trigger.yaml +16 -0
- package/evals/find-skills/tasks/positive-trigger.yaml +15 -0
- package/evals/git-commit/eval.yaml +26 -0
- package/evals/git-commit/tasks/negative-trigger.yaml +16 -0
- package/evals/git-commit/tasks/positive-trigger.yaml +15 -0
- package/evals/grill-me/eval.yaml +26 -0
- package/evals/grill-me/tasks/negative-trigger.yaml +16 -0
- package/evals/grill-me/tasks/positive-trigger.yaml +15 -0
- package/evals/grill-with-docs/eval.yaml +26 -0
- package/evals/grill-with-docs/tasks/negative-trigger.yaml +16 -0
- package/evals/grill-with-docs/tasks/positive-trigger.yaml +15 -0
- package/evals/harness-everything/eval.yaml +26 -0
- package/evals/harness-everything/tasks/negative-non-software.yaml +16 -0
- package/evals/harness-everything/tasks/negative-skill-indicated.yaml +15 -0
- package/evals/harness-everything/tasks/positive-tier1.yaml +16 -0
- package/evals/harness-everything/tasks/positive-tier2.yaml +16 -0
- package/evals/harness-everything/tasks/positive-tier3.yaml +16 -0
- package/evals/improve-codebase-architecture/eval.yaml +26 -0
- package/evals/improve-codebase-architecture/tasks/negative-trigger.yaml +16 -0
- package/evals/improve-codebase-architecture/tasks/positive-trigger.yaml +15 -0
- package/evals/install-cognitive-os/eval.yaml +26 -0
- package/evals/install-cognitive-os/tasks/negative-trigger.yaml +16 -0
- package/evals/install-cognitive-os/tasks/positive-trigger.yaml +15 -0
- package/evals/multi-agent-workspace/eval.yaml +26 -0
- package/evals/multi-agent-workspace/tasks/negative-trigger.yaml +15 -0
- package/evals/multi-agent-workspace/tasks/positive-trigger.yaml +15 -0
- package/evals/repo-docs/eval.yaml +26 -0
- package/evals/repo-docs/tasks/negative-trigger.yaml +16 -0
- package/evals/repo-docs/tasks/positive-trigger.yaml +15 -0
- package/evals/rewrite-commits/eval.yaml +26 -0
- package/evals/rewrite-commits/tasks/negative-trigger.yaml +16 -0
- package/evals/rewrite-commits/tasks/positive-trigger.yaml +15 -0
- package/evals/security-review/eval.yaml +26 -0
- package/evals/security-review/tasks/negative-trigger.yaml +16 -0
- package/evals/security-review/tasks/positive-trigger.yaml +15 -0
- package/evals/self-evolve/eval.yaml +26 -0
- package/evals/self-evolve/tasks/negative-trigger.yaml +16 -0
- package/evals/self-evolve/tasks/positive-trigger.yaml +15 -0
- package/evals/skill-creator/eval.yaml +26 -0
- package/evals/skill-creator/tasks/negative-trigger.yaml +16 -0
- package/evals/skill-creator/tasks/positive-trigger.yaml +15 -0
- package/evals/skill-style/eval.yaml +26 -0
- package/evals/skill-style/tasks/negative-trigger.yaml +16 -0
- package/evals/skill-style/tasks/positive-trigger.yaml +15 -0
- package/evals/tdd/eval.yaml +26 -0
- package/evals/tdd/tasks/negative-trivia.yaml +16 -0
- package/evals/tdd/tasks/positive-bugfix.yaml +15 -0
- package/evals/tdd/tasks/positive-feature.yaml +16 -0
- package/evals/tdd/tasks/positive-refactor.yaml +15 -0
- package/evals/to-spec/eval.yaml +26 -0
- package/evals/to-spec/tasks/negative-trigger.yaml +16 -0
- package/evals/to-spec/tasks/positive-trigger.yaml +15 -0
- package/evals/to-tickets/eval.yaml +26 -0
- package/evals/to-tickets/tasks/negative-trigger.yaml +15 -0
- package/evals/to-tickets/tasks/positive-trigger.yaml +15 -0
- package/evals/todo-driven-workflow/eval.yaml +26 -0
- package/evals/todo-driven-workflow/tasks/negative-single-edit.yaml +16 -0
- package/evals/todo-driven-workflow/tasks/positive-multi-step.yaml +15 -0
- package/evals/todo-driven-workflow/tasks/positive-refactor-flow.yaml +15 -0
- package/evals/using-git-worktrees/eval.yaml +26 -0
- package/evals/using-git-worktrees/tasks/negative-trigger.yaml +15 -0
- package/evals/using-git-worktrees/tasks/positive-trigger.yaml +15 -0
- package/evals/verification-loop/eval.yaml +26 -0
- package/evals/verification-loop/tasks/negative-discussion.yaml +16 -0
- package/evals/verification-loop/tasks/positive-pre-ship.yaml +15 -0
- package/evals/verify-before-claim/eval.yaml +26 -0
- package/evals/verify-before-claim/tasks/negative-trigger.yaml +16 -0
- package/evals/verify-before-claim/tasks/positive-trigger.yaml +15 -0
- package/evals/zoom-out/eval.yaml +26 -0
- package/evals/zoom-out/tasks/negative-trivial-edit.yaml +16 -0
- package/evals/zoom-out/tasks/positive-repeated-failure.yaml +15 -0
- package/fable-discipline/SKILL.md +41 -38
- package/fable-discipline/references/discipline-rules.md +22 -0
- package/fable-mode/CONTRACT-FORMAT.md +51 -51
- package/fable-mode/SKILL.md +39 -51
- package/fable-mode/agents/fable-orchestrator.md +99 -92
- package/fable-mode/agents/fable-verifier.md +32 -32
- package/fable-mode/agents/fable-worker-haiku.md +52 -48
- package/fable-mode/agents/fable-worker-sonnet.md +53 -49
- package/fable-mode/execution-guardrails/SKILL.md +43 -87
- package/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
- package/fable-mode/fable-haiku/SKILL.md +36 -48
- package/fable-mode/fable-haiku/references/routing-notes.md +26 -0
- package/fable-mode/fable-opus/SKILL.md +36 -0
- package/fable-mode/fable-sonnet/SKILL.md +36 -0
- package/fable-mode/model-matrix.json +32 -0
- package/fable-mode/references/execution-phases.md +37 -0
- package/fable-mode/references/model-matrix.md +39 -0
- package/fable-mode/scripts/model-selector.js +129 -0
- package/find-skills/SKILL.md +48 -0
- package/find-skills/references/discovery-flow.md +102 -0
- package/find-skills/scripts/use-skill.js +106 -0
- package/git-commit/SKILL.md +45 -55
- package/git-commit/guides/ANGULAR_STYLE.md +60 -60
- package/git-commit/guides/COMMIT_GENERATION.md +23 -23
- package/git-commit/guides/LANGUAGE_DETECTION.md +16 -16
- package/git-commit/guides/MAIN_REPO.md +14 -14
- package/git-commit/guides/SUBMODULES.md +27 -27
- package/git-commit/references/commit-flow.md +30 -0
- package/grill-me/SKILL.md +43 -36
- package/grill-me/references/grilling-playbook.md +38 -0
- package/grill-with-docs/ADR-FORMAT.md +47 -47
- package/grill-with-docs/CONTEXT-FORMAT.md +63 -63
- package/grill-with-docs/SKILL.md +41 -99
- package/grill-with-docs/references/session-playbook.md +97 -0
- package/harness-everything/SKILL.md +42 -141
- package/harness-everything/references/skill-registry.md +39 -0
- package/harness-everything/references/triage-and-tiers.md +116 -0
- package/harness-everything/scripts/bootstrap.js +203 -140
- package/harness-everything/scripts/routing-keywords.json +320 -0
- package/harness-everything/scripts/self-heal.js +241 -189
- package/harness-everything/scripts/tier-router.js +334 -219
- package/harness-everything/scripts/verify-gate.js +87 -18
- package/hooks/hooks.json +155 -155
- package/hooks/scripts/boundary-guard.js +55 -55
- package/hooks/scripts/contract-test.js +79 -79
- package/hooks/scripts/depth-guard.js +65 -65
- package/hooks/scripts/lib/harness-state.js +139 -228
- package/hooks/scripts/lib/platforms/claude.js +185 -42
- package/hooks/scripts/lib/platforms/codex.js +114 -46
- package/hooks/scripts/lib/platforms/continue.js +91 -41
- package/hooks/scripts/lib/platforms/copilot.js +109 -41
- package/hooks/scripts/lib/platforms/cursor.js +89 -41
- package/hooks/scripts/lib/platforms/hermes.js +57 -32
- package/hooks/scripts/lib/platforms/index.js +17 -17
- package/hooks/scripts/lib/platforms/worktrees.js +20 -20
- package/hooks/scripts/reset-circuit-breaker.js +30 -30
- package/hooks/scripts/rule-of-3-tracker.js +124 -91
- package/hooks/scripts/rule-of-3.js +14 -3
- package/hooks/scripts/state-persist.js +99 -99
- package/hooks/scripts/stop-gate.js +80 -80
- package/hooks/scripts/subagent-scope-guard.js +88 -88
- package/improve-codebase-architecture/SKILL.md +40 -44
- package/improve-codebase-architecture/guides/DEEPENING.md +37 -37
- package/improve-codebase-architecture/guides/HTML-REPORT.md +123 -123
- package/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -44
- package/improve-codebase-architecture/guides/LANGUAGE.md +53 -53
- package/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
- package/install-cognitive-os/SKILL.md +38 -95
- package/install-cognitive-os/references/cognitive-loop.md +27 -0
- package/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
- package/multi-agent-workspace/SKILL.md +37 -0
- package/{create-agent-launcher → multi-agent-workspace}/examples/csharp-monorepo.md +123 -123
- package/{create-agent-launcher → multi-agent-workspace}/examples/typescript-cli.md +126 -126
- package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-claude.md +77 -77
- package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-codex.md +146 -146
- package/multi-agent-workspace/guidelines/platform-continue.md +38 -0
- package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-copilot.md +74 -74
- package/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
- package/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
- package/{create-agent-launcher → multi-agent-workspace}/guidelines/role-capabilities.md +108 -108
- package/multi-agent-workspace/references/agency-agents.md +31 -0
- package/multi-agent-workspace/references/architecture-guide.md +32 -0
- package/multi-agent-workspace/references/orchestration.md +48 -0
- package/multi-agent-workspace/scripts/agency-catalog.js +190 -0
- package/multi-agent-workspace/scripts/index_memory.js +51 -0
- package/multi-agent-workspace/scripts/scaffold.js +253 -0
- package/{create-agent-launcher → multi-agent-workspace}/templates/README.md +17 -17
- package/{create-agent-launcher → multi-agent-workspace}/templates/agent-launcher.md +67 -67
- package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-csharp.md +55 -55
- package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-polyglot.md +61 -61
- package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-ts.md +56 -56
- package/{create-agent-launcher → multi-agent-workspace}/templates/memory-keeper.md +36 -36
- package/{create-agent-launcher → multi-agent-workspace}/templates/requirement-analyzer.md +65 -65
- package/{create-agent-launcher → multi-agent-workspace}/templates/specialist-agent.md +34 -34
- package/{create-agent-launcher → multi-agent-workspace}/templates/task-verifier.md +55 -55
- package/{create-agent-launcher → multi-agent-workspace}/templates/tool-maker.md +32 -32
- package/multi-agent-workspace/workflows/01-init.md +22 -0
- package/multi-agent-workspace/workflows/02-analysis.md +23 -0
- package/multi-agent-workspace/workflows/03-generation.md +27 -0
- package/multi-agent-workspace/workflows/04-launcher.md +16 -0
- package/opencode-plugin/README.md +94 -0
- package/opencode-plugin/hooks/circuit-breaker.js +121 -0
- package/opencode-plugin/hooks/compliance.js +128 -0
- package/opencode-plugin/hooks/post-edit.js +62 -0
- package/opencode-plugin/hooks/pre-complete.js +65 -0
- package/opencode-plugin/hooks/verify.js +140 -0
- package/opencode-plugin/plugin.json +17 -0
- package/opencode-plugin/test-hook-firing.js +198 -0
- package/package.json +50 -22
- package/references/definition-of-done.md +67 -0
- package/references/performance-checklist.md +153 -0
- package/references/platform-advisory-template.md +58 -0
- package/references/security-checklist.md +205 -0
- package/repo-docs/SKILL.md +46 -45
- package/repo-docs/references/process-guide.md +60 -0
- package/repo-docs/templates/agents-template.md +264 -264
- package/repo-docs/templates/knowledge-agents-template.md +50 -50
- package/repo-docs/templates/knowledge-readme-template.md +83 -83
- package/repo-docs/templates/manual-recon.md +117 -117
- package/repo-docs/templates/multi-skills-readme-template.md +72 -72
- package/repo-docs/templates/product-agents-template.md +78 -78
- package/repo-docs/templates/product-readme-template.md +95 -95
- package/repo-docs/templates/readme-template.md +136 -136
- package/repo-docs/templates/single-skill-readme-template.md +70 -70
- package/repo-docs/templates/skills-agents-template.md +60 -60
- package/rewrite-commits/SKILL.md +37 -32
- package/rewrite-commits/references/workflow.md +18 -0
- package/scripts/installer.js +546 -649
- package/scripts/lib/advisory-text.js +167 -163
- package/scripts/lib/claude-hooks.js +84 -71
- package/scripts/lib/gitignore.js +199 -80
- package/scripts/lib/manifest.js +146 -82
- package/scripts/lib/prompts.js +241 -241
- package/scripts/lib/skills.js +260 -172
- package/scripts/lib/workspace.js +28 -28
- package/scripts/verify-install.js +147 -0
- package/security-review/SKILL.md +50 -511
- package/security-review/guides/OWASP-PATTERNS.md +31 -0
- package/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
- package/security-review/references/security-checklist.md +478 -0
- package/security-review/scripts/audit-secrets.js +84 -0
- package/self-evolve/SKILL.md +47 -54
- package/self-evolve/references/memory-resolution.md +58 -0
- package/self-evolve/scripts/persist-memory.js +139 -40
- package/self-evolve/scripts/register-dynamic-skill.js +251 -0
- package/self-evolve/scripts/self-regression.js +110 -113
- package/skill-creator/SKILL.md +49 -91
- package/skill-creator/references/authoring-workflow.md +14 -0
- package/skill-creator/references/dynamic-generation-contract.md +21 -0
- package/skill-creator/references/quality-checklist.md +15 -0
- package/skill-creator/references/quality-principles.md +81 -81
- package/skill-creator/references/testing-workflow.md +20 -25
- package/skill-style/SKILL.md +42 -48
- package/skill-style/references/style-guide.md +36 -0
- package/tdd/SKILL.md +44 -53
- package/tdd/guides/deep-modules.md +33 -33
- package/tdd/guides/interface-design.md +31 -31
- package/tdd/guides/mocking.md +59 -59
- package/tdd/guides/refactoring.md +10 -10
- package/tdd/guides/tests.md +61 -61
- package/tdd/references/core-discipline.md +49 -0
- package/to-spec/SKILL.md +42 -0
- package/to-spec/references/process.md +77 -0
- package/to-spec/scripts/check-project-docs.js +259 -0
- package/to-spec/templates/cli-reference.md +31 -0
- package/to-spec/templates/dev-doc.md +27 -0
- package/to-spec/templates/feature-spec.md +59 -0
- package/to-spec/templates/schema-doc.md +31 -0
- package/to-tickets/SKILL.md +42 -0
- package/to-tickets/references/publishing-and-templates.md +97 -0
- package/todo-driven-workflow/SKILL.md +40 -54
- package/todo-driven-workflow/references/execution-guide.md +27 -0
- package/using-git-worktrees/SKILL.md +49 -161
- package/using-git-worktrees/references/workflow-details.md +108 -0
- package/verification-loop/SKILL.md +46 -138
- package/verification-loop/references/verification-phases.md +116 -0
- package/verification-loop/templates/verification-report.template.md +15 -0
- package/verify-before-claim/SKILL.md +43 -86
- package/verify-before-claim/references/verification-guide.md +73 -0
- package/zoom-out/SKILL.md +42 -90
- package/zoom-out/references/circuit-breaker.md +66 -0
- package/zoom-out/templates/zoom-out-report.template.md +20 -0
- package/build-multi-agent-system/AGENTS.md +0 -50
- package/build-multi-agent-system/README.md +0 -63
- package/build-multi-agent-system/SKILL.md +0 -68
- package/create-agent-launcher/SKILL.md +0 -48
- package/create-agent-launcher/guidelines/platform-gemini.md +0 -101
- package/create-agent-launcher/workflows/01-init.md +0 -22
- package/create-agent-launcher/workflows/02-analysis.md +0 -26
- package/create-agent-launcher/workflows/03-generation.md +0 -29
- package/create-agent-launcher/workflows/04-launcher.md +0 -20
- package/docs/workflows/build-multi-agent-system.md +0 -62
- package/docs/workflows/create-agent-launcher.md +0 -62
- package/eval-framework/behavioral-test.js +0 -105
- package/eval-framework/mechanism-test.js +0 -251
- package/harness-everything/scripts/todo-cli.js +0 -157
- package/skill-style/STYLE.md +0 -37
|
@@ -1,32 +1,57 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
name: 'hermes',
|
|
6
|
-
label: 'Hermes Agent',
|
|
7
|
-
getStateDir(workspaceRoot) {
|
|
8
|
-
return path.join(workspaceRoot, '.hermes', 'harness-state');
|
|
9
|
-
},
|
|
10
|
-
getIgnorePatterns(workspaceRoot) {
|
|
11
|
-
const patterns = [];
|
|
12
|
-
if (fs.existsSync(path.join(workspaceRoot, '.hermes', 'harness-state'))) {
|
|
13
|
-
patterns.push('.hermes/harness-state/');
|
|
14
|
-
}
|
|
15
|
-
return patterns;
|
|
16
|
-
},
|
|
17
|
-
isMatch(pattern, trimmedLine) {
|
|
18
|
-
if (pattern === '.hermes/harness-state/') {
|
|
19
|
-
return trimmedLine === '.hermes/' ||
|
|
20
|
-
trimmedLine === '.hermes' ||
|
|
21
|
-
trimmedLine === '.hermes/harness-state' ||
|
|
22
|
-
trimmedLine === '.hermes/harness-state/';
|
|
23
|
-
}
|
|
24
|
-
return trimmedLine === pattern || trimmedLine === pattern.slice(0, -1);
|
|
25
|
-
},
|
|
26
|
-
isInstalled(workspaceRoot, userHome, isGlobal) {
|
|
27
|
-
if (isGlobal) {
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
30
|
-
return fs.existsSync(path.join(workspaceRoot, '.hermes.md'));
|
|
31
|
-
}
|
|
32
|
-
}
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
name: 'hermes',
|
|
6
|
+
label: 'Hermes Agent',
|
|
7
|
+
getStateDir(workspaceRoot) {
|
|
8
|
+
return path.join(workspaceRoot, '.hermes', 'harness-state');
|
|
9
|
+
},
|
|
10
|
+
getIgnorePatterns(workspaceRoot) {
|
|
11
|
+
const patterns = [];
|
|
12
|
+
if (fs.existsSync(path.join(workspaceRoot, '.hermes', 'harness-state'))) {
|
|
13
|
+
patterns.push('.hermes/harness-state/');
|
|
14
|
+
}
|
|
15
|
+
return patterns;
|
|
16
|
+
},
|
|
17
|
+
isMatch(pattern, trimmedLine) {
|
|
18
|
+
if (pattern === '.hermes/harness-state/') {
|
|
19
|
+
return trimmedLine === '.hermes/' ||
|
|
20
|
+
trimmedLine === '.hermes' ||
|
|
21
|
+
trimmedLine === '.hermes/harness-state' ||
|
|
22
|
+
trimmedLine === '.hermes/harness-state/';
|
|
23
|
+
}
|
|
24
|
+
return trimmedLine === pattern || trimmedLine === pattern.slice(0, -1);
|
|
25
|
+
},
|
|
26
|
+
isInstalled(workspaceRoot, userHome, isGlobal) {
|
|
27
|
+
if (isGlobal) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
return fs.existsSync(path.join(workspaceRoot, '.hermes.md'));
|
|
31
|
+
},
|
|
32
|
+
getSkillsTarget({ workspaceRoot, userHome, isGlobal, manifest }) {
|
|
33
|
+
if (isGlobal) {
|
|
34
|
+
const globalAgentsDir = path.join(userHome, '.agents');
|
|
35
|
+
return {
|
|
36
|
+
path: path.join(globalAgentsDir, 'skills'),
|
|
37
|
+
label: '~/.agents/skills/',
|
|
38
|
+
manifestPath: manifest.getManifestPath(globalAgentsDir),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
},
|
|
43
|
+
install({ isGlobal, targetWorkspaceRoot, advisory }) {
|
|
44
|
+
if (!isGlobal) {
|
|
45
|
+
const targetFile = path.join(targetWorkspaceRoot, '.hermes.md');
|
|
46
|
+
advisory.injectAdvisoryText(targetFile, '# .hermes.md', '.hermes.md');
|
|
47
|
+
} else {
|
|
48
|
+
console.log(` ℹ️ Hermes Agent has no documented global instructions file (it reads .hermes.md from the current project directory only) - skipping global install for --hermes.`);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
uninstall({ removeLocal, removeGlobal, workspaceRoot, userHome }) {
|
|
52
|
+
const advisory = require('../../../../scripts/lib/advisory-text');
|
|
53
|
+
if (removeLocal) {
|
|
54
|
+
advisory.removeAdvisoryText(path.join(workspaceRoot, '.hermes.md'));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
const claude = require('./claude');
|
|
2
|
-
const cursor = require('./cursor');
|
|
3
|
-
const copilot = require('./copilot');
|
|
4
|
-
const codex = require('./codex');
|
|
5
|
-
const _continue = require('./continue');
|
|
6
|
-
const hermes = require('./hermes');
|
|
7
|
-
const worktrees = require('./worktrees');
|
|
8
|
-
|
|
9
|
-
module.exports = [
|
|
10
|
-
claude,
|
|
11
|
-
cursor,
|
|
12
|
-
copilot,
|
|
13
|
-
codex,
|
|
14
|
-
_continue,
|
|
15
|
-
hermes,
|
|
16
|
-
worktrees
|
|
17
|
-
];
|
|
1
|
+
const claude = require('./claude');
|
|
2
|
+
const cursor = require('./cursor');
|
|
3
|
+
const copilot = require('./copilot');
|
|
4
|
+
const codex = require('./codex');
|
|
5
|
+
const _continue = require('./continue');
|
|
6
|
+
const hermes = require('./hermes');
|
|
7
|
+
const worktrees = require('./worktrees');
|
|
8
|
+
|
|
9
|
+
module.exports = [
|
|
10
|
+
claude,
|
|
11
|
+
cursor,
|
|
12
|
+
copilot,
|
|
13
|
+
codex,
|
|
14
|
+
_continue,
|
|
15
|
+
hermes,
|
|
16
|
+
worktrees
|
|
17
|
+
];
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
name: 'worktrees',
|
|
6
|
-
label: 'Git Worktrees',
|
|
7
|
-
getIgnorePatterns(workspaceRoot) {
|
|
8
|
-
const patterns = [];
|
|
9
|
-
if (fs.existsSync(path.join(workspaceRoot, '.worktrees'))) {
|
|
10
|
-
patterns.push('.worktrees/');
|
|
11
|
-
}
|
|
12
|
-
if (fs.existsSync(path.join(workspaceRoot, 'worktrees'))) {
|
|
13
|
-
patterns.push('worktrees/');
|
|
14
|
-
}
|
|
15
|
-
return patterns;
|
|
16
|
-
},
|
|
17
|
-
isInstalled() {
|
|
18
|
-
return false; // Not a standalone platform hook/settings installer
|
|
19
|
-
}
|
|
20
|
-
};
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
name: 'worktrees',
|
|
6
|
+
label: 'Git Worktrees',
|
|
7
|
+
getIgnorePatterns(workspaceRoot) {
|
|
8
|
+
const patterns = [];
|
|
9
|
+
if (fs.existsSync(path.join(workspaceRoot, '.worktrees'))) {
|
|
10
|
+
patterns.push('.worktrees/');
|
|
11
|
+
}
|
|
12
|
+
if (fs.existsSync(path.join(workspaceRoot, 'worktrees'))) {
|
|
13
|
+
patterns.push('worktrees/');
|
|
14
|
+
}
|
|
15
|
+
return patterns;
|
|
16
|
+
},
|
|
17
|
+
isInstalled() {
|
|
18
|
+
return false; // Not a standalone platform hook/settings installer
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Manual escape hatch for the Rule of 3 circuit breaker. Run this directly
|
|
3
|
-
// in your own terminal (not through the agent — Bash is blocked while the
|
|
4
|
-
// breaker is tripped) to clear it without waiting for a new session.
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const { getWorkspaceRoot, getSessionDir, readCurrentSession } = require('./lib/harness-state');
|
|
8
|
-
|
|
9
|
-
// This is run directly by the human, not through the agent, so there's no
|
|
10
|
-
// hook payload to read a session_id from - resolve "the session that's
|
|
11
|
-
// currently blocked" via the pointer bootstrap.js wrote at its last
|
|
12
|
-
// SessionStart.
|
|
13
|
-
const root = getWorkspaceRoot();
|
|
14
|
-
const harnessDir = getSessionDir(root, readCurrentSession(root));
|
|
15
|
-
const stateFile = path.join(harnessDir, 'rule-of-3-state.json');
|
|
16
|
-
const reportFile = path.join(harnessDir, 'zoom-out-report.md');
|
|
17
|
-
|
|
18
|
-
if (fs.existsSync(stateFile)) {
|
|
19
|
-
fs.unlinkSync(stateFile);
|
|
20
|
-
console.log('Rule of 3 circuit breaker cleared.');
|
|
21
|
-
} else {
|
|
22
|
-
console.log('Rule of 3 circuit breaker is not currently tripped.');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// A human reset is a full clear: the stale reflection report belongs to the
|
|
26
|
-
// loop that was just abandoned.
|
|
27
|
-
if (fs.existsSync(reportFile)) {
|
|
28
|
-
fs.unlinkSync(reportFile);
|
|
29
|
-
console.log('Stale zoom-out report removed.');
|
|
30
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Manual escape hatch for the Rule of 3 circuit breaker. Run this directly
|
|
3
|
+
// in your own terminal (not through the agent — Bash is blocked while the
|
|
4
|
+
// breaker is tripped) to clear it without waiting for a new session.
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const { getWorkspaceRoot, getSessionDir, readCurrentSession } = require('./lib/harness-state');
|
|
8
|
+
|
|
9
|
+
// This is run directly by the human, not through the agent, so there's no
|
|
10
|
+
// hook payload to read a session_id from - resolve "the session that's
|
|
11
|
+
// currently blocked" via the pointer bootstrap.js wrote at its last
|
|
12
|
+
// SessionStart.
|
|
13
|
+
const root = getWorkspaceRoot();
|
|
14
|
+
const harnessDir = getSessionDir(root, readCurrentSession(root));
|
|
15
|
+
const stateFile = path.join(harnessDir, 'rule-of-3-state.json');
|
|
16
|
+
const reportFile = path.join(harnessDir, 'zoom-out-report.md');
|
|
17
|
+
|
|
18
|
+
if (fs.existsSync(stateFile)) {
|
|
19
|
+
fs.unlinkSync(stateFile);
|
|
20
|
+
console.log('Rule of 3 circuit breaker cleared.');
|
|
21
|
+
} else {
|
|
22
|
+
console.log('Rule of 3 circuit breaker is not currently tripped.');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// A human reset is a full clear: the stale reflection report belongs to the
|
|
26
|
+
// loop that was just abandoned.
|
|
27
|
+
if (fs.existsSync(reportFile)) {
|
|
28
|
+
fs.unlinkSync(reportFile);
|
|
29
|
+
console.log('Stale zoom-out report removed.');
|
|
30
|
+
}
|
|
@@ -1,91 +1,124 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const crypto = require('crypto');
|
|
5
|
-
const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
|
|
6
|
-
|
|
7
|
-
// PostToolUse hooks in Claude Code typically receive the tool output via stdin
|
|
8
|
-
let inputData = '';
|
|
9
|
-
|
|
10
|
-
process.stdin.on('data', chunk => {
|
|
11
|
-
inputData += chunk;
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
process.stdin.on('end', () => {
|
|
15
|
-
try {
|
|
16
|
-
const payload = JSON.parse(inputData);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const crypto = require('crypto');
|
|
5
|
+
const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
|
|
6
|
+
|
|
7
|
+
// PostToolUse hooks in Claude Code typically receive the tool output via stdin
|
|
8
|
+
let inputData = '';
|
|
9
|
+
|
|
10
|
+
process.stdin.on('data', chunk => {
|
|
11
|
+
inputData += chunk;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
process.stdin.on('end', () => {
|
|
15
|
+
try {
|
|
16
|
+
const payload = JSON.parse(inputData);
|
|
17
|
+
const toolResponse = payload.tool_response || {};
|
|
18
|
+
const stdout = toolResponse.stdout ?? payload.stdout ?? '';
|
|
19
|
+
const stderr = toolResponse.stderr ?? payload.stderr ?? '';
|
|
20
|
+
const rawExitCode = toolResponse.exitCode ?? toolResponse.exit_code ?? payload.exitCode;
|
|
21
|
+
const exitCode = typeof rawExitCode === 'number' ? rawExitCode : undefined;
|
|
22
|
+
|
|
23
|
+
const explicitFailure = exitCode !== undefined && exitCode !== 0;
|
|
24
|
+
const explicitSuccess = exitCode === 0;
|
|
25
|
+
const stderrSignal = typeof stderr === 'string' && stderr.trim().length > 0;
|
|
26
|
+
const looksLikeError = /\b(error|fail|failed|failure|exception|fatal|panic|traceback|denied|refused|cannot|unable)\b/i.test(stderr);
|
|
27
|
+
const isFailure = explicitFailure || (exitCode === undefined && stderrSignal && looksLikeError);
|
|
28
|
+
const errorText = (stderrSignal ? stderr : stdout) || '';
|
|
29
|
+
|
|
30
|
+
const stateFile = path.join(getSessionDir(getWorkspaceRoot(), payload.session_id), 'rule-of-3-state.json');
|
|
31
|
+
|
|
32
|
+
let state = { count: 0, lastHash: null, zoomOutResolved: false, zoomOutCycles: 0, lastFailureAt: 0 };
|
|
33
|
+
if (fs.existsSync(stateFile)) {
|
|
34
|
+
state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (isFailure && errorText) {
|
|
38
|
+
// Enhanced failure signature detection with context-aware categorization
|
|
39
|
+
// Hash includes: error message, file path, command attempted, and failure category
|
|
40
|
+
const filePath = payload.tool_input?.file_path || payload.tool_input?.filePath || '';
|
|
41
|
+
const command = payload.tool_input?.command || '';
|
|
42
|
+
|
|
43
|
+
// Categorize failure type for context-aware thresholds
|
|
44
|
+
let category = 'unknown';
|
|
45
|
+
if (/SyntaxError|Unexpected token|Syntax Error/i.test(errorText)) {
|
|
46
|
+
category = 'syntax';
|
|
47
|
+
} else if (/ENOENT|not found|No such file|找不到|不存在/i.test(errorText)) {
|
|
48
|
+
category = 'environment';
|
|
49
|
+
} else if (/timeout|timed out|超時|逾時/i.test(errorText)) {
|
|
50
|
+
category = 'timeout';
|
|
51
|
+
} else if (/test.*fail|assertion|AssertionError|測試.*失敗|斷言.*錯誤/i.test(errorText)) {
|
|
52
|
+
category = 'test';
|
|
53
|
+
} else if (/permission|denied|EACCES|權限/i.test(errorText)) {
|
|
54
|
+
category = 'permission';
|
|
55
|
+
} else if (/dependency|module not found|Cannot find module|模組.*找不到/i.test(errorText)) {
|
|
56
|
+
category = 'dependency';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Normalize error text with context for better loop detection
|
|
60
|
+
const normalized = errorText.slice(-400)
|
|
61
|
+
.toLowerCase()
|
|
62
|
+
.replace(/0x[0-9a-f]+/g, '#')
|
|
63
|
+
.replace(/\d+/g, '#')
|
|
64
|
+
.replace(/\s+/g, ' ')
|
|
65
|
+
.trim();
|
|
66
|
+
|
|
67
|
+
// Include file path and command in hash for better context
|
|
68
|
+
const contextString = `${category}:${filePath}:${command}:${normalized.slice(-200)}`;
|
|
69
|
+
const hash = crypto.createHash('md5').update(contextString).digest('hex');
|
|
70
|
+
|
|
71
|
+
// Context-aware thresholds: different failure types have different breaking points
|
|
72
|
+
let threshold = 3; // Default: 3 strikes
|
|
73
|
+
if (category === 'syntax') {
|
|
74
|
+
threshold = 3; // Same syntax error 3 times = stop
|
|
75
|
+
} else if (category === 'environment') {
|
|
76
|
+
threshold = 4; // Environment issues may need more exploration
|
|
77
|
+
} else if (category === 'test') {
|
|
78
|
+
threshold = 3; // Same test failure 3 times = stop
|
|
79
|
+
} else if (category === 'timeout') {
|
|
80
|
+
threshold = 2; // Timeouts are expensive, fail faster
|
|
81
|
+
} else if (category === 'permission') {
|
|
82
|
+
threshold = 2; // Permission issues rarely resolve by retrying
|
|
83
|
+
} else if (category === 'dependency') {
|
|
84
|
+
threshold = 4; // Dependency issues may need different approaches
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (state.lastHash === hash) {
|
|
88
|
+
state.count += 1;
|
|
89
|
+
state.category = category; // Track failure category for smarter decisions
|
|
90
|
+
} else {
|
|
91
|
+
state.count = 1;
|
|
92
|
+
state.lastHash = hash;
|
|
93
|
+
state.category = category;
|
|
94
|
+
// New signature = new problem: the zoom-out cycle budget starts over.
|
|
95
|
+
state.zoomOutCycles = 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Store threshold for this failure type
|
|
99
|
+
state.threshold = threshold;
|
|
100
|
+
|
|
101
|
+
// Any fresh failure re-arms the breaker. Without this, a signature that
|
|
102
|
+
// failed again after a success (or after a zoom-out release) would keep
|
|
103
|
+
// zoomOutResolved=true and the breaker could never trip on it again.
|
|
104
|
+
state.zoomOutResolved = false;
|
|
105
|
+
// rule-of-3.js only honors a zoom-out report written AFTER this moment,
|
|
106
|
+
// so a stale report can't unlock a later trip.
|
|
107
|
+
state.lastFailureAt = Date.now();
|
|
108
|
+
|
|
109
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8');
|
|
110
|
+
} else if (explicitSuccess) {
|
|
111
|
+
// Only reset on a *confirmed* zero exit code, not merely "not a failure".
|
|
112
|
+
if (state.count > 0 || state.zoomOutCycles > 0) {
|
|
113
|
+
state.count = 0;
|
|
114
|
+
state.zoomOutResolved = true;
|
|
115
|
+
state.zoomOutCycles = 0;
|
|
116
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
} catch (err) {
|
|
121
|
+
// silently fail
|
|
122
|
+
}
|
|
123
|
+
process.exit(0);
|
|
124
|
+
});
|
|
@@ -33,7 +33,11 @@ function readState(stateFile) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function isTripped(state) {
|
|
36
|
-
|
|
36
|
+
if (!state || state.zoomOutResolved) return false;
|
|
37
|
+
|
|
38
|
+
// Use context-aware thresholds if available, otherwise default to 3
|
|
39
|
+
const threshold = state.threshold || 3;
|
|
40
|
+
return state.count >= threshold;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
function anySessionTripped(root) {
|
|
@@ -41,10 +45,17 @@ function anySessionTripped(root) {
|
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
// The one mutation allowed while tripped: writing the reflection report.
|
|
48
|
+
const ALLOWED_WRITE_TOOLS = new Set([
|
|
49
|
+
'Write', 'Edit', 'create_file', 'replace_string_in_file',
|
|
50
|
+
'insert_edit_into_file', 'write_file', 'edit_file'
|
|
51
|
+
]);
|
|
52
|
+
|
|
44
53
|
function isReportWrite(payload, reportFile) {
|
|
45
54
|
if (!payload) return false;
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
const toolName = payload.tool_name || payload.toolName;
|
|
56
|
+
if (!ALLOWED_WRITE_TOOLS.has(toolName)) return false;
|
|
57
|
+
const input = payload.tool_input || payload.toolInput || payload.input || {};
|
|
58
|
+
const target = input.file_path || input.filePath || input.path || input.file;
|
|
48
59
|
if (!target) return false;
|
|
49
60
|
return path.resolve(target).toLowerCase() === path.resolve(reportFile).toLowerCase();
|
|
50
61
|
}
|