harness-everything 0.2.2 → 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 (496) 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 +10 -10
  174. package/docs/workflows/eval-harness.md +13 -6
  175. package/docs/workflows/fable-discipline.md +9 -9
  176. package/docs/workflows/fable-mode.md +29 -32
  177. package/docs/workflows/find-skills.md +36 -0
  178. package/docs/workflows/git-commit.md +18 -9
  179. package/docs/workflows/grill-me.md +11 -11
  180. package/docs/workflows/grill-with-docs.md +14 -7
  181. package/docs/workflows/harness-everything.md +95 -92
  182. package/docs/workflows/improve-codebase-architecture.md +15 -7
  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 +12 -7
  186. package/docs/workflows/security-review.md +26 -7
  187. package/docs/workflows/self-evolve.md +27 -44
  188. package/docs/workflows/skill-creator.md +80 -75
  189. package/docs/workflows/skill-style.md +64 -64
  190. package/docs/workflows/tdd.md +42 -39
  191. package/docs/workflows/to-spec.md +83 -0
  192. package/docs/workflows/to-tickets.md +80 -0
  193. package/docs/workflows/todo-driven-workflow.md +34 -36
  194. package/docs/workflows/using-git-worktrees.md +12 -8
  195. package/docs/workflows/verification-loop.md +16 -14
  196. package/docs/workflows/verify-before-claim.md +12 -8
  197. package/docs/workflows/zoom-out.md +22 -10
  198. package/environment-detection/SKILL.md +25 -61
  199. package/environment-detection/references/shell-syntax-rules.md +76 -0
  200. package/environment-detection/scripts/preflight.js +103 -93
  201. package/eval-framework/fixtures/bad-frontmatter-colon/SKILL.md +14 -0
  202. package/eval-framework/fixtures/duplicate-desc-skill-a/SKILL.md +14 -0
  203. package/eval-framework/fixtures/duplicate-desc-skill-b/SKILL.md +14 -0
  204. package/eval-framework/fixtures/missing-delimiter/SKILL.md +13 -0
  205. package/eval-framework/fixtures/over-budget-skill/SKILL.md +36 -0
  206. package/eval-harness/SKILL.md +34 -51
  207. package/eval-harness/references/scoring-rubric.md +68 -0
  208. package/eval-harness/scripts/evaluate.js +77 -61
  209. package/evals/environment-detection/eval.yaml +26 -0
  210. package/evals/environment-detection/tasks/negative-trigger.yaml +16 -0
  211. package/evals/environment-detection/tasks/positive-trigger.yaml +15 -0
  212. package/evals/eval-harness/eval.yaml +26 -0
  213. package/evals/eval-harness/tasks/negative-trigger.yaml +16 -0
  214. package/evals/eval-harness/tasks/positive-trigger.yaml +15 -0
  215. package/evals/fable-discipline/eval.yaml +26 -0
  216. package/evals/fable-discipline/tasks/negative-trigger.yaml +16 -0
  217. package/evals/fable-discipline/tasks/positive-trigger.yaml +15 -0
  218. package/evals/fable-mode/eval.yaml +26 -0
  219. package/evals/fable-mode/tasks/negative-tier2-no-model.yaml +18 -0
  220. package/evals/fable-mode/tasks/negative-trigger.yaml +16 -0
  221. package/evals/fable-mode/tasks/positive-haiku-mode.yaml +16 -0
  222. package/evals/fable-mode/tasks/positive-opus-mode.yaml +16 -0
  223. package/evals/fable-mode/tasks/positive-sonnet-mode.yaml +16 -0
  224. package/evals/fable-mode/tasks/positive-trigger.yaml +15 -0
  225. package/evals/find-skills/eval.yaml +26 -0
  226. package/evals/find-skills/tasks/negative-trigger.yaml +16 -0
  227. package/evals/find-skills/tasks/positive-trigger.yaml +15 -0
  228. package/evals/git-commit/eval.yaml +26 -0
  229. package/evals/git-commit/tasks/negative-trigger.yaml +16 -0
  230. package/evals/git-commit/tasks/positive-trigger.yaml +15 -0
  231. package/evals/grill-me/eval.yaml +26 -0
  232. package/evals/grill-me/tasks/negative-trigger.yaml +16 -0
  233. package/evals/grill-me/tasks/positive-trigger.yaml +15 -0
  234. package/evals/grill-with-docs/eval.yaml +26 -0
  235. package/evals/grill-with-docs/tasks/negative-trigger.yaml +16 -0
  236. package/evals/grill-with-docs/tasks/positive-trigger.yaml +15 -0
  237. package/evals/harness-everything/eval.yaml +26 -0
  238. package/evals/harness-everything/tasks/negative-non-software.yaml +16 -0
  239. package/evals/harness-everything/tasks/negative-skill-indicated.yaml +15 -0
  240. package/evals/harness-everything/tasks/positive-tier1.yaml +16 -0
  241. package/evals/harness-everything/tasks/positive-tier2.yaml +16 -0
  242. package/evals/harness-everything/tasks/positive-tier3.yaml +16 -0
  243. package/evals/improve-codebase-architecture/eval.yaml +26 -0
  244. package/evals/improve-codebase-architecture/tasks/negative-trigger.yaml +16 -0
  245. package/evals/improve-codebase-architecture/tasks/positive-trigger.yaml +15 -0
  246. package/evals/install-cognitive-os/eval.yaml +26 -0
  247. package/evals/install-cognitive-os/tasks/negative-trigger.yaml +16 -0
  248. package/evals/install-cognitive-os/tasks/positive-trigger.yaml +15 -0
  249. package/evals/multi-agent-workspace/eval.yaml +26 -0
  250. package/evals/multi-agent-workspace/tasks/negative-trigger.yaml +15 -0
  251. package/evals/multi-agent-workspace/tasks/positive-trigger.yaml +15 -0
  252. package/evals/repo-docs/eval.yaml +26 -0
  253. package/evals/repo-docs/tasks/negative-trigger.yaml +16 -0
  254. package/evals/repo-docs/tasks/positive-trigger.yaml +15 -0
  255. package/evals/rewrite-commits/eval.yaml +26 -0
  256. package/evals/rewrite-commits/tasks/negative-trigger.yaml +16 -0
  257. package/evals/rewrite-commits/tasks/positive-trigger.yaml +15 -0
  258. package/evals/security-review/eval.yaml +26 -0
  259. package/evals/security-review/tasks/negative-trigger.yaml +16 -0
  260. package/evals/security-review/tasks/positive-trigger.yaml +15 -0
  261. package/evals/self-evolve/eval.yaml +26 -0
  262. package/evals/self-evolve/tasks/negative-trigger.yaml +16 -0
  263. package/evals/self-evolve/tasks/positive-trigger.yaml +15 -0
  264. package/evals/skill-creator/eval.yaml +26 -0
  265. package/evals/skill-creator/tasks/negative-trigger.yaml +16 -0
  266. package/evals/skill-creator/tasks/positive-trigger.yaml +15 -0
  267. package/evals/skill-style/eval.yaml +26 -0
  268. package/evals/skill-style/tasks/negative-trigger.yaml +16 -0
  269. package/evals/skill-style/tasks/positive-trigger.yaml +15 -0
  270. package/evals/tdd/eval.yaml +26 -0
  271. package/evals/tdd/tasks/negative-trivia.yaml +16 -0
  272. package/evals/tdd/tasks/positive-bugfix.yaml +15 -0
  273. package/evals/tdd/tasks/positive-feature.yaml +16 -0
  274. package/evals/tdd/tasks/positive-refactor.yaml +15 -0
  275. package/evals/to-spec/eval.yaml +26 -0
  276. package/evals/to-spec/tasks/negative-trigger.yaml +16 -0
  277. package/evals/to-spec/tasks/positive-trigger.yaml +15 -0
  278. package/evals/to-tickets/eval.yaml +26 -0
  279. package/evals/to-tickets/tasks/negative-trigger.yaml +15 -0
  280. package/evals/to-tickets/tasks/positive-trigger.yaml +15 -0
  281. package/evals/todo-driven-workflow/eval.yaml +26 -0
  282. package/evals/todo-driven-workflow/tasks/negative-single-edit.yaml +16 -0
  283. package/evals/todo-driven-workflow/tasks/positive-multi-step.yaml +15 -0
  284. package/evals/todo-driven-workflow/tasks/positive-refactor-flow.yaml +15 -0
  285. package/evals/using-git-worktrees/eval.yaml +26 -0
  286. package/evals/using-git-worktrees/tasks/negative-trigger.yaml +15 -0
  287. package/evals/using-git-worktrees/tasks/positive-trigger.yaml +15 -0
  288. package/evals/verification-loop/eval.yaml +26 -0
  289. package/evals/verification-loop/tasks/negative-discussion.yaml +16 -0
  290. package/evals/verification-loop/tasks/positive-pre-ship.yaml +15 -0
  291. package/evals/verify-before-claim/eval.yaml +26 -0
  292. package/evals/verify-before-claim/tasks/negative-trigger.yaml +16 -0
  293. package/evals/verify-before-claim/tasks/positive-trigger.yaml +15 -0
  294. package/evals/zoom-out/eval.yaml +26 -0
  295. package/evals/zoom-out/tasks/negative-trivial-edit.yaml +16 -0
  296. package/evals/zoom-out/tasks/positive-repeated-failure.yaml +15 -0
  297. package/fable-discipline/SKILL.md +31 -28
  298. package/fable-discipline/references/discipline-rules.md +22 -0
  299. package/fable-mode/CONTRACT-FORMAT.md +51 -51
  300. package/fable-mode/SKILL.md +31 -43
  301. package/fable-mode/agents/fable-orchestrator.md +99 -92
  302. package/fable-mode/agents/fable-verifier.md +32 -32
  303. package/fable-mode/agents/fable-worker-haiku.md +52 -48
  304. package/fable-mode/agents/fable-worker-sonnet.md +53 -49
  305. package/fable-mode/execution-guardrails/SKILL.md +43 -87
  306. package/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
  307. package/fable-mode/fable-haiku/SKILL.md +36 -48
  308. package/fable-mode/fable-haiku/references/routing-notes.md +26 -0
  309. package/fable-mode/fable-opus/SKILL.md +36 -0
  310. package/fable-mode/fable-sonnet/SKILL.md +36 -0
  311. package/fable-mode/model-matrix.json +32 -0
  312. package/fable-mode/references/execution-phases.md +37 -0
  313. package/fable-mode/references/model-matrix.md +39 -0
  314. package/fable-mode/scripts/model-selector.js +129 -0
  315. package/find-skills/SKILL.md +48 -0
  316. package/find-skills/references/discovery-flow.md +102 -0
  317. package/find-skills/scripts/use-skill.js +106 -0
  318. package/git-commit/SKILL.md +35 -45
  319. package/git-commit/guides/ANGULAR_STYLE.md +60 -60
  320. package/git-commit/guides/COMMIT_GENERATION.md +23 -23
  321. package/git-commit/guides/LANGUAGE_DETECTION.md +16 -16
  322. package/git-commit/guides/MAIN_REPO.md +14 -14
  323. package/git-commit/guides/SUBMODULES.md +27 -27
  324. package/git-commit/references/commit-flow.md +30 -0
  325. package/grill-me/SKILL.md +34 -27
  326. package/grill-me/references/grilling-playbook.md +38 -0
  327. package/grill-with-docs/ADR-FORMAT.md +47 -47
  328. package/grill-with-docs/CONTEXT-FORMAT.md +63 -63
  329. package/grill-with-docs/SKILL.md +33 -91
  330. package/grill-with-docs/references/session-playbook.md +97 -0
  331. package/harness-everything/SKILL.md +29 -128
  332. package/harness-everything/examples/README.md +9 -9
  333. package/harness-everything/examples/todo-workflow.md +22 -22
  334. package/harness-everything/references/skill-registry.md +39 -0
  335. package/harness-everything/references/triage-and-tiers.md +116 -0
  336. package/harness-everything/scripts/bootstrap.js +203 -140
  337. package/harness-everything/scripts/routing-keywords.json +320 -0
  338. package/harness-everything/scripts/self-heal.js +241 -189
  339. package/harness-everything/scripts/tier-router.js +334 -219
  340. package/harness-everything/scripts/verify-gate.js +100 -31
  341. package/hooks/hooks.json +155 -155
  342. package/hooks/scripts/atomic-commit-check.js +68 -68
  343. package/hooks/scripts/boundary-guard.js +55 -55
  344. package/hooks/scripts/context-compact.js +114 -114
  345. package/hooks/scripts/contract-test.js +79 -79
  346. package/hooks/scripts/depth-guard.js +65 -65
  347. package/hooks/scripts/lib/harness-state.js +139 -228
  348. package/hooks/scripts/lib/platforms/claude.js +72 -19
  349. package/hooks/scripts/lib/platforms/codex.js +24 -6
  350. package/hooks/scripts/lib/platforms/continue.js +23 -5
  351. package/hooks/scripts/lib/platforms/copilot.js +23 -5
  352. package/hooks/scripts/lib/platforms/cursor.js +23 -5
  353. package/hooks/scripts/lib/platforms/hermes.js +57 -57
  354. package/hooks/scripts/lib/platforms/index.js +17 -17
  355. package/hooks/scripts/lib/platforms/worktrees.js +20 -20
  356. package/hooks/scripts/reset-circuit-breaker.js +30 -30
  357. package/hooks/scripts/rule-of-3-tracker.js +124 -91
  358. package/hooks/scripts/rule-of-3.js +187 -176
  359. package/hooks/scripts/state-persist.js +99 -99
  360. package/hooks/scripts/stop-gate.js +80 -80
  361. package/hooks/scripts/subagent-scope-guard.js +88 -88
  362. package/improve-codebase-architecture/SKILL.md +31 -35
  363. package/improve-codebase-architecture/guides/DEEPENING.md +37 -37
  364. package/improve-codebase-architecture/guides/HTML-REPORT.md +123 -123
  365. package/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -44
  366. package/improve-codebase-architecture/guides/LANGUAGE.md +53 -53
  367. package/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
  368. package/install-cognitive-os/SKILL.md +23 -80
  369. package/install-cognitive-os/references/cognitive-loop.md +27 -0
  370. package/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
  371. package/multi-agent-workspace/SKILL.md +37 -0
  372. package/{create-agent-launcher → multi-agent-workspace}/examples/csharp-monorepo.md +123 -123
  373. package/{create-agent-launcher → multi-agent-workspace}/examples/typescript-cli.md +126 -126
  374. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-claude.md +77 -77
  375. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-codex.md +146 -146
  376. package/multi-agent-workspace/guidelines/platform-continue.md +38 -0
  377. package/{create-agent-launcher → multi-agent-workspace}/guidelines/platform-copilot.md +74 -74
  378. package/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
  379. package/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
  380. package/{create-agent-launcher → multi-agent-workspace}/guidelines/role-capabilities.md +108 -108
  381. package/multi-agent-workspace/references/agency-agents.md +31 -0
  382. package/multi-agent-workspace/references/architecture-guide.md +32 -0
  383. package/multi-agent-workspace/references/orchestration.md +48 -0
  384. package/multi-agent-workspace/scripts/agency-catalog.js +190 -0
  385. package/multi-agent-workspace/scripts/index_memory.js +51 -0
  386. package/multi-agent-workspace/scripts/scaffold.js +253 -0
  387. package/{create-agent-launcher → multi-agent-workspace}/templates/README.md +17 -17
  388. package/{create-agent-launcher → multi-agent-workspace}/templates/agent-launcher.md +67 -67
  389. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-csharp.md +55 -55
  390. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-polyglot.md +61 -61
  391. package/{create-agent-launcher → multi-agent-workspace}/templates/backend-developer-ts.md +56 -56
  392. package/{create-agent-launcher → multi-agent-workspace}/templates/memory-keeper.md +36 -36
  393. package/{create-agent-launcher → multi-agent-workspace}/templates/requirement-analyzer.md +65 -65
  394. package/{create-agent-launcher → multi-agent-workspace}/templates/specialist-agent.md +34 -34
  395. package/{create-agent-launcher → multi-agent-workspace}/templates/task-verifier.md +55 -55
  396. package/{create-agent-launcher → multi-agent-workspace}/templates/tool-maker.md +32 -32
  397. package/multi-agent-workspace/workflows/01-init.md +22 -0
  398. package/multi-agent-workspace/workflows/02-analysis.md +23 -0
  399. package/multi-agent-workspace/workflows/03-generation.md +27 -0
  400. package/multi-agent-workspace/workflows/04-launcher.md +16 -0
  401. package/opencode-plugin/README.md +94 -0
  402. package/opencode-plugin/hooks/circuit-breaker.js +121 -0
  403. package/opencode-plugin/hooks/compliance.js +128 -0
  404. package/opencode-plugin/hooks/post-edit.js +62 -0
  405. package/opencode-plugin/hooks/pre-complete.js +65 -0
  406. package/opencode-plugin/hooks/verify.js +140 -0
  407. package/opencode-plugin/plugin.json +17 -0
  408. package/opencode-plugin/test-hook-firing.js +198 -0
  409. package/package.json +50 -22
  410. package/references/definition-of-done.md +67 -0
  411. package/references/performance-checklist.md +153 -0
  412. package/references/platform-advisory-template.md +58 -0
  413. package/references/security-checklist.md +205 -0
  414. package/repo-docs/SKILL.md +38 -37
  415. package/repo-docs/references/process-guide.md +60 -0
  416. package/repo-docs/templates/agents-template.md +264 -264
  417. package/repo-docs/templates/knowledge-agents-template.md +50 -50
  418. package/repo-docs/templates/knowledge-readme-template.md +83 -83
  419. package/repo-docs/templates/manual-recon.md +117 -117
  420. package/repo-docs/templates/multi-skills-readme-template.md +72 -72
  421. package/repo-docs/templates/product-agents-template.md +78 -78
  422. package/repo-docs/templates/product-readme-template.md +95 -95
  423. package/repo-docs/templates/readme-template.md +136 -136
  424. package/repo-docs/templates/single-skill-readme-template.md +70 -70
  425. package/repo-docs/templates/skills-agents-template.md +60 -60
  426. package/rewrite-commits/SKILL.md +22 -17
  427. package/rewrite-commits/references/workflow.md +18 -0
  428. package/scripts/installer.js +546 -506
  429. package/scripts/lib/advisory-text.js +8 -4
  430. package/scripts/lib/claude-hooks.js +18 -5
  431. package/scripts/lib/gitignore.js +199 -80
  432. package/scripts/lib/manifest.js +68 -4
  433. package/scripts/lib/prompts.js +1 -1
  434. package/scripts/lib/skills.js +87 -1
  435. package/scripts/verify-install.js +147 -0
  436. package/security-review/SKILL.md +35 -496
  437. package/security-review/guides/OWASP-PATTERNS.md +31 -0
  438. package/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
  439. package/security-review/references/security-checklist.md +478 -0
  440. package/security-review/scripts/audit-secrets.js +84 -0
  441. package/self-evolve/SKILL.md +38 -45
  442. package/self-evolve/references/memory-resolution.md +58 -0
  443. package/self-evolve/scripts/persist-memory.js +139 -40
  444. package/self-evolve/scripts/register-dynamic-skill.js +251 -0
  445. package/self-evolve/scripts/self-regression.js +110 -113
  446. package/skill-creator/SKILL.md +34 -76
  447. package/skill-creator/references/authoring-workflow.md +14 -0
  448. package/skill-creator/references/dynamic-generation-contract.md +21 -0
  449. package/skill-creator/references/quality-checklist.md +15 -0
  450. package/skill-creator/references/quality-principles.md +81 -81
  451. package/skill-creator/references/testing-workflow.md +27 -32
  452. package/skill-style/SKILL.md +33 -39
  453. package/skill-style/references/style-guide.md +36 -0
  454. package/tdd/SKILL.md +34 -43
  455. package/tdd/guides/deep-modules.md +33 -33
  456. package/tdd/guides/interface-design.md +31 -31
  457. package/tdd/guides/mocking.md +59 -59
  458. package/tdd/guides/refactoring.md +10 -10
  459. package/tdd/guides/tests.md +61 -61
  460. package/tdd/references/core-discipline.md +49 -0
  461. package/to-spec/SKILL.md +42 -0
  462. package/to-spec/references/process.md +77 -0
  463. package/to-spec/scripts/check-project-docs.js +259 -0
  464. package/to-spec/templates/cli-reference.md +31 -0
  465. package/to-spec/templates/dev-doc.md +27 -0
  466. package/to-spec/templates/feature-spec.md +59 -0
  467. package/to-spec/templates/schema-doc.md +31 -0
  468. package/to-tickets/SKILL.md +42 -0
  469. package/to-tickets/references/publishing-and-templates.md +97 -0
  470. package/todo-driven-workflow/SKILL.md +27 -41
  471. package/todo-driven-workflow/references/execution-guide.md +27 -0
  472. package/using-git-worktrees/SKILL.md +29 -141
  473. package/using-git-worktrees/references/workflow-details.md +108 -0
  474. package/verification-loop/SKILL.md +29 -121
  475. package/verification-loop/references/verification-phases.md +116 -0
  476. package/verification-loop/templates/verification-report.template.md +15 -0
  477. package/verify-before-claim/SKILL.md +27 -70
  478. package/verify-before-claim/references/verification-guide.md +73 -0
  479. package/zoom-out/SKILL.md +28 -76
  480. package/zoom-out/references/circuit-breaker.md +66 -0
  481. package/zoom-out/templates/zoom-out-report.template.md +20 -0
  482. package/build-multi-agent-system/AGENTS.md +0 -50
  483. package/build-multi-agent-system/README.md +0 -63
  484. package/build-multi-agent-system/SKILL.md +0 -68
  485. package/create-agent-launcher/SKILL.md +0 -48
  486. package/create-agent-launcher/guidelines/platform-gemini.md +0 -101
  487. package/create-agent-launcher/workflows/01-init.md +0 -22
  488. package/create-agent-launcher/workflows/02-analysis.md +0 -26
  489. package/create-agent-launcher/workflows/03-generation.md +0 -29
  490. package/create-agent-launcher/workflows/04-launcher.md +0 -20
  491. package/docs/workflows/build-multi-agent-system.md +0 -62
  492. package/docs/workflows/create-agent-launcher.md +0 -62
  493. package/eval-framework/behavioral-test.js +0 -105
  494. package/eval-framework/mechanism-test.js +0 -251
  495. package/harness-everything/scripts/todo-cli.js +0 -157
  496. package/skill-style/STYLE.md +0 -37
@@ -1,55 +1,55 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Boundary Guard (PreToolUse: Grep|Glob|Read)
4
- * Hard-blocks two concrete sources of context bloat / hallucination risk:
5
- * 1. Reading a large file whole instead of a scoped chunk (offset/limit).
6
- * 2. Searching inside known noise directories (node_modules, .git, build
7
- * output, etc.) that produce huge, low-signal result sets.
8
- * Fails open on any parse/lookup error - never blocks due to a bug here.
9
- */
10
- const fs = require('fs');
11
-
12
- const MAX_BYTES_WITHOUT_LIMIT = 512 * 1024; // 512KB
13
- const NOISE_DIRS = ['node_modules', '.git', 'dist', 'build', 'out', '.next', 'target', 'vendor', '__pycache__', '.venv', 'coverage'];
14
-
15
- let inputData = '';
16
- process.stdin.on('data', chunk => { inputData += chunk; });
17
- process.stdin.on('end', () => {
18
- try {
19
- const payload = JSON.parse(inputData);
20
- const toolName = payload.tool_name;
21
- const input = payload.tool_input || {};
22
-
23
- if (toolName === 'Read') {
24
- const filePath = input.file_path;
25
- if (filePath && !input.limit && fs.existsSync(filePath)) {
26
- const stat = fs.statSync(filePath);
27
- if (stat.isFile() && stat.size > MAX_BYTES_WITHOUT_LIMIT) {
28
- console.error(`[Boundary Guard] BLOCKED: "${filePath}" is ${(stat.size / 1024).toFixed(0)}KB.`);
29
- console.error(`Reading a file this large in one call risks context bloat and "lost in the middle" degradation.`);
30
- console.error(`Re-issue the Read with an explicit "offset"/"limit" to pull a targeted slice, or use Grep to locate the relevant section first.`);
31
- process.exit(2);
32
- }
33
- }
34
- }
35
-
36
- if (toolName === 'Grep' || toolName === 'Glob') {
37
- const searchPath = input.path || '';
38
- const pattern = input.pattern || '';
39
- const hitsNoiseDir = NOISE_DIRS.some(dir => {
40
- const asPathSegment = new RegExp(`(^|[\\\\/])${dir}($|[\\\\/])`);
41
- return asPathSegment.test(searchPath) || asPathSegment.test(pattern);
42
- });
43
- if (hitsNoiseDir) {
44
- console.error(`[Boundary Guard] BLOCKED: search targets a noise directory (${NOISE_DIRS.join(', ')}).`);
45
- console.error(`These produce huge, low-signal result sets and rarely contain what you're actually looking for.`);
46
- console.error(`Scope the search to source directories instead, or state explicitly why this directory must be searched.`);
47
- process.exit(2);
48
- }
49
- }
50
-
51
- process.exit(0);
52
- } catch (err) {
53
- process.exit(0);
54
- }
55
- });
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Boundary Guard (PreToolUse: Grep|Glob|Read)
4
+ * Hard-blocks two concrete sources of context bloat / hallucination risk:
5
+ * 1. Reading a large file whole instead of a scoped chunk (offset/limit).
6
+ * 2. Searching inside known noise directories (node_modules, .git, build
7
+ * output, etc.) that produce huge, low-signal result sets.
8
+ * Fails open on any parse/lookup error - never blocks due to a bug here.
9
+ */
10
+ const fs = require('fs');
11
+
12
+ const MAX_BYTES_WITHOUT_LIMIT = 512 * 1024; // 512KB
13
+ const NOISE_DIRS = ['node_modules', '.git', 'dist', 'build', 'out', '.next', 'target', 'vendor', '__pycache__', '.venv', 'coverage'];
14
+
15
+ let inputData = '';
16
+ process.stdin.on('data', chunk => { inputData += chunk; });
17
+ process.stdin.on('end', () => {
18
+ try {
19
+ const payload = JSON.parse(inputData);
20
+ const toolName = payload.tool_name;
21
+ const input = payload.tool_input || {};
22
+
23
+ if (toolName === 'Read') {
24
+ const filePath = input.file_path;
25
+ if (filePath && !input.limit && fs.existsSync(filePath)) {
26
+ const stat = fs.statSync(filePath);
27
+ if (stat.isFile() && stat.size > MAX_BYTES_WITHOUT_LIMIT) {
28
+ console.error(`[Boundary Guard] BLOCKED: "${filePath}" is ${(stat.size / 1024).toFixed(0)}KB.`);
29
+ console.error(`Reading a file this large in one call risks context bloat and "lost in the middle" degradation.`);
30
+ console.error(`Re-issue the Read with an explicit "offset"/"limit" to pull a targeted slice, or use Grep to locate the relevant section first.`);
31
+ process.exit(2);
32
+ }
33
+ }
34
+ }
35
+
36
+ if (toolName === 'Grep' || toolName === 'Glob') {
37
+ const searchPath = input.path || '';
38
+ const pattern = input.pattern || '';
39
+ const hitsNoiseDir = NOISE_DIRS.some(dir => {
40
+ const asPathSegment = new RegExp(`(^|[\\\\/])${dir}($|[\\\\/])`);
41
+ return asPathSegment.test(searchPath) || asPathSegment.test(pattern);
42
+ });
43
+ if (hitsNoiseDir) {
44
+ console.error(`[Boundary Guard] BLOCKED: search targets a noise directory (${NOISE_DIRS.join(', ')}).`);
45
+ console.error(`These produce huge, low-signal result sets and rarely contain what you're actually looking for.`);
46
+ console.error(`Scope the search to source directories instead, or state explicitly why this directory must be searched.`);
47
+ process.exit(2);
48
+ }
49
+ }
50
+
51
+ process.exit(0);
52
+ } catch (err) {
53
+ process.exit(0);
54
+ }
55
+ });
@@ -1,114 +1,114 @@
1
- #!/usr/bin/env node
2
- const { execSync } = require('child_process');
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
6
-
7
- function main(payload) {
8
- try {
9
- // Let's run a quick Git check to estimate context size from modified files
10
- const statusRaw = execSync('git status --porcelain', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
11
- if (!statusRaw) {
12
- process.exit(0);
13
- }
14
-
15
- const lines = statusRaw.split('\n').filter(Boolean);
16
- const modifiedCount = lines.length;
17
-
18
- let totalDiffLines = 0;
19
- try {
20
- const diffStat = execSync('git diff --numstat', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
21
- if (diffStat) {
22
- diffStat.split('\n').forEach(line => {
23
- const [added, deleted] = line.split('\t');
24
- if (added && added !== '-' && deleted && deleted !== '-') {
25
- totalDiffLines += parseInt(added) + parseInt(deleted);
26
- }
27
- });
28
- }
29
- } catch (err) {
30
- // Ignore git errors
31
- }
32
-
33
- // Thresholds for warning
34
- const HIGH_FILE_LIMIT = 6;
35
- const HIGH_LINE_LIMIT = 400;
36
-
37
- const overThreshold = modifiedCount >= HIGH_FILE_LIMIT || totalDiffLines >= HIGH_LINE_LIMIT;
38
-
39
- // Throttle: this hook fires on EVERY Bash/Edit/Write call, and a warning
40
- // about context bloat that repeats on every call becomes context bloat
41
- // itself (and trains the model to ignore hook output). Warn on the first
42
- // crossing, then only every 10th call while still over - or when the diff
43
- // has grown another 50% since the last warning.
44
- const stateFile = path.join(getSessionDir(getWorkspaceRoot(), payload && payload.session_id), 'context-compact-state.json');
45
- let state = { overCount: 0, lastWarnedLines: 0 };
46
- try {
47
- if (fs.existsSync(stateFile)) state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
48
- } catch (err) { /* use default */ }
49
-
50
- if (!overThreshold) {
51
- if (state.overCount > 0) {
52
- try {
53
- fs.writeFileSync(stateFile, JSON.stringify({ overCount: 0, lastWarnedLines: 0 }), 'utf8');
54
- } catch (err) { /* ignore */ }
55
- }
56
- process.exit(0);
57
- }
58
-
59
- state.overCount += 1;
60
- const onBeat = state.overCount === 1 || state.overCount % 10 === 0;
61
- const grewALot = totalDiffLines >= (state.lastWarnedLines || 0) * 1.5 && totalDiffLines > state.lastWarnedLines;
62
- const shouldWarn = onBeat || grewALot;
63
- if (shouldWarn) state.lastWarnedLines = totalDiffLines;
64
- try {
65
- fs.writeFileSync(stateFile, JSON.stringify(state), 'utf8');
66
- } catch (err) { /* ignore */ }
67
-
68
- if (shouldWarn) {
69
- // Plain stdout on exit 0 is only surfaced to Claude for UserPromptSubmit/
70
- // SessionStart - for PreToolUse it's written to a debug log Claude never
71
- // sees. To actually get an advisory (non-blocking) message in front of
72
- // Claude here, it has to go through hookSpecificOutput.additionalContext.
73
- const message = [
74
- `Harness OS - Context Bloat Warning`,
75
- `- Modified Files: ${modifiedCount}`,
76
- `- Accumulated Diff: ${totalDiffLines} lines`,
77
- ``,
78
- `Caution: Large number of modified files or big diffs will bloat the Agent context window, leading to:`,
79
- ` 1. "Lost in the Middle" reasoning degradation`,
80
- ` 2. Rapidly inflating token costs`,
81
- ``,
82
- `Recommended Action:`,
83
- ` - Run atomic commits or stage completed files.`,
84
- ` - Use targeted sub-folders rather than broad searches.`,
85
- ` - Ask user to run '/compact' or '/clear' if supported.`
86
- ].join('\n');
87
-
88
- console.log(JSON.stringify({
89
- hookSpecificOutput: {
90
- hookEventName: "PreToolUse",
91
- additionalContext: message
92
- }
93
- }));
94
- }
95
- } catch (err) {
96
- // Fail open - never block user execution on compaction checker
97
- }
98
-
99
- process.exit(0);
100
- }
101
-
102
- let inputData = '';
103
- const timeout = setTimeout(() => { main(null); }, 200);
104
- process.stdin.on('data', chunk => { inputData += chunk; });
105
- process.stdin.on('end', () => {
106
- clearTimeout(timeout);
107
- let payload = null;
108
- try { payload = JSON.parse(inputData.trim()); } catch (err) { /* no payload */ }
109
- main(payload);
110
- });
111
- process.stdin.on('error', () => {
112
- clearTimeout(timeout);
113
- main(null);
114
- });
1
+ #!/usr/bin/env node
2
+ const { execSync } = require('child_process');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { getWorkspaceRoot, getSessionDir } = require('./lib/harness-state');
6
+
7
+ function main(payload) {
8
+ try {
9
+ // Let's run a quick Git check to estimate context size from modified files
10
+ const statusRaw = execSync('git status --porcelain', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
11
+ if (!statusRaw) {
12
+ process.exit(0);
13
+ }
14
+
15
+ const lines = statusRaw.split('\n').filter(Boolean);
16
+ const modifiedCount = lines.length;
17
+
18
+ let totalDiffLines = 0;
19
+ try {
20
+ const diffStat = execSync('git diff --numstat', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
21
+ if (diffStat) {
22
+ diffStat.split('\n').forEach(line => {
23
+ const [added, deleted] = line.split('\t');
24
+ if (added && added !== '-' && deleted && deleted !== '-') {
25
+ totalDiffLines += parseInt(added) + parseInt(deleted);
26
+ }
27
+ });
28
+ }
29
+ } catch (err) {
30
+ // Ignore git errors
31
+ }
32
+
33
+ // Thresholds for warning
34
+ const HIGH_FILE_LIMIT = 6;
35
+ const HIGH_LINE_LIMIT = 400;
36
+
37
+ const overThreshold = modifiedCount >= HIGH_FILE_LIMIT || totalDiffLines >= HIGH_LINE_LIMIT;
38
+
39
+ // Throttle: this hook fires on EVERY Bash/Edit/Write call, and a warning
40
+ // about context bloat that repeats on every call becomes context bloat
41
+ // itself (and trains the model to ignore hook output). Warn on the first
42
+ // crossing, then only every 10th call while still over - or when the diff
43
+ // has grown another 50% since the last warning.
44
+ const stateFile = path.join(getSessionDir(getWorkspaceRoot(), payload && payload.session_id), 'context-compact-state.json');
45
+ let state = { overCount: 0, lastWarnedLines: 0 };
46
+ try {
47
+ if (fs.existsSync(stateFile)) state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
48
+ } catch (err) { /* use default */ }
49
+
50
+ if (!overThreshold) {
51
+ if (state.overCount > 0) {
52
+ try {
53
+ fs.writeFileSync(stateFile, JSON.stringify({ overCount: 0, lastWarnedLines: 0 }), 'utf8');
54
+ } catch (err) { /* ignore */ }
55
+ }
56
+ process.exit(0);
57
+ }
58
+
59
+ state.overCount += 1;
60
+ const onBeat = state.overCount === 1 || state.overCount % 10 === 0;
61
+ const grewALot = totalDiffLines >= (state.lastWarnedLines || 0) * 1.5 && totalDiffLines > state.lastWarnedLines;
62
+ const shouldWarn = onBeat || grewALot;
63
+ if (shouldWarn) state.lastWarnedLines = totalDiffLines;
64
+ try {
65
+ fs.writeFileSync(stateFile, JSON.stringify(state), 'utf8');
66
+ } catch (err) { /* ignore */ }
67
+
68
+ if (shouldWarn) {
69
+ // Plain stdout on exit 0 is only surfaced to Claude for UserPromptSubmit/
70
+ // SessionStart - for PreToolUse it's written to a debug log Claude never
71
+ // sees. To actually get an advisory (non-blocking) message in front of
72
+ // Claude here, it has to go through hookSpecificOutput.additionalContext.
73
+ const message = [
74
+ `Harness OS - Context Bloat Warning`,
75
+ `- Modified Files: ${modifiedCount}`,
76
+ `- Accumulated Diff: ${totalDiffLines} lines`,
77
+ ``,
78
+ `Caution: Large number of modified files or big diffs will bloat the Agent context window, leading to:`,
79
+ ` 1. "Lost in the Middle" reasoning degradation`,
80
+ ` 2. Rapidly inflating token costs`,
81
+ ``,
82
+ `Recommended Action:`,
83
+ ` - Run atomic commits or stage completed files.`,
84
+ ` - Use targeted sub-folders rather than broad searches.`,
85
+ ` - Ask user to run '/compact' or '/clear' if supported.`
86
+ ].join('\n');
87
+
88
+ console.log(JSON.stringify({
89
+ hookSpecificOutput: {
90
+ hookEventName: "PreToolUse",
91
+ additionalContext: message
92
+ }
93
+ }));
94
+ }
95
+ } catch (err) {
96
+ // Fail open - never block user execution on compaction checker
97
+ }
98
+
99
+ process.exit(0);
100
+ }
101
+
102
+ let inputData = '';
103
+ const timeout = setTimeout(() => { main(null); }, 200);
104
+ process.stdin.on('data', chunk => { inputData += chunk; });
105
+ process.stdin.on('end', () => {
106
+ clearTimeout(timeout);
107
+ let payload = null;
108
+ try { payload = JSON.parse(inputData.trim()); } catch (err) { /* no payload */ }
109
+ main(payload);
110
+ });
111
+ process.stdin.on('error', () => {
112
+ clearTimeout(timeout);
113
+ main(null);
114
+ });
@@ -1,79 +1,79 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Contract Test (PostToolUse: Bash|PowerShell)
4
- * Resolves fable-mode stage contracts. fable-orchestrator's discipline says
5
- * every stage check must be "re-run or spot-checked... before building on
6
- * its output" - but a verbal claim of "I re-ran it" isn't auditable. So the
7
- * orchestrator now writes .claude/harness-state/contracts/<stageId>.json with
8
- * status:"pending" and the exact checkCommand BEFORE running it. This hook
9
- * watches every shell call; when the command matches a pending contract's
10
- * checkCommand verbatim, it records pass/fail into that manifest using the
11
- * same exitCode-or-stderr heuristic as rule-of-3-tracker.js.
12
- * Contracts are shared across sessions, not scoped to one - the orchestrator
13
- * writes them proactively (not in response to a hook message) and has no
14
- * clean way to learn its own session_id, so a collision only matters if two
15
- * fable-mode orchestrations run in the same repo at once.
16
- * Contracts are audit trail, not synchronous enforcement - EXCEPT when a
17
- * check this hook just resolved comes back FAILED, it surfaces that loudly
18
- * (exit 2) so silently building on a failed stage doesn't slip through.
19
- * Fails open on any parse/lookup error.
20
- */
21
- const fs = require('fs');
22
- const path = require('path');
23
- const { getWorkspaceRoot, getStateRoot } = require('./lib/harness-state');
24
-
25
- let inputData = '';
26
- process.stdin.on('data', chunk => { inputData += chunk; });
27
- process.stdin.on('end', () => {
28
- try {
29
- const payload = JSON.parse(inputData);
30
- if (payload.tool_name !== 'Bash' && payload.tool_name !== 'PowerShell') process.exit(0);
31
-
32
- const command = ((payload.tool_input && payload.tool_input.command) || '').trim();
33
- if (!command) process.exit(0);
34
-
35
- const contractsDir = path.join(getStateRoot(getWorkspaceRoot()), 'contracts');
36
- if (!fs.existsSync(contractsDir)) process.exit(0);
37
-
38
- const toolResponse = payload.tool_response || {};
39
- const stdout = toolResponse.stdout ?? payload.stdout ?? '';
40
- const stderr = toolResponse.stderr ?? payload.stderr ?? '';
41
- const rawExitCode = toolResponse.exitCode ?? toolResponse.exit_code ?? payload.exitCode;
42
- const exitCode = typeof rawExitCode === 'number' ? rawExitCode : undefined;
43
- const stderrSignal = typeof stderr === 'string' && stderr.trim().length > 0;
44
- const failed = (exitCode !== undefined && exitCode !== 0) || (exitCode === undefined && stderrSignal);
45
-
46
- const files = fs.readdirSync(contractsDir).filter(f => f.endsWith('.json'));
47
- let firstFailure = null;
48
-
49
- for (const file of files) {
50
- const manifestPath = path.join(contractsDir, file);
51
- let manifest;
52
- try {
53
- manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
54
- } catch (e) {
55
- continue;
56
- }
57
- if (manifest.status !== 'pending') continue;
58
- if (!manifest.checkCommand || manifest.checkCommand.trim() !== command) continue;
59
-
60
- manifest.status = failed ? 'fail' : 'pass';
61
- manifest.evidence = ((stderrSignal ? stderr : stdout) || '').slice(-500).trim();
62
- manifest.verifiedAt = new Date().toISOString();
63
- fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf8');
64
-
65
- if (failed && !firstFailure) firstFailure = manifest;
66
- }
67
-
68
- if (firstFailure) {
69
- console.error(`[Contract Test] Stage "${firstFailure.stageId}" FAILED its named check: ${firstFailure.checkCommand}`);
70
- console.error(`Evidence: ${firstFailure.evidence || '(no output captured)'}`);
71
- console.error(`Do not build on this stage's output until it passes. Artifact: ${firstFailure.outputPath || '(no path recorded)'}`);
72
- process.exit(2);
73
- }
74
-
75
- process.exit(0);
76
- } catch (err) {
77
- process.exit(0);
78
- }
79
- });
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Contract Test (PostToolUse: Bash|PowerShell)
4
+ * Resolves fable-mode stage contracts. fable-orchestrator's discipline says
5
+ * every stage check must be "re-run or spot-checked... before building on
6
+ * its output" - but a verbal claim of "I re-ran it" isn't auditable. So the
7
+ * orchestrator now writes .claude/harness-everything/state/contracts/<stageId>.json with
8
+ * status:"pending" and the exact checkCommand BEFORE running it. This hook
9
+ * watches every shell call; when the command matches a pending contract's
10
+ * checkCommand verbatim, it records pass/fail into that manifest using the
11
+ * same exitCode-or-stderr heuristic as rule-of-3-tracker.js.
12
+ * Contracts are shared across sessions, not scoped to one - the orchestrator
13
+ * writes them proactively (not in response to a hook message) and has no
14
+ * clean way to learn its own session_id, so a collision only matters if two
15
+ * fable-mode orchestrations run in the same repo at once.
16
+ * Contracts are audit trail, not synchronous enforcement - EXCEPT when a
17
+ * check this hook just resolved comes back FAILED, it surfaces that loudly
18
+ * (exit 2) so silently building on a failed stage doesn't slip through.
19
+ * Fails open on any parse/lookup error.
20
+ */
21
+ const fs = require('fs');
22
+ const path = require('path');
23
+ const { getWorkspaceRoot, getStateRoot } = require('./lib/harness-state');
24
+
25
+ let inputData = '';
26
+ process.stdin.on('data', chunk => { inputData += chunk; });
27
+ process.stdin.on('end', () => {
28
+ try {
29
+ const payload = JSON.parse(inputData);
30
+ if (payload.tool_name !== 'Bash' && payload.tool_name !== 'PowerShell') process.exit(0);
31
+
32
+ const command = ((payload.tool_input && payload.tool_input.command) || '').trim();
33
+ if (!command) process.exit(0);
34
+
35
+ const contractsDir = path.join(getStateRoot(getWorkspaceRoot()), 'contracts');
36
+ if (!fs.existsSync(contractsDir)) process.exit(0);
37
+
38
+ const toolResponse = payload.tool_response || {};
39
+ const stdout = toolResponse.stdout ?? payload.stdout ?? '';
40
+ const stderr = toolResponse.stderr ?? payload.stderr ?? '';
41
+ const rawExitCode = toolResponse.exitCode ?? toolResponse.exit_code ?? payload.exitCode;
42
+ const exitCode = typeof rawExitCode === 'number' ? rawExitCode : undefined;
43
+ const stderrSignal = typeof stderr === 'string' && stderr.trim().length > 0;
44
+ const failed = (exitCode !== undefined && exitCode !== 0) || (exitCode === undefined && stderrSignal);
45
+
46
+ const files = fs.readdirSync(contractsDir).filter(f => f.endsWith('.json'));
47
+ let firstFailure = null;
48
+
49
+ for (const file of files) {
50
+ const manifestPath = path.join(contractsDir, file);
51
+ let manifest;
52
+ try {
53
+ manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
54
+ } catch (e) {
55
+ continue;
56
+ }
57
+ if (manifest.status !== 'pending') continue;
58
+ if (!manifest.checkCommand || manifest.checkCommand.trim() !== command) continue;
59
+
60
+ manifest.status = failed ? 'fail' : 'pass';
61
+ manifest.evidence = ((stderrSignal ? stderr : stdout) || '').slice(-500).trim();
62
+ manifest.verifiedAt = new Date().toISOString();
63
+ fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf8');
64
+
65
+ if (failed && !firstFailure) firstFailure = manifest;
66
+ }
67
+
68
+ if (firstFailure) {
69
+ console.error(`[Contract Test] Stage "${firstFailure.stageId}" FAILED its named check: ${firstFailure.checkCommand}`);
70
+ console.error(`Evidence: ${firstFailure.evidence || '(no output captured)'}`);
71
+ console.error(`Do not build on this stage's output until it passes. Artifact: ${firstFailure.outputPath || '(no path recorded)'}`);
72
+ process.exit(2);
73
+ }
74
+
75
+ process.exit(0);
76
+ } catch (err) {
77
+ process.exit(0);
78
+ }
79
+ });
@@ -1,65 +1,65 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Depth Guard (PreToolUse: Edit|Write)
4
- * Claude Code already refuses to Edit a file that wasn't Read first in the
5
- * same session - that's native behavior, not something this hook needs to
6
- * re-check. The gap is Write: it happily overwrites an existing file with
7
- * no prior Read at all. This hook closes that gap: blocks Write on a file
8
- * that already exists on disk unless a Read of that exact path shows up
9
- * earlier in this session's transcript.
10
- * Fails open on any parse/lookup error - never blocks due to a bug here.
11
- */
12
- const fs = require('fs');
13
- const path = require('path');
14
-
15
- let inputData = '';
16
- process.stdin.on('data', chunk => { inputData += chunk; });
17
- process.stdin.on('end', () => {
18
- try {
19
- const payload = JSON.parse(inputData);
20
- if (payload.tool_name !== 'Write') {
21
- process.exit(0);
22
- }
23
-
24
- const filePath = payload.tool_input && payload.tool_input.file_path;
25
- if (!filePath || !fs.existsSync(filePath)) {
26
- // New file - nothing to have read first.
27
- process.exit(0);
28
- }
29
-
30
- const transcriptPath = payload.transcript_path;
31
- if (!transcriptPath || !fs.existsSync(transcriptPath)) {
32
- // Can't verify either way - fail open.
33
- process.exit(0);
34
- }
35
-
36
- const target = path.resolve(filePath).toLowerCase();
37
- const lines = fs.readFileSync(transcriptPath, 'utf8').split('\n').filter(Boolean);
38
-
39
- const wasRead = lines.some(line => {
40
- try {
41
- const entry = JSON.parse(line);
42
- const content = entry && entry.message && entry.message.content;
43
- if (!Array.isArray(content)) return false;
44
- return content.some(block => {
45
- if (!block || block.type !== 'tool_use' || block.name !== 'Read') return false;
46
- const readPath = block.input && block.input.file_path;
47
- return readPath && path.resolve(readPath).toLowerCase() === target;
48
- });
49
- } catch (e) {
50
- return false;
51
- }
52
- });
53
-
54
- if (!wasRead) {
55
- console.error(`[Depth Guard] BLOCKED: "${filePath}" already exists but hasn't been Read in this session.`);
56
- console.error(`Write() overwrites the whole file - doing that blind risks destroying content you never looked at.`);
57
- console.error(`Read the file first (even a quick pass), then retry the Write, or use Edit for a targeted change.`);
58
- process.exit(2);
59
- }
60
-
61
- process.exit(0);
62
- } catch (err) {
63
- process.exit(0);
64
- }
65
- });
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Depth Guard (PreToolUse: Edit|Write)
4
+ * Claude Code already refuses to Edit a file that wasn't Read first in the
5
+ * same session - that's native behavior, not something this hook needs to
6
+ * re-check. The gap is Write: it happily overwrites an existing file with
7
+ * no prior Read at all. This hook closes that gap: blocks Write on a file
8
+ * that already exists on disk unless a Read of that exact path shows up
9
+ * earlier in this session's transcript.
10
+ * Fails open on any parse/lookup error - never blocks due to a bug here.
11
+ */
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+
15
+ let inputData = '';
16
+ process.stdin.on('data', chunk => { inputData += chunk; });
17
+ process.stdin.on('end', () => {
18
+ try {
19
+ const payload = JSON.parse(inputData);
20
+ if (payload.tool_name !== 'Write') {
21
+ process.exit(0);
22
+ }
23
+
24
+ const filePath = payload.tool_input && payload.tool_input.file_path;
25
+ if (!filePath || !fs.existsSync(filePath)) {
26
+ // New file - nothing to have read first.
27
+ process.exit(0);
28
+ }
29
+
30
+ const transcriptPath = payload.transcript_path;
31
+ if (!transcriptPath || !fs.existsSync(transcriptPath)) {
32
+ // Can't verify either way - fail open.
33
+ process.exit(0);
34
+ }
35
+
36
+ const target = path.resolve(filePath).toLowerCase();
37
+ const lines = fs.readFileSync(transcriptPath, 'utf8').split('\n').filter(Boolean);
38
+
39
+ const wasRead = lines.some(line => {
40
+ try {
41
+ const entry = JSON.parse(line);
42
+ const content = entry && entry.message && entry.message.content;
43
+ if (!Array.isArray(content)) return false;
44
+ return content.some(block => {
45
+ if (!block || block.type !== 'tool_use' || block.name !== 'Read') return false;
46
+ const readPath = block.input && block.input.file_path;
47
+ return readPath && path.resolve(readPath).toLowerCase() === target;
48
+ });
49
+ } catch (e) {
50
+ return false;
51
+ }
52
+ });
53
+
54
+ if (!wasRead) {
55
+ console.error(`[Depth Guard] BLOCKED: "${filePath}" already exists but hasn't been Read in this session.`);
56
+ console.error(`Write() overwrites the whole file - doing that blind risks destroying content you never looked at.`);
57
+ console.error(`Read the file first (even a quick pass), then retry the Write, or use Edit for a targeted change.`);
58
+ process.exit(2);
59
+ }
60
+
61
+ process.exit(0);
62
+ } catch (err) {
63
+ process.exit(0);
64
+ }
65
+ });