harness-everything 0.3.6 → 0.4.0

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 (573) hide show
  1. package/.agents/plugins/marketplace.json +20 -0
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +8 -7
  4. package/.github/workflows/ci.yml +23 -18
  5. package/.github/workflows/release.yml +53 -27
  6. package/.releaserc.json +113 -0
  7. package/AGENTS.md +34 -23
  8. package/BENCHMARK_SOP.md +38 -18
  9. package/CHANGELOG.md +194 -3
  10. package/CONTRIBUTING.md +17 -4
  11. package/PRIVACY.md +25 -0
  12. package/README.md +118 -87
  13. package/RELEASING.md +82 -0
  14. package/SUPPORT.md +27 -0
  15. package/TERMS.md +21 -0
  16. package/VERIFICATION.md +175 -286
  17. package/behavioral-evals/README.md +21 -0
  18. package/behavioral-evals/case-validator.js +194 -0
  19. package/behavioral-evals/cases/baseline-environment-detection.yaml +21 -0
  20. package/behavioral-evals/cases/baseline-eval-harness.yaml +27 -0
  21. package/behavioral-evals/cases/baseline-fable-discipline.yaml +31 -0
  22. package/behavioral-evals/cases/baseline-find-skills-exposure.yaml +49 -0
  23. package/behavioral-evals/cases/baseline-find-skills.yaml +21 -0
  24. package/behavioral-evals/cases/baseline-git-commit.yaml +2 -2
  25. package/behavioral-evals/cases/baseline-install-cognitive-os.yaml +24 -0
  26. package/behavioral-evals/cases/baseline-multi-agent-workspace.yaml +28 -0
  27. package/behavioral-evals/cases/baseline-rewrite-commits.yaml +34 -0
  28. package/behavioral-evals/cases/baseline-self-evolve.yaml +31 -0
  29. package/behavioral-evals/cases/baseline-skill-creator.yaml +20 -0
  30. package/behavioral-evals/cases/baseline-skill-style.yaml +21 -0
  31. package/behavioral-evals/cases/baseline-to-spec.yaml +34 -0
  32. package/behavioral-evals/cases/baseline-to-tickets.yaml +24 -0
  33. package/behavioral-evals/cases/baseline-todo-driven-workflow.yaml +32 -0
  34. package/behavioral-evals/cases/baseline-using-git-worktrees.yaml +15 -0
  35. package/behavioral-evals/cases/breaker-zoom-out-after-3.yaml +2 -2
  36. package/behavioral-evals/cases/pressure-complexity-skip.yaml +2 -2
  37. package/behavioral-evals/cases/pressure-scope-bypass.yaml +7 -2
  38. package/behavioral-evals/cases/pressure-sunk-cost-retry.yaml +7 -4
  39. package/behavioral-evals/cases/scope-discipline.yaml +2 -1
  40. package/behavioral-evals/cases/verify-before-done.yaml +7 -5
  41. package/behavioral-evals/evidence/2026-09-07/baseline-debugging/case.yaml +31 -0
  42. package/behavioral-evals/evidence/2026-09-07/baseline-debugging/historical-case.yaml +31 -0
  43. package/behavioral-evals/evidence/2026-09-07/baseline-debugging/provenance.json +42 -0
  44. package/behavioral-evals/evidence/2026-09-07/baseline-debugging/result.sanitized.json +20 -0
  45. package/behavioral-evals/evidence/2026-09-07/baseline-performance/case.yaml +34 -0
  46. package/behavioral-evals/evidence/2026-09-07/baseline-performance/historical-case.yaml +34 -0
  47. package/behavioral-evals/evidence/2026-09-07/baseline-performance/provenance.json +42 -0
  48. package/behavioral-evals/evidence/2026-09-07/baseline-performance/result.sanitized.json +20 -0
  49. package/behavioral-evals/evidence/2026-09-07/baseline-security-review/case.yaml +28 -0
  50. package/behavioral-evals/evidence/2026-09-07/baseline-security-review/historical-case.yaml +28 -0
  51. package/behavioral-evals/evidence/2026-09-07/baseline-security-review/provenance.json +42 -0
  52. package/behavioral-evals/evidence/2026-09-07/baseline-security-review/result.sanitized.json +20 -0
  53. package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/case.yaml +33 -0
  54. package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/historical-case.yaml +33 -0
  55. package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/provenance.json +42 -0
  56. package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/result.sanitized.json +20 -0
  57. package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/case.yaml +28 -0
  58. package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/historical-case.yaml +18 -0
  59. package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/provenance.json +30 -0
  60. package/behavioral-evals/evidence/2026-09-07/live-run-blocker.md +16 -0
  61. package/behavioral-evals/evidence/2026-09-07/manifest.json +88 -0
  62. package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/case.yaml +33 -0
  63. package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/historical-case.yaml +28 -0
  64. package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/provenance.json +30 -0
  65. package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/case.yaml +50 -0
  66. package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/historical-case.yaml +50 -0
  67. package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/provenance.json +42 -0
  68. package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/result.sanitized.json +20 -0
  69. package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/case.yaml +35 -0
  70. package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/historical-case.yaml +35 -0
  71. package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/provenance.json +42 -0
  72. package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/result.sanitized.json +20 -0
  73. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/case.yaml +43 -0
  74. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/historical-case.yaml +43 -0
  75. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/provenance.json +42 -0
  76. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/result.sanitized.json +24 -0
  77. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/case.yaml +43 -0
  78. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/historical-case.yaml +43 -0
  79. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/provenance.json +42 -0
  80. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/result.sanitized.json +20 -0
  81. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/case.yaml +43 -0
  82. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/historical-case.yaml +43 -0
  83. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/provenance.json +42 -0
  84. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/result.sanitized.json +24 -0
  85. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/case.yaml +50 -0
  86. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/historical-case.yaml +47 -0
  87. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/provenance.json +42 -0
  88. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/result.sanitized.json +24 -0
  89. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/case.yaml +50 -0
  90. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/historical-case.yaml +47 -0
  91. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/provenance.json +42 -0
  92. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/result.sanitized.json +20 -0
  93. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/case.yaml +50 -0
  94. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/historical-case.yaml +47 -0
  95. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/provenance.json +42 -0
  96. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/result.sanitized.json +24 -0
  97. package/behavioral-evals/evidence/2026-09-07/tdd-test-first/case.yaml +30 -0
  98. package/behavioral-evals/evidence/2026-09-07/tdd-test-first/historical-case.yaml +23 -0
  99. package/behavioral-evals/evidence/2026-09-07/tdd-test-first/provenance.json +30 -0
  100. package/behavioral-evals/evidence/2026-09-07/triage-matrix.json +426 -0
  101. package/behavioral-evals/evidence/2026-09-07/triage-matrix.md +24 -0
  102. package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/case.yaml +19 -0
  103. package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/historical-case.yaml +18 -0
  104. package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/provenance.json +30 -0
  105. package/behavioral-evals/evidence/2026-09-07/verify-before-done/case.yaml +33 -0
  106. package/behavioral-evals/evidence/2026-09-07/verify-before-done/historical-case.yaml +31 -0
  107. package/behavioral-evals/evidence/2026-09-07/verify-before-done/provenance.json +42 -0
  108. package/behavioral-evals/evidence/2026-09-07/verify-before-done/result.sanitized.json +20 -0
  109. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/case.yaml +33 -0
  110. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/historical-case.yaml +31 -0
  111. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/provenance.json +42 -0
  112. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/result.sanitized.json +20 -0
  113. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/case.yaml +33 -0
  114. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/historical-case.yaml +31 -0
  115. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/provenance.json +42 -0
  116. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/result.sanitized.json +20 -0
  117. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/case.yaml +33 -0
  118. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/historical-case.yaml +33 -0
  119. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/provenance.json +42 -0
  120. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/result.sanitized.json +480 -0
  121. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/transcript.sanitized.jsonl +95 -0
  122. package/behavioral-evals/evidence-tool.js +443 -0
  123. package/behavioral-evals/fixtures/claude-denied.jsonl +3 -0
  124. package/behavioral-evals/fixtures/claude-legacy.json +1 -0
  125. package/behavioral-evals/fixtures/claude-oral-only.jsonl +2 -0
  126. package/behavioral-evals/fixtures/claude-success.jsonl +5 -0
  127. package/behavioral-evals/fixtures/claude-truncated.jsonl +3 -0
  128. package/behavioral-evals/fixtures/opencode-success.jsonl +6 -0
  129. package/behavioral-evals/results/2026-08-31-baseline-add-feature.json +20 -0
  130. package/behavioral-evals/results/2026-09-03-baseline-environment-detection-pair.json +133 -0
  131. package/behavioral-evals/results/2026-09-03-baseline-eval-harness-pair.json +141 -0
  132. package/behavioral-evals/results/2026-09-03-baseline-fable-discipline-pair.json +149 -0
  133. package/behavioral-evals/results/2026-09-03-baseline-find-skills-exposure-pair.json +141 -0
  134. package/behavioral-evals/results/2026-09-03-baseline-find-skills-pair.json +141 -0
  135. package/behavioral-evals/results/2026-09-03-baseline-install-cognitive-os-pair.json +133 -0
  136. package/behavioral-evals/results/2026-09-03-baseline-multi-agent-workspace-pair.json +141 -0
  137. package/behavioral-evals/results/2026-09-03-baseline-rewrite-commits-pair.json +95 -0
  138. package/behavioral-evals/results/2026-09-03-baseline-self-evolve-pair.json +141 -0
  139. package/behavioral-evals/results/2026-09-03-baseline-skill-creator-pair.json +141 -0
  140. package/behavioral-evals/results/2026-09-03-baseline-skill-style-pair.json +133 -0
  141. package/behavioral-evals/results/2026-09-03-baseline-to-spec-pair.json +133 -0
  142. package/behavioral-evals/results/2026-09-03-baseline-to-tickets-pair.json +141 -0
  143. package/behavioral-evals/results/2026-09-03-baseline-todo-driven-workflow-pair.json +141 -0
  144. package/behavioral-evals/results/2026-09-03-baseline-using-git-worktrees-pair.json +133 -0
  145. package/behavioral-evals/results/2026-09-03-summary-both.json +41 -0
  146. package/behavioral-evals/results/2026-09-04-baseline-find-skills-pair.json +141 -0
  147. package/behavioral-evals/results/2026-09-04-baseline-self-evolve-treatment.json +80 -0
  148. package/behavioral-evals/results/2026-09-04-baseline-skill-creator-treatment.json +80 -0
  149. package/behavioral-evals/results/2026-09-04-summary-both.json +41 -0
  150. package/behavioral-evals/run-with-plugin.js +15 -31
  151. package/behavioral-evals/run.js +446 -105
  152. package/behavioral-evals/transcript-parser.js +591 -0
  153. package/bin/cli.js +24 -12
  154. package/ci/ab-test-cases/grill-me-adversarial.yaml +14 -4
  155. package/ci/ab-test-cases/tdd-test-first.yaml +13 -6
  156. package/ci/ab-test-cases/verification-loop-gates.yaml +20 -7
  157. package/ci/ab-test-cases/verify-before-claim-cites.yaml +7 -6
  158. package/ci/ab-test-harness.js +113 -38
  159. package/ci/action-gate-platform-doc.test.js +31 -0
  160. package/ci/action-gate.test.js +260 -0
  161. package/ci/cases/case2.json +2 -2
  162. package/ci/consistency-check.js +51 -5
  163. package/ci/description-collision.js +15 -6
  164. package/ci/disclosure-check.js +225 -0
  165. package/ci/doc-capability-consistency.test.js +180 -0
  166. package/ci/fixtures/phase4/parallel-disjoint.stages.json +32 -0
  167. package/ci/fixtures/phase4/parallel-read-only.stages.json +32 -0
  168. package/ci/installer-roundtrip.test.js +159 -0
  169. package/ci/invariant-routing.test.js +74 -0
  170. package/ci/issue99-runtime.test.js +218 -0
  171. package/ci/mechanism-2aa-codex-action-gate-policy.test.js +117 -0
  172. package/ci/mechanism-2ab-openai-plugin-sync-integrity.test.js +80 -0
  173. package/ci/mechanism-2j-behavioral-runner.test.js +43 -1
  174. package/ci/mechanism-2k-reference-check.test.js +57 -2
  175. package/ci/mechanism-2l-multi-agent-workspace.test.js +202 -6
  176. package/ci/mechanism-2m-self-repo-guard.test.js +65 -0
  177. package/ci/mechanism-2n-opencode-plugin.test.js +461 -0
  178. package/ci/mechanism-2o-state-home-isolation.test.js +183 -0
  179. package/ci/mechanism-2p-installer-links.test.js +183 -0
  180. package/ci/mechanism-2q-installer-global-shared-store.test.js +132 -0
  181. package/ci/mechanism-2r-uninstall-flags.test.js +148 -0
  182. package/ci/mechanism-2s-tdd-quality.test.js +203 -0
  183. package/ci/mechanism-2t-disclosure.test.js +90 -0
  184. package/ci/mechanism-2t-evidence-triage.test.js +200 -0
  185. package/ci/mechanism-2t-issue-20.test.js +75 -0
  186. package/ci/mechanism-2t-platform-skill-targets.test.js +164 -0
  187. package/ci/mechanism-2t-transcript-parser.test.js +179 -0
  188. package/ci/mechanism-2t-workspace-identity.test.js +200 -0
  189. package/ci/mechanism-2u-issue-42-regressions.test.js +239 -0
  190. package/ci/mechanism-2u-issue-44.test.js +35 -0
  191. package/ci/mechanism-2v-verifier-boundaries.test.js +138 -0
  192. package/ci/mechanism-2w-platform-compatibility.test.js +148 -0
  193. package/ci/mechanism-2x-release-automation.test.js +157 -0
  194. package/ci/mechanism-2x-release-commit-message.test.js +66 -0
  195. package/ci/mechanism-2y-release-tooling-compat.test.js +47 -0
  196. package/ci/mechanism-2z-claude-plugin-manifest.test.js +29 -0
  197. package/ci/mutation-check.js +53 -0
  198. package/ci/mutation-loader.js +57 -0
  199. package/ci/negative-controls.js +76 -46
  200. package/ci/openai-plugin-package.test.js +182 -0
  201. package/ci/openai-plugin-runtime.test.js +175 -0
  202. package/ci/openai-plugin-submission.test.js +101 -0
  203. package/ci/phase4-ensemble-memory.test.js +307 -0
  204. package/ci/reference-check.js +73 -25
  205. package/ci/release-consistency-check.js +24 -1
  206. package/ci/router-phase2-safety.test.js +81 -0
  207. package/ci/router-workflow-plan.test.js +264 -0
  208. package/ci/routing-check.js +6 -5
  209. package/ci/runner.js +6 -5
  210. package/ci/skill-routing-check.js +48 -11
  211. package/ci/test-behavioral-case-validation.js +62 -0
  212. package/ci/test-helper.js +10 -0
  213. package/ci/workflow-plan-consumers-edge.test.js +72 -0
  214. package/ci/workflow-plan-consumers.test.js +276 -0
  215. package/docs/architecture.md +137 -57
  216. package/docs/audit.md +22 -20
  217. package/docs/codex-action-gate.md +90 -0
  218. package/docs/issue-20-rollup.md +47 -0
  219. package/docs/mechanism-first-skill-mesh.md +22 -20
  220. package/docs/openai-plugin.md +118 -0
  221. package/docs/philosophy.md +28 -17
  222. package/docs/platform-capabilities.md +73 -0
  223. package/docs/platform-compatibility.json +270 -0
  224. package/docs/reflection.md +37 -22
  225. package/docs/release-evidence.md +25 -0
  226. package/docs/routing.md +157 -44
  227. package/docs/security-audit.md +38 -0
  228. package/docs/troubleshooting.md +82 -46
  229. package/docs/verifier-boundaries.md +45 -0
  230. package/docs/workflows/fable-mode.md +77 -21
  231. package/docs/workflows/find-skills.md +40 -0
  232. package/docs/workflows/grill-with-docs.md +2 -2
  233. package/docs/workflows/multi-agent-workspace.md +22 -10
  234. package/docs/workflows/self-evolve.md +33 -0
  235. package/docs/workflows/tdd.md +36 -0
  236. package/docs/workflows/todo-driven-workflow.md +33 -0
  237. package/environment-detection/SKILL.md +3 -3
  238. package/eval-harness/SKILL.md +7 -7
  239. package/eval-harness/scripts/evaluate.js +12 -10
  240. package/evals/evaluation-reports.md +14 -0
  241. package/evals/harness-everything/tasks/positive-tier1.yaml +1 -1
  242. package/evals/harness-everything/tasks/positive-tier2.yaml +1 -1
  243. package/evals/harness-everything/tasks/positive-tier3.yaml +1 -1
  244. package/evals/install-cognitive-os/tasks/positive-trigger.yaml +1 -1
  245. package/fable-discipline/SKILL.md +2 -2
  246. package/fable-mode/CONTRACT-FORMAT.md +147 -33
  247. package/fable-mode/SKILL.md +3 -3
  248. package/fable-mode/agents/fable-orchestrator.md +95 -35
  249. package/fable-mode/execution-guardrails/SKILL.md +2 -2
  250. package/fable-mode/fable-haiku/SKILL.md +3 -3
  251. package/fable-mode/fable-opus/SKILL.md +3 -3
  252. package/fable-mode/fable-sonnet/SKILL.md +3 -3
  253. package/fable-mode/scripts/ensemble-review.js +371 -0
  254. package/fable-mode/scripts/model-selector.js +134 -3
  255. package/fable-mode/scripts/workflow-plan-consumer.js +337 -0
  256. package/find-skills/SKILL.md +5 -5
  257. package/find-skills/references/discovery-flow.md +1 -1
  258. package/find-skills/scripts/use-skill.js +7 -1
  259. package/git-commit/SKILL.md +4 -11
  260. package/grill-me/SKILL.md +5 -5
  261. package/grill-with-docs/SKILL.md +7 -7
  262. package/grill-with-docs/references/session-playbook.md +6 -4
  263. package/harness-everything/SKILL.md +23 -22
  264. package/harness-everything/references/router-workflow-plan.md +128 -0
  265. package/harness-everything/references/triage-and-tiers.md +173 -96
  266. package/harness-everything/schemas/router-task-shape.schema.json +126 -0
  267. package/harness-everything/schemas/router-workflow-plan.schema.json +149 -0
  268. package/harness-everything/scripts/bootstrap.js +13 -4
  269. package/harness-everything/scripts/ensemble-policy.js +102 -0
  270. package/harness-everything/scripts/kernel-router.js +212 -0
  271. package/harness-everything/scripts/router-contract.js +612 -0
  272. package/harness-everything/scripts/self-heal.js +29 -20
  273. package/harness-everything/scripts/tier-router.js +346 -221
  274. package/hooks/hooks.json +60 -15
  275. package/hooks/scripts/action-gate-rules.json +77 -0
  276. package/hooks/scripts/action-gate.js +528 -0
  277. package/hooks/scripts/atomic-commit-check.js +5 -5
  278. package/hooks/scripts/codex-action-gate-post.js +46 -0
  279. package/hooks/scripts/codex-permission-request.js +140 -0
  280. package/hooks/scripts/context-compact.js +4 -3
  281. package/hooks/scripts/contract-test.js +118 -51
  282. package/hooks/scripts/lib/fable-contracts.js +121 -0
  283. package/hooks/scripts/lib/harness-state.js +164 -28
  284. package/hooks/scripts/lib/platforms/claude.js +45 -62
  285. package/hooks/scripts/lib/platforms/codex.js +35 -61
  286. package/hooks/scripts/lib/platforms/continue.js +7 -7
  287. package/hooks/scripts/lib/platforms/copilot.js +29 -53
  288. package/hooks/scripts/lib/platforms/hermes.js +71 -20
  289. package/hooks/scripts/openai-session-start.js +81 -0
  290. package/hooks/scripts/rule-of-3-tracker.js +9 -8
  291. package/hooks/scripts/rule-of-3.js +29 -21
  292. package/hooks/scripts/state-persist.js +5 -4
  293. package/hooks/scripts/stop-gate.js +2 -2
  294. package/hooks/scripts/subagent-scope-guard.js +144 -38
  295. package/hooks/scripts/subagent-start.js +19 -0
  296. package/hooks/scripts/subagent-stop.js +6 -0
  297. package/improve-codebase-architecture/SKILL.md +2 -4
  298. package/improve-codebase-architecture/references/README.md +16 -0
  299. package/install-cognitive-os/SKILL.md +28 -22
  300. package/multi-agent-workspace/SKILL.md +16 -15
  301. package/multi-agent-workspace/references/architecture-guide.md +13 -9
  302. package/multi-agent-workspace/references/orchestration.md +39 -22
  303. package/multi-agent-workspace/scripts/consume-workflow-plan.js +129 -0
  304. package/multi-agent-workspace/scripts/index_memory.js +79 -26
  305. package/multi-agent-workspace/scripts/path-boundary.js +59 -0
  306. package/multi-agent-workspace/scripts/project-docs-resolver.js +357 -0
  307. package/multi-agent-workspace/scripts/scaffold.js +258 -103
  308. package/multi-agent-workspace/templates/AGENTS.md +20 -0
  309. package/multi-agent-workspace/workflows/03-generation.md +8 -10
  310. package/multi-agent-workspace/workflows/04-launcher.md +5 -5
  311. package/opencode-plugin/README.md +114 -71
  312. package/opencode-plugin/hooks/verify.js +62 -12
  313. package/opencode-plugin/index.mjs +547 -0
  314. package/opencode-plugin/plugin.json +4 -12
  315. package/package.json +16 -3
  316. package/plugins/harness-everything/.codex-plugin/plugin.json +39 -0
  317. package/plugins/harness-everything/hooks/hooks.json +197 -0
  318. package/plugins/harness-everything/hooks/scripts/action-gate-rules.json +77 -0
  319. package/plugins/harness-everything/hooks/scripts/action-gate.js +528 -0
  320. package/plugins/harness-everything/hooks/scripts/atomic-commit-check.js +68 -0
  321. package/plugins/harness-everything/hooks/scripts/boundary-guard.js +55 -0
  322. package/plugins/harness-everything/hooks/scripts/codex-action-gate-post.js +46 -0
  323. package/plugins/harness-everything/hooks/scripts/codex-permission-request.js +140 -0
  324. package/plugins/harness-everything/hooks/scripts/context-compact.js +115 -0
  325. package/plugins/harness-everything/hooks/scripts/contract-test.js +146 -0
  326. package/plugins/harness-everything/hooks/scripts/depth-guard.js +65 -0
  327. package/plugins/harness-everything/hooks/scripts/lib/fable-contracts.js +121 -0
  328. package/plugins/harness-everything/hooks/scripts/lib/harness-state.js +275 -0
  329. package/plugins/harness-everything/hooks/scripts/lib/platforms/claude.js +168 -0
  330. package/plugins/harness-everything/hooks/scripts/lib/platforms/codex.js +88 -0
  331. package/plugins/harness-everything/hooks/scripts/lib/platforms/continue.js +91 -0
  332. package/plugins/harness-everything/hooks/scripts/lib/platforms/copilot.js +85 -0
  333. package/plugins/harness-everything/hooks/scripts/lib/platforms/cursor.js +89 -0
  334. package/plugins/harness-everything/hooks/scripts/lib/platforms/hermes.js +108 -0
  335. package/plugins/harness-everything/hooks/scripts/lib/platforms/index.js +17 -0
  336. package/plugins/harness-everything/hooks/scripts/lib/platforms/worktrees.js +20 -0
  337. package/plugins/harness-everything/hooks/scripts/lib/workspace.js +290 -0
  338. package/plugins/harness-everything/hooks/scripts/openai-session-start.js +81 -0
  339. package/plugins/harness-everything/hooks/scripts/reset-circuit-breaker.js +30 -0
  340. package/plugins/harness-everything/hooks/scripts/rule-of-3-tracker.js +125 -0
  341. package/plugins/harness-everything/hooks/scripts/rule-of-3.js +195 -0
  342. package/plugins/harness-everything/hooks/scripts/state-persist.js +100 -0
  343. package/plugins/harness-everything/hooks/scripts/stop-gate.js +80 -0
  344. package/plugins/harness-everything/hooks/scripts/subagent-scope-guard.js +194 -0
  345. package/plugins/harness-everything/hooks/scripts/subagent-start.js +19 -0
  346. package/plugins/harness-everything/hooks/scripts/subagent-stop.js +6 -0
  347. package/plugins/harness-everything/hooks/session-start.js +81 -0
  348. package/plugins/harness-everything/plugin.json +43 -0
  349. package/plugins/harness-everything/scripts/lib/advisory-text.js +174 -0
  350. package/plugins/harness-everything/skills/environment-detection/SKILL.md +41 -0
  351. package/plugins/harness-everything/skills/environment-detection/references/shell-syntax-rules.md +76 -0
  352. package/plugins/harness-everything/skills/environment-detection/scripts/preflight.js +103 -0
  353. package/plugins/harness-everything/skills/eval-harness/SKILL.md +42 -0
  354. package/plugins/harness-everything/skills/eval-harness/references/scoring-rubric.md +68 -0
  355. package/plugins/harness-everything/skills/eval-harness/scripts/evaluate.js +79 -0
  356. package/plugins/harness-everything/skills/fable-discipline/SKILL.md +41 -0
  357. package/plugins/harness-everything/skills/fable-discipline/references/discipline-rules.md +22 -0
  358. package/plugins/harness-everything/skills/fable-mode/CONTRACT-FORMAT.md +165 -0
  359. package/plugins/harness-everything/skills/fable-mode/SKILL.md +39 -0
  360. package/plugins/harness-everything/skills/fable-mode/agents/fable-orchestrator.md +159 -0
  361. package/plugins/harness-everything/skills/fable-mode/agents/fable-verifier.md +32 -0
  362. package/plugins/harness-everything/skills/fable-mode/agents/fable-worker-haiku.md +52 -0
  363. package/plugins/harness-everything/skills/fable-mode/agents/fable-worker-sonnet.md +53 -0
  364. package/plugins/harness-everything/skills/fable-mode/execution-guardrails/SKILL.md +43 -0
  365. package/plugins/harness-everything/skills/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
  366. package/plugins/harness-everything/skills/fable-mode/fable-haiku/SKILL.md +36 -0
  367. package/plugins/harness-everything/skills/fable-mode/fable-haiku/references/routing-notes.md +26 -0
  368. package/plugins/harness-everything/skills/fable-mode/fable-opus/SKILL.md +36 -0
  369. package/plugins/harness-everything/skills/fable-mode/fable-sonnet/SKILL.md +36 -0
  370. package/plugins/harness-everything/skills/fable-mode/model-matrix.json +32 -0
  371. package/plugins/harness-everything/skills/fable-mode/references/execution-phases.md +37 -0
  372. package/plugins/harness-everything/skills/fable-mode/references/model-matrix.md +39 -0
  373. package/plugins/harness-everything/skills/fable-mode/scripts/ensemble-review.js +371 -0
  374. package/plugins/harness-everything/skills/fable-mode/scripts/model-selector.js +260 -0
  375. package/plugins/harness-everything/skills/fable-mode/scripts/workflow-plan-consumer.js +337 -0
  376. package/plugins/harness-everything/skills/find-skills/SKILL.md +48 -0
  377. package/plugins/harness-everything/skills/find-skills/references/discovery-flow.md +102 -0
  378. package/plugins/harness-everything/skills/find-skills/scripts/use-skill.js +112 -0
  379. package/plugins/harness-everything/skills/git-commit/SKILL.md +38 -0
  380. package/plugins/harness-everything/skills/git-commit/guides/ANGULAR_STYLE.md +61 -0
  381. package/plugins/harness-everything/skills/git-commit/guides/COMMIT_GENERATION.md +24 -0
  382. package/plugins/harness-everything/skills/git-commit/guides/LANGUAGE_DETECTION.md +16 -0
  383. package/plugins/harness-everything/skills/git-commit/guides/MAIN_REPO.md +15 -0
  384. package/plugins/harness-everything/skills/git-commit/guides/SUBMODULES.md +27 -0
  385. package/plugins/harness-everything/skills/git-commit/references/commit-flow.md +30 -0
  386. package/plugins/harness-everything/skills/grill-me/SKILL.md +43 -0
  387. package/plugins/harness-everything/skills/grill-me/references/grilling-playbook.md +38 -0
  388. package/plugins/harness-everything/skills/grill-with-docs/ADR-FORMAT.md +47 -0
  389. package/plugins/harness-everything/skills/grill-with-docs/CONTEXT-FORMAT.md +63 -0
  390. package/plugins/harness-everything/skills/grill-with-docs/SKILL.md +41 -0
  391. package/plugins/harness-everything/skills/grill-with-docs/references/session-playbook.md +99 -0
  392. package/plugins/harness-everything/skills/harness-everything/SKILL.md +43 -0
  393. package/plugins/harness-everything/skills/harness-everything/examples/README.md +9 -0
  394. package/plugins/harness-everything/skills/harness-everything/examples/todo-workflow.md +22 -0
  395. package/plugins/harness-everything/skills/harness-everything/references/router-workflow-plan.md +128 -0
  396. package/plugins/harness-everything/skills/harness-everything/references/skill-registry.md +39 -0
  397. package/plugins/harness-everything/skills/harness-everything/references/triage-and-tiers.md +193 -0
  398. package/plugins/harness-everything/skills/harness-everything/schemas/router-task-shape.schema.json +126 -0
  399. package/plugins/harness-everything/skills/harness-everything/schemas/router-workflow-plan.schema.json +149 -0
  400. package/plugins/harness-everything/skills/harness-everything/scripts/bootstrap.js +212 -0
  401. package/plugins/harness-everything/skills/harness-everything/scripts/ensemble-policy.js +102 -0
  402. package/plugins/harness-everything/skills/harness-everything/scripts/kernel-router.js +212 -0
  403. package/plugins/harness-everything/skills/harness-everything/scripts/router-contract.js +612 -0
  404. package/plugins/harness-everything/skills/harness-everything/scripts/routing-keywords.json +320 -0
  405. package/plugins/harness-everything/skills/harness-everything/scripts/self-heal.js +250 -0
  406. package/plugins/harness-everything/skills/harness-everything/scripts/tier-router.js +459 -0
  407. package/plugins/harness-everything/skills/harness-everything/scripts/verify-gate.js +100 -0
  408. package/plugins/harness-everything/skills/improve-codebase-architecture/SKILL.md +38 -0
  409. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/DEEPENING.md +37 -0
  410. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/HTML-REPORT.md +123 -0
  411. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -0
  412. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/LANGUAGE.md +53 -0
  413. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
  414. package/plugins/harness-everything/skills/improve-codebase-architecture/references/README.md +16 -0
  415. package/plugins/harness-everything/skills/install-cognitive-os/SKILL.md +44 -0
  416. package/plugins/harness-everything/skills/install-cognitive-os/references/cognitive-loop.md +27 -0
  417. package/plugins/harness-everything/skills/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
  418. package/plugins/harness-everything/skills/multi-agent-workspace/SKILL.md +38 -0
  419. package/plugins/harness-everything/skills/multi-agent-workspace/examples/csharp-monorepo.md +123 -0
  420. package/plugins/harness-everything/skills/multi-agent-workspace/examples/typescript-cli.md +126 -0
  421. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-claude.md +77 -0
  422. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-codex.md +146 -0
  423. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-continue.md +38 -0
  424. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-copilot.md +74 -0
  425. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
  426. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
  427. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/role-capabilities.md +108 -0
  428. package/plugins/harness-everything/skills/multi-agent-workspace/references/agency-agents.md +31 -0
  429. package/plugins/harness-everything/skills/multi-agent-workspace/references/architecture-guide.md +36 -0
  430. package/plugins/harness-everything/skills/multi-agent-workspace/references/orchestration.md +65 -0
  431. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/agency-catalog.js +190 -0
  432. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/consume-workflow-plan.js +129 -0
  433. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/index_memory.js +104 -0
  434. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/path-boundary.js +59 -0
  435. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/project-docs-resolver.js +357 -0
  436. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/scaffold.js +408 -0
  437. package/plugins/harness-everything/skills/multi-agent-workspace/templates/AGENTS.md +20 -0
  438. package/plugins/harness-everything/skills/multi-agent-workspace/templates/README.md +17 -0
  439. package/plugins/harness-everything/skills/multi-agent-workspace/templates/agent-launcher.md +68 -0
  440. package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-csharp.md +56 -0
  441. package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-polyglot.md +62 -0
  442. package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-ts.md +57 -0
  443. package/plugins/harness-everything/skills/multi-agent-workspace/templates/memory-keeper.md +37 -0
  444. package/plugins/harness-everything/skills/multi-agent-workspace/templates/requirement-analyzer.md +66 -0
  445. package/plugins/harness-everything/skills/multi-agent-workspace/templates/specialist-agent.md +34 -0
  446. package/plugins/harness-everything/skills/multi-agent-workspace/templates/task-verifier.md +56 -0
  447. package/plugins/harness-everything/skills/multi-agent-workspace/templates/tool-maker.md +33 -0
  448. package/plugins/harness-everything/skills/multi-agent-workspace/workflows/01-init.md +22 -0
  449. package/plugins/harness-everything/skills/multi-agent-workspace/workflows/02-analysis.md +23 -0
  450. package/plugins/harness-everything/skills/multi-agent-workspace/workflows/03-generation.md +25 -0
  451. package/plugins/harness-everything/skills/multi-agent-workspace/workflows/04-launcher.md +16 -0
  452. package/plugins/harness-everything/skills/repo-docs/SKILL.md +42 -0
  453. package/plugins/harness-everything/skills/repo-docs/references/process-guide.md +60 -0
  454. package/plugins/harness-everything/skills/repo-docs/templates/agents-template.md +264 -0
  455. package/plugins/harness-everything/skills/repo-docs/templates/knowledge-agents-template.md +50 -0
  456. package/plugins/harness-everything/skills/repo-docs/templates/knowledge-readme-template.md +83 -0
  457. package/plugins/harness-everything/skills/repo-docs/templates/manual-recon.md +117 -0
  458. package/plugins/harness-everything/skills/repo-docs/templates/multi-skills-readme-template.md +72 -0
  459. package/plugins/harness-everything/skills/repo-docs/templates/product-agents-template.md +78 -0
  460. package/plugins/harness-everything/skills/repo-docs/templates/product-readme-template.md +95 -0
  461. package/plugins/harness-everything/skills/repo-docs/templates/readme-template.md +136 -0
  462. package/plugins/harness-everything/skills/repo-docs/templates/single-skill-readme-template.md +70 -0
  463. package/plugins/harness-everything/skills/repo-docs/templates/skills-agents-template.md +60 -0
  464. package/plugins/harness-everything/skills/rewrite-commits/SKILL.md +37 -0
  465. package/plugins/harness-everything/skills/rewrite-commits/references/workflow.md +18 -0
  466. package/plugins/harness-everything/skills/security-review/SKILL.md +47 -0
  467. package/plugins/harness-everything/skills/security-review/guides/OWASP-PATTERNS.md +31 -0
  468. package/plugins/harness-everything/skills/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
  469. package/plugins/harness-everything/skills/security-review/references/security-checklist.md +478 -0
  470. package/plugins/harness-everything/skills/security-review/scripts/audit-secrets.js +85 -0
  471. package/plugins/harness-everything/skills/self-evolve/SKILL.md +45 -0
  472. package/plugins/harness-everything/skills/self-evolve/references/memory-resolution.md +61 -0
  473. package/plugins/harness-everything/skills/self-evolve/scripts/persist-memory.js +272 -0
  474. package/plugins/harness-everything/skills/self-evolve/scripts/register-dynamic-skill.js +253 -0
  475. package/plugins/harness-everything/skills/self-evolve/scripts/self-regression.js +125 -0
  476. package/plugins/harness-everything/skills/skill-creator/SKILL.md +47 -0
  477. package/plugins/harness-everything/skills/skill-creator/references/authoring-workflow.md +14 -0
  478. package/plugins/harness-everything/skills/skill-creator/references/dynamic-generation-contract.md +21 -0
  479. package/plugins/harness-everything/skills/skill-creator/references/quality-checklist.md +16 -0
  480. package/plugins/harness-everything/skills/skill-creator/references/quality-principles.md +81 -0
  481. package/plugins/harness-everything/skills/skill-creator/references/testing-workflow.md +27 -0
  482. package/plugins/harness-everything/skills/skill-style/SKILL.md +42 -0
  483. package/plugins/harness-everything/skills/skill-style/references/style-guide.md +62 -0
  484. package/plugins/harness-everything/skills/tdd/SKILL.md +38 -0
  485. package/plugins/harness-everything/skills/tdd/fixtures/pass-evidence.json +100 -0
  486. package/plugins/harness-everything/skills/tdd/fixtures/quality-scenarios.json +20 -0
  487. package/plugins/harness-everything/skills/tdd/guides/deep-modules.md +33 -0
  488. package/plugins/harness-everything/skills/tdd/guides/interface-design.md +31 -0
  489. package/plugins/harness-everything/skills/tdd/guides/mocking.md +59 -0
  490. package/plugins/harness-everything/skills/tdd/guides/refactoring.md +10 -0
  491. package/plugins/harness-everything/skills/tdd/guides/tests.md +61 -0
  492. package/plugins/harness-everything/skills/tdd/references/core-discipline.md +51 -0
  493. package/plugins/harness-everything/skills/tdd/references/integration-testing.md +13 -0
  494. package/plugins/harness-everything/skills/tdd/references/quality-model.md +68 -0
  495. package/plugins/harness-everything/skills/tdd/references/unit-testing.md +15 -0
  496. package/plugins/harness-everything/skills/tdd/schemas/quality-evidence.schema.json +211 -0
  497. package/plugins/harness-everything/skills/tdd/schemas/quality-report.schema.json +110 -0
  498. package/plugins/harness-everything/skills/tdd/scripts/quality-gate.js +475 -0
  499. package/plugins/harness-everything/skills/to-spec/SKILL.md +40 -0
  500. package/plugins/harness-everything/skills/to-spec/references/process.md +77 -0
  501. package/plugins/harness-everything/skills/to-spec/scripts/check-project-docs.js +239 -0
  502. package/plugins/harness-everything/skills/to-spec/scripts/project-docs-resolver.js +111 -0
  503. package/plugins/harness-everything/skills/to-spec/templates/cli-reference.md +31 -0
  504. package/plugins/harness-everything/skills/to-spec/templates/dev-doc.md +27 -0
  505. package/plugins/harness-everything/skills/to-spec/templates/feature-spec.md +59 -0
  506. package/plugins/harness-everything/skills/to-spec/templates/schema-doc.md +31 -0
  507. package/plugins/harness-everything/skills/to-tickets/SKILL.md +42 -0
  508. package/plugins/harness-everything/skills/to-tickets/references/publishing-and-templates.md +97 -0
  509. package/plugins/harness-everything/skills/todo-driven-workflow/SKILL.md +42 -0
  510. package/plugins/harness-everything/skills/todo-driven-workflow/references/execution-guide.md +27 -0
  511. package/plugins/harness-everything/skills/using-git-worktrees/SKILL.md +49 -0
  512. package/plugins/harness-everything/skills/using-git-worktrees/references/workflow-details.md +108 -0
  513. package/plugins/harness-everything/skills/verification-loop/SKILL.md +46 -0
  514. package/plugins/harness-everything/skills/verification-loop/references/verification-phases.md +116 -0
  515. package/plugins/harness-everything/skills/verification-loop/templates/verification-report.template.md +15 -0
  516. package/plugins/harness-everything/skills/verify-before-claim/SKILL.md +43 -0
  517. package/plugins/harness-everything/skills/verify-before-claim/references/verification-guide.md +73 -0
  518. package/plugins/harness-everything/skills/zoom-out/SKILL.md +42 -0
  519. package/plugins/harness-everything/skills/zoom-out/references/circuit-breaker.md +66 -0
  520. package/plugins/harness-everything/skills/zoom-out/templates/zoom-out-report.template.md +20 -0
  521. package/repo-docs/SKILL.md +3 -7
  522. package/rewrite-commits/SKILL.md +2 -2
  523. package/scripts/build-openai-submission.js +158 -0
  524. package/scripts/installer.js +86 -11
  525. package/scripts/lib/advisory-text.js +25 -18
  526. package/scripts/lib/execution-contract.js +70 -0
  527. package/scripts/lib/manifest.js +34 -38
  528. package/scripts/lib/path-boundary.js +90 -0
  529. package/scripts/lib/skills.js +124 -70
  530. package/scripts/lib/workspace.js +269 -7
  531. package/scripts/sync-openai-plugin.js +91 -0
  532. package/scripts/sync-release-version.js +212 -0
  533. package/security-review/SKILL.md +4 -7
  534. package/security-review/scripts/audit-secrets.js +9 -8
  535. package/self-evolve/SKILL.md +9 -11
  536. package/self-evolve/references/memory-resolution.md +4 -1
  537. package/self-evolve/scripts/persist-memory.js +221 -88
  538. package/self-evolve/scripts/register-dynamic-skill.js +12 -10
  539. package/self-evolve/scripts/self-regression.js +23 -8
  540. package/skill-creator/SKILL.md +12 -14
  541. package/skill-creator/references/quality-checklist.md +1 -0
  542. package/skill-style/SKILL.md +4 -4
  543. package/skill-style/references/style-guide.md +29 -3
  544. package/submission/openai/README.md +67 -0
  545. package/submission/openai/listing.json +31 -0
  546. package/submission/openai/test-cases.json +61 -0
  547. package/tdd/SKILL.md +20 -26
  548. package/tdd/fixtures/pass-evidence.json +100 -0
  549. package/tdd/fixtures/quality-scenarios.json +20 -0
  550. package/tdd/references/core-discipline.md +2 -0
  551. package/tdd/references/integration-testing.md +13 -0
  552. package/tdd/references/quality-model.md +68 -0
  553. package/tdd/references/unit-testing.md +15 -0
  554. package/tdd/schemas/quality-evidence.schema.json +211 -0
  555. package/tdd/schemas/quality-report.schema.json +110 -0
  556. package/tdd/scripts/quality-gate.js +475 -0
  557. package/to-spec/SKILL.md +3 -5
  558. package/to-spec/scripts/check-project-docs.js +42 -62
  559. package/to-spec/scripts/project-docs-resolver.js +111 -0
  560. package/to-tickets/SKILL.md +4 -4
  561. package/todo-driven-workflow/SKILL.md +6 -4
  562. package/using-git-worktrees/SKILL.md +3 -3
  563. package/verification-loop/SKILL.md +4 -4
  564. package/verify-before-claim/SKILL.md +2 -2
  565. package/zoom-out/SKILL.md +4 -4
  566. package/ab-test-deep-analysis-2026-08-27.md +0 -383
  567. package/ab-test-results-2026-08-27.md +0 -152
  568. package/ab-test-statistical-analysis-31cases.md +0 -193
  569. package/opencode-plugin/hooks/circuit-breaker.js +0 -121
  570. package/opencode-plugin/hooks/compliance.js +0 -128
  571. package/opencode-plugin/hooks/post-edit.js +0 -62
  572. package/opencode-plugin/hooks/pre-complete.js +0 -65
  573. package/opencode-plugin/test-hook-firing.js +0 -198
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+ const path = require('path');
7
+ const { spawn, spawnSync } = require('child_process');
8
+
9
+ const ROOT = path.resolve(__dirname, '..');
10
+ const actionGatePath = path.join(ROOT, 'hooks', 'scripts', 'action-gate.js');
11
+ const pluginActionGatePath = path.join(ROOT, 'plugins', 'harness-everything', 'hooks', 'scripts', 'action-gate.js');
12
+ const rulesPath = path.join(ROOT, 'hooks', 'scripts', 'action-gate-rules.json');
13
+ const actionGate = require(actionGatePath);
14
+ const claudePlatform = require(path.join(ROOT, 'hooks', 'scripts', 'lib', 'platforms', 'claude.js'));
15
+
16
+ let failed = 0;
17
+ function check(condition, message) {
18
+ if (condition) console.log(` PASS ${message}`);
19
+ else {
20
+ console.error(` FAIL ${message}`);
21
+ failed++;
22
+ }
23
+ }
24
+
25
+ function collectCommands(manifest) {
26
+ const commands = [];
27
+ for (const [event, groups] of Object.entries((manifest && manifest.hooks) || {})) {
28
+ for (const group of groups || []) {
29
+ for (const hook of group.hooks || []) {
30
+ if (hook.type === 'command' && hook.command) commands.push({ event, command: hook.command });
31
+ }
32
+ }
33
+ }
34
+ return commands;
35
+ }
36
+
37
+ function scriptFromClaudeCommand(command, pluginRoot) {
38
+ const match = String(command).match(/^node\s+"([^"]+)"/);
39
+ if (!match) return null;
40
+ return match[1].replace(/\$\{CLAUDE_PLUGIN_ROOT\}/g, pluginRoot);
41
+ }
42
+
43
+ function probeHookModule(entry, script, cwd) {
44
+ if (entry.event === 'SessionStart') {
45
+ return spawnSync(process.execPath, [script], {
46
+ cwd,
47
+ encoding: 'utf8',
48
+ input: JSON.stringify({
49
+ hook_event_name: 'SessionStart',
50
+ session_id: 'issue99-cwd-probe',
51
+ cwd,
52
+ }),
53
+ env: { ...process.env, CLAUDE_PLUGIN_ROOT: ROOT },
54
+ });
55
+ }
56
+ return spawnSync(process.execPath, ['-e', 'require(process.argv[1])', script], {
57
+ cwd,
58
+ encoding: 'utf8',
59
+ env: { ...process.env, CLAUDE_PLUGIN_ROOT: ROOT },
60
+ });
61
+ }
62
+
63
+ function readAudit(sessionDir, toolUseId) {
64
+ const file = path.join(sessionDir, 'action-gate', `${toolUseId}.json`);
65
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
66
+ }
67
+
68
+ function makePayload(command, options = {}) {
69
+ return {
70
+ session_id: options.sessionId || 'issue99',
71
+ hook_event_name: options.event || 'PreToolUse',
72
+ tool_name: options.tool || 'Bash',
73
+ tool_use_id: options.toolUseId || 'issue99-tool',
74
+ tool_input: { command },
75
+ cwd: options.cwd || ROOT,
76
+ };
77
+ }
78
+
79
+ function runTimerExitCase(scriptPath, cwd) {
80
+ return new Promise((resolve, reject) => {
81
+ const child = spawn(process.execPath, [scriptPath], {
82
+ cwd,
83
+ env: {
84
+ ...process.env,
85
+ HARNESS_ACTION_GATE_HOST: 'codex',
86
+ HARNESS_ACTION_GATE_STDIN_TIMEOUT_MS: '50',
87
+ },
88
+ stdio: ['pipe', 'pipe', 'pipe'],
89
+ });
90
+ let stdout = '';
91
+ let stderr = '';
92
+ child.stdout.on('data', chunk => { stdout += chunk.toString(); });
93
+ child.stderr.on('data', chunk => { stderr += chunk.toString(); });
94
+ child.on('error', reject);
95
+ child.on('close', code => resolve({ code, stdout, stderr }));
96
+
97
+ child.stdin.write(JSON.stringify(makePayload('git push --force origin main', {
98
+ toolUseId: 'timer-block',
99
+ cwd,
100
+ })));
101
+ setTimeout(() => child.stdin.end(), 140);
102
+ });
103
+ }
104
+
105
+ async function main() {
106
+ console.log('=== Issue #99 — runtime correctness ===');
107
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-issue99-'));
108
+ const sessionDir = path.join(tempRoot, 'session');
109
+ fs.mkdirSync(sessionDir, { recursive: true });
110
+
111
+ try {
112
+ const hooks = JSON.parse(fs.readFileSync(path.join(ROOT, 'hooks', 'hooks.json'), 'utf8'));
113
+ const commands = collectCommands(hooks);
114
+ check(commands.length > 0, 'canonical Claude hook manifest contains command hooks');
115
+ check(commands.every(entry => entry.command.includes('${CLAUDE_PLUGIN_ROOT}/')), 'every canonical Claude plugin hook is anchored to CLAUDE_PLUGIN_ROOT');
116
+
117
+ for (const entry of commands) {
118
+ const script = scriptFromClaudeCommand(entry.command, ROOT);
119
+ check(Boolean(script) && fs.existsSync(script), `${entry.event} hook resolves from plugin root: ${path.relative(ROOT, script || '')}`);
120
+ if (!script || !fs.existsSync(script)) continue;
121
+ const loaded = probeHookModule(entry, script, tempRoot);
122
+ check(
123
+ loaded.status === 0 && !/MODULE_NOT_FOUND|Cannot find module/i.test(`${loaded.stdout}\n${loaded.stderr}`),
124
+ `${entry.event} hook resolves and starts from unrelated cwd`,
125
+ );
126
+ }
127
+
128
+ const targetWorkspace = path.join(tempRoot, 'installed-project');
129
+ fs.mkdirSync(targetWorkspace, { recursive: true });
130
+ const claudeHooks = {
131
+ mergeHarnessHooks(config, resolved) { config.hooks = resolved; },
132
+ removeHarnessHooks() {},
133
+ };
134
+ const manifest = {
135
+ PACKAGE_NAME: 'harness-everything',
136
+ HARNESS_AUTHOR: 'Miya Daniel',
137
+ getManifestPath(dir) { return path.join(dir, 'harness-manifest.json'); },
138
+ };
139
+ claudePlatform.install({
140
+ isGlobal: false,
141
+ targetWorkspaceRoot: targetWorkspace,
142
+ harnessSourceDir: ROOT,
143
+ packageVersion: 'issue99-test',
144
+ claudeHooks,
145
+ manifest,
146
+ });
147
+ const installedSettings = JSON.parse(fs.readFileSync(path.join(targetWorkspace, '.claude', 'settings.json'), 'utf8'));
148
+ const installedCommands = collectCommands(installedSettings);
149
+ check(installedCommands.length === commands.length, 'Claude installer preserves the full hook command set');
150
+ for (const entry of installedCommands) {
151
+ check(!entry.command.includes('${CLAUDE_PLUGIN_ROOT}'), `${entry.event} installer substitutes CLAUDE_PLUGIN_ROOT`);
152
+ const match = entry.command.match(/^node\s+"([^"]+)"/);
153
+ check(Boolean(match) && path.isAbsolute(match[1]) && fs.existsSync(match[1]), `${entry.event} installer writes an existing absolute hook path`);
154
+ }
155
+
156
+ const table = actionGate.loadRuleTable(rulesPath);
157
+ const outside = process.platform === 'win32' ? 'C:\\harness-issue99-critical' : '/opt/harness-issue99-critical';
158
+ const safeOne = path.join(os.tmpdir(), 'harness-issue99-safe-a');
159
+ const safeTwo = path.join(os.tmpdir(), 'harness-issue99-safe-b');
160
+
161
+ const chainedBash = makePayload(`rm -rf "${safeOne}" && rm -rf "${outside}"`, { toolUseId: 'bash-chain' });
162
+ const chainedBashDecision = actionGate.evaluatePreToolUse(chainedBash, { host: 'claude', sessionDir, ruleTable: table });
163
+ check(chainedBashDecision.kind === 'defer' && chainedBashDecision.rule.id === 'recursive-delete', 'chained rm checks every target and gates the outside-scratch delete');
164
+
165
+ const safeBashDecision = actionGate.evaluatePreToolUse(
166
+ makePayload(`rm -rf "${safeOne}" && rm -rf "${safeTwo}"`, { toolUseId: 'bash-safe-chain' }),
167
+ { host: 'claude', sessionDir, ruleTable: table },
168
+ );
169
+ check(safeBashDecision.kind === 'allow', 'chained rm remains exempt when every target is scratch/temp');
170
+
171
+ const chainedPs = makePayload(
172
+ `Remove-Item -Recurse -Force "${safeOne}"; Remove-Item -Recurse -Force "${outside}"`,
173
+ { tool: 'PowerShell', toolUseId: 'ps-chain' },
174
+ );
175
+ const chainedPsDecision = actionGate.evaluatePreToolUse(chainedPs, { host: 'claude', sessionDir, ruleTable: table });
176
+ check(chainedPsDecision.kind === 'defer' && chainedPsDecision.rule.id === 'powershell-recursive-force-delete', 'chained Remove-Item checks every target and gates the outside-scratch delete');
177
+
178
+ const pre = makePayload('npm publish', { toolUseId: 'post-error-preserve' });
179
+ actionGate.evaluatePreToolUse(pre, { host: 'claude', sessionDir, ruleTable: table });
180
+ actionGate.processEvent({ ...pre, hook_event_name: 'PostToolUse' }, { sessionDir });
181
+ const beforeError = readAudit(sessionDir, 'post-error-preserve');
182
+ check(beforeError.disposition === 'executed', 'setup: approved payload reaches executed before audit-error probe');
183
+
184
+ const postError = actionGate.internalErrorDecision(
185
+ { ...pre, hook_event_name: 'PostToolUse' },
186
+ new Error('synthetic post-tool audit failure'),
187
+ { host: 'claude', sessionDir },
188
+ );
189
+ check(postError.kind === 'audit-error' && postError.exitCode === 0 && postError.stdout === null, 'PostToolUse internal error never emits a PreToolUse ask decision');
190
+ check(readAudit(sessionDir, 'post-error-preserve').disposition === 'executed', 'PostToolUse internal error does not overwrite an executed audit record');
191
+
192
+ const stopError = actionGate.internalErrorDecision(
193
+ { ...pre, hook_event_name: 'Stop' },
194
+ new Error('synthetic stop audit failure'),
195
+ { host: 'claude', sessionDir },
196
+ );
197
+ check(stopError.kind === 'audit-error' && stopError.stdout === null, 'Stop internal error remains an audit error, not an authorization prompt');
198
+
199
+ check(fs.readFileSync(actionGatePath, 'utf8') === fs.readFileSync(pluginActionGatePath, 'utf8'), 'canonical and Codex/OpenAI plugin action-gate runtimes are byte-identical');
200
+
201
+ const timerResult = await runTimerExitCase(actionGatePath, tempRoot);
202
+ check(timerResult.code === 2, 'stdin timeout path preserves Codex exit-2 fail-closed decision');
203
+ check(/git-force-push/.test(timerResult.stderr), 'stdin timeout block still reports the matched destructive rule');
204
+ } catch (err) {
205
+ console.error(err.stack || err.message);
206
+ failed++;
207
+ } finally {
208
+ try { fs.rmSync(tempRoot, { recursive: true, force: true }); } catch (_) {}
209
+ }
210
+
211
+ console.log(`\n${failed === 0 ? 'PASS' : 'FAIL'}: issue #99 runtime correctness (${failed} failure${failed === 1 ? '' : 's'})`);
212
+ process.exit(failed === 0 ? 0 : 1);
213
+ }
214
+
215
+ main().catch(err => {
216
+ console.error(err.stack || err.message);
217
+ process.exit(1);
218
+ });
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const assert = require('assert');
5
+ const fs = require('fs');
6
+ const os = require('os');
7
+ const path = require('path');
8
+
9
+ const ROOT = path.resolve(__dirname, '..');
10
+ const actionGate = require(path.join(ROOT, 'hooks', 'scripts', 'action-gate.js'));
11
+ const permissionRequest = require(path.join(ROOT, 'hooks', 'scripts', 'codex-permission-request.js'));
12
+
13
+ const pluginRoot = path.join(ROOT, 'plugins', 'harness-everything');
14
+ const pluginHooksPath = path.join(pluginRoot, 'hooks', 'hooks.json');
15
+ const canonicalPost = path.join(ROOT, 'hooks', 'scripts', 'codex-action-gate-post.js');
16
+ const packagedPost = path.join(pluginRoot, 'hooks', 'scripts', 'codex-action-gate-post.js');
17
+ const canonicalPermission = path.join(ROOT, 'hooks', 'scripts', 'codex-permission-request.js');
18
+ const packagedPermission = path.join(pluginRoot, 'hooks', 'scripts', 'codex-permission-request.js');
19
+
20
+ function payload(command, options = {}) {
21
+ return {
22
+ session_id: options.sessionId || 'codex-action-gate-policy-test',
23
+ hook_event_name: options.event || 'PreToolUse',
24
+ turn_id: options.turnId || 'turn_policy_test',
25
+ tool_name: options.tool || 'Bash',
26
+ tool_use_id: options.toolUseId || 'toolu_policy_test',
27
+ tool_input: options.tool === 'apply_patch' ? { patch: command } : { command },
28
+ permission_mode: options.permissionMode || 'default',
29
+ cwd: ROOT,
30
+ };
31
+ }
32
+
33
+ function commandPaths(hooks) {
34
+ const paths = [];
35
+ for (const groups of Object.values(hooks || {})) {
36
+ for (const group of groups || []) {
37
+ for (const hook of group.hooks || []) {
38
+ for (const field of ['command', 'commandWindows']) {
39
+ const command = hook[field];
40
+ if (typeof command !== 'string') continue;
41
+ const match = command.match(/(?:\$PLUGIN_ROOT|%PLUGIN_ROOT%)[\\/]([^"']+)/);
42
+ if (match) paths.push(match[1].replace(/\\/g, '/'));
43
+ }
44
+ }
45
+ }
46
+ }
47
+ return paths;
48
+ }
49
+
50
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-codex-policy-'));
51
+ const sessionDir = path.join(tempRoot, 'session');
52
+ fs.mkdirSync(sessionDir, { recursive: true });
53
+
54
+ try {
55
+ assert.ok(fs.existsSync(canonicalPost), 'Codex PostToolUse adapter must live in canonical hooks/scripts so plugin:sync cannot delete it');
56
+ assert.ok(fs.existsSync(packagedPost), 'Codex PostToolUse adapter must be packaged');
57
+ assert.strictEqual(fs.readFileSync(canonicalPost, 'utf8'), fs.readFileSync(packagedPost, 'utf8'), 'canonical and packaged Codex PostToolUse adapters must be byte-equivalent');
58
+
59
+ assert.ok(fs.existsSync(canonicalPermission), 'Codex PermissionRequest adapter must live in canonical hooks/scripts');
60
+ assert.ok(fs.existsSync(packagedPermission), 'Codex PermissionRequest adapter must be packaged');
61
+ assert.strictEqual(fs.readFileSync(canonicalPermission, 'utf8'), fs.readFileSync(packagedPermission, 'utf8'), 'canonical and packaged PermissionRequest adapters must be byte-equivalent');
62
+
63
+ const hookConfig = JSON.parse(fs.readFileSync(pluginHooksPath, 'utf8'));
64
+ assert.ok(Array.isArray(hookConfig.hooks.PermissionRequest), 'Codex plugin must declare PermissionRequest');
65
+ assert.ok(!Object.prototype.hasOwnProperty.call(hookConfig.hooks, 'PostToolUseFailure'), 'Codex plugin must not invent PostToolUseFailure');
66
+ const permissionCommands = hookConfig.hooks.PermissionRequest.flatMap(group => (group.hooks || []).map(hook => hook.command || ''));
67
+ assert.ok(permissionCommands.some(command => command.includes('codex-permission-request.js')), 'PermissionRequest must invoke the native approval observer');
68
+
69
+ for (const relativePath of new Set(commandPaths(hookConfig.hooks))) {
70
+ assert.ok(fs.existsSync(path.join(pluginRoot, relativePath)), `hook command target must exist in plugin package: ${relativePath}`);
71
+ }
72
+
73
+ const table = actionGate.loadRuleTable(path.join(ROOT, 'hooks', 'scripts', 'action-gate-rules.json'));
74
+ const destructive = payload('git push --force origin main', { toolUseId: 'codex-hard-block' });
75
+ const pre = actionGate.evaluatePreToolUse(destructive, { host: 'codex', sessionDir, ruleTable: table });
76
+ assert.strictEqual(pre.kind, 'block', 'Codex destructive PreToolUse must remain fail-closed');
77
+ assert.strictEqual(pre.exitCode, 2, 'Codex destructive PreToolUse must use the supported exit-2 block fallback');
78
+ assert.strictEqual(pre.stdout, null, 'Codex PreToolUse must never emit permissionDecision=ask');
79
+ assert.ok(pre.stderr.includes('git-force-push'), 'Codex block reason must identify the matched rule');
80
+
81
+ const approvalPayload = payload('git push --force origin main', {
82
+ event: 'PermissionRequest',
83
+ toolUseId: undefined,
84
+ turnId: 'turn_native_approval',
85
+ });
86
+ delete approvalPayload.tool_use_id;
87
+ const approval = permissionRequest.processPayload(approvalPayload, { sessionDir, ruleTable: table });
88
+ assert.strictEqual(approval.kind, 'defer', 'PermissionRequest must defer to Codex native approval');
89
+ assert.strictEqual(approval.exitCode, 0, 'PermissionRequest observer must not block an approval already surfaced by Codex');
90
+ assert.strictEqual(approval.stdout, null, 'PermissionRequest observer must emit no allow/deny decision');
91
+ assert.strictEqual(approval.record.disposition, 'deferred-to-codex-approval');
92
+ assert.strictEqual(approval.record.matchedRule, 'git-force-push');
93
+ assert.strictEqual(approval.record.exactToolCallCorrelation, false, 'PermissionRequest audit must not claim unavailable tool_use_id correlation');
94
+ assert.strictEqual(approval.record.correlation, 'turn-id-and-payload-hash-only');
95
+ assert.ok(fs.existsSync(approval.auditFile), 'PermissionRequest audit evidence must be persisted');
96
+
97
+ const stored = JSON.parse(fs.readFileSync(approval.auditFile, 'utf8'));
98
+ assert.strictEqual(stored.payloadHash, permissionRequest.hashExact('git push --force origin main'), 'PermissionRequest audit must hash the exact tool payload');
99
+ assert.ok(!Object.prototype.hasOwnProperty.call(stored, 'command'), 'PermissionRequest audit must not persist raw command text');
100
+ assert.ok(!Object.prototype.hasOwnProperty.call(stored, 'toolInput'), 'PermissionRequest audit must not persist raw tool input');
101
+
102
+ const safeApproval = permissionRequest.processPayload(payload('git status', {
103
+ event: 'PermissionRequest',
104
+ turnId: 'turn_safe_native_approval',
105
+ }), { sessionDir, ruleTable: table });
106
+ assert.strictEqual(safeApproval.kind, 'defer');
107
+ assert.strictEqual(safeApproval.record.matchedRule, null, 'native approval audit may exist even when Harness classifier has no destructive match');
108
+
109
+ const error = permissionRequest.internalErrorResult(new Error('synthetic failure'));
110
+ assert.strictEqual(error.exitCode, 0, 'PermissionRequest audit failure must not override an approval Codex already surfaced');
111
+ assert.strictEqual(error.stdout, null, 'PermissionRequest audit failure must not emit allow/deny/ask');
112
+ assert.ok(/Native Codex approval flow remains authoritative/.test(error.stderr));
113
+
114
+ console.log('PASS: Codex action-gate uses supported hard blocking plus non-authorizing native PermissionRequest observation.');
115
+ } finally {
116
+ fs.rmSync(tempRoot, { recursive: true, force: true });
117
+ }
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const assert = require('assert');
5
+ const crypto = require('crypto');
6
+ const { spawnSync } = require('child_process');
7
+ const fs = require('fs');
8
+ const os = require('os');
9
+ const path = require('path');
10
+
11
+ const ROOT = path.resolve(__dirname, '..');
12
+
13
+ function treeDigest(root) {
14
+ const hash = crypto.createHash('sha256');
15
+ function visit(dir, relative = '') {
16
+ const entries = fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
17
+ for (const entry of entries) {
18
+ const rel = relative ? `${relative}/${entry.name}` : entry.name;
19
+ const full = path.join(dir, entry.name);
20
+ hash.update(`${entry.isDirectory() ? 'D' : 'F'}:${rel}\0`);
21
+ if (entry.isDirectory()) visit(full, rel);
22
+ else if (entry.isFile()) hash.update(fs.readFileSync(full));
23
+ }
24
+ }
25
+ visit(root);
26
+ return hash.digest('hex');
27
+ }
28
+
29
+ const tempBase = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-plugin-sync-'));
30
+ const copyRoot = path.join(tempBase, 'repo');
31
+
32
+ try {
33
+ fs.cpSync(ROOT, copyRoot, {
34
+ recursive: true,
35
+ filter(source) {
36
+ const rel = path.relative(ROOT, source).replace(/\\/g, '/');
37
+ if (!rel) return true;
38
+ return !(
39
+ rel === '.git' || rel.startsWith('.git/') ||
40
+ rel === 'node_modules' || rel.startsWith('node_modules/') ||
41
+ rel === '.harness' || rel.startsWith('.harness/')
42
+ );
43
+ },
44
+ });
45
+
46
+ const pluginRoot = path.join(copyRoot, 'plugins', 'harness-everything');
47
+ const before = treeDigest(pluginRoot);
48
+ const run = spawnSync(process.execPath, [path.join(copyRoot, 'scripts', 'sync-openai-plugin.js')], {
49
+ cwd: copyRoot,
50
+ encoding: 'utf8',
51
+ });
52
+ assert.strictEqual(run.status, 0, `plugin:sync equivalent failed:\n${run.stdout}\n${run.stderr}`);
53
+ const after = treeDigest(pluginRoot);
54
+ assert.strictEqual(after, before, 'sync-openai-plugin.js must be idempotent against the committed plugin package');
55
+
56
+ const hooks = JSON.parse(fs.readFileSync(path.join(pluginRoot, 'hooks', 'hooks.json'), 'utf8'));
57
+ const referenced = new Set();
58
+ for (const groups of Object.values(hooks.hooks || {})) {
59
+ for (const group of groups || []) {
60
+ for (const hook of group.hooks || []) {
61
+ for (const field of ['command', 'commandWindows']) {
62
+ const command = hook[field];
63
+ if (typeof command !== 'string') continue;
64
+ const match = command.match(/(?:\$PLUGIN_ROOT|%PLUGIN_ROOT%)[\\/]([^"']+)/);
65
+ if (match) referenced.add(match[1].replace(/\\/g, '/'));
66
+ }
67
+ }
68
+ }
69
+ }
70
+ for (const relative of referenced) {
71
+ assert.ok(fs.existsSync(path.join(pluginRoot, relative)), `sync must preserve every hook target: ${relative}`);
72
+ }
73
+
74
+ assert.ok(fs.existsSync(path.join(pluginRoot, 'hooks', 'scripts', 'codex-action-gate-post.js')), 'sync must preserve the Codex PostToolUse adapter');
75
+ assert.ok(fs.existsSync(path.join(pluginRoot, 'hooks', 'scripts', 'codex-permission-request.js')), 'sync must preserve the Codex PermissionRequest adapter');
76
+
77
+ console.log('PASS: OpenAI/Codex plugin sync is idempotent and preserves every referenced hook runtime file.');
78
+ } finally {
79
+ fs.rmSync(tempBase, { recursive: true, force: true });
80
+ }
@@ -1,5 +1,8 @@
1
1
  const helper = require('./test-helper');
2
- const { buildEngineInvocation } = require('../behavioral-evals/run');
2
+ const fs = require('fs');
3
+ const os = require('os');
4
+ const path = require('path');
5
+ const { buildEngineInvocation, buildWorkspace } = require('../behavioral-evals/run');
3
6
 
4
7
  console.log('\n[2j] Behavioral runner argv integrity...');
5
8
  const prompt = "Add punctuation stripping to slug.js, then run npm test. Do not truncate this request.";
@@ -16,5 +19,44 @@ const baseline = buildEngineInvocation('claude', prompt, 'C:/fixture with spaces
16
19
  helper.check('2j. Claude baseline excludes user customizations', baseline.args.includes('--safe-mode') && baseline.args.includes('--setting-sources') && baseline.args.includes('project,local'), JSON.stringify(baseline.args));
17
20
  const treatment = buildEngineInvocation('claude', prompt, 'C:/fixture with spaces', 16, 'treatment');
18
21
  helper.check('2j. Claude treatment keeps only project/local customizations', treatment.args.includes('--setting-sources') && treatment.args.includes('project,local') && !treatment.args.includes('--safe-mode'), JSON.stringify(treatment.args));
22
+ helper.check('2j. Claude emits parseable verbose stream JSON', treatment.args.includes('--output-format') && treatment.args.includes('stream-json') && treatment.args.includes('--verbose') && !treatment.args.includes('json'), JSON.stringify(treatment.args));
23
+
24
+ let validWorkspace = null;
25
+ try {
26
+ validWorkspace = buildWorkspace({
27
+ id: 'fixture-valid',
28
+ fixture: { files: [{ path: 'nested/fixture.txt', content: 'fixture smoke proof' }] },
29
+ });
30
+ helper.check(
31
+ '2j. behavioral workspace builder accepts a valid nested fixture through the public execution contract',
32
+ fs.readFileSync(path.join(validWorkspace, 'nested', 'fixture.txt'), 'utf8') === 'fixture smoke proof\n',
33
+ validWorkspace
34
+ );
35
+ } catch (error) {
36
+ helper.check(
37
+ '2j. behavioral workspace builder accepts a valid nested fixture through the public execution contract',
38
+ false,
39
+ error && error.stack ? error.stack : String(error)
40
+ );
41
+ } finally {
42
+ if (validWorkspace) fs.rmSync(validWorkspace, { recursive: true, force: true });
43
+ }
44
+
45
+ const traversalTarget = path.join(os.tmpdir(), `harness-behavioral-traversal-${process.pid}-${Date.now()}.txt`);
46
+ let traversalError = null;
47
+ try {
48
+ buildWorkspace({ id: 'fixture-traversal', fixture: { files: [{ path: `../${path.basename(traversalTarget)}`, content: 'path traversal proof' }] } });
49
+ } catch (error) {
50
+ traversalError = error;
51
+ }
52
+ helper.check(
53
+ '2j. behavioral fixtures reject traversal for the expected boundary reason',
54
+ Boolean(
55
+ traversalError &&
56
+ /path must stay inside the generated workspace/.test(traversalError.message) &&
57
+ !fs.existsSync(traversalTarget)
58
+ ),
59
+ traversalError && traversalError.stack ? traversalError.stack : traversalTarget
60
+ );
19
61
 
20
62
  helper.finish();
@@ -7,14 +7,69 @@ console.log('\n[2k] Skill reference checker negative control...');
7
7
  const root = helper.tempDir('.mechanism-test-reference-check');
8
8
  const skill = path.join(root, 'fixture-skill');
9
9
  fs.mkdirSync(skill, { recursive: true });
10
- fs.writeFileSync(path.join(skill, 'SKILL.md'), 'Run `scripts/missing.js` before editing.\n');
10
+ fs.writeFileSync(path.join(skill, 'SKILL.md'), 'Run `<this-skill-dir>/scripts/missing.js` before editing.\n');
11
11
  let result = checkSkillReferences(root, ['fixture-skill']);
12
- helper.check('2k. dangling executable reference fails', result.failures.length === 1 && result.failures[0].reference === 'scripts/missing.js', JSON.stringify(result.failures));
12
+ helper.check('2k. dangling executable reference fails', result.failures.length === 1 && result.failures[0].reference === '<this-skill-dir>/scripts/missing.js', JSON.stringify(result.failures));
13
13
 
14
14
  fs.mkdirSync(path.join(skill, 'scripts'), { recursive: true });
15
15
  fs.writeFileSync(path.join(skill, 'scripts', 'missing.js'), '');
16
16
  result = checkSkillReferences(root, ['fixture-skill']);
17
17
  helper.check('2k. existing executable reference passes', result.failures.length === 0, JSON.stringify(result.failures));
18
18
 
19
+ // Regression: skill-local paths must say which base they use. A bare path
20
+ // used to pass because the checker guessed the current skill directory.
21
+ fs.mkdirSync(path.join(skill, 'references'), { recursive: true });
22
+ fs.writeFileSync(path.join(skill, 'references', 'guide.md'), '');
23
+ fs.writeFileSync(path.join(skill, 'SKILL.md'), 'Deep dive: `references/guide.md`\n');
24
+ result = checkSkillReferences(root, ['fixture-skill']);
25
+ helper.check(
26
+ '2k. bare skill-local paths fail the explicit marker rule',
27
+ result.failures.length === 1 && result.failures[0].reference === 'references/guide.md' && result.failures[0].target.includes('bare path'),
28
+ JSON.stringify(result.failures)
29
+ );
30
+ fs.writeFileSync(path.join(skill, 'SKILL.md'), 'Deep dive: `<this-skill-dir>/references/guide.md`\n');
31
+ result = checkSkillReferences(root, ['fixture-skill']);
32
+ helper.check('2k. explicit skill-local paths pass', result.failures.length === 0, JSON.stringify(result.failures));
33
+
34
+ // --- placeholder heads are authoritative and unknown ones fail ------------
35
+ // Regression: `<this-skill-dir>/hooks/x.js` used to jump to the repo root
36
+ // because a hardcoded ROOT_PREFIXES list outranked the explicit placeholder.
37
+ fs.mkdirSync(path.join(root, 'hooks'), { recursive: true });
38
+ fs.writeFileSync(path.join(root, 'hooks', 'shared.js'), '');
39
+ fs.writeFileSync(path.join(skill, 'SKILL.md'), 'Run `<this-skill-dir>/hooks/shared.js` first.\n');
40
+ result = checkSkillReferences(root, ['fixture-skill']);
41
+ helper.check(
42
+ '2k. <this-skill-dir>/ is authoritative and never falls back to the repo root',
43
+ result.failures.length === 1 && result.failures[0].target.split(path.sep).join('/') === 'fixture-skill/hooks/shared.js',
44
+ JSON.stringify(result.failures)
45
+ );
46
+
47
+ fs.mkdirSync(path.join(skill, 'hooks'), { recursive: true });
48
+ fs.writeFileSync(path.join(skill, 'hooks', 'shared.js'), '');
49
+ result = checkSkillReferences(root, ['fixture-skill']);
50
+ helper.check('2k. <this-skill-dir>/ resolves under the skill itself', result.failures.length === 0, JSON.stringify(result.failures));
51
+
52
+ // `../` reaches a sibling of the skill directory.
53
+ fs.writeFileSync(path.join(root, 'shared-note.md'), '');
54
+ fs.writeFileSync(path.join(skill, 'SKILL.md'), 'Deep dive: `<this-skill-dir>/../shared-note.md`\n');
55
+ result = checkSkillReferences(root, ['fixture-skill']);
56
+ helper.check('2k. <this-skill-dir>/../ reaches a sibling', result.failures.length === 0, JSON.stringify(result.failures));
57
+
58
+ // Regression: a typo'd placeholder used to be skipped silently, which made
59
+ // every path in the file invisible to this gate instead of failing it.
60
+ fs.writeFileSync(path.join(skill, 'SKILL.md'), 'Deep dive: `<this_folder>/../shared-note.md`\n');
61
+ result = checkSkillReferences(root, ['fixture-skill']);
62
+ helper.check(
63
+ '2k. unknown placeholder fails instead of being skipped',
64
+ result.failures.length === 1 && result.failures[0].target.indexOf('unknown placeholder <this_folder>') === 0,
65
+ JSON.stringify(result.failures)
66
+ );
67
+
68
+ // `<workspace>/` names a path in the USER's project, so it is deliberately
69
+ // recorded as unchecked rather than resolved against this repo.
70
+ fs.writeFileSync(path.join(skill, 'SKILL.md'), 'Writes `<workspace>/tasks/todo.md` as it goes.\n');
71
+ result = checkSkillReferences(root, ['fixture-skill']);
72
+ helper.check('2k. <workspace>/ paths are skipped, not resolved locally', result.failures.length === 0, JSON.stringify(result.failures));
73
+
19
74
  fs.rmSync(root, { recursive: true, force: true });
20
75
  helper.finish();