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.
Files changed (494) hide show
  1. package/.claude-plugin/marketplace.json +27 -0
  2. package/.claude-plugin/plugin.json +51 -0
  3. package/.gitattributes +1 -0
  4. package/.github/workflows/behavioral-evals.yml +36 -0
  5. package/.github/workflows/ci.yml +117 -0
  6. package/.github/workflows/release.yml +45 -0
  7. package/.husky/commit-msg +1 -0
  8. package/.waza.yaml +22 -0
  9. package/AGENTS.md +60 -2
  10. package/BENCHMARK_SOP.md +62 -62
  11. package/CHANGELOG.md +297 -114
  12. package/CODE_OF_CONDUCT.md +24 -0
  13. package/CONTRIBUTING.md +47 -0
  14. package/Dockerfile +18 -18
  15. package/LICENSE +201 -201
  16. package/README.md +279 -197
  17. package/SECURITY.md +33 -0
  18. package/VERIFICATION.md +394 -347
  19. package/ab-test-deep-analysis-2026-08-27.md +383 -0
  20. package/ab-test-results-2026-08-27.md +152 -0
  21. package/ab-test-statistical-analysis-31cases.md +193 -0
  22. package/behavioral-evals/README.md +85 -0
  23. package/behavioral-evals/analyze-plugin-results.js +110 -0
  24. package/behavioral-evals/cases/baseline-add-feature.yaml +34 -0
  25. package/behavioral-evals/cases/baseline-api-design.yaml +32 -0
  26. package/behavioral-evals/cases/baseline-debugging.yaml +31 -0
  27. package/behavioral-evals/cases/baseline-dependency.yaml +24 -0
  28. package/behavioral-evals/cases/baseline-documentation.yaml +34 -0
  29. package/behavioral-evals/cases/baseline-error-handling.yaml +31 -0
  30. package/behavioral-evals/cases/baseline-git-commit.yaml +33 -0
  31. package/behavioral-evals/cases/baseline-performance-monitoring.yaml +28 -0
  32. package/behavioral-evals/cases/baseline-performance.yaml +34 -0
  33. package/behavioral-evals/cases/baseline-refactor-with-tests.yaml +35 -0
  34. package/behavioral-evals/cases/baseline-refactor.yaml +27 -0
  35. package/behavioral-evals/cases/baseline-security-review.yaml +28 -0
  36. package/behavioral-evals/cases/baseline-simple-bugfix.yaml +33 -0
  37. package/behavioral-evals/cases/baseline-tdd-workflow.yaml +28 -0
  38. package/behavioral-evals/cases/breaker-zoom-out-after-3.yaml +50 -0
  39. package/behavioral-evals/cases/pressure-budget-skip-review.yaml +27 -0
  40. package/behavioral-evals/cases/pressure-bypass-review.yaml +27 -0
  41. package/behavioral-evals/cases/pressure-complexity-skip.yaml +37 -0
  42. package/behavioral-evals/cases/pressure-expert-skip-testing.yaml +31 -0
  43. package/behavioral-evals/cases/pressure-fatigue-skip.yaml +33 -0
  44. package/behavioral-evals/cases/pressure-management-skip-all.yaml +28 -0
  45. package/behavioral-evals/cases/pressure-scope-bypass.yaml +28 -0
  46. package/behavioral-evals/cases/pressure-skip-docs.yaml +50 -0
  47. package/behavioral-evals/cases/pressure-skip-error-handling.yaml +35 -0
  48. package/behavioral-evals/cases/pressure-skip-security.yaml +32 -0
  49. package/behavioral-evals/cases/pressure-skip-tests.yaml +27 -0
  50. package/behavioral-evals/cases/pressure-skip-verification.yaml +43 -0
  51. package/behavioral-evals/cases/pressure-social-skip-review.yaml +28 -0
  52. package/behavioral-evals/cases/pressure-sunk-cost-retry.yaml +47 -0
  53. package/behavioral-evals/cases/scope-discipline.yaml +32 -0
  54. package/behavioral-evals/cases/tier1-no-overplan.yaml +26 -0
  55. package/behavioral-evals/cases/verify-before-done.yaml +31 -0
  56. package/behavioral-evals/results/.gitkeep +0 -0
  57. package/behavioral-evals/results/2026-08-23-breaker-zoom-out-after-3.json +20 -0
  58. package/behavioral-evals/results/2026-08-23-pressure-skip-verification.json +20 -0
  59. package/behavioral-evals/results/2026-08-23-pressure-sunk-cost-retry.json +20 -0
  60. package/behavioral-evals/results/2026-08-23-scope-discipline.json +16 -0
  61. package/behavioral-evals/results/2026-08-23-tier1-no-overplan.json +20 -0
  62. package/behavioral-evals/results/2026-08-23-verify-before-done.json +20 -0
  63. package/behavioral-evals/results/2026-08-27-baseline-add-feature.json +20 -0
  64. package/behavioral-evals/results/2026-08-27-baseline-api-design.json +20 -0
  65. package/behavioral-evals/results/2026-08-27-baseline-debugging.json +20 -0
  66. package/behavioral-evals/results/2026-08-27-baseline-dependency.json +16 -0
  67. package/behavioral-evals/results/2026-08-27-baseline-documentation.json +20 -0
  68. package/behavioral-evals/results/2026-08-27-baseline-error-handling.json +20 -0
  69. package/behavioral-evals/results/2026-08-27-baseline-git-commit.json +20 -0
  70. package/behavioral-evals/results/2026-08-27-baseline-performance-monitoring.json +20 -0
  71. package/behavioral-evals/results/2026-08-27-baseline-performance.json +20 -0
  72. package/behavioral-evals/results/2026-08-27-baseline-refactor-with-tests.json +20 -0
  73. package/behavioral-evals/results/2026-08-27-baseline-refactor.json +20 -0
  74. package/behavioral-evals/results/2026-08-27-baseline-security-review.json +20 -0
  75. package/behavioral-evals/results/2026-08-27-baseline-simple-bugfix.json +20 -0
  76. package/behavioral-evals/results/2026-08-27-baseline-tdd-workflow.json +24 -0
  77. package/behavioral-evals/results/2026-08-27-breaker-zoom-out-after-3.json +20 -0
  78. package/behavioral-evals/results/2026-08-27-pressure-budget-skip-review.json +16 -0
  79. package/behavioral-evals/results/2026-08-27-pressure-bypass-review.json +20 -0
  80. package/behavioral-evals/results/2026-08-27-pressure-complexity-skip.json +20 -0
  81. package/behavioral-evals/results/2026-08-27-pressure-expert-skip-testing.json +16 -0
  82. package/behavioral-evals/results/2026-08-27-pressure-fatigue-skip.json +16 -0
  83. package/behavioral-evals/results/2026-08-27-pressure-management-skip-all.json +20 -0
  84. package/behavioral-evals/results/2026-08-27-pressure-skip-docs.json +20 -0
  85. package/behavioral-evals/results/2026-08-27-pressure-skip-error-handling.json +20 -0
  86. package/behavioral-evals/results/2026-08-27-pressure-skip-security.json +20 -0
  87. package/behavioral-evals/results/2026-08-27-pressure-skip-tests.json +20 -0
  88. package/behavioral-evals/results/2026-08-27-pressure-skip-verification.json +24 -0
  89. package/behavioral-evals/results/2026-08-27-pressure-social-skip-review.json +20 -0
  90. package/behavioral-evals/results/2026-08-27-pressure-sunk-cost-retry.json +24 -0
  91. package/behavioral-evals/results/2026-08-27-scope-discipline.json +16 -0
  92. package/behavioral-evals/results/2026-08-27-tier1-no-overplan.json +20 -0
  93. package/behavioral-evals/results/2026-08-27-verify-before-done.json +20 -0
  94. package/behavioral-evals/results/run-20260827-115509.log +287 -0
  95. package/behavioral-evals/run-with-plugin.js +316 -0
  96. package/behavioral-evals/run.js +587 -0
  97. package/benchmarks/README.md +63 -0
  98. package/benchmarks/ab-test-2026-08-26/results.json +55 -0
  99. package/benchmarks/results/logs/.gitkeep +0 -0
  100. package/benchmarks/results/logs/test-a-harness.md +31 -0
  101. package/benchmarks/results/logs/test-a-vanilla.md +28 -0
  102. package/benchmarks/results/logs/test-b-micro-loop-harness.md +48 -0
  103. package/benchmarks/results/logs/test-b-micro-loop-vanilla.md +36 -0
  104. package/benchmarks/results/logs/test-c-attention-loss-harness.md +40 -0
  105. package/benchmarks/results/logs/test-c-attention-loss-vanilla.md +63 -0
  106. package/benchmarks/results/logs/test-d-knowledge-boundary-harness.md +24 -0
  107. package/benchmarks/results/logs/test-d-knowledge-boundary-vanilla.md +29 -0
  108. package/benchmarks/results/logs/test-e-shell-awareness-harness.md +20 -0
  109. package/benchmarks/results/logs/test-e-shell-awareness-vanilla.md +20 -0
  110. package/benchmarks/results/logs/test-f-fact-audit-harness.md +16 -0
  111. package/benchmarks/results/logs/test-f-fact-audit-vanilla.md +16 -0
  112. package/benchmarks/results/results.json +158 -0
  113. package/benchmarks/run.js +220 -0
  114. package/benchmarks/schema.json +44 -0
  115. package/bin/cli.js +152 -97
  116. package/ci/ab-test-cases/grill-me-adversarial.yaml +18 -0
  117. package/ci/ab-test-cases/tdd-test-first.yaml +23 -0
  118. package/ci/ab-test-cases/verification-loop-gates.yaml +25 -0
  119. package/ci/ab-test-cases/verify-before-claim-cites.yaml +18 -0
  120. package/ci/ab-test-harness.js +410 -0
  121. package/{eval-framework → ci}/cases/case1.json +5 -5
  122. package/ci/cases/case10-small-feature.json +5 -0
  123. package/ci/cases/case11-readme-typo-update.json +5 -0
  124. package/ci/cases/case12-chinese-macro-audit.json +5 -0
  125. package/{eval-framework → ci}/cases/case2.json +5 -5
  126. package/{eval-framework → ci}/cases/case3.json +5 -5
  127. package/{eval-framework → ci}/cases/case4-zh-tier2.json +5 -5
  128. package/{eval-framework → ci}/cases/case5-zh-tier3.json +5 -5
  129. package/ci/cases/case6-macro-skill-audit.json +5 -0
  130. package/ci/cases/case7-macro-reference-audit.json +5 -0
  131. package/ci/cases/case8-controlled-ab-benchmark.json +5 -0
  132. package/ci/cases/case9-four-issue-audit.json +5 -0
  133. package/ci/consistency-check.js +347 -0
  134. package/ci/description-collision.js +109 -0
  135. package/ci/fable-mode-test.js +120 -0
  136. package/ci/fixtures/agency-agents/divisions.json +6 -0
  137. package/ci/fixtures/agency-agents/engineering/code-reviewer.md +11 -0
  138. package/ci/fixtures/agency-agents/testing/reality-checker.md +11 -0
  139. package/ci/fixtures/bad-frontmatter-colon/SKILL.md +16 -0
  140. package/ci/fixtures/duplicate-description/skill-a/SKILL.md +16 -0
  141. package/ci/fixtures/duplicate-description/skill-b/SKILL.md +16 -0
  142. package/ci/mechanism-2a-rule-of-3.test.js +46 -0
  143. package/ci/mechanism-2b-boundary-guard.test.js +16 -0
  144. package/ci/mechanism-2c-state-persist.test.js +29 -0
  145. package/ci/mechanism-2d-fact-audit.test.js +18 -0
  146. package/ci/mechanism-2e-scope-guard.test.js +24 -0
  147. package/ci/mechanism-2f-stop-gate.test.js +23 -0
  148. package/ci/mechanism-2g-platform-ignore.test.js +88 -0
  149. package/ci/mechanism-2h-installer-manifest.test.js +147 -0
  150. package/ci/mechanism-2i-crlf-frontmatter.test.js +145 -0
  151. package/ci/mechanism-2i-install-verification.test.js +34 -0
  152. package/ci/mechanism-2j-behavioral-runner.test.js +20 -0
  153. package/ci/mechanism-2k-reference-check.test.js +20 -0
  154. package/ci/mechanism-2l-multi-agent-workspace.test.js +105 -0
  155. package/ci/mechanism-test.js +71 -0
  156. package/ci/negative-controls.js +84 -0
  157. package/ci/reference-check.js +112 -0
  158. package/ci/release-consistency-check.js +123 -0
  159. package/ci/routing-check.js +90 -0
  160. package/{eval-framework → ci}/runner.js +56 -56
  161. package/ci/skill-routing-check.js +98 -0
  162. package/ci/test-helper.js +104 -0
  163. package/ci/test-negative-controls.js +148 -0
  164. package/commitlint.config.js +25 -0
  165. package/docker-verify.sh +266 -266
  166. package/docs/architecture.md +99 -95
  167. package/docs/audit.md +53 -0
  168. package/docs/mechanism-first-skill-mesh.md +163 -0
  169. package/docs/philosophy.md +47 -45
  170. package/docs/reflection.md +48 -34
  171. package/docs/routing.md +58 -45
  172. package/docs/troubleshooting.md +284 -0
  173. package/docs/workflows/environment-detection.md +63 -63
  174. package/docs/workflows/eval-harness.md +64 -57
  175. package/docs/workflows/fable-discipline.md +59 -59
  176. package/docs/workflows/fable-mode.md +12 -15
  177. package/docs/workflows/find-skills.md +36 -0
  178. package/docs/workflows/git-commit.md +71 -62
  179. package/docs/workflows/grill-me.md +62 -62
  180. package/docs/workflows/grill-with-docs.md +69 -62
  181. package/docs/workflows/harness-everything.md +95 -92
  182. package/docs/workflows/improve-codebase-architecture.md +68 -60
  183. package/docs/workflows/install-cognitive-os.md +60 -60
  184. package/docs/workflows/multi-agent-workspace.md +42 -0
  185. package/docs/workflows/repo-docs.md +64 -59
  186. package/docs/workflows/rewrite-commits.md +60 -60
  187. package/docs/workflows/security-review.md +77 -58
  188. package/docs/workflows/self-evolve.md +42 -59
  189. package/docs/workflows/skill-creator.md +80 -75
  190. package/docs/workflows/skill-style.md +64 -64
  191. package/docs/workflows/tdd.md +7 -4
  192. package/docs/workflows/to-spec.md +83 -0
  193. package/docs/workflows/to-tickets.md +80 -0
  194. package/docs/workflows/todo-driven-workflow.md +28 -30
  195. package/docs/workflows/using-git-worktrees.md +67 -63
  196. package/docs/workflows/verification-loop.md +71 -69
  197. package/docs/workflows/verify-before-claim.md +64 -60
  198. package/docs/workflows/zoom-out.md +74 -62
  199. package/environment-detection/SKILL.md +41 -77
  200. package/environment-detection/references/shell-syntax-rules.md +76 -0
  201. package/environment-detection/scripts/preflight.js +103 -93
  202. package/eval-framework/fixtures/bad-frontmatter-colon/SKILL.md +14 -0
  203. package/eval-framework/fixtures/duplicate-desc-skill-a/SKILL.md +14 -0
  204. package/eval-framework/fixtures/duplicate-desc-skill-b/SKILL.md +14 -0
  205. package/eval-framework/fixtures/missing-delimiter/SKILL.md +13 -0
  206. package/eval-framework/fixtures/over-budget-skill/SKILL.md +36 -0
  207. package/eval-harness/SKILL.md +42 -59
  208. package/eval-harness/references/scoring-rubric.md +68 -0
  209. package/eval-harness/scripts/evaluate.js +77 -61
  210. package/evals/environment-detection/eval.yaml +26 -0
  211. package/evals/environment-detection/tasks/negative-trigger.yaml +16 -0
  212. package/evals/environment-detection/tasks/positive-trigger.yaml +15 -0
  213. package/evals/eval-harness/eval.yaml +26 -0
  214. package/evals/eval-harness/tasks/negative-trigger.yaml +16 -0
  215. package/evals/eval-harness/tasks/positive-trigger.yaml +15 -0
  216. package/evals/fable-discipline/eval.yaml +26 -0
  217. package/evals/fable-discipline/tasks/negative-trigger.yaml +16 -0
  218. package/evals/fable-discipline/tasks/positive-trigger.yaml +15 -0
  219. package/evals/fable-mode/eval.yaml +26 -0
  220. package/evals/fable-mode/tasks/negative-tier2-no-model.yaml +18 -0
  221. package/evals/fable-mode/tasks/negative-trigger.yaml +16 -0
  222. package/evals/fable-mode/tasks/positive-haiku-mode.yaml +16 -0
  223. package/evals/fable-mode/tasks/positive-opus-mode.yaml +16 -0
  224. package/evals/fable-mode/tasks/positive-sonnet-mode.yaml +16 -0
  225. package/evals/fable-mode/tasks/positive-trigger.yaml +15 -0
  226. package/evals/find-skills/eval.yaml +26 -0
  227. package/evals/find-skills/tasks/negative-trigger.yaml +16 -0
  228. package/evals/find-skills/tasks/positive-trigger.yaml +15 -0
  229. package/evals/git-commit/eval.yaml +26 -0
  230. package/evals/git-commit/tasks/negative-trigger.yaml +16 -0
  231. package/evals/git-commit/tasks/positive-trigger.yaml +15 -0
  232. package/evals/grill-me/eval.yaml +26 -0
  233. package/evals/grill-me/tasks/negative-trigger.yaml +16 -0
  234. package/evals/grill-me/tasks/positive-trigger.yaml +15 -0
  235. package/evals/grill-with-docs/eval.yaml +26 -0
  236. package/evals/grill-with-docs/tasks/negative-trigger.yaml +16 -0
  237. package/evals/grill-with-docs/tasks/positive-trigger.yaml +15 -0
  238. package/evals/harness-everything/eval.yaml +26 -0
  239. package/evals/harness-everything/tasks/negative-non-software.yaml +16 -0
  240. package/evals/harness-everything/tasks/negative-skill-indicated.yaml +15 -0
  241. package/evals/harness-everything/tasks/positive-tier1.yaml +16 -0
  242. package/evals/harness-everything/tasks/positive-tier2.yaml +16 -0
  243. package/evals/harness-everything/tasks/positive-tier3.yaml +16 -0
  244. package/evals/improve-codebase-architecture/eval.yaml +26 -0
  245. package/evals/improve-codebase-architecture/tasks/negative-trigger.yaml +16 -0
  246. package/evals/improve-codebase-architecture/tasks/positive-trigger.yaml +15 -0
  247. package/evals/install-cognitive-os/eval.yaml +26 -0
  248. package/evals/install-cognitive-os/tasks/negative-trigger.yaml +16 -0
  249. package/evals/install-cognitive-os/tasks/positive-trigger.yaml +15 -0
  250. package/evals/multi-agent-workspace/eval.yaml +26 -0
  251. package/evals/multi-agent-workspace/tasks/negative-trigger.yaml +15 -0
  252. package/evals/multi-agent-workspace/tasks/positive-trigger.yaml +15 -0
  253. package/evals/repo-docs/eval.yaml +26 -0
  254. package/evals/repo-docs/tasks/negative-trigger.yaml +16 -0
  255. package/evals/repo-docs/tasks/positive-trigger.yaml +15 -0
  256. package/evals/rewrite-commits/eval.yaml +26 -0
  257. package/evals/rewrite-commits/tasks/negative-trigger.yaml +16 -0
  258. package/evals/rewrite-commits/tasks/positive-trigger.yaml +15 -0
  259. package/evals/security-review/eval.yaml +26 -0
  260. package/evals/security-review/tasks/negative-trigger.yaml +16 -0
  261. package/evals/security-review/tasks/positive-trigger.yaml +15 -0
  262. package/evals/self-evolve/eval.yaml +26 -0
  263. package/evals/self-evolve/tasks/negative-trigger.yaml +16 -0
  264. package/evals/self-evolve/tasks/positive-trigger.yaml +15 -0
  265. package/evals/skill-creator/eval.yaml +26 -0
  266. package/evals/skill-creator/tasks/negative-trigger.yaml +16 -0
  267. package/evals/skill-creator/tasks/positive-trigger.yaml +15 -0
  268. package/evals/skill-style/eval.yaml +26 -0
  269. package/evals/skill-style/tasks/negative-trigger.yaml +16 -0
  270. package/evals/skill-style/tasks/positive-trigger.yaml +15 -0
  271. package/evals/tdd/eval.yaml +26 -0
  272. package/evals/tdd/tasks/negative-trivia.yaml +16 -0
  273. package/evals/tdd/tasks/positive-bugfix.yaml +15 -0
  274. package/evals/tdd/tasks/positive-feature.yaml +16 -0
  275. package/evals/tdd/tasks/positive-refactor.yaml +15 -0
  276. package/evals/to-spec/eval.yaml +26 -0
  277. package/evals/to-spec/tasks/negative-trigger.yaml +16 -0
  278. package/evals/to-spec/tasks/positive-trigger.yaml +15 -0
  279. package/evals/to-tickets/eval.yaml +26 -0
  280. package/evals/to-tickets/tasks/negative-trigger.yaml +15 -0
  281. package/evals/to-tickets/tasks/positive-trigger.yaml +15 -0
  282. package/evals/todo-driven-workflow/eval.yaml +26 -0
  283. package/evals/todo-driven-workflow/tasks/negative-single-edit.yaml +16 -0
  284. package/evals/todo-driven-workflow/tasks/positive-multi-step.yaml +15 -0
  285. package/evals/todo-driven-workflow/tasks/positive-refactor-flow.yaml +15 -0
  286. package/evals/using-git-worktrees/eval.yaml +26 -0
  287. package/evals/using-git-worktrees/tasks/negative-trigger.yaml +15 -0
  288. package/evals/using-git-worktrees/tasks/positive-trigger.yaml +15 -0
  289. package/evals/verification-loop/eval.yaml +26 -0
  290. package/evals/verification-loop/tasks/negative-discussion.yaml +16 -0
  291. package/evals/verification-loop/tasks/positive-pre-ship.yaml +15 -0
  292. package/evals/verify-before-claim/eval.yaml +26 -0
  293. package/evals/verify-before-claim/tasks/negative-trigger.yaml +16 -0
  294. package/evals/verify-before-claim/tasks/positive-trigger.yaml +15 -0
  295. package/evals/zoom-out/eval.yaml +26 -0
  296. package/evals/zoom-out/tasks/negative-trivial-edit.yaml +16 -0
  297. package/evals/zoom-out/tasks/positive-repeated-failure.yaml +15 -0
  298. package/fable-discipline/SKILL.md +41 -38
  299. package/fable-discipline/references/discipline-rules.md +22 -0
  300. package/fable-mode/CONTRACT-FORMAT.md +51 -51
  301. package/fable-mode/SKILL.md +39 -51
  302. package/fable-mode/agents/fable-orchestrator.md +99 -92
  303. package/fable-mode/agents/fable-verifier.md +32 -32
  304. package/fable-mode/agents/fable-worker-haiku.md +52 -48
  305. package/fable-mode/agents/fable-worker-sonnet.md +53 -49
  306. package/fable-mode/execution-guardrails/SKILL.md +43 -87
  307. package/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
  308. package/fable-mode/fable-haiku/SKILL.md +36 -48
  309. package/fable-mode/fable-haiku/references/routing-notes.md +26 -0
  310. package/fable-mode/fable-opus/SKILL.md +36 -0
  311. package/fable-mode/fable-sonnet/SKILL.md +36 -0
  312. package/fable-mode/model-matrix.json +32 -0
  313. package/fable-mode/references/execution-phases.md +37 -0
  314. package/fable-mode/references/model-matrix.md +39 -0
  315. package/fable-mode/scripts/model-selector.js +129 -0
  316. package/find-skills/SKILL.md +48 -0
  317. package/find-skills/references/discovery-flow.md +102 -0
  318. package/find-skills/scripts/use-skill.js +106 -0
  319. package/git-commit/SKILL.md +45 -55
  320. package/git-commit/guides/ANGULAR_STYLE.md +60 -60
  321. package/git-commit/guides/COMMIT_GENERATION.md +23 -23
  322. package/git-commit/guides/LANGUAGE_DETECTION.md +16 -16
  323. package/git-commit/guides/MAIN_REPO.md +14 -14
  324. package/git-commit/guides/SUBMODULES.md +27 -27
  325. package/git-commit/references/commit-flow.md +30 -0
  326. package/grill-me/SKILL.md +43 -36
  327. package/grill-me/references/grilling-playbook.md +38 -0
  328. package/grill-with-docs/ADR-FORMAT.md +47 -47
  329. package/grill-with-docs/CONTEXT-FORMAT.md +63 -63
  330. package/grill-with-docs/SKILL.md +41 -99
  331. package/grill-with-docs/references/session-playbook.md +97 -0
  332. package/harness-everything/SKILL.md +42 -141
  333. package/harness-everything/references/skill-registry.md +39 -0
  334. package/harness-everything/references/triage-and-tiers.md +116 -0
  335. package/harness-everything/scripts/bootstrap.js +203 -140
  336. package/harness-everything/scripts/routing-keywords.json +320 -0
  337. package/harness-everything/scripts/self-heal.js +241 -189
  338. package/harness-everything/scripts/tier-router.js +334 -219
  339. package/harness-everything/scripts/verify-gate.js +87 -18
  340. package/hooks/hooks.json +155 -155
  341. package/hooks/scripts/boundary-guard.js +55 -55
  342. package/hooks/scripts/contract-test.js +79 -79
  343. package/hooks/scripts/depth-guard.js +65 -65
  344. package/hooks/scripts/lib/harness-state.js +139 -228
  345. package/hooks/scripts/lib/platforms/claude.js +185 -42
  346. package/hooks/scripts/lib/platforms/codex.js +114 -46
  347. package/hooks/scripts/lib/platforms/continue.js +91 -41
  348. package/hooks/scripts/lib/platforms/copilot.js +109 -41
  349. package/hooks/scripts/lib/platforms/cursor.js +89 -41
  350. package/hooks/scripts/lib/platforms/hermes.js +57 -32
  351. package/hooks/scripts/lib/platforms/index.js +17 -17
  352. package/hooks/scripts/lib/platforms/worktrees.js +20 -20
  353. package/hooks/scripts/reset-circuit-breaker.js +30 -30
  354. package/hooks/scripts/rule-of-3-tracker.js +124 -91
  355. package/hooks/scripts/rule-of-3.js +14 -3
  356. package/hooks/scripts/state-persist.js +99 -99
  357. package/hooks/scripts/stop-gate.js +80 -80
  358. package/hooks/scripts/subagent-scope-guard.js +88 -88
  359. package/improve-codebase-architecture/SKILL.md +40 -44
  360. package/improve-codebase-architecture/guides/DEEPENING.md +37 -37
  361. package/improve-codebase-architecture/guides/HTML-REPORT.md +123 -123
  362. package/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -44
  363. package/improve-codebase-architecture/guides/LANGUAGE.md +53 -53
  364. package/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
  365. package/install-cognitive-os/SKILL.md +38 -95
  366. package/install-cognitive-os/references/cognitive-loop.md +27 -0
  367. package/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
  368. package/multi-agent-workspace/SKILL.md +37 -0
  369. package/{create-agent-launcher → multi-agent-workspace}/examples/csharp-monorepo.md +123 -123
  370. package/{create-agent-launcher → multi-agent-workspace}/examples/typescript-cli.md +126 -126
  371. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-claude.md +77 -77
  372. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-codex.md +146 -146
  373. package/multi-agent-workspace/guidelines/platform-continue.md +38 -0
  374. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-copilot.md +74 -74
  375. package/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
  376. package/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
  377. package/{create-agent-launcher → multi-agent-workspace}/guidelines/role-capabilities.md +108 -108
  378. package/multi-agent-workspace/references/agency-agents.md +31 -0
  379. package/multi-agent-workspace/references/architecture-guide.md +32 -0
  380. package/multi-agent-workspace/references/orchestration.md +48 -0
  381. package/multi-agent-workspace/scripts/agency-catalog.js +190 -0
  382. package/multi-agent-workspace/scripts/index_memory.js +51 -0
  383. package/multi-agent-workspace/scripts/scaffold.js +253 -0
  384. package/{create-agent-launcher → multi-agent-workspace}/templates/README.md +17 -17
  385. package/{create-agent-launcher → multi-agent-workspace}/templates/agent-launcher.md +67 -67
  386. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-csharp.md +55 -55
  387. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-polyglot.md +61 -61
  388. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-ts.md +56 -56
  389. package/{create-agent-launcher → multi-agent-workspace}/templates/memory-keeper.md +36 -36
  390. package/{create-agent-launcher → multi-agent-workspace}/templates/requirement-analyzer.md +65 -65
  391. package/{create-agent-launcher → multi-agent-workspace}/templates/specialist-agent.md +34 -34
  392. package/{create-agent-launcher → multi-agent-workspace}/templates/task-verifier.md +55 -55
  393. package/{create-agent-launcher → multi-agent-workspace}/templates/tool-maker.md +32 -32
  394. package/multi-agent-workspace/workflows/01-init.md +22 -0
  395. package/multi-agent-workspace/workflows/02-analysis.md +23 -0
  396. package/multi-agent-workspace/workflows/03-generation.md +27 -0
  397. package/multi-agent-workspace/workflows/04-launcher.md +16 -0
  398. package/opencode-plugin/README.md +94 -0
  399. package/opencode-plugin/hooks/circuit-breaker.js +121 -0
  400. package/opencode-plugin/hooks/compliance.js +128 -0
  401. package/opencode-plugin/hooks/post-edit.js +62 -0
  402. package/opencode-plugin/hooks/pre-complete.js +65 -0
  403. package/opencode-plugin/hooks/verify.js +140 -0
  404. package/opencode-plugin/plugin.json +17 -0
  405. package/opencode-plugin/test-hook-firing.js +198 -0
  406. package/package.json +50 -22
  407. package/references/definition-of-done.md +67 -0
  408. package/references/performance-checklist.md +153 -0
  409. package/references/platform-advisory-template.md +58 -0
  410. package/references/security-checklist.md +205 -0
  411. package/repo-docs/SKILL.md +46 -45
  412. package/repo-docs/references/process-guide.md +60 -0
  413. package/repo-docs/templates/agents-template.md +264 -264
  414. package/repo-docs/templates/knowledge-agents-template.md +50 -50
  415. package/repo-docs/templates/knowledge-readme-template.md +83 -83
  416. package/repo-docs/templates/manual-recon.md +117 -117
  417. package/repo-docs/templates/multi-skills-readme-template.md +72 -72
  418. package/repo-docs/templates/product-agents-template.md +78 -78
  419. package/repo-docs/templates/product-readme-template.md +95 -95
  420. package/repo-docs/templates/readme-template.md +136 -136
  421. package/repo-docs/templates/single-skill-readme-template.md +70 -70
  422. package/repo-docs/templates/skills-agents-template.md +60 -60
  423. package/rewrite-commits/SKILL.md +37 -32
  424. package/rewrite-commits/references/workflow.md +18 -0
  425. package/scripts/installer.js +546 -649
  426. package/scripts/lib/advisory-text.js +167 -163
  427. package/scripts/lib/claude-hooks.js +84 -71
  428. package/scripts/lib/gitignore.js +199 -80
  429. package/scripts/lib/manifest.js +146 -82
  430. package/scripts/lib/prompts.js +241 -241
  431. package/scripts/lib/skills.js +260 -172
  432. package/scripts/lib/workspace.js +28 -28
  433. package/scripts/verify-install.js +147 -0
  434. package/security-review/SKILL.md +50 -511
  435. package/security-review/guides/OWASP-PATTERNS.md +31 -0
  436. package/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
  437. package/security-review/references/security-checklist.md +478 -0
  438. package/security-review/scripts/audit-secrets.js +84 -0
  439. package/self-evolve/SKILL.md +47 -54
  440. package/self-evolve/references/memory-resolution.md +58 -0
  441. package/self-evolve/scripts/persist-memory.js +139 -40
  442. package/self-evolve/scripts/register-dynamic-skill.js +251 -0
  443. package/self-evolve/scripts/self-regression.js +110 -113
  444. package/skill-creator/SKILL.md +49 -91
  445. package/skill-creator/references/authoring-workflow.md +14 -0
  446. package/skill-creator/references/dynamic-generation-contract.md +21 -0
  447. package/skill-creator/references/quality-checklist.md +15 -0
  448. package/skill-creator/references/quality-principles.md +81 -81
  449. package/skill-creator/references/testing-workflow.md +20 -25
  450. package/skill-style/SKILL.md +42 -48
  451. package/skill-style/references/style-guide.md +36 -0
  452. package/tdd/SKILL.md +44 -53
  453. package/tdd/guides/deep-modules.md +33 -33
  454. package/tdd/guides/interface-design.md +31 -31
  455. package/tdd/guides/mocking.md +59 -59
  456. package/tdd/guides/refactoring.md +10 -10
  457. package/tdd/guides/tests.md +61 -61
  458. package/tdd/references/core-discipline.md +49 -0
  459. package/to-spec/SKILL.md +42 -0
  460. package/to-spec/references/process.md +77 -0
  461. package/to-spec/scripts/check-project-docs.js +259 -0
  462. package/to-spec/templates/cli-reference.md +31 -0
  463. package/to-spec/templates/dev-doc.md +27 -0
  464. package/to-spec/templates/feature-spec.md +59 -0
  465. package/to-spec/templates/schema-doc.md +31 -0
  466. package/to-tickets/SKILL.md +42 -0
  467. package/to-tickets/references/publishing-and-templates.md +97 -0
  468. package/todo-driven-workflow/SKILL.md +40 -54
  469. package/todo-driven-workflow/references/execution-guide.md +27 -0
  470. package/using-git-worktrees/SKILL.md +49 -161
  471. package/using-git-worktrees/references/workflow-details.md +108 -0
  472. package/verification-loop/SKILL.md +46 -138
  473. package/verification-loop/references/verification-phases.md +116 -0
  474. package/verification-loop/templates/verification-report.template.md +15 -0
  475. package/verify-before-claim/SKILL.md +43 -86
  476. package/verify-before-claim/references/verification-guide.md +73 -0
  477. package/zoom-out/SKILL.md +42 -90
  478. package/zoom-out/references/circuit-breaker.md +66 -0
  479. package/zoom-out/templates/zoom-out-report.template.md +20 -0
  480. package/build-multi-agent-system/AGENTS.md +0 -50
  481. package/build-multi-agent-system/README.md +0 -63
  482. package/build-multi-agent-system/SKILL.md +0 -68
  483. package/create-agent-launcher/SKILL.md +0 -48
  484. package/create-agent-launcher/guidelines/platform-gemini.md +0 -101
  485. package/create-agent-launcher/workflows/01-init.md +0 -22
  486. package/create-agent-launcher/workflows/02-analysis.md +0 -26
  487. package/create-agent-launcher/workflows/03-generation.md +0 -29
  488. package/create-agent-launcher/workflows/04-launcher.md +0 -20
  489. package/docs/workflows/build-multi-agent-system.md +0 -62
  490. package/docs/workflows/create-agent-launcher.md +0 -62
  491. package/eval-framework/behavioral-test.js +0 -105
  492. package/eval-framework/mechanism-test.js +0 -251
  493. package/harness-everything/scripts/todo-cli.js +0 -157
  494. 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
- // Claude Code's documented PostToolUse payload nests tool output under
18
- // tool_response rather than at the top level, and does not guarantee a
19
- // numeric exit code field. Treating a missing/unknown exit code as a
20
- // failure (the old `exitCode !== 0` check) flags every successful call
21
- // as an error. Only count a call as a failure when we have positive
22
- // evidence of one.
23
- const toolResponse = payload.tool_response || {};
24
- const stdout = toolResponse.stdout ?? payload.stdout ?? '';
25
- const stderr = toolResponse.stderr ?? payload.stderr ?? '';
26
- const rawExitCode = toolResponse.exitCode ?? toolResponse.exit_code ?? payload.exitCode;
27
- const exitCode = typeof rawExitCode === 'number' ? rawExitCode : undefined;
28
-
29
- const explicitFailure = exitCode !== undefined && exitCode !== 0;
30
- const explicitSuccess = exitCode === 0;
31
- const stderrSignal = typeof stderr === 'string' && stderr.trim().length > 0;
32
- // Without an exit code, bare stderr is not enough evidence: plenty of
33
- // tools chat on stderr while succeeding (git, npm warnings, progress
34
- // bars), and three identical warnings must not trip the breaker. Require
35
- // the text to actually look like a failure.
36
- const looksLikeError = /\b(error|fail|failed|failure|exception|fatal|panic|traceback|denied|refused|cannot|unable)\b/i.test(stderr);
37
- const isFailure = explicitFailure || (exitCode === undefined && stderrSignal && looksLikeError);
38
- const errorText = (stderrSignal ? stderr : stdout) || '';
39
-
40
- const stateFile = path.join(getSessionDir(getWorkspaceRoot(), payload.session_id), 'rule-of-3-state.json');
41
-
42
- let state = { count: 0, lastHash: null, zoomOutResolved: false, zoomOutCycles: 0, lastFailureAt: 0 };
43
- if (fs.existsSync(stateFile)) {
44
- state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
45
- }
46
-
47
- if (isFailure && errorText) {
48
- // Hash the tail of the error to identify identical loops. Normalize
49
- // first: timestamps, line numbers, addresses and counters vary between
50
- // otherwise-identical failures, and an ever-changing hash would hide a
51
- // genuine loop from the breaker.
52
- const normalized = errorText.slice(-400)
53
- .toLowerCase()
54
- .replace(/0x[0-9a-f]+/g, '#')
55
- .replace(/\d+/g, '#')
56
- .replace(/\s+/g, ' ')
57
- .trim();
58
- const hash = crypto.createHash('md5').update(normalized.slice(-200)).digest('hex');
59
-
60
- if (state.lastHash === hash) {
61
- state.count += 1;
62
- } else {
63
- state.count = 1;
64
- state.lastHash = hash;
65
- // New signature = new problem: the zoom-out cycle budget starts over.
66
- state.zoomOutCycles = 0;
67
- }
68
- // Any fresh failure re-arms the breaker. Without this, a signature that
69
- // failed again after a success (or after a zoom-out release) would keep
70
- // zoomOutResolved=true and the breaker could never trip on it again.
71
- state.zoomOutResolved = false;
72
- // rule-of-3.js only honors a zoom-out report written AFTER this moment,
73
- // so a stale report can't unlock a later trip.
74
- state.lastFailureAt = Date.now();
75
-
76
- fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8');
77
- } else if (explicitSuccess) {
78
- // Only reset on a *confirmed* zero exit code, not merely "not a failure".
79
- if (state.count > 0 || state.zoomOutCycles > 0) {
80
- state.count = 0;
81
- state.zoomOutResolved = true;
82
- state.zoomOutCycles = 0;
83
- fs.writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8');
84
- }
85
- }
86
-
87
- } catch (err) {
88
- // silently fail
89
- }
90
- process.exit(0);
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
- return !!state && state.count >= 3 && !state.zoomOutResolved;
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
- if (payload.tool_name !== 'Write' && payload.tool_name !== 'Edit') return false;
47
- const target = payload.tool_input && payload.tool_input.file_path;
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
  }