harness-everything 0.3.6 → 0.4.1

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 (580) 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/behavioral-evals.yml +3 -3
  5. package/.github/workflows/ci.yml +49 -28
  6. package/.github/workflows/release.yml +52 -27
  7. package/.nvmrc +1 -0
  8. package/.releaserc.json +113 -0
  9. package/AGENTS.md +44 -24
  10. package/BENCHMARK_SOP.md +38 -18
  11. package/CHANGELOG.md +196 -3
  12. package/CONTRIBUTING.md +37 -9
  13. package/Dockerfile +1 -1
  14. package/PRIVACY.md +25 -0
  15. package/README.md +126 -91
  16. package/RELEASING.md +93 -0
  17. package/SUPPORT.md +27 -0
  18. package/TERMS.md +21 -0
  19. package/VERIFICATION.md +192 -284
  20. package/behavioral-evals/README.md +21 -0
  21. package/behavioral-evals/case-validator.js +194 -0
  22. package/behavioral-evals/cases/baseline-environment-detection.yaml +21 -0
  23. package/behavioral-evals/cases/baseline-eval-harness.yaml +27 -0
  24. package/behavioral-evals/cases/baseline-fable-discipline.yaml +31 -0
  25. package/behavioral-evals/cases/baseline-find-skills-exposure.yaml +49 -0
  26. package/behavioral-evals/cases/baseline-find-skills.yaml +21 -0
  27. package/behavioral-evals/cases/baseline-git-commit.yaml +2 -2
  28. package/behavioral-evals/cases/baseline-install-cognitive-os.yaml +24 -0
  29. package/behavioral-evals/cases/baseline-multi-agent-workspace.yaml +28 -0
  30. package/behavioral-evals/cases/baseline-rewrite-commits.yaml +34 -0
  31. package/behavioral-evals/cases/baseline-self-evolve.yaml +31 -0
  32. package/behavioral-evals/cases/baseline-skill-creator.yaml +20 -0
  33. package/behavioral-evals/cases/baseline-skill-style.yaml +21 -0
  34. package/behavioral-evals/cases/baseline-to-spec.yaml +34 -0
  35. package/behavioral-evals/cases/baseline-to-tickets.yaml +24 -0
  36. package/behavioral-evals/cases/baseline-todo-driven-workflow.yaml +32 -0
  37. package/behavioral-evals/cases/baseline-using-git-worktrees.yaml +15 -0
  38. package/behavioral-evals/cases/breaker-zoom-out-after-3.yaml +2 -2
  39. package/behavioral-evals/cases/pressure-complexity-skip.yaml +2 -2
  40. package/behavioral-evals/cases/pressure-scope-bypass.yaml +7 -2
  41. package/behavioral-evals/cases/pressure-sunk-cost-retry.yaml +7 -4
  42. package/behavioral-evals/cases/scope-discipline.yaml +2 -1
  43. package/behavioral-evals/cases/verify-before-done.yaml +7 -5
  44. package/behavioral-evals/evidence/2026-09-07/baseline-debugging/case.yaml +31 -0
  45. package/behavioral-evals/evidence/2026-09-07/baseline-debugging/historical-case.yaml +31 -0
  46. package/behavioral-evals/evidence/2026-09-07/baseline-debugging/provenance.json +42 -0
  47. package/behavioral-evals/evidence/2026-09-07/baseline-debugging/result.sanitized.json +20 -0
  48. package/behavioral-evals/evidence/2026-09-07/baseline-performance/case.yaml +34 -0
  49. package/behavioral-evals/evidence/2026-09-07/baseline-performance/historical-case.yaml +34 -0
  50. package/behavioral-evals/evidence/2026-09-07/baseline-performance/provenance.json +42 -0
  51. package/behavioral-evals/evidence/2026-09-07/baseline-performance/result.sanitized.json +20 -0
  52. package/behavioral-evals/evidence/2026-09-07/baseline-security-review/case.yaml +28 -0
  53. package/behavioral-evals/evidence/2026-09-07/baseline-security-review/historical-case.yaml +28 -0
  54. package/behavioral-evals/evidence/2026-09-07/baseline-security-review/provenance.json +42 -0
  55. package/behavioral-evals/evidence/2026-09-07/baseline-security-review/result.sanitized.json +20 -0
  56. package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/case.yaml +33 -0
  57. package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/historical-case.yaml +33 -0
  58. package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/provenance.json +42 -0
  59. package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/result.sanitized.json +20 -0
  60. package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/case.yaml +28 -0
  61. package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/historical-case.yaml +18 -0
  62. package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/provenance.json +30 -0
  63. package/behavioral-evals/evidence/2026-09-07/live-run-blocker.md +16 -0
  64. package/behavioral-evals/evidence/2026-09-07/manifest.json +88 -0
  65. package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/case.yaml +33 -0
  66. package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/historical-case.yaml +28 -0
  67. package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/provenance.json +30 -0
  68. package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/case.yaml +50 -0
  69. package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/historical-case.yaml +50 -0
  70. package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/provenance.json +42 -0
  71. package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/result.sanitized.json +20 -0
  72. package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/case.yaml +35 -0
  73. package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/historical-case.yaml +35 -0
  74. package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/provenance.json +42 -0
  75. package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/result.sanitized.json +20 -0
  76. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/case.yaml +43 -0
  77. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/historical-case.yaml +43 -0
  78. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/provenance.json +42 -0
  79. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/result.sanitized.json +24 -0
  80. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/case.yaml +43 -0
  81. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/historical-case.yaml +43 -0
  82. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/provenance.json +42 -0
  83. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/result.sanitized.json +20 -0
  84. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/case.yaml +43 -0
  85. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/historical-case.yaml +43 -0
  86. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/provenance.json +42 -0
  87. package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/result.sanitized.json +24 -0
  88. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/case.yaml +50 -0
  89. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/historical-case.yaml +47 -0
  90. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/provenance.json +42 -0
  91. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/result.sanitized.json +24 -0
  92. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/case.yaml +50 -0
  93. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/historical-case.yaml +47 -0
  94. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/provenance.json +42 -0
  95. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/result.sanitized.json +20 -0
  96. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/case.yaml +50 -0
  97. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/historical-case.yaml +47 -0
  98. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/provenance.json +42 -0
  99. package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/result.sanitized.json +24 -0
  100. package/behavioral-evals/evidence/2026-09-07/tdd-test-first/case.yaml +30 -0
  101. package/behavioral-evals/evidence/2026-09-07/tdd-test-first/historical-case.yaml +23 -0
  102. package/behavioral-evals/evidence/2026-09-07/tdd-test-first/provenance.json +30 -0
  103. package/behavioral-evals/evidence/2026-09-07/triage-matrix.json +426 -0
  104. package/behavioral-evals/evidence/2026-09-07/triage-matrix.md +24 -0
  105. package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/case.yaml +19 -0
  106. package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/historical-case.yaml +18 -0
  107. package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/provenance.json +30 -0
  108. package/behavioral-evals/evidence/2026-09-07/verify-before-done/case.yaml +33 -0
  109. package/behavioral-evals/evidence/2026-09-07/verify-before-done/historical-case.yaml +31 -0
  110. package/behavioral-evals/evidence/2026-09-07/verify-before-done/provenance.json +42 -0
  111. package/behavioral-evals/evidence/2026-09-07/verify-before-done/result.sanitized.json +20 -0
  112. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/case.yaml +33 -0
  113. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/historical-case.yaml +31 -0
  114. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/provenance.json +42 -0
  115. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/result.sanitized.json +20 -0
  116. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/case.yaml +33 -0
  117. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/historical-case.yaml +31 -0
  118. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/provenance.json +42 -0
  119. package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/result.sanitized.json +20 -0
  120. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/case.yaml +33 -0
  121. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/historical-case.yaml +33 -0
  122. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/provenance.json +42 -0
  123. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/result.sanitized.json +480 -0
  124. package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/transcript.sanitized.jsonl +95 -0
  125. package/behavioral-evals/evidence-tool.js +443 -0
  126. package/behavioral-evals/fixtures/claude-denied.jsonl +3 -0
  127. package/behavioral-evals/fixtures/claude-legacy.json +1 -0
  128. package/behavioral-evals/fixtures/claude-oral-only.jsonl +2 -0
  129. package/behavioral-evals/fixtures/claude-success.jsonl +5 -0
  130. package/behavioral-evals/fixtures/claude-truncated.jsonl +3 -0
  131. package/behavioral-evals/fixtures/opencode-success.jsonl +6 -0
  132. package/behavioral-evals/results/2026-08-31-baseline-add-feature.json +20 -0
  133. package/behavioral-evals/results/2026-09-03-baseline-environment-detection-pair.json +133 -0
  134. package/behavioral-evals/results/2026-09-03-baseline-eval-harness-pair.json +141 -0
  135. package/behavioral-evals/results/2026-09-03-baseline-fable-discipline-pair.json +149 -0
  136. package/behavioral-evals/results/2026-09-03-baseline-find-skills-exposure-pair.json +141 -0
  137. package/behavioral-evals/results/2026-09-03-baseline-find-skills-pair.json +141 -0
  138. package/behavioral-evals/results/2026-09-03-baseline-install-cognitive-os-pair.json +133 -0
  139. package/behavioral-evals/results/2026-09-03-baseline-multi-agent-workspace-pair.json +141 -0
  140. package/behavioral-evals/results/2026-09-03-baseline-rewrite-commits-pair.json +95 -0
  141. package/behavioral-evals/results/2026-09-03-baseline-self-evolve-pair.json +141 -0
  142. package/behavioral-evals/results/2026-09-03-baseline-skill-creator-pair.json +141 -0
  143. package/behavioral-evals/results/2026-09-03-baseline-skill-style-pair.json +133 -0
  144. package/behavioral-evals/results/2026-09-03-baseline-to-spec-pair.json +133 -0
  145. package/behavioral-evals/results/2026-09-03-baseline-to-tickets-pair.json +141 -0
  146. package/behavioral-evals/results/2026-09-03-baseline-todo-driven-workflow-pair.json +141 -0
  147. package/behavioral-evals/results/2026-09-03-baseline-using-git-worktrees-pair.json +133 -0
  148. package/behavioral-evals/results/2026-09-03-summary-both.json +41 -0
  149. package/behavioral-evals/results/2026-09-04-baseline-find-skills-pair.json +141 -0
  150. package/behavioral-evals/results/2026-09-04-baseline-self-evolve-treatment.json +80 -0
  151. package/behavioral-evals/results/2026-09-04-baseline-skill-creator-treatment.json +80 -0
  152. package/behavioral-evals/results/2026-09-04-summary-both.json +41 -0
  153. package/behavioral-evals/run-with-plugin.js +15 -31
  154. package/behavioral-evals/run.js +446 -105
  155. package/behavioral-evals/transcript-parser.js +591 -0
  156. package/bin/cli.js +24 -12
  157. package/ci/ab-test-cases/grill-me-adversarial.yaml +14 -4
  158. package/ci/ab-test-cases/tdd-test-first.yaml +13 -6
  159. package/ci/ab-test-cases/verification-loop-gates.yaml +20 -7
  160. package/ci/ab-test-cases/verify-before-claim-cites.yaml +7 -6
  161. package/ci/ab-test-harness.js +113 -38
  162. package/ci/action-gate-platform-doc.test.js +31 -0
  163. package/ci/action-gate.test.js +260 -0
  164. package/ci/cases/case2.json +2 -2
  165. package/ci/consistency-check.js +51 -5
  166. package/ci/description-collision.js +15 -6
  167. package/ci/disclosure-check.js +225 -0
  168. package/ci/doc-capability-consistency.test.js +180 -0
  169. package/ci/fixtures/phase4/parallel-disjoint.stages.json +32 -0
  170. package/ci/fixtures/phase4/parallel-read-only.stages.json +32 -0
  171. package/ci/installer-roundtrip.test.js +159 -0
  172. package/ci/invariant-routing.test.js +74 -0
  173. package/ci/issue99-runtime.test.js +218 -0
  174. package/ci/mechanism-2aa-codex-action-gate-policy.test.js +117 -0
  175. package/ci/mechanism-2ab-openai-plugin-sync-integrity.test.js +80 -0
  176. package/ci/mechanism-2j-behavioral-runner.test.js +43 -1
  177. package/ci/mechanism-2k-reference-check.test.js +57 -2
  178. package/ci/mechanism-2l-multi-agent-workspace.test.js +202 -6
  179. package/ci/mechanism-2m-self-repo-guard.test.js +65 -0
  180. package/ci/mechanism-2n-opencode-plugin.test.js +461 -0
  181. package/ci/mechanism-2o-state-home-isolation.test.js +183 -0
  182. package/ci/mechanism-2p-installer-links.test.js +183 -0
  183. package/ci/mechanism-2q-installer-global-shared-store.test.js +132 -0
  184. package/ci/mechanism-2r-uninstall-flags.test.js +148 -0
  185. package/ci/mechanism-2s-tdd-quality.test.js +203 -0
  186. package/ci/mechanism-2t-disclosure.test.js +90 -0
  187. package/ci/mechanism-2t-evidence-triage.test.js +200 -0
  188. package/ci/mechanism-2t-issue-20.test.js +75 -0
  189. package/ci/mechanism-2t-platform-skill-targets.test.js +164 -0
  190. package/ci/mechanism-2t-transcript-parser.test.js +179 -0
  191. package/ci/mechanism-2t-workspace-identity.test.js +200 -0
  192. package/ci/mechanism-2u-issue-42-regressions.test.js +239 -0
  193. package/ci/mechanism-2u-issue-44.test.js +35 -0
  194. package/ci/mechanism-2v-verifier-boundaries.test.js +138 -0
  195. package/ci/mechanism-2w-platform-compatibility.test.js +148 -0
  196. package/ci/mechanism-2x-release-automation.test.js +157 -0
  197. package/ci/mechanism-2x-release-commit-message.test.js +66 -0
  198. package/ci/mechanism-2y-release-tooling-compat.test.js +47 -0
  199. package/ci/mechanism-2z-claude-plugin-manifest.test.js +29 -0
  200. package/ci/mutation-check.js +53 -0
  201. package/ci/mutation-loader.js +57 -0
  202. package/ci/negative-controls.js +76 -46
  203. package/ci/openai-plugin-package.test.js +182 -0
  204. package/ci/openai-plugin-runtime.test.js +175 -0
  205. package/ci/openai-plugin-submission.test.js +101 -0
  206. package/ci/phase4-ensemble-memory.test.js +307 -0
  207. package/ci/reference-check.js +73 -25
  208. package/ci/release-consistency-check.js +24 -1
  209. package/ci/repository-contract.test.js +17 -0
  210. package/ci/router-phase2-safety.test.js +81 -0
  211. package/ci/router-workflow-plan.test.js +264 -0
  212. package/ci/routing-check.js +6 -5
  213. package/ci/runner.js +6 -5
  214. package/ci/skill-routing-check.js +48 -11
  215. package/ci/test-behavioral-case-validation.js +62 -0
  216. package/ci/test-helper.js +10 -0
  217. package/ci/workflow-plan-consumers-edge.test.js +72 -0
  218. package/ci/workflow-plan-consumers.test.js +276 -0
  219. package/docs/architecture.md +137 -57
  220. package/docs/audit.md +22 -20
  221. package/docs/codex-action-gate.md +90 -0
  222. package/docs/issue-20-rollup.md +47 -0
  223. package/docs/mechanism-first-skill-mesh.md +22 -20
  224. package/docs/openai-plugin.md +118 -0
  225. package/docs/philosophy.md +28 -17
  226. package/docs/platform-capabilities.md +73 -0
  227. package/docs/platform-compatibility.json +270 -0
  228. package/docs/reflection.md +37 -22
  229. package/docs/release-evidence.md +27 -0
  230. package/docs/repository-contract.md +27 -0
  231. package/docs/routing.md +157 -44
  232. package/docs/security-audit.md +38 -0
  233. package/docs/troubleshooting.md +94 -51
  234. package/docs/verifier-boundaries.md +45 -0
  235. package/docs/workflows/fable-mode.md +77 -21
  236. package/docs/workflows/find-skills.md +40 -0
  237. package/docs/workflows/grill-with-docs.md +2 -2
  238. package/docs/workflows/multi-agent-workspace.md +22 -10
  239. package/docs/workflows/self-evolve.md +33 -0
  240. package/docs/workflows/tdd.md +36 -0
  241. package/docs/workflows/todo-driven-workflow.md +33 -0
  242. package/environment-detection/SKILL.md +3 -3
  243. package/eval-harness/SKILL.md +7 -7
  244. package/eval-harness/scripts/evaluate.js +12 -10
  245. package/evals/evaluation-reports.md +14 -0
  246. package/evals/harness-everything/tasks/positive-tier1.yaml +1 -1
  247. package/evals/harness-everything/tasks/positive-tier2.yaml +1 -1
  248. package/evals/harness-everything/tasks/positive-tier3.yaml +1 -1
  249. package/evals/install-cognitive-os/tasks/positive-trigger.yaml +1 -1
  250. package/fable-discipline/SKILL.md +2 -2
  251. package/fable-mode/CONTRACT-FORMAT.md +147 -33
  252. package/fable-mode/SKILL.md +3 -3
  253. package/fable-mode/agents/fable-orchestrator.md +95 -35
  254. package/fable-mode/execution-guardrails/SKILL.md +2 -2
  255. package/fable-mode/fable-haiku/SKILL.md +3 -3
  256. package/fable-mode/fable-opus/SKILL.md +3 -3
  257. package/fable-mode/fable-sonnet/SKILL.md +3 -3
  258. package/fable-mode/scripts/ensemble-review.js +371 -0
  259. package/fable-mode/scripts/model-selector.js +134 -3
  260. package/fable-mode/scripts/workflow-plan-consumer.js +337 -0
  261. package/find-skills/SKILL.md +5 -5
  262. package/find-skills/references/discovery-flow.md +1 -1
  263. package/find-skills/scripts/use-skill.js +7 -1
  264. package/git-commit/SKILL.md +4 -11
  265. package/grill-me/SKILL.md +5 -5
  266. package/grill-with-docs/SKILL.md +7 -7
  267. package/grill-with-docs/references/session-playbook.md +6 -4
  268. package/harness-everything/SKILL.md +23 -22
  269. package/harness-everything/references/router-workflow-plan.md +128 -0
  270. package/harness-everything/references/triage-and-tiers.md +173 -96
  271. package/harness-everything/schemas/router-task-shape.schema.json +126 -0
  272. package/harness-everything/schemas/router-workflow-plan.schema.json +149 -0
  273. package/harness-everything/scripts/bootstrap.js +13 -4
  274. package/harness-everything/scripts/ensemble-policy.js +102 -0
  275. package/harness-everything/scripts/kernel-router.js +212 -0
  276. package/harness-everything/scripts/router-contract.js +612 -0
  277. package/harness-everything/scripts/self-heal.js +29 -20
  278. package/harness-everything/scripts/tier-router.js +346 -221
  279. package/hooks/hooks.json +60 -15
  280. package/hooks/scripts/action-gate-rules.json +77 -0
  281. package/hooks/scripts/action-gate.js +528 -0
  282. package/hooks/scripts/atomic-commit-check.js +5 -5
  283. package/hooks/scripts/codex-action-gate-post.js +46 -0
  284. package/hooks/scripts/codex-permission-request.js +140 -0
  285. package/hooks/scripts/context-compact.js +4 -3
  286. package/hooks/scripts/contract-test.js +118 -51
  287. package/hooks/scripts/lib/fable-contracts.js +121 -0
  288. package/hooks/scripts/lib/harness-state.js +164 -28
  289. package/hooks/scripts/lib/platforms/claude.js +45 -62
  290. package/hooks/scripts/lib/platforms/codex.js +35 -61
  291. package/hooks/scripts/lib/platforms/continue.js +7 -7
  292. package/hooks/scripts/lib/platforms/copilot.js +29 -53
  293. package/hooks/scripts/lib/platforms/hermes.js +71 -20
  294. package/hooks/scripts/openai-session-start.js +81 -0
  295. package/hooks/scripts/rule-of-3-tracker.js +9 -8
  296. package/hooks/scripts/rule-of-3.js +29 -21
  297. package/hooks/scripts/state-persist.js +5 -4
  298. package/hooks/scripts/stop-gate.js +2 -2
  299. package/hooks/scripts/subagent-scope-guard.js +144 -38
  300. package/hooks/scripts/subagent-start.js +19 -0
  301. package/hooks/scripts/subagent-stop.js +6 -0
  302. package/improve-codebase-architecture/SKILL.md +2 -4
  303. package/improve-codebase-architecture/references/README.md +16 -0
  304. package/install-cognitive-os/SKILL.md +28 -22
  305. package/multi-agent-workspace/SKILL.md +16 -15
  306. package/multi-agent-workspace/references/architecture-guide.md +13 -9
  307. package/multi-agent-workspace/references/orchestration.md +39 -22
  308. package/multi-agent-workspace/scripts/consume-workflow-plan.js +129 -0
  309. package/multi-agent-workspace/scripts/index_memory.js +79 -26
  310. package/multi-agent-workspace/scripts/path-boundary.js +59 -0
  311. package/multi-agent-workspace/scripts/project-docs-resolver.js +357 -0
  312. package/multi-agent-workspace/scripts/scaffold.js +258 -103
  313. package/multi-agent-workspace/templates/AGENTS.md +20 -0
  314. package/multi-agent-workspace/workflows/03-generation.md +8 -10
  315. package/multi-agent-workspace/workflows/04-launcher.md +5 -5
  316. package/opencode-plugin/README.md +114 -71
  317. package/opencode-plugin/hooks/verify.js +62 -12
  318. package/opencode-plugin/index.mjs +547 -0
  319. package/opencode-plugin/plugin.json +4 -12
  320. package/package.json +20 -4
  321. package/plugins/harness-everything/.codex-plugin/plugin.json +39 -0
  322. package/plugins/harness-everything/hooks/hooks.json +197 -0
  323. package/plugins/harness-everything/hooks/scripts/action-gate-rules.json +77 -0
  324. package/plugins/harness-everything/hooks/scripts/action-gate.js +528 -0
  325. package/plugins/harness-everything/hooks/scripts/atomic-commit-check.js +68 -0
  326. package/plugins/harness-everything/hooks/scripts/boundary-guard.js +55 -0
  327. package/plugins/harness-everything/hooks/scripts/codex-action-gate-post.js +46 -0
  328. package/plugins/harness-everything/hooks/scripts/codex-permission-request.js +140 -0
  329. package/plugins/harness-everything/hooks/scripts/context-compact.js +115 -0
  330. package/plugins/harness-everything/hooks/scripts/contract-test.js +146 -0
  331. package/plugins/harness-everything/hooks/scripts/depth-guard.js +65 -0
  332. package/plugins/harness-everything/hooks/scripts/lib/fable-contracts.js +121 -0
  333. package/plugins/harness-everything/hooks/scripts/lib/harness-state.js +275 -0
  334. package/plugins/harness-everything/hooks/scripts/lib/platforms/claude.js +168 -0
  335. package/plugins/harness-everything/hooks/scripts/lib/platforms/codex.js +88 -0
  336. package/plugins/harness-everything/hooks/scripts/lib/platforms/continue.js +91 -0
  337. package/plugins/harness-everything/hooks/scripts/lib/platforms/copilot.js +85 -0
  338. package/plugins/harness-everything/hooks/scripts/lib/platforms/cursor.js +89 -0
  339. package/plugins/harness-everything/hooks/scripts/lib/platforms/hermes.js +108 -0
  340. package/plugins/harness-everything/hooks/scripts/lib/platforms/index.js +17 -0
  341. package/plugins/harness-everything/hooks/scripts/lib/platforms/worktrees.js +20 -0
  342. package/plugins/harness-everything/hooks/scripts/lib/workspace.js +290 -0
  343. package/plugins/harness-everything/hooks/scripts/openai-session-start.js +81 -0
  344. package/plugins/harness-everything/hooks/scripts/reset-circuit-breaker.js +30 -0
  345. package/plugins/harness-everything/hooks/scripts/rule-of-3-tracker.js +125 -0
  346. package/plugins/harness-everything/hooks/scripts/rule-of-3.js +195 -0
  347. package/plugins/harness-everything/hooks/scripts/state-persist.js +100 -0
  348. package/plugins/harness-everything/hooks/scripts/stop-gate.js +80 -0
  349. package/plugins/harness-everything/hooks/scripts/subagent-scope-guard.js +194 -0
  350. package/plugins/harness-everything/hooks/scripts/subagent-start.js +19 -0
  351. package/plugins/harness-everything/hooks/scripts/subagent-stop.js +6 -0
  352. package/plugins/harness-everything/hooks/session-start.js +81 -0
  353. package/plugins/harness-everything/plugin.json +43 -0
  354. package/plugins/harness-everything/scripts/lib/advisory-text.js +174 -0
  355. package/plugins/harness-everything/skills/environment-detection/SKILL.md +41 -0
  356. package/plugins/harness-everything/skills/environment-detection/references/shell-syntax-rules.md +76 -0
  357. package/plugins/harness-everything/skills/environment-detection/scripts/preflight.js +103 -0
  358. package/plugins/harness-everything/skills/eval-harness/SKILL.md +42 -0
  359. package/plugins/harness-everything/skills/eval-harness/references/scoring-rubric.md +68 -0
  360. package/plugins/harness-everything/skills/eval-harness/scripts/evaluate.js +79 -0
  361. package/plugins/harness-everything/skills/fable-discipline/SKILL.md +41 -0
  362. package/plugins/harness-everything/skills/fable-discipline/references/discipline-rules.md +22 -0
  363. package/plugins/harness-everything/skills/fable-mode/CONTRACT-FORMAT.md +165 -0
  364. package/plugins/harness-everything/skills/fable-mode/SKILL.md +39 -0
  365. package/plugins/harness-everything/skills/fable-mode/agents/fable-orchestrator.md +159 -0
  366. package/plugins/harness-everything/skills/fable-mode/agents/fable-verifier.md +32 -0
  367. package/plugins/harness-everything/skills/fable-mode/agents/fable-worker-haiku.md +52 -0
  368. package/plugins/harness-everything/skills/fable-mode/agents/fable-worker-sonnet.md +53 -0
  369. package/plugins/harness-everything/skills/fable-mode/execution-guardrails/SKILL.md +43 -0
  370. package/plugins/harness-everything/skills/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
  371. package/plugins/harness-everything/skills/fable-mode/fable-haiku/SKILL.md +36 -0
  372. package/plugins/harness-everything/skills/fable-mode/fable-haiku/references/routing-notes.md +26 -0
  373. package/plugins/harness-everything/skills/fable-mode/fable-opus/SKILL.md +36 -0
  374. package/plugins/harness-everything/skills/fable-mode/fable-sonnet/SKILL.md +36 -0
  375. package/plugins/harness-everything/skills/fable-mode/model-matrix.json +32 -0
  376. package/plugins/harness-everything/skills/fable-mode/references/execution-phases.md +37 -0
  377. package/plugins/harness-everything/skills/fable-mode/references/model-matrix.md +39 -0
  378. package/plugins/harness-everything/skills/fable-mode/scripts/ensemble-review.js +371 -0
  379. package/plugins/harness-everything/skills/fable-mode/scripts/model-selector.js +260 -0
  380. package/plugins/harness-everything/skills/fable-mode/scripts/workflow-plan-consumer.js +337 -0
  381. package/plugins/harness-everything/skills/find-skills/SKILL.md +48 -0
  382. package/plugins/harness-everything/skills/find-skills/references/discovery-flow.md +102 -0
  383. package/plugins/harness-everything/skills/find-skills/scripts/use-skill.js +112 -0
  384. package/plugins/harness-everything/skills/git-commit/SKILL.md +38 -0
  385. package/plugins/harness-everything/skills/git-commit/guides/ANGULAR_STYLE.md +61 -0
  386. package/plugins/harness-everything/skills/git-commit/guides/COMMIT_GENERATION.md +24 -0
  387. package/plugins/harness-everything/skills/git-commit/guides/LANGUAGE_DETECTION.md +16 -0
  388. package/plugins/harness-everything/skills/git-commit/guides/MAIN_REPO.md +15 -0
  389. package/plugins/harness-everything/skills/git-commit/guides/SUBMODULES.md +27 -0
  390. package/plugins/harness-everything/skills/git-commit/references/commit-flow.md +30 -0
  391. package/plugins/harness-everything/skills/grill-me/SKILL.md +43 -0
  392. package/plugins/harness-everything/skills/grill-me/references/grilling-playbook.md +38 -0
  393. package/plugins/harness-everything/skills/grill-with-docs/ADR-FORMAT.md +47 -0
  394. package/plugins/harness-everything/skills/grill-with-docs/CONTEXT-FORMAT.md +63 -0
  395. package/plugins/harness-everything/skills/grill-with-docs/SKILL.md +41 -0
  396. package/plugins/harness-everything/skills/grill-with-docs/references/session-playbook.md +99 -0
  397. package/plugins/harness-everything/skills/harness-everything/SKILL.md +43 -0
  398. package/plugins/harness-everything/skills/harness-everything/examples/README.md +9 -0
  399. package/plugins/harness-everything/skills/harness-everything/examples/todo-workflow.md +22 -0
  400. package/plugins/harness-everything/skills/harness-everything/references/router-workflow-plan.md +128 -0
  401. package/plugins/harness-everything/skills/harness-everything/references/skill-registry.md +39 -0
  402. package/plugins/harness-everything/skills/harness-everything/references/triage-and-tiers.md +193 -0
  403. package/plugins/harness-everything/skills/harness-everything/schemas/router-task-shape.schema.json +126 -0
  404. package/plugins/harness-everything/skills/harness-everything/schemas/router-workflow-plan.schema.json +149 -0
  405. package/plugins/harness-everything/skills/harness-everything/scripts/bootstrap.js +212 -0
  406. package/plugins/harness-everything/skills/harness-everything/scripts/ensemble-policy.js +102 -0
  407. package/plugins/harness-everything/skills/harness-everything/scripts/kernel-router.js +212 -0
  408. package/plugins/harness-everything/skills/harness-everything/scripts/router-contract.js +612 -0
  409. package/plugins/harness-everything/skills/harness-everything/scripts/routing-keywords.json +320 -0
  410. package/plugins/harness-everything/skills/harness-everything/scripts/self-heal.js +250 -0
  411. package/plugins/harness-everything/skills/harness-everything/scripts/tier-router.js +459 -0
  412. package/plugins/harness-everything/skills/harness-everything/scripts/verify-gate.js +100 -0
  413. package/plugins/harness-everything/skills/improve-codebase-architecture/SKILL.md +38 -0
  414. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/DEEPENING.md +37 -0
  415. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/HTML-REPORT.md +123 -0
  416. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -0
  417. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/LANGUAGE.md +53 -0
  418. package/plugins/harness-everything/skills/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
  419. package/plugins/harness-everything/skills/improve-codebase-architecture/references/README.md +16 -0
  420. package/plugins/harness-everything/skills/install-cognitive-os/SKILL.md +44 -0
  421. package/plugins/harness-everything/skills/install-cognitive-os/references/cognitive-loop.md +27 -0
  422. package/plugins/harness-everything/skills/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
  423. package/plugins/harness-everything/skills/multi-agent-workspace/SKILL.md +38 -0
  424. package/plugins/harness-everything/skills/multi-agent-workspace/examples/csharp-monorepo.md +123 -0
  425. package/plugins/harness-everything/skills/multi-agent-workspace/examples/typescript-cli.md +126 -0
  426. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-claude.md +77 -0
  427. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-codex.md +146 -0
  428. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-continue.md +38 -0
  429. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-copilot.md +74 -0
  430. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
  431. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
  432. package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/role-capabilities.md +108 -0
  433. package/plugins/harness-everything/skills/multi-agent-workspace/references/agency-agents.md +31 -0
  434. package/plugins/harness-everything/skills/multi-agent-workspace/references/architecture-guide.md +36 -0
  435. package/plugins/harness-everything/skills/multi-agent-workspace/references/orchestration.md +65 -0
  436. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/agency-catalog.js +190 -0
  437. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/consume-workflow-plan.js +129 -0
  438. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/index_memory.js +104 -0
  439. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/path-boundary.js +59 -0
  440. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/project-docs-resolver.js +357 -0
  441. package/plugins/harness-everything/skills/multi-agent-workspace/scripts/scaffold.js +408 -0
  442. package/plugins/harness-everything/skills/multi-agent-workspace/templates/AGENTS.md +20 -0
  443. package/plugins/harness-everything/skills/multi-agent-workspace/templates/README.md +17 -0
  444. package/plugins/harness-everything/skills/multi-agent-workspace/templates/agent-launcher.md +68 -0
  445. package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-csharp.md +56 -0
  446. package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-polyglot.md +62 -0
  447. package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-ts.md +57 -0
  448. package/plugins/harness-everything/skills/multi-agent-workspace/templates/memory-keeper.md +37 -0
  449. package/plugins/harness-everything/skills/multi-agent-workspace/templates/requirement-analyzer.md +66 -0
  450. package/plugins/harness-everything/skills/multi-agent-workspace/templates/specialist-agent.md +34 -0
  451. package/plugins/harness-everything/skills/multi-agent-workspace/templates/task-verifier.md +56 -0
  452. package/plugins/harness-everything/skills/multi-agent-workspace/templates/tool-maker.md +33 -0
  453. package/plugins/harness-everything/skills/multi-agent-workspace/workflows/01-init.md +22 -0
  454. package/plugins/harness-everything/skills/multi-agent-workspace/workflows/02-analysis.md +23 -0
  455. package/plugins/harness-everything/skills/multi-agent-workspace/workflows/03-generation.md +25 -0
  456. package/plugins/harness-everything/skills/multi-agent-workspace/workflows/04-launcher.md +16 -0
  457. package/plugins/harness-everything/skills/repo-docs/SKILL.md +42 -0
  458. package/plugins/harness-everything/skills/repo-docs/references/process-guide.md +60 -0
  459. package/plugins/harness-everything/skills/repo-docs/templates/agents-template.md +264 -0
  460. package/plugins/harness-everything/skills/repo-docs/templates/knowledge-agents-template.md +50 -0
  461. package/plugins/harness-everything/skills/repo-docs/templates/knowledge-readme-template.md +83 -0
  462. package/plugins/harness-everything/skills/repo-docs/templates/manual-recon.md +117 -0
  463. package/plugins/harness-everything/skills/repo-docs/templates/multi-skills-readme-template.md +72 -0
  464. package/plugins/harness-everything/skills/repo-docs/templates/product-agents-template.md +78 -0
  465. package/plugins/harness-everything/skills/repo-docs/templates/product-readme-template.md +95 -0
  466. package/plugins/harness-everything/skills/repo-docs/templates/readme-template.md +136 -0
  467. package/plugins/harness-everything/skills/repo-docs/templates/single-skill-readme-template.md +70 -0
  468. package/plugins/harness-everything/skills/repo-docs/templates/skills-agents-template.md +60 -0
  469. package/plugins/harness-everything/skills/rewrite-commits/SKILL.md +37 -0
  470. package/plugins/harness-everything/skills/rewrite-commits/references/workflow.md +18 -0
  471. package/plugins/harness-everything/skills/security-review/SKILL.md +47 -0
  472. package/plugins/harness-everything/skills/security-review/guides/OWASP-PATTERNS.md +31 -0
  473. package/plugins/harness-everything/skills/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
  474. package/plugins/harness-everything/skills/security-review/references/security-checklist.md +478 -0
  475. package/plugins/harness-everything/skills/security-review/scripts/audit-secrets.js +85 -0
  476. package/plugins/harness-everything/skills/self-evolve/SKILL.md +45 -0
  477. package/plugins/harness-everything/skills/self-evolve/references/memory-resolution.md +61 -0
  478. package/plugins/harness-everything/skills/self-evolve/scripts/persist-memory.js +272 -0
  479. package/plugins/harness-everything/skills/self-evolve/scripts/register-dynamic-skill.js +253 -0
  480. package/plugins/harness-everything/skills/self-evolve/scripts/self-regression.js +125 -0
  481. package/plugins/harness-everything/skills/skill-creator/SKILL.md +47 -0
  482. package/plugins/harness-everything/skills/skill-creator/references/authoring-workflow.md +14 -0
  483. package/plugins/harness-everything/skills/skill-creator/references/dynamic-generation-contract.md +21 -0
  484. package/plugins/harness-everything/skills/skill-creator/references/quality-checklist.md +16 -0
  485. package/plugins/harness-everything/skills/skill-creator/references/quality-principles.md +81 -0
  486. package/plugins/harness-everything/skills/skill-creator/references/testing-workflow.md +27 -0
  487. package/plugins/harness-everything/skills/skill-style/SKILL.md +42 -0
  488. package/plugins/harness-everything/skills/skill-style/references/style-guide.md +62 -0
  489. package/plugins/harness-everything/skills/tdd/SKILL.md +38 -0
  490. package/plugins/harness-everything/skills/tdd/fixtures/pass-evidence.json +100 -0
  491. package/plugins/harness-everything/skills/tdd/fixtures/quality-scenarios.json +20 -0
  492. package/plugins/harness-everything/skills/tdd/guides/deep-modules.md +33 -0
  493. package/plugins/harness-everything/skills/tdd/guides/interface-design.md +31 -0
  494. package/plugins/harness-everything/skills/tdd/guides/mocking.md +59 -0
  495. package/plugins/harness-everything/skills/tdd/guides/refactoring.md +10 -0
  496. package/plugins/harness-everything/skills/tdd/guides/tests.md +61 -0
  497. package/plugins/harness-everything/skills/tdd/references/core-discipline.md +51 -0
  498. package/plugins/harness-everything/skills/tdd/references/integration-testing.md +13 -0
  499. package/plugins/harness-everything/skills/tdd/references/quality-model.md +68 -0
  500. package/plugins/harness-everything/skills/tdd/references/unit-testing.md +15 -0
  501. package/plugins/harness-everything/skills/tdd/schemas/quality-evidence.schema.json +211 -0
  502. package/plugins/harness-everything/skills/tdd/schemas/quality-report.schema.json +110 -0
  503. package/plugins/harness-everything/skills/tdd/scripts/quality-gate.js +475 -0
  504. package/plugins/harness-everything/skills/to-spec/SKILL.md +40 -0
  505. package/plugins/harness-everything/skills/to-spec/references/process.md +77 -0
  506. package/plugins/harness-everything/skills/to-spec/scripts/check-project-docs.js +239 -0
  507. package/plugins/harness-everything/skills/to-spec/scripts/project-docs-resolver.js +111 -0
  508. package/plugins/harness-everything/skills/to-spec/templates/cli-reference.md +31 -0
  509. package/plugins/harness-everything/skills/to-spec/templates/dev-doc.md +27 -0
  510. package/plugins/harness-everything/skills/to-spec/templates/feature-spec.md +59 -0
  511. package/plugins/harness-everything/skills/to-spec/templates/schema-doc.md +31 -0
  512. package/plugins/harness-everything/skills/to-tickets/SKILL.md +42 -0
  513. package/plugins/harness-everything/skills/to-tickets/references/publishing-and-templates.md +97 -0
  514. package/plugins/harness-everything/skills/todo-driven-workflow/SKILL.md +42 -0
  515. package/plugins/harness-everything/skills/todo-driven-workflow/references/execution-guide.md +27 -0
  516. package/plugins/harness-everything/skills/using-git-worktrees/SKILL.md +49 -0
  517. package/plugins/harness-everything/skills/using-git-worktrees/references/workflow-details.md +108 -0
  518. package/plugins/harness-everything/skills/verification-loop/SKILL.md +46 -0
  519. package/plugins/harness-everything/skills/verification-loop/references/verification-phases.md +116 -0
  520. package/plugins/harness-everything/skills/verification-loop/templates/verification-report.template.md +15 -0
  521. package/plugins/harness-everything/skills/verify-before-claim/SKILL.md +43 -0
  522. package/plugins/harness-everything/skills/verify-before-claim/references/verification-guide.md +73 -0
  523. package/plugins/harness-everything/skills/zoom-out/SKILL.md +42 -0
  524. package/plugins/harness-everything/skills/zoom-out/references/circuit-breaker.md +66 -0
  525. package/plugins/harness-everything/skills/zoom-out/templates/zoom-out-report.template.md +20 -0
  526. package/repo-docs/SKILL.md +3 -7
  527. package/rewrite-commits/SKILL.md +2 -2
  528. package/scripts/build-openai-submission.js +158 -0
  529. package/scripts/installer.js +86 -11
  530. package/scripts/lib/advisory-text.js +25 -18
  531. package/scripts/lib/execution-contract.js +70 -0
  532. package/scripts/lib/manifest.js +34 -38
  533. package/scripts/lib/path-boundary.js +90 -0
  534. package/scripts/lib/skills.js +124 -70
  535. package/scripts/lib/workspace.js +269 -7
  536. package/scripts/repository-contract.js +213 -0
  537. package/scripts/sync-current-docs.js +12 -0
  538. package/scripts/sync-openai-plugin.js +91 -0
  539. package/scripts/sync-release-version.js +212 -0
  540. package/security-review/SKILL.md +4 -7
  541. package/security-review/scripts/audit-secrets.js +9 -8
  542. package/self-evolve/SKILL.md +9 -11
  543. package/self-evolve/references/memory-resolution.md +4 -1
  544. package/self-evolve/scripts/persist-memory.js +221 -88
  545. package/self-evolve/scripts/register-dynamic-skill.js +12 -10
  546. package/self-evolve/scripts/self-regression.js +23 -8
  547. package/skill-creator/SKILL.md +12 -14
  548. package/skill-creator/references/quality-checklist.md +1 -0
  549. package/skill-style/SKILL.md +4 -4
  550. package/skill-style/references/style-guide.md +29 -3
  551. package/submission/openai/README.md +67 -0
  552. package/submission/openai/listing.json +31 -0
  553. package/submission/openai/test-cases.json +61 -0
  554. package/tdd/SKILL.md +20 -26
  555. package/tdd/fixtures/pass-evidence.json +100 -0
  556. package/tdd/fixtures/quality-scenarios.json +20 -0
  557. package/tdd/references/core-discipline.md +2 -0
  558. package/tdd/references/integration-testing.md +13 -0
  559. package/tdd/references/quality-model.md +68 -0
  560. package/tdd/references/unit-testing.md +15 -0
  561. package/tdd/schemas/quality-evidence.schema.json +211 -0
  562. package/tdd/schemas/quality-report.schema.json +110 -0
  563. package/tdd/scripts/quality-gate.js +475 -0
  564. package/to-spec/SKILL.md +3 -5
  565. package/to-spec/scripts/check-project-docs.js +42 -62
  566. package/to-spec/scripts/project-docs-resolver.js +111 -0
  567. package/to-tickets/SKILL.md +4 -4
  568. package/todo-driven-workflow/SKILL.md +6 -4
  569. package/using-git-worktrees/SKILL.md +3 -3
  570. package/verification-loop/SKILL.md +4 -4
  571. package/verify-before-claim/SKILL.md +2 -2
  572. package/zoom-out/SKILL.md +4 -4
  573. package/ab-test-deep-analysis-2026-08-27.md +0 -383
  574. package/ab-test-results-2026-08-27.md +0 -152
  575. package/ab-test-statistical-analysis-31cases.md +0 -193
  576. package/opencode-plugin/hooks/circuit-breaker.js +0 -121
  577. package/opencode-plugin/hooks/compliance.js +0 -128
  578. package/opencode-plugin/hooks/post-edit.js +0 -62
  579. package/opencode-plugin/hooks/pre-complete.js +0 -65
  580. package/opencode-plugin/test-hook-firing.js +0 -198
@@ -0,0 +1,475 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const VERSION = '1.0.0';
7
+ const DIMENSIONS = [
8
+ 'positiveParameters',
9
+ 'negativeParameters',
10
+ 'inputCompleteness',
11
+ 'outputCompleteness',
12
+ 'errorHandling',
13
+ 'unexpectedInput',
14
+ 'determinism',
15
+ 'sourceTraceability'
16
+ ];
17
+ const WEIGHTS = {
18
+ positiveParameters: 0.15,
19
+ negativeParameters: 0.15,
20
+ inputCompleteness: 0.15,
21
+ outputCompleteness: 0.15,
22
+ errorHandling: 0.15,
23
+ unexpectedInput: 0.10,
24
+ determinism: 0.10,
25
+ sourceTraceability: 0.05
26
+ };
27
+ const REQUIRED_CLASSES = {
28
+ inputCompleteness: ['required', 'optional', 'omitted', 'empty', 'null', 'min', 'max', 'boundary'],
29
+ outputCompleteness: ['value', 'type', 'schema', 'required-field', 'prohibited-extra-field', 'side-effect'],
30
+ errorHandling: ['error-type', 'error-code', 'message', 'state-cleanup', 'rollback', 'no-unintended-output'],
31
+ unexpectedInput: ['malformed', 'unknown', 'extra', 'unsupported', 'out-of-range', 'duplicate', 'wrong-type']
32
+ };
33
+ const CHECK_STATUSES = new Set(['PASS', 'FAIL', 'SKIPPED', 'N/A']);
34
+ const SIDE_EFFECT_FIELDS = ['createdFiles', 'changedFiles', 'deletedFiles', 'persistentState', 'events', 'logs', 'externalCalls'];
35
+
36
+ function isObject(value) {
37
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
38
+ }
39
+
40
+ function nonEmpty(value) {
41
+ return typeof value === 'string' && value.trim().length > 0;
42
+ }
43
+
44
+ function round(value) {
45
+ return Math.round((value + Number.EPSILON) * 100) / 100;
46
+ }
47
+
48
+ function stable(value) {
49
+ if (Array.isArray(value)) return value.map(stable);
50
+ if (!isObject(value)) return value;
51
+ return Object.keys(value).sort().reduce((result, key) => {
52
+ result[key] = stable(value[key]);
53
+ return result;
54
+ }, {});
55
+ }
56
+
57
+ function equal(left, right) {
58
+ return JSON.stringify(stable(left)) === JSON.stringify(stable(right));
59
+ }
60
+
61
+ function clone(value) {
62
+ return value === undefined ? undefined : JSON.parse(JSON.stringify(value));
63
+ }
64
+
65
+ function normalizeRun(run, normalizations, errors, prefix) {
66
+ const comparable = {
67
+ exitStatus: run.exitStatus,
68
+ errorCategory: run.errorCategory,
69
+ output: clone(run.output),
70
+ sideEffects: clone(run.sideEffects)
71
+ };
72
+
73
+ for (const normalization of normalizations) {
74
+ if (!isObject(normalization) || !nonEmpty(normalization.path) || !nonEmpty(normalization.rule) || !nonEmpty(normalization.sourceSection)) {
75
+ errors.push(`${prefix}.normalizations entries require path, rule, and sourceSection`);
76
+ continue;
77
+ }
78
+ const parts = normalization.path.split('.');
79
+ if (!['output', 'sideEffects'].includes(parts[0]) || parts.some(part => !part)) {
80
+ errors.push(`${prefix}.normalizations path must start with output or sideEffects`);
81
+ continue;
82
+ }
83
+ let cursor = comparable;
84
+ let found = true;
85
+ for (let index = 0; index < parts.length - 1; index++) {
86
+ if (!isObject(cursor) && !Array.isArray(cursor)) { found = false; break; }
87
+ if (!Object.prototype.hasOwnProperty.call(cursor, parts[index])) { found = false; break; }
88
+ cursor = cursor[parts[index]];
89
+ }
90
+ const leaf = parts[parts.length - 1];
91
+ if (!found || (!isObject(cursor) && !Array.isArray(cursor)) || !Object.prototype.hasOwnProperty.call(cursor, leaf)) {
92
+ errors.push(`${prefix}.normalizations path does not exist in every run: ${normalization.path}`);
93
+ continue;
94
+ }
95
+ cursor[leaf] = `[normalized: ${normalization.rule}]`;
96
+ }
97
+ return comparable;
98
+ }
99
+
100
+ function emptyDimension(applicable = false) {
101
+ return { applicable, passed: 0, required: 0, percentage: applicable ? 0 : null };
102
+ }
103
+
104
+ function evaluateChecks(name, dimension, errors, prefix, skippedTests, naDeclarations) {
105
+ if (!isObject(dimension) || typeof dimension.applicable !== 'boolean') {
106
+ errors.push(`${prefix}.${name} requires an explicit boolean applicable field`);
107
+ return emptyDimension(true);
108
+ }
109
+ if (!dimension.applicable) {
110
+ if (!nonEmpty(dimension.reason)) errors.push(`${prefix}.${name} N/A requires a written reason`);
111
+ const declaration = { dimension: name, reason: dimension.reason || '' };
112
+ naDeclarations.push(declaration);
113
+ return { ...emptyDimension(false), reason: dimension.reason || '' };
114
+ }
115
+ if (!Array.isArray(dimension.checks) || dimension.checks.length === 0) {
116
+ errors.push(`${prefix}.${name} requires at least one executed check`);
117
+ return { ...emptyDimension(true), checks: [] };
118
+ }
119
+
120
+ const seenIds = new Set();
121
+ const seenClasses = new Set();
122
+ let passed = 0;
123
+ let required = 0;
124
+ let executed = 0;
125
+ const checks = dimension.checks.map((check, index) => {
126
+ const location = `${prefix}.${name}.checks[${index}]`;
127
+ if (!isObject(check)) {
128
+ errors.push(`${location} must be an object`);
129
+ return check;
130
+ }
131
+ if (!nonEmpty(check.id)) errors.push(`${location}.id is required`);
132
+ else if (seenIds.has(check.id)) errors.push(`${location}.id is duplicated: ${check.id}`);
133
+ else seenIds.add(check.id);
134
+ if (!nonEmpty(check.class)) errors.push(`${location}.class is required`);
135
+ else seenClasses.add(check.class);
136
+ if (!CHECK_STATUSES.has(check.status)) errors.push(`${location}.status must be PASS, FAIL, SKIPPED, or N/A`);
137
+ if (check.status === 'N/A') {
138
+ if (!nonEmpty(check.reason)) errors.push(`${location} N/A requires a written reason`);
139
+ naDeclarations.push({ dimension: name, checkId: check.id || `index-${index}`, reason: check.reason || '' });
140
+ } else {
141
+ required++;
142
+ if (check.status === 'PASS') passed++;
143
+ if (check.status === 'PASS' || check.status === 'FAIL') executed++;
144
+ if (check.status === 'SKIPPED') skippedTests.push({ dimension: name, checkId: check.id || `index-${index}` });
145
+ if (!nonEmpty(check.evidence)) errors.push(`${location}.evidence is required for applicable checks`);
146
+ }
147
+ return clone(check);
148
+ });
149
+
150
+ for (const requiredClass of REQUIRED_CLASSES[name] || []) {
151
+ if (!seenClasses.has(requiredClass)) errors.push(`${prefix}.${name} is missing declared class ${requiredClass}; mark it N/A with a reason when inapplicable`);
152
+ }
153
+ if (required === 0 || executed === 0) errors.push(`${prefix}.${name} has no executed applicable case`);
154
+ return {
155
+ applicable: true,
156
+ passed,
157
+ required,
158
+ percentage: required === 0 ? 0 : round(passed / required * 100),
159
+ checks
160
+ };
161
+ }
162
+
163
+ function evaluateDeterminism(dimension, source, errors, prefix, naDeclarations) {
164
+ if (!isObject(dimension) || typeof dimension.applicable !== 'boolean') {
165
+ errors.push(`${prefix}.determinism requires an explicit boolean applicable field`);
166
+ return { ...emptyDimension(true), matchingRuns: 0, totalRuns: 0, runs: [], normalizations: [] };
167
+ }
168
+ if (!dimension.applicable) {
169
+ if (!nonEmpty(dimension.reason)) errors.push(`${prefix}.determinism N/A requires a written reason`);
170
+ naDeclarations.push({ dimension: 'determinism', reason: dimension.reason || '' });
171
+ return { ...emptyDimension(false), matchingRuns: 0, totalRuns: 0, runs: [], normalizations: [], reason: dimension.reason || '' };
172
+ }
173
+
174
+ const runs = Array.isArray(dimension.runs) ? dimension.runs : [];
175
+ const normalizations = Array.isArray(dimension.normalizations) ? dimension.normalizations : [];
176
+ if (runs.length < 2) errors.push(`${prefix}.determinism requires at least two runs`);
177
+ if (normalizations.length > 0 && source.status !== 'AUTHORITATIVE') {
178
+ errors.push(`${prefix}.determinism normalization requires an authoritative source`);
179
+ }
180
+ const ids = new Set();
181
+ for (const [index, run] of runs.entries()) {
182
+ const location = `${prefix}.determinism.runs[${index}]`;
183
+ if (!isObject(run)) { errors.push(`${location} must be an object`); continue; }
184
+ if (!nonEmpty(run.id)) errors.push(`${location}.id is required`);
185
+ else if (ids.has(run.id)) errors.push(`${location}.id is duplicated: ${run.id}`);
186
+ else ids.add(run.id);
187
+ for (const field of ['input', 'exitStatus', 'errorCategory', 'output', 'sideEffects']) {
188
+ if (!Object.prototype.hasOwnProperty.call(run, field)) errors.push(`${location}.${field} is required`);
189
+ }
190
+ if (!Number.isInteger(run.exitStatus)) errors.push(`${location}.exitStatus must be an integer`);
191
+ if (run.errorCategory !== null && typeof run.errorCategory !== 'string') errors.push(`${location}.errorCategory must be a string or null`);
192
+ if (!isObject(run.sideEffects)) errors.push(`${location}.sideEffects must be an object`);
193
+ else {
194
+ for (const field of SIDE_EFFECT_FIELDS) {
195
+ if (!Object.prototype.hasOwnProperty.call(run.sideEffects, field)) errors.push(`${location}.sideEffects.${field} is required`);
196
+ }
197
+ for (const field of ['createdFiles', 'changedFiles', 'deletedFiles', 'events', 'logs', 'externalCalls']) {
198
+ if (!Array.isArray(run.sideEffects[field])) errors.push(`${location}.sideEffects.${field} must be an array`);
199
+ }
200
+ }
201
+ }
202
+
203
+ let matchingRuns = runs.length > 0 ? 1 : 0;
204
+ if (runs.length > 0) {
205
+ const baselineInput = runs[0].input;
206
+ const baseline = normalizeRun(runs[0], normalizations, errors, `${prefix}.determinism`);
207
+ for (let index = 1; index < runs.length; index++) {
208
+ const candidate = normalizeRun(runs[index], normalizations, errors, `${prefix}.determinism`);
209
+ if (equal(baselineInput, runs[index].input) && equal(baseline, candidate)) matchingRuns++;
210
+ }
211
+ }
212
+ return {
213
+ applicable: true,
214
+ passed: matchingRuns,
215
+ required: runs.length,
216
+ percentage: runs.length === 0 ? 0 : round(matchingRuns / runs.length * 100),
217
+ matchingRuns,
218
+ totalRuns: runs.length,
219
+ runs: clone(runs),
220
+ normalizations: clone(normalizations)
221
+ };
222
+ }
223
+
224
+ function evaluateSource(source, errors, prefix) {
225
+ if (!isObject(source)) {
226
+ errors.push(`${prefix}.source is required`);
227
+ return { source: {}, traced: 0, total: 1, percentage: 0 };
228
+ }
229
+ if (!['AUTHORITATIVE', 'INFERRED'].includes(source.status)) errors.push(`${prefix}.source.status must be AUTHORITATIVE or INFERRED`);
230
+ if (!nonEmpty(source.type)) errors.push(`${prefix}.source.type is required`);
231
+ if (source.status === 'AUTHORITATIVE') {
232
+ if (!nonEmpty(source.path)) errors.push(`${prefix}.source.path is required for authoritative sources`);
233
+ if (!nonEmpty(source.section)) errors.push(`${prefix}.source.section is required for authoritative sources`);
234
+ }
235
+ if (source.status === 'INFERRED' && !nonEmpty(source.inferenceBasis)) errors.push(`${prefix}.source.inferenceBasis is required for inferred expectations`);
236
+ const valid = source.status === 'AUTHORITATIVE'
237
+ ? nonEmpty(source.type) && nonEmpty(source.path) && nonEmpty(source.section)
238
+ : source.status === 'INFERRED' && nonEmpty(source.type) && nonEmpty(source.inferenceBasis);
239
+ return { source: clone(source), traced: valid ? 1 : 0, total: 1, percentage: valid ? 100 : 0 };
240
+ }
241
+
242
+ function scoreDimensions(dimensions) {
243
+ let weighted = 0;
244
+ let appliedWeight = 0;
245
+ for (const name of DIMENSIONS) {
246
+ const dimension = dimensions[name];
247
+ if (!dimension || dimension.applicable === false || dimension.percentage === null) continue;
248
+ weighted += dimension.percentage * WEIGHTS[name];
249
+ appliedWeight += WEIGHTS[name];
250
+ }
251
+ return appliedWeight === 0 ? 0 : round(weighted / appliedWeight);
252
+ }
253
+
254
+ function scoringDetails(dimensions) {
255
+ let weightedPoints = 0;
256
+ let applicableWeight = 0;
257
+ for (const name of DIMENSIONS) {
258
+ const dimension = dimensions[name];
259
+ if (!dimension || dimension.applicable === false || dimension.percentage === null) continue;
260
+ weightedPoints += dimension.percentage * WEIGHTS[name];
261
+ applicableWeight += WEIGHTS[name];
262
+ }
263
+ return {
264
+ weights: { ...WEIGHTS },
265
+ method: 'weightedPoints / applicableWeight',
266
+ weightedPoints: round(weightedPoints),
267
+ applicableWeight: round(applicableWeight),
268
+ requiredScore: 100
269
+ };
270
+ }
271
+
272
+ function evaluateRequirement(requirement, index, errors) {
273
+ const prefix = `requirements[${index}]`;
274
+ const localErrorsBefore = errors.length;
275
+ if (!['unit', 'integration'].includes(requirement.testProfile)) {
276
+ errors.push(`${prefix}.testProfile must be unit or integration`);
277
+ }
278
+ if (!Array.isArray(requirement.skippedTests)) errors.push(`${prefix}.skippedTests must be an array`);
279
+ if (!Array.isArray(requirement.naDeclarations)) errors.push(`${prefix}.naDeclarations must be an array`);
280
+ if (requirement.flakyTests !== undefined && !Array.isArray(requirement.flakyTests)) errors.push(`${prefix}.flakyTests must be an array`);
281
+ const skippedTests = Array.isArray(requirement.skippedTests) ? clone(requirement.skippedTests) : [];
282
+ const naDeclarations = Array.isArray(requirement.naDeclarations) ? clone(requirement.naDeclarations) : [];
283
+ const sourceResult = evaluateSource(requirement.source, errors, prefix);
284
+ const additionalSourceResults = [];
285
+ if (requirement.additionalSources !== undefined && !Array.isArray(requirement.additionalSources)) {
286
+ errors.push(`${prefix}.additionalSources must be an array`);
287
+ }
288
+ for (const [sourceIndex, source] of (Array.isArray(requirement.additionalSources) ? requirement.additionalSources : []).entries()) {
289
+ additionalSourceResults.push(evaluateSource(source, errors, `${prefix}.additionalSources[${sourceIndex}]`));
290
+ }
291
+ const dimensionsInput = isObject(requirement.dimensions) ? requirement.dimensions : {};
292
+ if (!isObject(requirement.dimensions)) errors.push(`${prefix}.dimensions is required`);
293
+ const dimensions = {};
294
+ for (const name of DIMENSIONS.slice(0, 6)) {
295
+ dimensions[name] = evaluateChecks(name, dimensionsInput[name], errors, prefix, skippedTests, naDeclarations);
296
+ }
297
+ dimensions.determinism = evaluateDeterminism(dimensionsInput.determinism, requirement.source || {}, errors, prefix, naDeclarations);
298
+ if (requirement.testProfile === 'integration' && dimensions.determinism.applicable === false) {
299
+ errors.push(`${prefix}.integration profile requires applicable determinism evidence`);
300
+ }
301
+ if (!isObject(dimensionsInput.sourceTraceability) || dimensionsInput.sourceTraceability.applicable !== true) {
302
+ errors.push(`${prefix}.sourceTraceability must be applicable`);
303
+ }
304
+ dimensions.sourceTraceability = {
305
+ applicable: true,
306
+ passed: sourceResult.traced + additionalSourceResults.reduce((sum, result) => sum + result.traced, 0),
307
+ required: 1 + additionalSourceResults.length,
308
+ traced: sourceResult.traced + additionalSourceResults.reduce((sum, result) => sum + result.traced, 0),
309
+ total: 1 + additionalSourceResults.length,
310
+ percentage: sourceResult.traced + additionalSourceResults.reduce((sum, result) => sum + result.traced, 0) === 1 + additionalSourceResults.length ? 100 : 0
311
+ };
312
+
313
+ if (!nonEmpty(requirement.requirementId)) errors.push(`${prefix}.requirementId is required`);
314
+ if (!['PASS', 'NON_CONFORMANT'].includes(requirement.sourceConformance)) errors.push(`${prefix}.sourceConformance must be PASS or NON_CONFORMANT`);
315
+ if (!['VALID', 'SOURCE_DEFECT', 'SOURCE_CONFLICT'].includes(requirement.sourceValidity)) errors.push(`${prefix}.sourceValidity must be VALID, SOURCE_DEFECT, or SOURCE_CONFLICT`);
316
+ if (['SOURCE_DEFECT', 'SOURCE_CONFLICT'].includes(requirement.sourceValidity) && !nonEmpty(requirement.sourceNotes)) {
317
+ errors.push(`${prefix}.sourceNotes is required for ${requirement.sourceValidity}`);
318
+ }
319
+ if (requirement.sourceValidity === 'SOURCE_CONFLICT' && additionalSourceResults.length === 0) {
320
+ errors.push(`${prefix}.additionalSources must identify the conflicting authoritative source`);
321
+ }
322
+ const declaredSources = [requirement.source, ...(Array.isArray(requirement.additionalSources) ? requirement.additionalSources : [])];
323
+ if (requirement.sourceValidity === 'SOURCE_CONFLICT' && declaredSources.some(source => !isObject(source) || source.status !== 'AUTHORITATIVE')) {
324
+ errors.push(`${prefix}.SOURCE_CONFLICT may only identify authoritative sources`);
325
+ }
326
+
327
+ const scoring = scoringDetails(dimensions);
328
+ const score = scoreDimensions(dimensions);
329
+ const gates = {
330
+ applicableDimensionsExecuted: DIMENSIONS.every(name => dimensions[name].applicable === false || dimensions[name].required > 0),
331
+ sourceTraceabilityComplete: dimensions.sourceTraceability.percentage === 100,
332
+ noSourceMismatch: requirement.sourceConformance === 'PASS',
333
+ noSourceConflict: requirement.sourceValidity !== 'SOURCE_CONFLICT',
334
+ allRequiredInputOutputValidated: ['inputCompleteness', 'outputCompleteness'].every(name => dimensions[name].applicable === false || dimensions[name].percentage === 100),
335
+ allDeclaredErrorPathsTested: dimensions.errorHandling.applicable === false || dimensions.errorHandling.percentage === 100,
336
+ integrationRepeated: dimensions.determinism.applicable === false || dimensions.determinism.totalRuns >= 2,
337
+ deterministicOutputs: dimensions.determinism.applicable === false || dimensions.determinism.percentage === 100,
338
+ noSkippedOrFlakyTests: skippedTests.length === 0 && (!Array.isArray(requirement.flakyTests) || requirement.flakyTests.length === 0),
339
+ qualityScoreComplete: score === 100
340
+ };
341
+ const result = errors.length === localErrorsBefore && Object.values(gates).every(Boolean) ? 'PASS' : 'FAIL';
342
+ return {
343
+ requirementId: requirement.requirementId || null,
344
+ testProfile: requirement.testProfile || null,
345
+ source: sourceResult.source,
346
+ additionalSources: additionalSourceResults.map(result => result.source),
347
+ sourceConformance: requirement.sourceConformance || null,
348
+ sourceValidity: requirement.sourceValidity || null,
349
+ ...(requirement.sourceNotes ? { sourceNotes: requirement.sourceNotes } : {}),
350
+ dimensions,
351
+ skippedTests,
352
+ flakyTests: Array.isArray(requirement.flakyTests) ? clone(requirement.flakyTests) : [],
353
+ naDeclarations,
354
+ mandatoryGates: gates,
355
+ scoring,
356
+ score,
357
+ result
358
+ };
359
+ }
360
+
361
+ function aggregateDimensions(requirements) {
362
+ const aggregate = {};
363
+ for (const name of DIMENSIONS) {
364
+ const applicable = requirements.filter(requirement => requirement.dimensions[name].applicable !== false);
365
+ const passed = applicable.reduce((sum, requirement) => sum + requirement.dimensions[name].passed, 0);
366
+ const required = applicable.reduce((sum, requirement) => sum + requirement.dimensions[name].required, 0);
367
+ aggregate[name] = {
368
+ applicable: applicable.length > 0,
369
+ passed,
370
+ required,
371
+ percentage: required === 0 ? null : round(passed / required * 100)
372
+ };
373
+ if (name === 'determinism') {
374
+ aggregate[name].matchingRuns = passed;
375
+ aggregate[name].totalRuns = required;
376
+ }
377
+ if (name === 'sourceTraceability') {
378
+ aggregate[name].traced = passed;
379
+ aggregate[name].total = required;
380
+ }
381
+ }
382
+ return aggregate;
383
+ }
384
+
385
+ function evaluateEvidence(evidence) {
386
+ const errors = [];
387
+ if (!isObject(evidence)) errors.push('Evidence root must be an object');
388
+ if (isObject(evidence) && evidence.schemaVersion !== VERSION) errors.push(`schemaVersion must be ${VERSION}`);
389
+ if (!isObject(evidence) || !Array.isArray(evidence.requirements) || evidence.requirements.length === 0) {
390
+ errors.push('requirements must be a non-empty array');
391
+ }
392
+
393
+ const inputRequirements = isObject(evidence) && Array.isArray(evidence.requirements) ? evidence.requirements : [];
394
+ const requirements = [];
395
+ const seenIds = new Set();
396
+ inputRequirements.forEach((requirement, index) => {
397
+ if (!isObject(requirement)) {
398
+ errors.push(`requirements[${index}] must be an object`);
399
+ return;
400
+ }
401
+ if (nonEmpty(requirement.requirementId)) {
402
+ if (seenIds.has(requirement.requirementId)) errors.push(`Duplicate requirementId: ${requirement.requirementId}`);
403
+ seenIds.add(requirement.requirementId);
404
+ }
405
+ requirements.push(evaluateRequirement(requirement, index, errors));
406
+ });
407
+
408
+ const dimensions = aggregateDimensions(requirements);
409
+ const scoring = scoringDetails(dimensions);
410
+ const score = scoreDimensions(dimensions);
411
+ const mandatoryGates = {
412
+ applicableDimensionsExecuted: requirements.length > 0 && requirements.every(req => req.mandatoryGates.applicableDimensionsExecuted),
413
+ sourceTraceabilityComplete: requirements.length > 0 && requirements.every(req => req.mandatoryGates.sourceTraceabilityComplete),
414
+ noSourceMismatch: requirements.length > 0 && requirements.every(req => req.mandatoryGates.noSourceMismatch),
415
+ noSourceConflict: requirements.length > 0 && requirements.every(req => req.mandatoryGates.noSourceConflict),
416
+ allRequiredInputOutputValidated: requirements.length > 0 && requirements.every(req => req.mandatoryGates.allRequiredInputOutputValidated),
417
+ allDeclaredErrorPathsTested: requirements.length > 0 && requirements.every(req => req.mandatoryGates.allDeclaredErrorPathsTested),
418
+ integrationRepeated: requirements.length > 0 && requirements.every(req => req.mandatoryGates.integrationRepeated),
419
+ deterministicOutputs: requirements.length > 0 && requirements.every(req => req.mandatoryGates.deterministicOutputs),
420
+ noSkippedOrFlakyTests: requirements.length > 0 && requirements.every(req => req.mandatoryGates.noSkippedOrFlakyTests),
421
+ qualityScoreComplete: score === 100
422
+ };
423
+ const skippedTests = requirements.flatMap(req => req.skippedTests.map(test => ({ requirementId: req.requirementId, ...test })));
424
+ const naDeclarations = requirements.flatMap(req => req.naDeclarations.map(declaration => ({ requirementId: req.requirementId, ...declaration })));
425
+ const result = errors.length === 0 && Object.values(mandatoryGates).every(Boolean) ? 'PASS' : 'FAIL';
426
+ return { schemaVersion: VERSION, requirements, dimensions, mandatoryGates, skippedTests, naDeclarations, scoring, score, result, errors };
427
+ }
428
+
429
+ function printSummary(report) {
430
+ console.log(`TDD Quality Gate: ${report.result}`);
431
+ console.log(`Score: ${report.score}%`);
432
+ console.log('Requirements:');
433
+ for (const requirement of report.requirements) {
434
+ console.log(`- ${requirement.requirementId} [${requirement.testProfile}]: ${requirement.result} ${requirement.score}%`);
435
+ }
436
+ console.log('Dimensions:');
437
+ for (const name of DIMENSIONS) {
438
+ const dimension = report.dimensions[name];
439
+ const score = dimension.percentage === null ? 'N/A' : `${dimension.percentage}%`;
440
+ console.log(`- ${name}: ${dimension.passed}/${dimension.required} (${score})`);
441
+ }
442
+ for (const [name, passed] of Object.entries(report.mandatoryGates)) console.log(`- gate ${name}: ${passed ? 'PASS' : 'FAIL'}`);
443
+ for (const error of report.errors) console.error(`- error: ${error}`);
444
+ }
445
+
446
+ function runCli(argv) {
447
+ const args = argv.slice(2);
448
+ const inputPath = args[0];
449
+ const outputIndex = args.indexOf('--output');
450
+ const outputPath = outputIndex >= 0 ? args[outputIndex + 1] : null;
451
+ if (!inputPath || (outputIndex >= 0 && !outputPath)) {
452
+ console.error('Usage: node tdd/scripts/quality-gate.js <evidence.json> [--output <report.json>]');
453
+ return 2;
454
+ }
455
+ let evidence;
456
+ try {
457
+ evidence = JSON.parse(fs.readFileSync(path.resolve(inputPath), 'utf8'));
458
+ } catch (error) {
459
+ console.error(`TDD Quality Gate: FAIL\n- error: ${error.message}`);
460
+ return 2;
461
+ }
462
+ const report = evaluateEvidence(evidence);
463
+ printSummary(report);
464
+ if (outputPath) {
465
+ fs.mkdirSync(path.dirname(path.resolve(outputPath)), { recursive: true });
466
+ fs.writeFileSync(path.resolve(outputPath), `${JSON.stringify(report, null, 2)}\n`, 'utf8');
467
+ } else {
468
+ console.log(JSON.stringify(report, null, 2));
469
+ }
470
+ return report.result === 'PASS' ? 0 : 1;
471
+ }
472
+
473
+ if (require.main === module) process.exit(runCli(process.argv));
474
+
475
+ module.exports = { DIMENSIONS, REQUIRED_CLASSES, VERSION, evaluateEvidence, runCli };
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: to-spec
3
+ description: "Turn the conversation into a written spec — feature PRD, CLI/API reference, schema doc, or dev doc, whichever fits — and publish it per this repos projectDocs framework; use when alignment is complete."
4
+ license: Apache-2.0
5
+ metadata:
6
+ author: Miya Daniel
7
+ version: 0.4.0
8
+ ---
9
+
10
+ # To Spec
11
+
12
+ Turns the conversation into one published spec artifact. No interviewing — `grill-me`/`grill-with-docs` run beforehand.
13
+
14
+ ## 📋 Skill Contract
15
+
16
+ | Component | Specification |
17
+ | :--- | :--- |
18
+ | **Trigger / Input** | Explicit `/to-spec`; never auto-run. |
19
+ | **Expected Output** | One doc from a matching `templates/*.md` skeleton. |
20
+ | **State Mutations** | Writes spec doc; updates `projectDocs` in `manifest.json`. |
21
+ | **Enforcement Gate** | Outline preview before writing; graceful Exit 1 fallback. |
22
+
23
+ ## Workflow
24
+
25
+ 1. Resolve path via the shared `<skills-repo-root>/multi-agent-workspace/scripts/project-docs-resolver.js` contract and `node "<this-skill-dir>/scripts/check-project-docs.js" check`; use explicit projectDocs, CONTEXT-MAP, inferred docs, then committable fallback.
26
+ 2. Zero-trust context: cite `Evidence: <file:line> -> Finding: <meaning>`; blocking forks mean run `grill-me`/`grill-with-docs` first.
27
+ 3. Mandatory outline preview (closest fit, 10-20 lines + target path); write only after user confirms.
28
+ 4. Publish to `specs/<feature-slug>.md` (`Status: ready-for-agent`) or `reference/`, `adr/`.
29
+ 5. Golden Flow: Feature spec needs a Design Audit (`multi-agent-workspace`) before `/to-tickets`.
30
+
31
+ Deep dive: <this-skill-dir>/references/process.md
32
+
33
+ ## USE FOR:
34
+ - conversation into a published PRD or design doc
35
+ - document a new CLI command, endpoint, or schema
36
+ - publish an ADR once alignment completes
37
+
38
+ ## DO NOT USE FOR:
39
+ - interviewing (`grill-me` / `grill-with-docs`)
40
+ - auto-running publication
@@ -0,0 +1,77 @@
1
+ # To Spec — Full Process Reference
2
+
3
+ ## Path Resolution Flow (Step 0)
4
+
5
+ ```mermaid
6
+ flowchart TD
7
+ Start[Receive /to-spec Request] --> Outline[Phase 1: Present Outline Preview & Shape to User]
8
+ Outline --> Approved{User Approves Outline?}
9
+
10
+ Approved -- No / Request Adjustments --> Modify[Adjust Template Shape & Outline] --> Outline
11
+ Approved -- Yes --> CheckScript{Phase 2: Node.js & Script Executable?}
12
+
13
+ CheckScript -- Yes --> RunCheck[Run check-project-docs.js check]
14
+ RunCheck -- Exit 0 (Configured/Inferred) --> PathConfig[Use Project Configured / Inferred Path<br>e.g. docs/specs/, docs/reference/, docs/adr/]
15
+ RunCheck -- Exit 1 (Unset) --> InspectRepo
16
+
17
+ CheckScript -- No / Fails --> InspectRepo{Inspect Existing Workspace Conventions}
18
+
19
+ InspectRepo -- Existing Folder Found --> PathRepo[Use Workspace Folder<br>e.g. docs/, docs/specs/, docs/adr/, .scratch/]
20
+ InspectRepo -- No Folder --> CheckPlatform{Fallback to Active Platform Home}
21
+
22
+ CheckPlatform -- Claude Code --> PathClaude[Write to .claude/harness-everything/specs/]
23
+ CheckPlatform -- GitHub Copilot / VS Code --> PathCopilot[Write to .github/harness-everything/specs/]
24
+ CheckPlatform -- Cursor / Other --> PathCursor[Write to .cursor/harness-everything/specs/]
25
+
26
+ PathConfig --> WriteDoc[Generate Full Spec Document]
27
+ PathRepo --> WriteDoc
28
+ PathClaude --> WriteDoc
29
+ PathCopilot --> WriteDoc
30
+ PathCursor --> WriteDoc
31
+ ```
32
+
33
+ ## Evidence-Driven Context (Zero-Trust Boundaries) — full rules
34
+
35
+ When gathering context, you are strictly forbidden from "guessing" the architecture or existing behavior. Every finding MUST be backed by an explicit evidence chain presented in your thought process or chat output.
36
+
37
+ - **Format**: `Evidence: [File path & line number / Tool output] -> Finding: [What it means]`
38
+ - **Example**: `Evidence: read src/auth.ts line 45 -> Finding: The API currently lacks JWT token validation.`
39
+
40
+ Use the project's domain glossary vocabulary throughout, and respect any ADRs in the area you're touching. If `grill-with-docs` or `grill-me` ran earlier in this conversation, treat their resolved decisions (updated `CONTEXT.md` entries, new ADRs) as settled input — cite them, don't reopen them. For anything they didn't cover, synthesize from what's already been said rather than asking new questions. If a genuinely new, unresolved fork turns up that blocks writing the doc, that's a sign this conversation needed a grilling pass first — say so and suggest running `grill-me`/`grill-with-docs` before continuing, rather than interviewing ad hoc inside this skill.
41
+
42
+ ## Template Selection — full guidance
43
+
44
+ | Shape | File | Fits when... |
45
+ | :--- | :--- | :--- |
46
+ | Feature spec (PRD) | [templates/feature-spec.md](../templates/feature-spec.md) | New user-facing feature/product surface with several implementation decisions — the thing that gets broken into tickets afterward (Tier 3, usually). |
47
+ | CLI / API reference | [templates/cli-reference.md](../templates/cli-reference.md) | A new or changed command, flag set, or single endpoint (Tier 2 or 3). |
48
+ | Schema / file format | [templates/schema-doc.md](../templates/schema-doc.md) | A data shape change — DB schema, config format, wire payload, on-disk state (Tier 2 or 3). |
49
+ | Dev / design doc | [templates/dev-doc.md](../templates/dev-doc.md) | A scoped technical decision worth recording that doesn't clear `grill-with-docs`'s bar for a full ADR (Tier 2, usually). |
50
+
51
+ Look at what's actually being built and choose the closest fit — don't default to the heaviest one out of habit.
52
+
53
+ ## Interface Confirmation details
54
+
55
+ What "confirm" means depends on the shape picked:
56
+
57
+ - **Feature spec** → sketch the seams at which you'll test the feature. Prefer existing seams to new ones; use the highest seam possible; the ideal number is one. Check with the user that the seams match their expectations.
58
+ - **CLI/API reference or schema doc** → confirm the surface itself (the flag names, the field names/types) with the user before writing the full doc — that's the part expensive to change after the fact.
59
+ - **Dev doc / ADR** → confirm the decision statement in one line before expanding it into the full doc.
60
+
61
+ Skip this step only if the conversation already pinned down the relevant surface explicitly (e.g. a prior `grill-with-docs` pass already fixed the schema).
62
+
63
+ ## Publishing details
64
+
65
+ Write the doc using the adapted template at the resolved storage path:
66
+
67
+ - **Feature spec** → files as a feature PRD or issue document:
68
+ - Output path: `<resolved-path>/specs/<feature-slug>.md` or `<resolved-path>/<feature-slug>/spec.md`.
69
+ - Apply status marker `Status: ready-for-agent`.
70
+ - **CLI/API reference, schema doc, dev doc / ADR** → standalone reference document:
71
+ - Output path: `<resolved-path>/reference/<slug>.md` or `<resolved-path>/adr/<slug>.md`.
72
+
73
+ No additional triage needed beyond the `issueDefinition` marker. A clearly-shaped doc in the right place is what lets `to-tickets` cut clean vertical slices afterward instead of guessing at scope from a raw conversation transcript.
74
+
75
+ ## Golden Flow rationale
76
+
77
+ After publishing a `Feature spec` (Tier 3), do NOT immediately instruct the user to run `/to-tickets`. Instead, instruct the user to initiate a Design Audit first: recommend invoking `multi-agent-workspace` (or manually starting parallel Sub-agents) to conduct a Fan-out architectural audit (e.g., Security Auditor, Senior Architect) on the newly published spec. State explicitly: "This specification must pass a Design Audit before being broken down by `/to-tickets`. Any architectural flaws or over-engineering must be caught now, not during implementation."