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,53 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const path = require('path');
5
+ const { spawnSync } = require('child_process');
6
+
7
+ const ROOT = path.resolve(__dirname, '..');
8
+ const loader = path.join(__dirname, 'mutation-loader.js');
9
+ const checks = [
10
+ ['physical path boundaries', 'scripts/lib/path-boundary.js', 'ci/mechanism-2v-verifier-boundaries.test.js'],
11
+ ['exact execution commands', 'scripts/lib/execution-contract.js', 'ci/mechanism-2v-verifier-boundaries.test.js'],
12
+ ['archive output boundaries', 'behavioral-evals/evidence-tool.js', 'ci/mechanism-2t-pr66-evidence-triage.test.js'],
13
+ ['legacy migration boundaries', 'multi-agent-workspace/scripts/scaffold.js', 'ci/mechanism-2l-multi-agent-workspace.test.js'],
14
+ ['global installer fallback', 'scripts/installer.js', 'ci/mechanism-2q-installer-global-shared-store.test.js'],
15
+ ['transcript command qualifiers', 'behavioral-evals/transcript-parser.js', 'ci/mechanism-2t-transcript-parser.test.js'],
16
+ ['fixture path boundaries', 'behavioral-evals/run.js', 'ci/mechanism-2j-behavioral-runner.test.js'],
17
+ ['unbound workspace identity', 'scripts/lib/workspace.js', 'ci/mechanism-2u-issue-42-regressions.test.js'],
18
+ ];
19
+
20
+ let failures = 0;
21
+ for (const [label, target, testFile] of checks) {
22
+ const result = spawnSync(process.execPath, ['--require', loader, path.join(ROOT, testFile)], {
23
+ cwd: ROOT,
24
+ env: {
25
+ ...process.env,
26
+ HARNESS_MUTATION: {
27
+ 'scripts/lib/path-boundary.js': 'path-boundary',
28
+ 'scripts/lib/execution-contract.js': 'execution-contract',
29
+ 'behavioral-evals/evidence-tool.js': 'evidence-tool',
30
+ 'multi-agent-workspace/scripts/scaffold.js': 'scaffold-migration',
31
+ 'scripts/installer.js': 'installer-global',
32
+ 'behavioral-evals/transcript-parser.js': 'transcript-command',
33
+ 'behavioral-evals/run.js': 'runner-fixture',
34
+ 'scripts/lib/workspace.js': 'workspace-identity',
35
+ }[target],
36
+ HARNESS_MUTATION_TARGET: path.join(ROOT, target),
37
+ NODE_OPTIONS: `--require=${loader}`,
38
+ },
39
+ encoding: 'utf8'
40
+ });
41
+ if (result.status === 0) {
42
+ console.error(`FAIL mutation survived: ${label} (${target})`);
43
+ failures++;
44
+ } else {
45
+ console.log(`PASS mutation was caught: ${label} (${testFile})`);
46
+ }
47
+ }
48
+
49
+ if (failures) {
50
+ console.error(`Mutation check failed: ${failures} mutation(s) survived.`);
51
+ process.exit(1);
52
+ }
53
+ console.log(`Mutation check passed: ${checks.length} production mutations were rejected by focused tests.`);
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const Module = require('module');
5
+ const path = require('path');
6
+
7
+ const target = process.env.HARNESS_MUTATION_TARGET && path.resolve(process.env.HARNESS_MUTATION_TARGET);
8
+ const mutation = process.env.HARNESS_MUTATION;
9
+ const originalLoader = Module._extensions['.js'];
10
+
11
+ const mutations = {
12
+ 'path-boundary': (source) => source.replace(
13
+ ' assertNoLinkComponents(root, candidate);',
14
+ ' // mutation: skip physical link-component validation'
15
+ ),
16
+ 'execution-contract': (source) => source.replace(
17
+ ' return left !== null && left === right;',
18
+ ' return left !== null; // mutation: accept every non-null command'
19
+ ),
20
+ 'evidence-tool': (source) => source
21
+ .replace(' const containedDestination = assertContainedPath(archiveRoot, destination).target;', ' const containedDestination = destination; // mutation: skip destination boundary')
22
+ .replace(' const contained = assertContainedPath(archiveRoot, target).target;', ' const contained = target; // mutation: skip archive write boundary'),
23
+ 'scaffold-migration': (source) => source.replace(
24
+ ' assertContainedPath(workspaceRoot, legacyRoot);',
25
+ ' // mutation: skip linked legacy-root validation'
26
+ ),
27
+ 'installer-global': (source) => source.replace(
28
+ 'const workspaceRoot = detectedWorkspaceRoot || path.resolve(process.cwd());',
29
+ 'const workspaceRoot = detectedWorkspaceRoot; // mutation: restore null global workspace'
30
+ ),
31
+ 'transcript-command': (source) => source.replace(
32
+ ' if (target.command !== undefined && (!isObject(call.input) || !commandMatches(call.input.command, target.command))) return false;',
33
+ ' // mutation: ignore command qualifiers'
34
+ ),
35
+ 'runner-fixture': (source) => source.replace(
36
+ ' const relative = normalizeRepoPath(file && file.path);',
37
+ ' const relative = file && file.path; // mutation: skip fixture path normalization'
38
+ ),
39
+ 'workspace-identity': (source) => source.replace(
40
+ ' if (!workspaceRoot) return UNBOUND_WORKSPACE_KEY;',
41
+ ' if (!workspaceRoot) return path.basename(process.cwd()); // mutation: derive unbound identity from cwd'
42
+ ),
43
+ };
44
+
45
+ if (target && mutation && mutations[mutation]) {
46
+ const transform = mutations[mutation];
47
+ Module._extensions['.js'] = function loadWithMutation(mod, filename) {
48
+ const source = fs.readFileSync(filename, 'utf8');
49
+ if (path.resolve(filename) === target) {
50
+ const mutated = transform(source);
51
+ if (mutated === source) throw new Error(`mutation was not applied to ${filename}`);
52
+ mod._compile(mutated, filename);
53
+ return;
54
+ }
55
+ originalLoader(mod, filename);
56
+ };
57
+ }
@@ -7,11 +7,12 @@
7
7
  */
8
8
  const fs = require('fs');
9
9
  const path = require('path');
10
- const { execSync } = require('child_process');
10
+ const { spawnSync } = require('child_process');
11
11
 
12
12
  const ROOT = path.resolve(__dirname, '..');
13
13
  let passed = 0;
14
14
  let failed = 0;
15
+ let fixtureCounter = 0;
15
16
 
16
17
  function test(name, fn) {
17
18
  try {
@@ -29,56 +30,85 @@ function assert(condition, msg) {
29
30
  if (!condition) throw new Error(msg || 'assertion failed');
30
31
  }
31
32
 
32
- // --- 1. Consistency gate rejects malformed frontmatter ---------------------
33
- test('consistency-check rejects unquoted colon in frontmatter', () => {
34
- const fixture = path.join(ROOT, 'ci/fixtures/bad-frontmatter-colon/SKILL.md');
35
- assert(fs.existsSync(fixture), `fixture not found: ${fixture}`);
36
- const raw = fs.readFileSync(fixture, 'utf8');
37
- const fmMatch = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
38
- assert(fmMatch, 'fixture has no frontmatter');
39
- const fm = fmMatch[1];
40
- const desc = (fm.match(/^description:\s*(.+)$/m) || [])[1] || '';
41
- // Unquoted colon in value should be caught
42
- assert(desc.includes(':') && !/^["']/.test(desc), 'description should contain unquoted colon');
43
- });
33
+ function runGate(script) {
34
+ const result = spawnSync(process.execPath, [path.join(ROOT, 'ci', script)], {
35
+ cwd: ROOT,
36
+ encoding: 'utf8',
37
+ env: process.env,
38
+ });
39
+ return {
40
+ ...result,
41
+ output: `${result.stdout || ''}\n${result.stderr || ''}`,
42
+ };
43
+ }
44
44
 
45
- // --- 2. Collision gate rejects identical descriptions ----------------------
46
- test('collision detection rejects two skills with identical descriptions', () => {
47
- const skillA = path.join(ROOT, 'ci/fixtures/duplicate-description/skill-a/SKILL.md');
48
- const skillB = path.join(ROOT, 'ci/fixtures/duplicate-description/skill-b/SKILL.md');
49
- assert(fs.existsSync(skillA) && fs.existsSync(skillB), 'duplicate fixtures not found');
50
- const fmA = fs.readFileSync(skillA, 'utf8').match(/^---\r?\n([\s\S]*?)\r?\n---/)[1];
51
- const fmB = fs.readFileSync(skillB, 'utf8').match(/^---\r?\n([\s\S]*?)\r?\n---/)[1];
52
- const descA = (fmA.match(/^description:\s*(.+)$/m) || [])[1] || '';
53
- const descB = (fmB.match(/^description:\s*(.+)$/m) || [])[1] || '';
54
- assert(descA === descB && descA.length > 0, 'descriptions should be identical and non-empty');
55
- // In a real run, collision detection would flag this
56
- });
45
+ function installFixture(source, label) {
46
+ const target = path.join(ROOT, `issue20-negative-${process.pid}-${++fixtureCounter}-${label}`);
47
+ assert(!fs.existsSync(target), `refusing to overwrite existing path: ${target}`);
48
+ fs.cpSync(path.join(ROOT, source), target, { recursive: true });
49
+ return target;
50
+ }
57
51
 
58
- // --- 3. Token gate rejects oversized SKILL.md -----------------------------
59
- test('token-budget gate exists in consistency-check.js', () => {
60
- const checkSrc = fs.readFileSync(path.join(ROOT, 'ci/consistency-check.js'), 'utf8');
61
- assert(checkSrc.includes('TOKEN_HARD_LIMIT'), 'consistency-check.js should define TOKEN_HARD_LIMIT');
62
- assert(checkSrc.includes('word count'), 'consistency-check.js should check word count');
63
- });
52
+ function removeFixtures(targets) {
53
+ for (const target of targets.reverse()) {
54
+ fs.rmSync(target, { recursive: true, force: true });
55
+ }
56
+ }
64
57
 
65
- // --- 4. YAML frontmatter validator exists ----------------------------------
66
- test('frontmatter syntax validator exists in consistency-check.js', () => {
67
- const checkSrc = fs.readFileSync(path.join(ROOT, 'ci/consistency-check.js'), 'utf8');
68
- assert(checkSrc.includes('validateFrontmatterSyntax'), 'consistency-check.js should have validateFrontmatterSyntax');
69
- assert(checkSrc.includes('unquoted colon'), 'validator should check for unquoted colons');
70
- });
58
+ function expectGateFailure(name, script, fixtures, matcher) {
59
+ test(name, () => {
60
+ const targets = [];
61
+ try {
62
+ for (const fixture of fixtures) targets.push(installFixture(fixture.source, fixture.label));
63
+ const result = runGate(script);
64
+ assert(result.status !== 0, `${script} unexpectedly passed (exit ${result.status})`);
65
+ assert(matcher.test(result.output), `${script} failed without the expected diagnostic:\n${result.output}`);
66
+ console.log(` real gate: ${script} exited ${result.status}`);
67
+ } finally {
68
+ removeFixtures(targets);
69
+ }
70
+ });
71
+ }
72
+
73
+ expectGateFailure(
74
+ 'consistency-check rejects malformed frontmatter',
75
+ 'consistency-check.js',
76
+ [{ source: 'ci/fixtures/bad-frontmatter-colon', label: 'bad-frontmatter' }],
77
+ /frontmatter YAML syntax valid|YAMLException|unquoted colon/i
78
+ );
79
+
80
+ expectGateFailure(
81
+ 'consistency-check rejects a missing frontmatter delimiter',
82
+ 'consistency-check.js',
83
+ [{ source: 'eval-framework/fixtures/missing-delimiter', label: 'missing-delimiter' }],
84
+ /delimiter|frontmatter/i
85
+ );
86
+
87
+ expectGateFailure(
88
+ 'description-collision rejects duplicate descriptions',
89
+ 'description-collision.js',
90
+ [
91
+ { source: 'ci/fixtures/duplicate-description/skill-a', label: 'duplicate-a' },
92
+ { source: 'ci/fixtures/duplicate-description/skill-b', label: 'duplicate-b' },
93
+ ],
94
+ /COLLISION/i
95
+ );
96
+
97
+ expectGateFailure(
98
+ 'consistency-check rejects an over-budget skill',
99
+ 'consistency-check.js',
100
+ [{ source: 'eval-framework/fixtures/over-budget-skill', label: 'over-budget' }],
101
+ /exceeds hard limit|word count/i
102
+ );
71
103
 
72
- // --- 5. Consistency check actually fails on the bad fixture ----------------
73
- test('consistency-check.js exits non-zero when fixtures are discoverable', () => {
74
- // This tests that the gate logic works; the fixture is nested so won't be
75
- // discovered by the normal scan, but the validator function itself catches it.
76
- const checkSrc = fs.readFileSync(path.join(ROOT, 'ci/consistency-check.js'), 'utf8');
77
- // The validator should call check() with false for unquoted colons
78
- assert(checkSrc.includes("check(\n") || checkSrc.includes('check(`'), 'check() function is called');
104
+ test('normal repository passes the exercised gates', () => {
105
+ const consistency = runGate('consistency-check.js');
106
+ const collision = runGate('description-collision.js');
107
+ assert(consistency.status === 0, `consistency-check failed (exit ${consistency.status})`);
108
+ assert(collision.status === 0, `description-collision failed (exit ${collision.status})`);
109
+ console.log(' real gates: consistency-check.js and description-collision.js exited 0');
79
110
  });
80
111
 
81
- // --- Summary ---------------------------------------------------------------
82
112
  console.log(`\nNegative control results: ${passed} passed, ${failed} failed`);
83
113
  if (failed > 0) process.exit(1);
84
- console.log('All negative controls verified.');
114
+ console.log('All negative controls verified by executing the real gates.');
@@ -0,0 +1,182 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+ const crypto = require('crypto');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const { spawnSync } = require('child_process');
8
+
9
+ const ROOT = path.resolve(__dirname, '..');
10
+ const PLUGIN = path.join(ROOT, 'plugins', 'harness-everything');
11
+ const SOURCE_MANIFEST = JSON.parse(fs.readFileSync(path.join(ROOT, '.claude-plugin', 'plugin.json'), 'utf8'));
12
+ const PLUGIN_MANIFEST = JSON.parse(fs.readFileSync(path.join(PLUGIN, '.codex-plugin', 'plugin.json'), 'utf8'));
13
+ const PORTABLE_MANIFEST = JSON.parse(fs.readFileSync(path.join(PLUGIN, 'plugin.json'), 'utf8'));
14
+
15
+ function sha256(file) {
16
+ const bytes = fs.readFileSync(file);
17
+ // Git stores text blobs with LF, while a Windows checkout may materialize
18
+ // canonical files with CRLF. Package parity compares canonical content, not
19
+ // platform checkout EOL bytes.
20
+ const normalized = bytes.includes(0)
21
+ ? bytes
22
+ : Buffer.from(bytes.toString('utf8').replace(/\r\n/g, '\n'), 'utf8');
23
+ return crypto.createHash('sha256').update(normalized).digest('hex');
24
+ }
25
+
26
+ function filesUnder(root, base = root, out = []) {
27
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
28
+ const full = path.join(root, entry.name);
29
+ if (entry.isDirectory()) filesUnder(full, base, out);
30
+ else if (entry.isFile()) out.push(path.relative(base, full).replace(/\\/g, '/'));
31
+ }
32
+ return out.sort();
33
+ }
34
+
35
+ function assertTreesEqual(source, packaged, name) {
36
+ assert.ok(fs.existsSync(packaged), `${name}: packaged skill directory missing`);
37
+ const sourceFiles = filesUnder(source);
38
+ const packagedFiles = filesUnder(packaged);
39
+ assert.deepStrictEqual(packagedFiles, sourceFiles, `${name}: packaged file list drifted from canonical source`);
40
+ for (const relative of sourceFiles) {
41
+ assert.strictEqual(
42
+ sha256(path.join(packaged, relative)),
43
+ sha256(path.join(source, relative)),
44
+ `${name}/${relative}: packaged content drifted from canonical source`
45
+ );
46
+ }
47
+ }
48
+
49
+ assert.strictEqual(PLUGIN_MANIFEST.name, 'harness-everything');
50
+ assert.strictEqual(PLUGIN_MANIFEST.version, SOURCE_MANIFEST.version, 'OpenAI plugin version must match canonical plugin version');
51
+ assert.strictEqual(PLUGIN_MANIFEST.skills, './skills/');
52
+ assert.strictEqual(PLUGIN_MANIFEST.hooks, './hooks/hooks.json');
53
+ assert.strictEqual(PORTABLE_MANIFEST.$schema, 'https://agent-plugins.org/schemas/1.0.0/plugin.schema.json');
54
+ assert.strictEqual(PORTABLE_MANIFEST.name, PLUGIN_MANIFEST.name);
55
+ assert.strictEqual(PORTABLE_MANIFEST.version, PLUGIN_MANIFEST.version);
56
+ assert.strictEqual(PORTABLE_MANIFEST.description, PLUGIN_MANIFEST.description);
57
+ assert.deepStrictEqual(PORTABLE_MANIFEST.author, PLUGIN_MANIFEST.author);
58
+ assert.strictEqual(PORTABLE_MANIFEST.homepage, PLUGIN_MANIFEST.homepage);
59
+ assert.strictEqual(PORTABLE_MANIFEST.repository, PLUGIN_MANIFEST.repository);
60
+ assert.strictEqual(PORTABLE_MANIFEST.license, PLUGIN_MANIFEST.license);
61
+ assert.deepStrictEqual(PORTABLE_MANIFEST.keywords, PLUGIN_MANIFEST.keywords);
62
+ assert.ok(!Object.prototype.hasOwnProperty.call(PORTABLE_MANIFEST, 'skills'), 'portable plugin manifest must use the root skills/ convention');
63
+ const portableOpenAI = PORTABLE_MANIFEST.extensions?.['com.openai'];
64
+ assert.ok(portableOpenAI, 'portable plugin manifest must expose the OpenAI extension');
65
+ assert.strictEqual(portableOpenAI.hooks, PLUGIN_MANIFEST.hooks);
66
+ assert.deepStrictEqual(portableOpenAI.interface, PLUGIN_MANIFEST.interface, 'portable and compatibility interface metadata drifted');
67
+ assert.ok(!Object.prototype.hasOwnProperty.call(PLUGIN_MANIFEST, 'agents'), 'OpenAI manifest must not claim an undocumented agents field');
68
+ assert.ok(!Object.prototype.hasOwnProperty.call(PLUGIN_MANIFEST, 'mcpServers'), 'skill-only package must not add MCP without a demonstrated requirement');
69
+ assert.ok(!Object.prototype.hasOwnProperty.call(PLUGIN_MANIFEST, 'apps'), 'skill-only package must not claim a connected app');
70
+
71
+ const requiredInterfaceFields = [
72
+ 'displayName',
73
+ 'shortDescription',
74
+ 'longDescription',
75
+ 'developerName',
76
+ 'category',
77
+ 'capabilities',
78
+ 'websiteURL',
79
+ 'privacyPolicyURL',
80
+ 'termsOfServiceURL',
81
+ 'defaultPrompt'
82
+ ];
83
+ for (const field of requiredInterfaceFields) {
84
+ assert.ok(Object.prototype.hasOwnProperty.call(PLUGIN_MANIFEST.interface || {}, field), `OpenAI interface missing ${field}`);
85
+ }
86
+ assert.strictEqual(PLUGIN_MANIFEST.interface.displayName, 'Harness Everything');
87
+ assert.strictEqual(PLUGIN_MANIFEST.interface.category, 'Developer Tools');
88
+ assert.deepStrictEqual(PLUGIN_MANIFEST.interface.capabilities, ['Interactive', 'Read', 'Write']);
89
+ assert.ok(Array.isArray(PLUGIN_MANIFEST.interface.defaultPrompt), 'defaultPrompt must be an array');
90
+ assert.ok(PLUGIN_MANIFEST.interface.defaultPrompt.length > 0 && PLUGIN_MANIFEST.interface.defaultPrompt.length <= 3, 'defaultPrompt must contain 1-3 entries');
91
+ for (const prompt of PLUGIN_MANIFEST.interface.defaultPrompt) {
92
+ assert.ok(prompt.length <= 128, `defaultPrompt exceeds 128 characters: ${prompt}`);
93
+ }
94
+
95
+ const publicationDocs = [
96
+ ['privacyPolicyURL', 'PRIVACY.md'],
97
+ ['termsOfServiceURL', 'TERMS.md']
98
+ ];
99
+ for (const [field, filename] of publicationDocs) {
100
+ const value = PLUGIN_MANIFEST.interface[field];
101
+ assert.match(value, /^https:\/\/github\.com\/dyphn1\/Harness-everything\/blob\/main\//, `${field} must use a public HTTPS repository URL`);
102
+ assert.ok(fs.existsSync(path.join(ROOT, filename)), `${field} target document is missing: ${filename}`);
103
+ }
104
+
105
+ const skillNames = (SOURCE_MANIFEST.skills || []).map(entry => path.basename(entry)).sort();
106
+ const packagedSkillNames = fs.readdirSync(path.join(PLUGIN, 'skills'), { withFileTypes: true })
107
+ .filter(entry => entry.isDirectory())
108
+ .map(entry => entry.name)
109
+ .sort();
110
+ assert.strictEqual(skillNames.length, 26, 'canonical suite should contain 26 skills');
111
+ assert.deepStrictEqual(packagedSkillNames, skillNames, 'OpenAI package must contain exactly the canonical skill set');
112
+ for (const entry of SOURCE_MANIFEST.skills) {
113
+ const source = path.resolve(ROOT, entry);
114
+ const name = path.basename(source);
115
+ assertTreesEqual(source, path.join(PLUGIN, 'skills', name), name);
116
+ }
117
+
118
+ const marketplace = JSON.parse(fs.readFileSync(path.join(ROOT, '.agents', 'plugins', 'marketplace.json'), 'utf8'));
119
+ assert.strictEqual(marketplace.name, 'harness-everything', 'marketplace should use the publication name, not a local-only label');
120
+ assert.strictEqual(marketplace.interface?.displayName, 'Harness Everything');
121
+ const marketEntry = marketplace.plugins.find(plugin => plugin.name === 'harness-everything');
122
+ assert.ok(marketEntry, 'repo marketplace must expose harness-everything');
123
+ assert.strictEqual(marketEntry.source.source, 'local');
124
+ assert.strictEqual(marketEntry.source.path, './plugins/harness-everything');
125
+ assert.strictEqual(marketEntry.policy?.installation, 'AVAILABLE');
126
+ assert.strictEqual(marketEntry.policy?.authentication, 'ON_INSTALL');
127
+ assert.strictEqual(marketEntry.category, 'Developer Tools');
128
+ assert.ok(fs.existsSync(path.join(ROOT, marketEntry.source.path, '.codex-plugin', 'plugin.json')), 'marketplace source must resolve to an installable plugin');
129
+
130
+ const hooks = JSON.parse(fs.readFileSync(path.join(PLUGIN, 'hooks', 'hooks.json'), 'utf8'));
131
+ assert.ok(hooks.hooks.SessionStart?.length, 'SessionStart hook missing');
132
+ assert.ok(hooks.hooks.UserPromptSubmit?.length, 'UserPromptSubmit hook missing');
133
+ assert.ok(hooks.hooks.PreToolUse?.length, 'PreToolUse hook missing');
134
+ assert.ok(hooks.hooks.PostToolUse?.length, 'PostToolUse hook missing');
135
+ assert.ok(hooks.hooks.SubagentStart?.length, 'SubagentStart hook missing');
136
+ assert.ok(hooks.hooks.SubagentStop?.length, 'SubagentStop hook missing');
137
+ assert.ok(hooks.hooks.Stop?.length, 'Stop hook missing');
138
+ const hookText = JSON.stringify(hooks);
139
+ assert.match(hookText, /PLUGIN_ROOT/, 'plugin hooks must resolve from PLUGIN_ROOT');
140
+ assert.match(hookText, /commandWindows/, 'plugin hooks need a Windows command override');
141
+
142
+ const session = spawnSync(process.execPath, [path.join(PLUGIN, 'hooks', 'session-start.js')], { encoding: 'utf8' });
143
+ assert.strictEqual(session.status, 0, session.stderr);
144
+ assert.match(session.stdout, /Cognitive OS policy is active/);
145
+ assert.match(session.stdout, /Route before execution/);
146
+ assert.match(session.stdout, /Verify before claim/);
147
+ assert.match(session.stdout, /3 same-signature failures/);
148
+
149
+ const kernel = path.join(PLUGIN, 'skills', 'harness-everything', 'scripts', 'kernel-router.js');
150
+ function route(prompt) {
151
+ return spawnSync(process.execPath, [kernel], {
152
+ input: JSON.stringify({ prompt }),
153
+ encoding: 'utf8',
154
+ cwd: ROOT,
155
+ env: { ...process.env }
156
+ });
157
+ }
158
+
159
+ const prompt = 'Fix a bug in an API endpoint and add a unit test.';
160
+ const first = route(prompt);
161
+ const second = route(prompt);
162
+ assert.strictEqual(first.status, 0, first.stderr);
163
+ assert.strictEqual(second.status, 0, second.stderr);
164
+ assert.strictEqual(first.stdout, second.stdout, 'identical routing input must produce identical output');
165
+ assert.match(first.stdout, /RECOMMENDED TIER:\s*Tier 2/i);
166
+ assert.match(first.stdout, /REQUIRED HARNESS INVARIANTS/);
167
+ assert.match(first.stdout, /SUGGESTED SKILLS \(ADVISORY/);
168
+ assert.doesNotMatch(first.stdout, /BASE EXECUTION LOOP/);
169
+ assert.match(first.stdout, /Do not enforce workflow order/);
170
+
171
+ const trivial = route('Update one README typo');
172
+ assert.strictEqual(trivial.status, 0, trivial.stderr);
173
+ assert.match(trivial.stdout, /RECOMMENDED TIER:\s*Tier 1/i);
174
+ assert.match(trivial.stdout, /No mandatory domain skill/);
175
+
176
+ const unmatched = route('frobnicate the quux');
177
+ assert.strictEqual(unmatched.status, 0, unmatched.stderr);
178
+ assert.match(unmatched.stdout, /RECOMMENDED TIER:\s*Unclassified/i);
179
+ assert.match(unmatched.stdout, /"tier":"unclassified"/i);
180
+ assert.doesNotMatch(unmatched.stdout, /RECOMMENDED TIER:\s*Tier 1/i);
181
+
182
+ console.log(`OpenAI plugin package verified: ${skillNames.length} skills, publication metadata, hooks, marketplace, deterministic routing.`);
@@ -0,0 +1,175 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+ const path = require('path');
7
+ const { spawnSync } = require('child_process');
8
+
9
+ const ROOT = path.resolve(__dirname, '..');
10
+ const PLUGIN = path.join(ROOT, 'plugins', 'harness-everything');
11
+ const HOOKS_FILE = path.join(PLUGIN, 'hooks', 'hooks.json');
12
+ const hooks = JSON.parse(fs.readFileSync(HOOKS_FILE, 'utf8')).hooks;
13
+
14
+ const EXPECTED_EVENTS = [
15
+ 'SessionStart',
16
+ 'UserPromptSubmit',
17
+ 'PreToolUse',
18
+ 'PostToolUse',
19
+ 'SubagentStart',
20
+ 'SubagentStop',
21
+ 'Stop'
22
+ ];
23
+
24
+ for (const event of EXPECTED_EVENTS) {
25
+ assert.ok(Array.isArray(hooks[event]) && hooks[event].length > 0, `${event} hook missing`);
26
+ }
27
+
28
+ const hookText = JSON.stringify(hooks);
29
+ assert.match(hookText, /PLUGIN_ROOT/, 'OpenAI hooks must resolve from PLUGIN_ROOT');
30
+ assert.match(hookText, /commandWindows/, 'OpenAI hooks need Windows command overrides');
31
+
32
+ const commandPaths = [];
33
+ for (const entries of Object.values(hooks)) {
34
+ for (const entry of entries) {
35
+ for (const command of entry.hooks || []) {
36
+ assert.strictEqual(command.type, 'command');
37
+ assert.ok(command.commandWindows, 'every packaged command hook needs a Windows override');
38
+ const match = command.command.match(/\$PLUGIN_ROOT\/([^"']+)/);
39
+ if (match) commandPaths.push(path.join(PLUGIN, match[1]));
40
+ }
41
+ }
42
+ }
43
+ for (const commandPath of commandPaths) {
44
+ assert.ok(fs.existsSync(commandPath), `packaged hook command is missing: ${path.relative(PLUGIN, commandPath)}`);
45
+ }
46
+
47
+ function filesUnder(root, out = []) {
48
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
49
+ const full = path.join(root, entry.name);
50
+ if (entry.isDirectory()) filesUnder(full, out);
51
+ else if (entry.isFile()) out.push(full);
52
+ }
53
+ return out;
54
+ }
55
+
56
+ for (const file of filesUnder(path.join(PLUGIN, 'hooks')).filter(file => file.endsWith('.js'))) {
57
+ const syntax = spawnSync(process.execPath, ['--check', file], { encoding: 'utf8' });
58
+ assert.strictEqual(syntax.status, 0, `${path.relative(PLUGIN, file)} does not parse: ${syntax.stderr}`);
59
+ }
60
+ assert.ok(fs.existsSync(path.join(PLUGIN, 'scripts', 'lib', 'advisory-text.js')));
61
+ const packagedState = fs.readFileSync(path.join(PLUGIN, 'hooks', 'scripts', 'lib', 'harness-state.js'), 'utf8');
62
+ assert.doesNotMatch(packagedState, /\.\.\/\.\.\/\.\.\/scripts[\\/]lib[\\/]workspace/);
63
+
64
+ function runHook(relative, payload, stateHome) {
65
+ return spawnSync(process.execPath, [path.join(PLUGIN, relative)], {
66
+ input: JSON.stringify(payload),
67
+ encoding: 'utf8',
68
+ cwd: ROOT,
69
+ env: { ...process.env, HARNESS_STATE_HOME: stateHome }
70
+ });
71
+ }
72
+
73
+ const fixture = fs.mkdtempSync(path.join(os.tmpdir(), 'harness-openai-runtime-'));
74
+ const stateHome = path.join(fixture, 'state-home');
75
+ const gitInit = spawnSync('git', ['init', '--quiet'], { cwd: fixture, encoding: 'utf8' });
76
+ assert.strictEqual(gitInit.status, 0, gitInit.stderr);
77
+ const sessionPayload = {
78
+ hook_event_name: 'SessionStart',
79
+ session_id: 'openai-runtime-test',
80
+ cwd: fixture,
81
+ source: 'startup'
82
+ };
83
+
84
+ const session = runHook('hooks/session-start.js', sessionPayload, stateHome);
85
+ assert.strictEqual(session.status, 0, session.stderr);
86
+ const sessionOutput = JSON.parse(session.stdout);
87
+ assert.strictEqual(sessionOutput.hookSpecificOutput.hookEventName, 'SessionStart');
88
+ assert.match(sessionOutput.hookSpecificOutput.additionalContext, /Route before execution/);
89
+ assert.match(sessionOutput.hookSpecificOutput.additionalContext, /Verify before claim/);
90
+
91
+ const persist = runHook('hooks/scripts/state-persist.js', {
92
+ hook_event_name: 'PostToolUse',
93
+ session_id: 'openai-runtime-test',
94
+ cwd: fixture,
95
+ tool_name: 'apply_patch',
96
+ tool_input: { command: '*** Begin Patch\n*** Update File: src/example.js\n*** End Patch' },
97
+ tool_response: { exitCode: 0, stdout: '', stderr: '' }
98
+ }, stateHome);
99
+ assert.strictEqual(persist.status, 0, persist.stderr);
100
+
101
+ function findFile(root, filename) {
102
+ if (!fs.existsSync(root)) return null;
103
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
104
+ const full = path.join(root, entry.name);
105
+ if (entry.isDirectory()) {
106
+ const found = findFile(full, filename);
107
+ if (found) return found;
108
+ } else if (entry.isFile() && entry.name === filename) {
109
+ return full;
110
+ }
111
+ }
112
+ return null;
113
+ }
114
+
115
+ const handoff = findFile(stateHome, 'handoff-state.json');
116
+ assert.ok(handoff, 'SessionStart/state-persist should create a handoff state file');
117
+ assert.ok(JSON.parse(fs.readFileSync(handoff, 'utf8')).lastEditAt, 'apply_patch must count as an edit');
118
+
119
+ const sessionDir = path.dirname(handoff);
120
+ fs.writeFileSync(path.join(sessionDir, 'rule-of-3-state.json'), JSON.stringify({
121
+ count: 3,
122
+ threshold: 3,
123
+ lastHash: 'runtime-test-failure',
124
+ lastFailureAt: 0
125
+ }), 'utf8');
126
+ const reportFile = path.join(sessionDir, 'zoom-out-report.md');
127
+ const reportWrite = runHook('hooks/scripts/rule-of-3.js', {
128
+ hook_event_name: 'PreToolUse',
129
+ session_id: 'openai-runtime-test',
130
+ cwd: fixture,
131
+ tool_name: 'apply_patch',
132
+ tool_input: { patch: `*** Add File: ${reportFile}\n## Goal` }
133
+ }, stateHome);
134
+ assert.strictEqual(reportWrite.status, 0, 'apply_patch must be allowed to write the zoom-out report');
135
+
136
+ const mixedPatch = runHook('hooks/scripts/rule-of-3.js', {
137
+ hook_event_name: 'PreToolUse',
138
+ session_id: 'openai-runtime-test',
139
+ cwd: fixture,
140
+ tool_name: 'apply_patch',
141
+ tool_input: { patch: `*** Update File: ${reportFile}\n@@\n*** Update File: unrelated.txt\n@@` }
142
+ }, stateHome);
143
+ assert.strictEqual(mixedPatch.status, 2, 'report exemption must not allow a mixed apply_patch');
144
+
145
+ const blockedPatch = runHook('hooks/scripts/rule-of-3.js', {
146
+ hook_event_name: 'PreToolUse',
147
+ session_id: 'openai-runtime-test',
148
+ cwd: fixture,
149
+ tool_name: 'apply_patch',
150
+ tool_input: { patch: '*** Update File: unrelated.txt\n@@' }
151
+ }, stateHome);
152
+ assert.strictEqual(blockedPatch.status, 2, 'tripped circuit breaker must block unrelated apply_patch writes');
153
+
154
+ const subagentStart = runHook('hooks/scripts/subagent-start.js', {
155
+ hook_event_name: 'SubagentStart',
156
+ session_id: 'openai-runtime-test',
157
+ cwd: fixture,
158
+ agent_type: 'worker'
159
+ }, stateHome);
160
+ assert.strictEqual(subagentStart.status, 0, subagentStart.stderr);
161
+ const subagentOutput = JSON.parse(subagentStart.stdout);
162
+ assert.strictEqual(subagentOutput.hookSpecificOutput.hookEventName, 'SubagentStart');
163
+ assert.match(subagentOutput.hookSpecificOutput.additionalContext, /scope/i);
164
+
165
+ fs.writeFileSync(path.join(fixture, 'unplanned-change.txt'), 'scope regression\n', 'utf8');
166
+ const subagentStop = runHook('hooks/scripts/subagent-stop.js', {
167
+ hook_event_name: 'SubagentStop',
168
+ session_id: 'openai-runtime-test',
169
+ cwd: fixture,
170
+ agent_type: 'worker'
171
+ }, stateHome);
172
+ assert.strictEqual(subagentStop.status, 2, subagentStop.stderr);
173
+ assert.match(subagentStop.stderr, /Subagent Scope Guard/);
174
+
175
+ console.log('OpenAI plugin runtime compatibility verified.');