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,99 +1,99 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
|
|
5
|
-
|
|
6
|
-
// Commands that count as "verification ran" for the Stop gate
|
|
7
|
-
// (hooks/scripts/stop-gate.js). Recall over precision: under-blocking the
|
|
8
|
-
// gate is the correct failure direction, so a broad net is fine.
|
|
9
|
-
const VERIFY_COMMAND_RE = /\b(test|spec|jest|vitest|mocha|pytest|rspec|phpunit|tsc|eslint|lint|build|compile|verify|check)\b/i;
|
|
10
|
-
|
|
11
|
-
let inputData = '';
|
|
12
|
-
const timeout = setTimeout(() => {
|
|
13
|
-
processState(null);
|
|
14
|
-
}, 200);
|
|
15
|
-
|
|
16
|
-
process.stdin.on('data', chunk => {
|
|
17
|
-
inputData += chunk;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
process.stdin.on('end', () => {
|
|
21
|
-
clearTimeout(timeout);
|
|
22
|
-
try {
|
|
23
|
-
const payload = JSON.parse(inputData.trim());
|
|
24
|
-
processState(payload);
|
|
25
|
-
} catch (err) {
|
|
26
|
-
processState(null);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
function processState(payload) {
|
|
31
|
-
try {
|
|
32
|
-
const sessionId = payload && payload.session_id;
|
|
33
|
-
const stateFile = path.join(getSessionDir(getWorkspaceRoot(), sessionId), 'handoff-state.json');
|
|
34
|
-
|
|
35
|
-
// Merge into the existing state rather than replacing it, so the
|
|
36
|
-
// failure/idle status and the Stop-gate milestones can coexist.
|
|
37
|
-
let state = { status: 'idle', timestamp: new Date().toISOString() };
|
|
38
|
-
if (fs.existsSync(stateFile)) {
|
|
39
|
-
try { state = JSON.parse(fs.readFileSync(stateFile, 'utf8')); } catch (e) { /* keep default */ }
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (payload) {
|
|
43
|
-
// Claude Code nests tool output under tool_response, not at the top
|
|
44
|
-
// level, and uses tool_name rather than tool. A numeric exit code
|
|
45
|
-
// also isn't guaranteed to be present at all - only trust it when
|
|
46
|
-
// it's actually a number; fall back to a stderr signal otherwise.
|
|
47
|
-
const toolResponse = payload.tool_response || {};
|
|
48
|
-
const stdout = toolResponse.stdout ?? payload.stdout ?? '';
|
|
49
|
-
const stderr = toolResponse.stderr ?? payload.stderr ?? '';
|
|
50
|
-
const rawExitCode = toolResponse.exitCode ?? toolResponse.exit_code ?? payload.exitCode;
|
|
51
|
-
const exitCode = typeof rawExitCode === 'number' ? rawExitCode : undefined;
|
|
52
|
-
const stderrSignal = typeof stderr === 'string' && stderr.trim().length > 0;
|
|
53
|
-
const isFailed = (exitCode !== undefined && exitCode !== 0) || (exitCode === undefined && stderrSignal);
|
|
54
|
-
const toolName = payload.tool_name || payload.tool || 'command';
|
|
55
|
-
|
|
56
|
-
if (isFailed) {
|
|
57
|
-
// Truncate output to avoid state bloat
|
|
58
|
-
let output = (stderrSignal ? stderr : stdout) || payload.output || '';
|
|
59
|
-
if (output.length > 500) {
|
|
60
|
-
output = '...' + output.slice(-500);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
state.status = 'failed';
|
|
64
|
-
state.timestamp = new Date().toISOString();
|
|
65
|
-
state.tool = toolName;
|
|
66
|
-
state.exitCode = exitCode;
|
|
67
|
-
state.errorSummary = output.trim();
|
|
68
|
-
} else if (exitCode === 0 && state.status === 'failed') {
|
|
69
|
-
// Clear failed state or mark as idle/resolved
|
|
70
|
-
state.lastResolved = { tool: state.tool, timestamp: state.timestamp };
|
|
71
|
-
state.status = 'idle';
|
|
72
|
-
state.timestamp = new Date().toISOString();
|
|
73
|
-
delete state.exitCode;
|
|
74
|
-
delete state.errorSummary;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Milestones for the Stop gate: when did the last mutation happen, and
|
|
78
|
-
// has any verification-ish command succeeded since.
|
|
79
|
-
if (toolName === 'Edit' || toolName === 'Write') {
|
|
80
|
-
state.lastEditAt = Date.now();
|
|
81
|
-
} else if ((toolName === 'Bash' || toolName === 'PowerShell') && !isFailed) {
|
|
82
|
-
const command = (payload.tool_input && payload.tool_input.command) || '';
|
|
83
|
-
if (VERIFY_COMMAND_RE.test(command)) {
|
|
84
|
-
state.lastVerifyAt = Date.now();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8');
|
|
89
|
-
} else {
|
|
90
|
-
// No standard input payload, or invalid JSON. Just maintain a heartbeat timestamp
|
|
91
|
-
if (!fs.existsSync(stateFile)) {
|
|
92
|
-
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8');
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
} catch (err) {
|
|
96
|
-
// Fail silently in hooks
|
|
97
|
-
}
|
|
98
|
-
process.exit(0);
|
|
99
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
|
|
5
|
+
|
|
6
|
+
// Commands that count as "verification ran" for the Stop gate
|
|
7
|
+
// (hooks/scripts/stop-gate.js). Recall over precision: under-blocking the
|
|
8
|
+
// gate is the correct failure direction, so a broad net is fine.
|
|
9
|
+
const VERIFY_COMMAND_RE = /\b(test|spec|jest|vitest|mocha|pytest|rspec|phpunit|tsc|eslint|lint|build|compile|verify|check)\b/i;
|
|
10
|
+
|
|
11
|
+
let inputData = '';
|
|
12
|
+
const timeout = setTimeout(() => {
|
|
13
|
+
processState(null);
|
|
14
|
+
}, 200);
|
|
15
|
+
|
|
16
|
+
process.stdin.on('data', chunk => {
|
|
17
|
+
inputData += chunk;
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
process.stdin.on('end', () => {
|
|
21
|
+
clearTimeout(timeout);
|
|
22
|
+
try {
|
|
23
|
+
const payload = JSON.parse(inputData.trim());
|
|
24
|
+
processState(payload);
|
|
25
|
+
} catch (err) {
|
|
26
|
+
processState(null);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function processState(payload) {
|
|
31
|
+
try {
|
|
32
|
+
const sessionId = payload && payload.session_id;
|
|
33
|
+
const stateFile = path.join(getSessionDir(getWorkspaceRoot(), sessionId), 'handoff-state.json');
|
|
34
|
+
|
|
35
|
+
// Merge into the existing state rather than replacing it, so the
|
|
36
|
+
// failure/idle status and the Stop-gate milestones can coexist.
|
|
37
|
+
let state = { status: 'idle', timestamp: new Date().toISOString() };
|
|
38
|
+
if (fs.existsSync(stateFile)) {
|
|
39
|
+
try { state = JSON.parse(fs.readFileSync(stateFile, 'utf8')); } catch (e) { /* keep default */ }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (payload) {
|
|
43
|
+
// Claude Code nests tool output under tool_response, not at the top
|
|
44
|
+
// level, and uses tool_name rather than tool. A numeric exit code
|
|
45
|
+
// also isn't guaranteed to be present at all - only trust it when
|
|
46
|
+
// it's actually a number; fall back to a stderr signal otherwise.
|
|
47
|
+
const toolResponse = payload.tool_response || {};
|
|
48
|
+
const stdout = toolResponse.stdout ?? payload.stdout ?? '';
|
|
49
|
+
const stderr = toolResponse.stderr ?? payload.stderr ?? '';
|
|
50
|
+
const rawExitCode = toolResponse.exitCode ?? toolResponse.exit_code ?? payload.exitCode;
|
|
51
|
+
const exitCode = typeof rawExitCode === 'number' ? rawExitCode : undefined;
|
|
52
|
+
const stderrSignal = typeof stderr === 'string' && stderr.trim().length > 0;
|
|
53
|
+
const isFailed = (exitCode !== undefined && exitCode !== 0) || (exitCode === undefined && stderrSignal);
|
|
54
|
+
const toolName = payload.tool_name || payload.tool || 'command';
|
|
55
|
+
|
|
56
|
+
if (isFailed) {
|
|
57
|
+
// Truncate output to avoid state bloat
|
|
58
|
+
let output = (stderrSignal ? stderr : stdout) || payload.output || '';
|
|
59
|
+
if (output.length > 500) {
|
|
60
|
+
output = '...' + output.slice(-500);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
state.status = 'failed';
|
|
64
|
+
state.timestamp = new Date().toISOString();
|
|
65
|
+
state.tool = toolName;
|
|
66
|
+
state.exitCode = exitCode;
|
|
67
|
+
state.errorSummary = output.trim();
|
|
68
|
+
} else if (exitCode === 0 && state.status === 'failed') {
|
|
69
|
+
// Clear failed state or mark as idle/resolved
|
|
70
|
+
state.lastResolved = { tool: state.tool, timestamp: state.timestamp };
|
|
71
|
+
state.status = 'idle';
|
|
72
|
+
state.timestamp = new Date().toISOString();
|
|
73
|
+
delete state.exitCode;
|
|
74
|
+
delete state.errorSummary;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Milestones for the Stop gate: when did the last mutation happen, and
|
|
78
|
+
// has any verification-ish command succeeded since.
|
|
79
|
+
if (toolName === 'Edit' || toolName === 'Write') {
|
|
80
|
+
state.lastEditAt = Date.now();
|
|
81
|
+
} else if ((toolName === 'Bash' || toolName === 'PowerShell') && !isFailed) {
|
|
82
|
+
const command = (payload.tool_input && payload.tool_input.command) || '';
|
|
83
|
+
if (VERIFY_COMMAND_RE.test(command)) {
|
|
84
|
+
state.lastVerifyAt = Date.now();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8');
|
|
89
|
+
} else {
|
|
90
|
+
// No standard input payload, or invalid JSON. Just maintain a heartbeat timestamp
|
|
91
|
+
if (!fs.existsSync(stateFile)) {
|
|
92
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} catch (err) {
|
|
96
|
+
// Fail silently in hooks
|
|
97
|
+
}
|
|
98
|
+
process.exit(0);
|
|
99
|
+
}
|
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Stop Gate (Stop hook - Claude Code only)
|
|
4
|
-
* The pre-delivery gate (verification-loop) was prose-only, and prose decays
|
|
5
|
-
* as context grows. This makes the one check that matters mechanical: ending
|
|
6
|
-
* the turn with edits that were never followed by a successful
|
|
7
|
-
* verification-ish command (test/build/lint - tracked by state-persist.js)
|
|
8
|
-
* while uncommitted changes sit in the tree gets bounced back ONCE per edit
|
|
9
|
-
* batch. Objective facts only; fails open on any error.
|
|
10
|
-
*/
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
const path = require('path');
|
|
13
|
-
const { execSync } = require('child_process');
|
|
14
|
-
const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
|
|
15
|
-
|
|
16
|
-
function decide(payload) {
|
|
17
|
-
try {
|
|
18
|
-
// Loop guard: if this stop already resulted from a Stop-hook block,
|
|
19
|
-
// always let it through - one bounce is the contract, never a cage.
|
|
20
|
-
if (payload && payload.stop_hook_active) {
|
|
21
|
-
process.exit(0);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const root = getWorkspaceRoot();
|
|
25
|
-
const sessionDir = getSessionDir(root, payload && payload.session_id);
|
|
26
|
-
const handoffFile = path.join(sessionDir, 'handoff-state.json');
|
|
27
|
-
const gateFile = path.join(sessionDir, 'stop-gate-state.json');
|
|
28
|
-
|
|
29
|
-
if (!fs.existsSync(handoffFile)) process.exit(0);
|
|
30
|
-
const handoff = JSON.parse(fs.readFileSync(handoffFile, 'utf8'));
|
|
31
|
-
const lastEditAt = handoff.lastEditAt || 0;
|
|
32
|
-
const lastVerifyAt = handoff.lastVerifyAt || 0;
|
|
33
|
-
|
|
34
|
-
// No edits this session, or verification already ran after the last edit.
|
|
35
|
-
if (!lastEditAt || lastVerifyAt >= lastEditAt) process.exit(0);
|
|
36
|
-
|
|
37
|
-
// One bounce per edit batch: if we already blocked for this exact edit
|
|
38
|
-
// timestamp, the model either verified (which moves lastVerifyAt) or
|
|
39
|
-
// explicitly chose not to - don't nag twice for the same batch.
|
|
40
|
-
let gate = {};
|
|
41
|
-
if (fs.existsSync(gateFile)) {
|
|
42
|
-
try { gate = JSON.parse(fs.readFileSync(gateFile, 'utf8')); } catch (e) { /* ignore */ }
|
|
43
|
-
}
|
|
44
|
-
if (gate.blockedForEditAt === lastEditAt) process.exit(0);
|
|
45
|
-
|
|
46
|
-
// Only relevant when unverified work is actually sitting in the tree.
|
|
47
|
-
const dirty = execSync('git status --porcelain', {
|
|
48
|
-
cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore']
|
|
49
|
-
}).trim();
|
|
50
|
-
if (!dirty) process.exit(0);
|
|
51
|
-
|
|
52
|
-
fs.writeFileSync(gateFile, JSON.stringify({ blockedForEditAt: lastEditAt }, null, 2), 'utf8');
|
|
53
|
-
|
|
54
|
-
console.error(`[Stop Gate] Turn is ending with uncommitted edits and no successful verification command (test/build/lint) since the last edit.`);
|
|
55
|
-
console.error(`Before delivering: run the relevant check from 'verification-loop' - even a single targeted test beats none.`);
|
|
56
|
-
console.error(`If verification is genuinely not applicable (docs-only change, analysis-only turn, the Human Partner told you to stop), state that explicitly in your reply and stop again.`);
|
|
57
|
-
console.error(`This gate bounces at most once per edit batch.`);
|
|
58
|
-
process.exit(2);
|
|
59
|
-
} catch (err) {
|
|
60
|
-
// Fail open - a broken gate must never trap the session.
|
|
61
|
-
process.exit(0);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
let inputData = '';
|
|
66
|
-
const timeout = setTimeout(() => {
|
|
67
|
-
decide(null);
|
|
68
|
-
}, 200);
|
|
69
|
-
|
|
70
|
-
process.stdin.on('data', chunk => { inputData += chunk; });
|
|
71
|
-
process.stdin.on('end', () => {
|
|
72
|
-
clearTimeout(timeout);
|
|
73
|
-
let payload = null;
|
|
74
|
-
try { payload = JSON.parse(inputData.trim()); } catch (err) { /* no payload */ }
|
|
75
|
-
decide(payload);
|
|
76
|
-
});
|
|
77
|
-
process.stdin.on('error', () => {
|
|
78
|
-
clearTimeout(timeout);
|
|
79
|
-
decide(null);
|
|
80
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Stop Gate (Stop hook - Claude Code only)
|
|
4
|
+
* The pre-delivery gate (verification-loop) was prose-only, and prose decays
|
|
5
|
+
* as context grows. This makes the one check that matters mechanical: ending
|
|
6
|
+
* the turn with edits that were never followed by a successful
|
|
7
|
+
* verification-ish command (test/build/lint - tracked by state-persist.js)
|
|
8
|
+
* while uncommitted changes sit in the tree gets bounced back ONCE per edit
|
|
9
|
+
* batch. Objective facts only; fails open on any error.
|
|
10
|
+
*/
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const { execSync } = require('child_process');
|
|
14
|
+
const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
|
|
15
|
+
|
|
16
|
+
function decide(payload) {
|
|
17
|
+
try {
|
|
18
|
+
// Loop guard: if this stop already resulted from a Stop-hook block,
|
|
19
|
+
// always let it through - one bounce is the contract, never a cage.
|
|
20
|
+
if (payload && payload.stop_hook_active) {
|
|
21
|
+
process.exit(0);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const root = getWorkspaceRoot();
|
|
25
|
+
const sessionDir = getSessionDir(root, payload && payload.session_id);
|
|
26
|
+
const handoffFile = path.join(sessionDir, 'handoff-state.json');
|
|
27
|
+
const gateFile = path.join(sessionDir, 'stop-gate-state.json');
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(handoffFile)) process.exit(0);
|
|
30
|
+
const handoff = JSON.parse(fs.readFileSync(handoffFile, 'utf8'));
|
|
31
|
+
const lastEditAt = handoff.lastEditAt || 0;
|
|
32
|
+
const lastVerifyAt = handoff.lastVerifyAt || 0;
|
|
33
|
+
|
|
34
|
+
// No edits this session, or verification already ran after the last edit.
|
|
35
|
+
if (!lastEditAt || lastVerifyAt >= lastEditAt) process.exit(0);
|
|
36
|
+
|
|
37
|
+
// One bounce per edit batch: if we already blocked for this exact edit
|
|
38
|
+
// timestamp, the model either verified (which moves lastVerifyAt) or
|
|
39
|
+
// explicitly chose not to - don't nag twice for the same batch.
|
|
40
|
+
let gate = {};
|
|
41
|
+
if (fs.existsSync(gateFile)) {
|
|
42
|
+
try { gate = JSON.parse(fs.readFileSync(gateFile, 'utf8')); } catch (e) { /* ignore */ }
|
|
43
|
+
}
|
|
44
|
+
if (gate.blockedForEditAt === lastEditAt) process.exit(0);
|
|
45
|
+
|
|
46
|
+
// Only relevant when unverified work is actually sitting in the tree.
|
|
47
|
+
const dirty = execSync('git status --porcelain', {
|
|
48
|
+
cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore']
|
|
49
|
+
}).trim();
|
|
50
|
+
if (!dirty) process.exit(0);
|
|
51
|
+
|
|
52
|
+
fs.writeFileSync(gateFile, JSON.stringify({ blockedForEditAt: lastEditAt }, null, 2), 'utf8');
|
|
53
|
+
|
|
54
|
+
console.error(`[Stop Gate] Turn is ending with uncommitted edits and no successful verification command (test/build/lint) since the last edit.`);
|
|
55
|
+
console.error(`Before delivering: run the relevant check from 'verification-loop' - even a single targeted test beats none.`);
|
|
56
|
+
console.error(`If verification is genuinely not applicable (docs-only change, analysis-only turn, the Human Partner told you to stop), state that explicitly in your reply and stop again.`);
|
|
57
|
+
console.error(`This gate bounces at most once per edit batch.`);
|
|
58
|
+
process.exit(2);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
// Fail open - a broken gate must never trap the session.
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let inputData = '';
|
|
66
|
+
const timeout = setTimeout(() => {
|
|
67
|
+
decide(null);
|
|
68
|
+
}, 200);
|
|
69
|
+
|
|
70
|
+
process.stdin.on('data', chunk => { inputData += chunk; });
|
|
71
|
+
process.stdin.on('end', () => {
|
|
72
|
+
clearTimeout(timeout);
|
|
73
|
+
let payload = null;
|
|
74
|
+
try { payload = JSON.parse(inputData.trim()); } catch (err) { /* no payload */ }
|
|
75
|
+
decide(payload);
|
|
76
|
+
});
|
|
77
|
+
process.stdin.on('error', () => {
|
|
78
|
+
clearTimeout(timeout);
|
|
79
|
+
decide(null);
|
|
80
|
+
});
|
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Subagent Scope Guard (PreToolUse + PostToolUse: Task)
|
|
4
|
-
* Grounded in a real incident: a subagent briefed as "read-only, verify and
|
|
5
|
-
* report a verdict" still had full tool access by default and made
|
|
6
|
-
* substantial unrequested edits (a GitBook restructure, ~115 deleted lines)
|
|
7
|
-
* in a large parallel fan-out. It was only caught because someone happened
|
|
8
|
-
* to run `git status` on the whole repo afterward.
|
|
9
|
-
*
|
|
10
|
-
* This hook makes that check automatic instead of relying on remembering to
|
|
11
|
-
* do it: PreToolUse snapshots `git status --porcelain` the first time a Task
|
|
12
|
-
* spawn starts (shared baseline across any parallel/nested Task calls in the
|
|
13
|
-
* same burst), PostToolUse diffs the current status against that baseline
|
|
14
|
-
* and surfaces every changed file - not just the ones the task was expected
|
|
15
|
-
* to touch, since "expected" can't be reliably inferred from a natural-
|
|
16
|
-
* language task brief. It cannot block (the subagent already ran), only
|
|
17
|
-
* makes the diff impossible to miss.
|
|
18
|
-
* Fails open on any error - this is visibility, not a hard gate.
|
|
19
|
-
*/
|
|
20
|
-
const { execSync } = require('child_process');
|
|
21
|
-
const fs = require('fs');
|
|
22
|
-
const path = require('path');
|
|
23
|
-
const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
|
|
24
|
-
|
|
25
|
-
function gitStatus(root) {
|
|
26
|
-
try {
|
|
27
|
-
return execSync('git status --porcelain', { cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
28
|
-
} catch (err) {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let inputData = '';
|
|
34
|
-
process.stdin.on('data', chunk => { inputData += chunk; });
|
|
35
|
-
process.stdin.on('end', () => {
|
|
36
|
-
try {
|
|
37
|
-
const payload = JSON.parse(inputData);
|
|
38
|
-
if (payload.tool_name !== 'Task') process.exit(0);
|
|
39
|
-
|
|
40
|
-
const root = getWorkspaceRoot();
|
|
41
|
-
const stateFile = path.join(getSessionDir(root, payload.session_id), 'subagent-scope-state.json');
|
|
42
|
-
|
|
43
|
-
if (payload.hook_event_name === 'PreToolUse') {
|
|
44
|
-
// Only set the baseline if one isn't already pending - parallel/nested
|
|
45
|
-
// Task calls in the same burst share it, so the eventual diff covers
|
|
46
|
-
// everything the whole burst touched, not just the last one.
|
|
47
|
-
if (!fs.existsSync(stateFile)) {
|
|
48
|
-
const status = gitStatus(root);
|
|
49
|
-
if (status !== null) {
|
|
50
|
-
fs.writeFileSync(stateFile, JSON.stringify({ baseline: status }, null, 2), 'utf8');
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
process.exit(0);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (payload.hook_event_name === 'PostToolUse') {
|
|
57
|
-
if (!fs.existsSync(stateFile)) process.exit(0);
|
|
58
|
-
|
|
59
|
-
const { baseline } = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
|
|
60
|
-
const current = gitStatus(root);
|
|
61
|
-
if (current === null) process.exit(0);
|
|
62
|
-
|
|
63
|
-
const baselineLines = new Set(baseline.split('\n').filter(Boolean));
|
|
64
|
-
const currentLines = current.split('\n').filter(Boolean);
|
|
65
|
-
const newlyChanged = currentLines.filter(line => !baselineLines.has(line));
|
|
66
|
-
|
|
67
|
-
if (newlyChanged.length > 0) {
|
|
68
|
-
console.error(`[Subagent Scope Guard] ${newlyChanged.length} file(s) changed since this Task burst started:`);
|
|
69
|
-
newlyChanged.forEach(line => console.error(` ${line}`));
|
|
70
|
-
console.error(`Confirm every one of these was actually in scope before trusting or committing this output.`);
|
|
71
|
-
console.error(`Do not "git add -A" - stage files explicitly by path so anything unexpected here stays visible.`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Roll the baseline forward so the next Task burst only reports what's
|
|
75
|
-
// new since this report, not the same files over and over.
|
|
76
|
-
fs.writeFileSync(stateFile, JSON.stringify({ baseline: current }, null, 2), 'utf8');
|
|
77
|
-
|
|
78
|
-
if (newlyChanged.length > 0) {
|
|
79
|
-
process.exit(2);
|
|
80
|
-
}
|
|
81
|
-
process.exit(0);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
process.exit(0);
|
|
85
|
-
} catch (err) {
|
|
86
|
-
process.exit(0);
|
|
87
|
-
}
|
|
88
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Subagent Scope Guard (PreToolUse + PostToolUse: Task)
|
|
4
|
+
* Grounded in a real incident: a subagent briefed as "read-only, verify and
|
|
5
|
+
* report a verdict" still had full tool access by default and made
|
|
6
|
+
* substantial unrequested edits (a GitBook restructure, ~115 deleted lines)
|
|
7
|
+
* in a large parallel fan-out. It was only caught because someone happened
|
|
8
|
+
* to run `git status` on the whole repo afterward.
|
|
9
|
+
*
|
|
10
|
+
* This hook makes that check automatic instead of relying on remembering to
|
|
11
|
+
* do it: PreToolUse snapshots `git status --porcelain` the first time a Task
|
|
12
|
+
* spawn starts (shared baseline across any parallel/nested Task calls in the
|
|
13
|
+
* same burst), PostToolUse diffs the current status against that baseline
|
|
14
|
+
* and surfaces every changed file - not just the ones the task was expected
|
|
15
|
+
* to touch, since "expected" can't be reliably inferred from a natural-
|
|
16
|
+
* language task brief. It cannot block (the subagent already ran), only
|
|
17
|
+
* makes the diff impossible to miss.
|
|
18
|
+
* Fails open on any error - this is visibility, not a hard gate.
|
|
19
|
+
*/
|
|
20
|
+
const { execSync } = require('child_process');
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
|
|
24
|
+
|
|
25
|
+
function gitStatus(root) {
|
|
26
|
+
try {
|
|
27
|
+
return execSync('git status --porcelain', { cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
28
|
+
} catch (err) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let inputData = '';
|
|
34
|
+
process.stdin.on('data', chunk => { inputData += chunk; });
|
|
35
|
+
process.stdin.on('end', () => {
|
|
36
|
+
try {
|
|
37
|
+
const payload = JSON.parse(inputData);
|
|
38
|
+
if (payload.tool_name !== 'Task') process.exit(0);
|
|
39
|
+
|
|
40
|
+
const root = getWorkspaceRoot();
|
|
41
|
+
const stateFile = path.join(getSessionDir(root, payload.session_id), 'subagent-scope-state.json');
|
|
42
|
+
|
|
43
|
+
if (payload.hook_event_name === 'PreToolUse') {
|
|
44
|
+
// Only set the baseline if one isn't already pending - parallel/nested
|
|
45
|
+
// Task calls in the same burst share it, so the eventual diff covers
|
|
46
|
+
// everything the whole burst touched, not just the last one.
|
|
47
|
+
if (!fs.existsSync(stateFile)) {
|
|
48
|
+
const status = gitStatus(root);
|
|
49
|
+
if (status !== null) {
|
|
50
|
+
fs.writeFileSync(stateFile, JSON.stringify({ baseline: status }, null, 2), 'utf8');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (payload.hook_event_name === 'PostToolUse') {
|
|
57
|
+
if (!fs.existsSync(stateFile)) process.exit(0);
|
|
58
|
+
|
|
59
|
+
const { baseline } = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
|
|
60
|
+
const current = gitStatus(root);
|
|
61
|
+
if (current === null) process.exit(0);
|
|
62
|
+
|
|
63
|
+
const baselineLines = new Set(baseline.split('\n').filter(Boolean));
|
|
64
|
+
const currentLines = current.split('\n').filter(Boolean);
|
|
65
|
+
const newlyChanged = currentLines.filter(line => !baselineLines.has(line));
|
|
66
|
+
|
|
67
|
+
if (newlyChanged.length > 0) {
|
|
68
|
+
console.error(`[Subagent Scope Guard] ${newlyChanged.length} file(s) changed since this Task burst started:`);
|
|
69
|
+
newlyChanged.forEach(line => console.error(` ${line}`));
|
|
70
|
+
console.error(`Confirm every one of these was actually in scope before trusting or committing this output.`);
|
|
71
|
+
console.error(`Do not "git add -A" - stage files explicitly by path so anything unexpected here stays visible.`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Roll the baseline forward so the next Task burst only reports what's
|
|
75
|
+
// new since this report, not the same files over and over.
|
|
76
|
+
fs.writeFileSync(stateFile, JSON.stringify({ baseline: current }, null, 2), 'utf8');
|
|
77
|
+
|
|
78
|
+
if (newlyChanged.length > 0) {
|
|
79
|
+
process.exit(2);
|
|
80
|
+
}
|
|
81
|
+
process.exit(0);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
process.exit(0);
|
|
85
|
+
} catch (err) {
|
|
86
|
+
process.exit(0);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
@@ -1,44 +1,40 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: improve-codebase-architecture
|
|
3
|
-
description: Discovers and transforms shallow modules into deep ones
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
| **
|
|
17
|
-
| **
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- `improve-codebase-architecture/guides/DEEPENING.md` — Deepening opportunities & modular depth rules
|
|
42
|
-
- `improve-codebase-architecture/guides/INTERFACE-DESIGN.md` — Principles of interface design and seams
|
|
43
|
-
- `improve-codebase-architecture/guides/LANGUAGE.md` — Language-specific refactoring and pattern guidelines
|
|
44
|
-
- `improve-codebase-architecture/guides/HTML-REPORT.md` — Creating visual reports with Mermaid diagrams
|
|
1
|
+
---
|
|
2
|
+
name: improve-codebase-architecture
|
|
3
|
+
description: Discovers and transforms shallow or bloated modules into deep, SRP-compliant ones by splitting oversized objects/functions, extracting seams, and decoupling interfaces.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: Miya Daniel
|
|
7
|
+
version: 0.3.6
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Improve Codebase Architecture (Deep & SRP Refactoring)
|
|
11
|
+
|
|
12
|
+
## 📋 Skill Contract
|
|
13
|
+
|
|
14
|
+
| Component | Specification |
|
|
15
|
+
| :--- | :--- |
|
|
16
|
+
| **Trigger / Input** | "refactor architecture", "split object/class", "apply SRP", tech debt |
|
|
17
|
+
| **Expected Output** | SRP proposal, Characterization Test safety net, TDD-guided extraction. |
|
|
18
|
+
| **State Mutations** | Extracts classes/functions/objects; adds characterization tests. |
|
|
19
|
+
| **Enforcement Gate** | Scan docs first; Characterization Tests before refactoring untested code; >3 cascading errors → rollback + `zoom-out`. |
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
1. `[Discover]`: no blind refactoring — scan `CONTEXT.md`, `docs/adr/`, core interfaces first. Targets: SRP violations (>300 lines / >10 complexity), shallow modules, coupled seams.
|
|
24
|
+
2. `[Think]`: present the Deepening & SRP proposal (object splitting + seam abstraction) until approved.
|
|
25
|
+
3. `[Try]`: launch `tdd`; Characterization Tests first if legacy code lacks tests; extract incrementally, verifying tests after each change.
|
|
26
|
+
4. `[Summarize]`/`[Self-Evolve]`: >3 cascading errors → rollback + `zoom-out`; record traps in `self-evolve`.
|
|
27
|
+
|
|
28
|
+
Guides: `improve-codebase-architecture/guides/DEEPENING.md`, `improve-codebase-architecture/guides/INTERFACE-DESIGN.md`, `improve-codebase-architecture/guides/LANGUAGE.md`, `improve-codebase-architecture/guides/HTML-REPORT.md`.
|
|
29
|
+
|
|
30
|
+
## USE FOR:
|
|
31
|
+
- "refactor this architecture"
|
|
32
|
+
- "split this oversized class"
|
|
33
|
+
- "apply SRP here"
|
|
34
|
+
- "decouple these modules"
|
|
35
|
+
|
|
36
|
+
## DO NOT USE FOR:
|
|
37
|
+
- Features or bugfixes (use `tdd`)
|
|
38
|
+
- Style-only cleanups with no structure change
|
|
39
|
+
|
|
40
|
+
Deep dive: guides/refactoring-workflow.md
|