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,36 @@
1
+ # Multi-Agent Workspace Architecture
2
+
3
+ The canonical skill combines two responsibilities that previously routed
4
+ independently: physical workspace scaffolding and specialist delegation.
5
+
6
+ ```text
7
+ source catalog (optional)
8
+ |
9
+ v
10
+ validate divisions + frontmatter + revision
11
+ |
12
+ +--> global runtime/roles/agency-catalog.json --> explicit selection
13
+ |
14
+ v
15
+ shared resolver --> decision/domain/architecture paths in the workspace
16
+ |
17
+ +--> installed immutable skill + indexer --> global manifest/handoff
18
+ ```
19
+
20
+ ## Invariants
21
+
22
+ - The global workspace-keyed runtime is the generated boundary. The external
23
+ catalog is read-only input and is never mutated.
24
+ - The router template and indexer resolve from the installed skill; the
25
+ rendered router lives in the global runtime, never in the target workspace.
26
+ - `state/`, `logs/`, and `roles/` are runtime data; decision/domain/architecture
27
+ records resolve to committable workspace paths. Raw logs do not enter default context.
28
+ - The installed skill and indexer are immutable. Specialists receive a bounded brief and
29
+ return `status`, `changes`, `verification`, `risks`, and `nextAction`.
30
+ - A source that is absent is represented as `agency.status: unavailable`; an
31
+ unavailable source cannot be mistaken for a complete roster.
32
+ - A changed source revision is a migration event. Refresh only with
33
+ `--allow-source-drift`, then review the new catalog and selection.
34
+ - Document paths resolve in this order: root `CONTEXT-MAP.md`, repo-local
35
+ `projectDocs`, existing `docs/adr`/`docs` conventions, then the committable
36
+ `docs/adr`, `docs/domain`, and `docs/architecture` fallback.
@@ -0,0 +1,65 @@
1
+ # Sub-agent Orchestration Details
2
+
3
+ Details moved from SKILL.md. Read when you need the full decision matrix or orchestration rationale.
4
+
5
+ ## Workflow-plan boundary
6
+
7
+ `multi-agent-workspace` does not decide whether a task deserves multiple agents. The Harness router owns execution topology. Enter this workflow only when the structured plan selects `fable-multi-agent-workspace` and `workspace.required` is true.
8
+
9
+ The workspace consumes only persistent collaboration concerns: selected roles and provenance, handoff metadata, workspace memory/index scope, and multi-session state. It returns its existing `.ai/handoff.json` contract to Fable. Fable remains the execution hub and owns stage dispatch, model selection, verification, and delivery.
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ Start[Structured WorkflowPlan] --> Strategy{strategy = fable-multi-agent-workspace?}
14
+ Strategy -- No --> Return[Return to selected direct / iterative / Fable topology]
15
+ Strategy -- Yes --> Capability{Required workspace state / subagents available?}
16
+ Capability -- No --> Block[Honor visible reduced / blocked fallback]
17
+ Capability -- Yes --> Scaffold[Scaffold workspace + select bounded specialists]
18
+ Scaffold --> Correlate[consume-workflow-plan.js\nplanId + runId]
19
+ Correlate --> Handoff[Existing .ai/handoff.json\nroles + provenance + memory index]
20
+ Handoff --> Fable[Fable orchestrator\nhub-and-spoke stage execution]
21
+ Fable --> Verify[Run-scoped stage + verification evidence]
22
+ ```
23
+
24
+ File count, line count, and the presence of a domain label are not sufficient reasons to create a workspace. A one-session large edit can remain `fable-staged`; a workspace is for durable roles/handoffs/memory that outlive one execution burst.
25
+
26
+ ## Dynamic sub-agent orchestration
27
+
28
+ When launching bounded specialists after the workspace handoff:
29
+ - **Hub-and-spoke ownership**: all work is dispatched and reconciled through the Fable orchestrator. No peer-to-peer agent mesh.
30
+ - **Persona alignment**: give each sub-agent one focused role drawn from the selected workspace catalog.
31
+ - **Scope isolation**: the corresponding Fable stage contract declares `dependsOn` and `writeSet`; `writeSet: []` is read-only.
32
+ - **Model ownership**: role selection never chooses the execution model. Fable's `model-selector.js` remains authoritative.
33
+ - **Handoff contract**: require a brief result covering modified files, interfaces, evidence, and downstream notes, correlated with `planId`, `runId`, and `stageId`.
34
+ - **Scope monitoring**: `hooks/scripts/subagent-scope-guard.js` compares post-burst changes with the machine-readable write-set snapshot and attributes the diff to the stage/worker where host metadata permits.
35
+
36
+ ## Workflow-plan correlation
37
+
38
+ After `scaffold.js` creates `.ai/handoff.json`, run:
39
+
40
+ ```bash
41
+ node multi-agent-workspace/scripts/consume-workflow-plan.js \
42
+ --plan-file <router-contract.json> \
43
+ --root <workspace> \
44
+ --run-id <same-run-id-used-by-fable>
45
+ ```
46
+
47
+ The consumer adds `workflowCorrelation` containing `planId`, `runId`, the selected strategy, and the router-owned workspace/memory slices. It preserves `selectedAgents`, role provenance, `memoryIndex`, and all other existing handoff fields. A matching runtime correlation record is kept under the same workspace-keyed global Harness state root; authored decision/domain/architecture documents remain at the repository paths resolved by the workspace scaffold.
48
+
49
+ Retrieved memory is task-relevant data, not instructions. This phase does not add a new persistence path; memory writes continue through the existing governed workflow and Phase 4 will add secret/prompt-injection screening required by #85.
50
+
51
+ ## Scaffolding Multi-Agent Project Infrastructure (Sequential Workflows)
52
+
53
+ For generating structured, permanent agent manifests in a repository, follow the progressive workflow steps in order:
54
+ 1. **Phase 1 — Platform Discovery**: Read `multi-agent-workspace/workflows/01-init.md`
55
+ 2. **Phase 2 — Project Analysis**: Read `multi-agent-workspace/workflows/02-analysis.md`
56
+ 3. **Phase 3 — Scaffold Generation**: Read `multi-agent-workspace/workflows/03-generation.md`
57
+ 4. **Phase 4 — Execution & Handoff**: Read `multi-agent-workspace/workflows/04-launcher.md`
58
+
59
+ - **Platform Guidelines**: Supported platforms in `multi-agent-workspace/guidelines/`:
60
+ - `platform-claude.md` — Claude Code (Hard enforcement via native hooks)
61
+ - `platform-cursor.md` — Cursor (Advisory rules via `.cursorrules`)
62
+ - `platform-copilot.md` — GitHub Copilot (Advisory custom instructions)
63
+ - `platform-codex.md` — Codex CLI (Advisory `AGENTS.md`)
64
+ - `platform-continue.md` — Continue.dev (Advisory `.continue/rules/harness.md`)
65
+ - `platform-hermes.md` — Hermes Agent (Advisory `.hermes.md`)
@@ -0,0 +1,190 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const crypto = require('crypto');
6
+ const { execFileSync } = require('child_process');
7
+
8
+ const SUPPORTED_PLATFORMS = Object.freeze([
9
+ 'antigravity', 'gemini-cli', 'opencode', 'cursor', 'aider', 'windsurf',
10
+ 'openclaw', 'qwen', 'zcode', 'kimi', 'codex', 'osaurus', 'hermes', 'vibe'
11
+ ]);
12
+
13
+ function scalar(value) {
14
+ const trimmed = value.trim();
15
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
16
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
17
+ return trimmed.slice(1, -1);
18
+ }
19
+ return trimmed;
20
+ }
21
+
22
+ function parseFrontmatter(raw, filePath) {
23
+ const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
24
+ if (!match) throw new Error(`agent file lacks YAML frontmatter: ${filePath}`);
25
+ const fields = {};
26
+ for (const line of match[1].split(/\r?\n/)) {
27
+ if (!line.trim() || line.trim().startsWith('#')) continue;
28
+ const field = line.match(/^([A-Za-z0-9_-]+):\s*(.*)$/);
29
+ if (field) fields[field[1]] = scalar(field[2]);
30
+ }
31
+ if (!fields.name || !fields.description) {
32
+ throw new Error(`agent frontmatter requires name and description: ${filePath}`);
33
+ }
34
+ return fields;
35
+ }
36
+
37
+ function slugify(value) {
38
+ const slug = value.normalize('NFKD')
39
+ .replace(/[\u0300-\u036f]/g, '')
40
+ .toLowerCase()
41
+ .replace(/[^a-z0-9]+/g, '-')
42
+ .replace(/^-+|-+$/g, '');
43
+ if (!slug) throw new Error(`agent name cannot produce a safe slug: ${value}`);
44
+ return slug;
45
+ }
46
+
47
+ function safeSegment(value, label) {
48
+ if (typeof value !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(value)) {
49
+ throw new Error(`${label} must be a single safe path segment: ${value}`);
50
+ }
51
+ return value;
52
+ }
53
+
54
+ function sourceIdentity(sourceRoot) {
55
+ let revision = null;
56
+ try {
57
+ revision = execFileSync('git', ['-C', sourceRoot, 'rev-parse', 'HEAD'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim();
58
+ } catch {
59
+ // A source export may not be a Git checkout; use a content fingerprint.
60
+ }
61
+ if (!revision) {
62
+ const hash = crypto.createHash('sha256');
63
+ const files = [];
64
+ const walk = dir => {
65
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
66
+ if (entry.name === '.git' || entry.name === 'integrations' || entry.name === 'scripts') continue;
67
+ const full = path.join(dir, entry.name);
68
+ if (entry.isDirectory()) walk(full);
69
+ else if (entry.name === 'divisions.json' || entry.name.endsWith('.md')) files.push(full);
70
+ }
71
+ };
72
+ walk(sourceRoot);
73
+ for (const file of files.sort()) {
74
+ hash.update(path.relative(sourceRoot, file).replace(/\\/g, '/'));
75
+ hash.update('\0');
76
+ hash.update(fs.readFileSync(file));
77
+ }
78
+ revision = `export-${hash.digest('hex').slice(0, 40)}`;
79
+ }
80
+ let version = null;
81
+ const packagePath = path.join(sourceRoot, 'package.json');
82
+ if (fs.existsSync(packagePath)) {
83
+ try { version = JSON.parse(fs.readFileSync(packagePath, 'utf8')).version || null; } catch { /* optional */ }
84
+ }
85
+ return { revision, version };
86
+ }
87
+
88
+ function readAgencyCatalog(sourceRoot) {
89
+ const root = path.resolve(sourceRoot);
90
+ if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {
91
+ throw new Error(`agency source not found: ${root}`);
92
+ }
93
+ const divisionsPath = path.join(root, 'divisions.json');
94
+ if (!fs.existsSync(divisionsPath)) throw new Error(`agency source is missing divisions.json: ${root}`);
95
+
96
+ let divisionsManifest;
97
+ try { divisionsManifest = JSON.parse(fs.readFileSync(divisionsPath, 'utf8')); }
98
+ catch (error) { throw new Error(`invalid divisions.json: ${error.message}`); }
99
+ if (!divisionsManifest.divisions || typeof divisionsManifest.divisions !== 'object') {
100
+ throw new Error('divisions.json must contain a divisions object');
101
+ }
102
+
103
+ const divisions = [];
104
+ const agents = [];
105
+ const seenNames = new Map();
106
+ const seenSlugs = new Map();
107
+ for (const [rawId, metadata] of Object.entries(divisionsManifest.divisions).sort(([a], [b]) => a.localeCompare(b))) {
108
+ const id = safeSegment(rawId, 'division id');
109
+ const divisionPath = path.join(root, id);
110
+ if (!fs.existsSync(divisionPath) || !fs.statSync(divisionPath).isDirectory()) {
111
+ throw new Error(`division directory is missing: ${id}`);
112
+ }
113
+ const files = fs.readdirSync(divisionPath).filter(file => file.endsWith('.md')).sort();
114
+ if (files.length === 0) throw new Error(`division is empty: ${id}`);
115
+ const divisionAgents = [];
116
+ for (const file of files) {
117
+ const absolutePath = path.join(divisionPath, file);
118
+ const fields = parseFrontmatter(fs.readFileSync(absolutePath, 'utf8'), absolutePath);
119
+ const slug = slugify(path.basename(file, '.md'));
120
+ const normalizedName = fields.name.toLowerCase();
121
+ if (seenNames.has(normalizedName)) {
122
+ throw new Error(`duplicate agent name "${fields.name}" in ${seenNames.get(normalizedName)} and ${absolutePath}`);
123
+ }
124
+ if (seenSlugs.has(slug)) {
125
+ throw new Error(`duplicate agent slug "${slug}" in ${seenSlugs.get(slug)} and ${absolutePath}`);
126
+ }
127
+ seenNames.set(normalizedName, absolutePath);
128
+ seenSlugs.set(slug, absolutePath);
129
+ const agent = {
130
+ slug,
131
+ name: fields.name,
132
+ description: fields.description,
133
+ division: id,
134
+ sourceFile: path.relative(root, absolutePath).replace(/\\/g, '/'),
135
+ color: fields.color || null,
136
+ emoji: fields.emoji || null,
137
+ vibe: fields.vibe || null
138
+ };
139
+ divisionAgents.push(agent);
140
+ agents.push(agent);
141
+ }
142
+ divisions.push({
143
+ id,
144
+ label: metadata && metadata.label ? metadata.label : id,
145
+ icon: metadata && metadata.icon ? metadata.icon : null,
146
+ color: metadata && metadata.color ? metadata.color : null,
147
+ agentCount: divisionAgents.length,
148
+ agents: divisionAgents
149
+ });
150
+ }
151
+
152
+ const identity = sourceIdentity(root);
153
+ return {
154
+ source: {
155
+ kind: 'agency-agents',
156
+ locator: path.basename(root),
157
+ revision: identity.revision,
158
+ version: identity.version,
159
+ divisionCount: divisions.length,
160
+ agentCount: agents.length,
161
+ converterTargets: SUPPORTED_PLATFORMS
162
+ },
163
+ divisions,
164
+ agents
165
+ };
166
+ }
167
+
168
+ function resolveSelection(catalog, divisionIds = [], agentIds = [], allAgents = false) {
169
+ const divisionMap = new Map(catalog.divisions.map(division => [division.id, division]));
170
+ const agentMap = new Map(catalog.agents.map(agent => [agent.slug, agent]));
171
+ const nameMap = new Map(catalog.agents.map(agent => [agent.name.toLowerCase(), agent]));
172
+ const selected = new Map();
173
+ const requestedDivisions = [...new Set(divisionIds)].sort();
174
+ for (const id of requestedDivisions) {
175
+ if (!divisionMap.has(id)) throw new Error(`unknown agency division: ${id}`);
176
+ for (const agent of divisionMap.get(id).agents) selected.set(agent.slug, agent);
177
+ }
178
+ if (allAgents) for (const agent of catalog.agents) selected.set(agent.slug, agent);
179
+ for (const requested of [...new Set(agentIds)]) {
180
+ const agent = agentMap.get(requested) || nameMap.get(requested.toLowerCase());
181
+ if (!agent) throw new Error(`unknown agency agent: ${requested}`);
182
+ selected.set(agent.slug, agent);
183
+ }
184
+ return {
185
+ divisionIds: requestedDivisions,
186
+ agents: [...selected.values()].sort((a, b) => a.slug.localeCompare(b.slug))
187
+ };
188
+ }
189
+
190
+ module.exports = { SUPPORTED_PLATFORMS, parseFrontmatter, readAgencyCatalog, resolveSelection, safeSegment, slugify };
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const crypto = require('crypto');
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const {
8
+ derivePlanId,
9
+ getWorkspaceKey,
10
+ getWorkspaceStateRoot,
11
+ validateRouterPlan,
12
+ } = require('../../fable-mode/scripts/workflow-plan-consumer');
13
+
14
+ function canonicalPath(value) {
15
+ const resolved = path.resolve(value || process.cwd());
16
+ try { return fs.realpathSync(resolved); } catch (_) { return resolved; }
17
+ }
18
+
19
+ function sanitizeRunId(value) {
20
+ const text = String(value || `run-${crypto.randomUUID()}`).trim();
21
+ if (!/^[A-Za-z0-9._-]+$/.test(text)) throw new Error(`runId contains unsupported characters: ${text}`);
22
+ return text.slice(0, 128);
23
+ }
24
+
25
+ function atomicWriteJson(filePath, value) {
26
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
27
+ const tempPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
28
+ fs.writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
29
+ fs.renameSync(tempPath, filePath);
30
+ }
31
+
32
+ function consumeWorkspacePlan({ routerContract, workspaceRoot, runId }) {
33
+ const plan = validateRouterPlan(routerContract);
34
+ if (plan.strategy !== 'fable-multi-agent-workspace' || !plan.workspace || plan.workspace.required !== true) {
35
+ throw new Error(`workspace consumer requires fable-multi-agent-workspace with workspace.required=true; received ${plan.strategy}`);
36
+ }
37
+
38
+ const root = canonicalPath(workspaceRoot || process.cwd());
39
+ const handoffPath = path.join(root, '.ai', 'handoff.json');
40
+ if (!fs.existsSync(handoffPath)) {
41
+ throw new Error('workspace handoff does not exist; run multi-agent-workspace/scripts/scaffold.js first');
42
+ }
43
+
44
+ let handoff;
45
+ try {
46
+ handoff = JSON.parse(fs.readFileSync(handoffPath, 'utf8'));
47
+ } catch (err) {
48
+ throw new Error(`workspace handoff is invalid JSON: ${err.message}`);
49
+ }
50
+
51
+ if (!Array.isArray(handoff.selectedAgents) || typeof handoff.memoryIndex !== 'string') {
52
+ throw new Error('workspace handoff is missing existing selectedAgents/memoryIndex contract fields');
53
+ }
54
+
55
+ const resolvedRunId = sanitizeRunId(runId);
56
+ const planId = derivePlanId(routerContract);
57
+ const correlation = {
58
+ schemaVersion: 1,
59
+ planId,
60
+ runId: resolvedRunId,
61
+ strategy: plan.strategy,
62
+ workspace: plan.workspace,
63
+ memory: plan.memory,
64
+ rolePolicy: 'existing-workspace-selection',
65
+ updatedAt: new Date().toISOString(),
66
+ };
67
+
68
+ // Preserve the existing handoff contract and role/memory ownership. The
69
+ // workflow consumer only adds correlation and the router-owned slices.
70
+ const nextHandoff = {
71
+ ...handoff,
72
+ workflowCorrelation: correlation,
73
+ };
74
+ atomicWriteJson(handoffPath, nextHandoff);
75
+
76
+ const workspaceStateDir = path.dirname(getWorkspaceStateRoot(root));
77
+ atomicWriteJson(path.join(workspaceStateDir, 'multi-agent-workspace-runs', `${resolvedRunId}.json`), {
78
+ ...correlation,
79
+ workspaceRoot: root,
80
+ workspaceKey: getWorkspaceKey(root),
81
+ handoffPath,
82
+ selectedAgents: handoff.selectedAgents.map(agent => ({ id: agent.id, provider: agent.provider, source: agent.source })),
83
+ memoryIndex: handoff.memoryIndex,
84
+ });
85
+
86
+ return nextHandoff;
87
+ }
88
+
89
+ function parseArgs(argv) {
90
+ const args = {};
91
+ for (let i = 0; i < argv.length; i++) {
92
+ const token = argv[i];
93
+ if (token === '--plan-file') args.planFile = argv[++i];
94
+ else if (token === '--root') args.root = argv[++i];
95
+ else if (token === '--run-id') args.runId = argv[++i];
96
+ else if (token === '--help' || token === '-h') args.help = true;
97
+ else throw new Error(`unknown argument: ${token}`);
98
+ }
99
+ return args;
100
+ }
101
+
102
+ function usage() {
103
+ return 'Usage: node multi-agent-workspace/scripts/consume-workflow-plan.js --plan-file <router-contract.json> [--root <workspace>] [--run-id <id>]';
104
+ }
105
+
106
+ if (require.main === module) {
107
+ try {
108
+ const args = parseArgs(process.argv.slice(2));
109
+ if (args.help) {
110
+ console.log(usage());
111
+ process.exit(0);
112
+ }
113
+ if (!args.planFile) throw new Error(usage());
114
+ const routerContract = JSON.parse(fs.readFileSync(path.resolve(args.planFile), 'utf8'));
115
+ const handoff = consumeWorkspacePlan({
116
+ routerContract,
117
+ workspaceRoot: args.root || process.cwd(),
118
+ runId: args.runId,
119
+ });
120
+ process.stdout.write(`${JSON.stringify(handoff)}\n`);
121
+ } catch (err) {
122
+ console.error(`[WORKSPACE PLAN CONSUMER] ${err.message}`);
123
+ process.exit(2);
124
+ }
125
+ }
126
+
127
+ module.exports = {
128
+ consumeWorkspacePlan,
129
+ };
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const { getWorkspaceRoot, getRuntimeRoot, resolveProjectDocs } = require('./project-docs-resolver');
7
+
8
+ function option(args, ...names) {
9
+ for (const name of names) {
10
+ const index = args.indexOf(name);
11
+ if (index !== -1) return args[index + 1];
12
+ }
13
+ return undefined;
14
+ }
15
+
16
+ function manifestFromArgs(args) {
17
+ const workspace = path.resolve(option(args, '--workspace', '--root') || getWorkspaceRoot());
18
+ const manifestPath = path.resolve(option(args, '--manifest') || path.join(getRuntimeRoot(workspace), 'manifest.json'));
19
+ if (!fs.existsSync(manifestPath)) {
20
+ throw new Error(`manifest not found: ${manifestPath}; pass --workspace or --manifest explicitly`);
21
+ }
22
+ let manifest;
23
+ try { manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')); }
24
+ catch (error) { throw new Error(`invalid manifest: ${error.message}`); }
25
+ return { workspace, manifestPath, manifest };
26
+ }
27
+
28
+ function linkPath(workspace, absolute) {
29
+ const relative = path.relative(workspace, absolute).replace(/\\/g, '/');
30
+ return relative && !relative.startsWith('../') ? relative : path.resolve(absolute).replace(/\\/g, '/');
31
+ }
32
+
33
+ function linkTarget(workspace, absolute) {
34
+ const relative = path.relative(workspace, absolute).replace(/\\/g, '/');
35
+ if (relative && !relative.startsWith('../')) return relative;
36
+ const normalized = path.resolve(absolute).replace(/\\/g, '/');
37
+ return encodeURI(`file://${normalized.startsWith('/') ? '' : '/'}${normalized}`);
38
+ }
39
+
40
+ function buildIndex(input) {
41
+ // Keep the old string form for consumers that imported buildIndex directly;
42
+ // path resolution still comes from an explicit workspace, never output depth.
43
+ const args = typeof input === 'string' ? ['--workspace', input] : (Array.isArray(input) ? input : null);
44
+ const resolved = args ? manifestFromArgs(args) : {
45
+ workspace: path.resolve(input.workspace || getWorkspaceRoot()),
46
+ manifestPath: path.resolve(input.manifest),
47
+ manifest: input.manifestData || JSON.parse(fs.readFileSync(path.resolve(input.manifest), 'utf8'))
48
+ };
49
+ const { workspace, manifest } = resolved;
50
+ const selected = Array.isArray(manifest.selectedAgents) ? manifest.selectedAgents : [];
51
+ const paths = manifest.paths || resolveProjectDocs(workspace).paths;
52
+ const lines = [
53
+ '# Multi-Agent Memory Index', '',
54
+ 'This index is generated from the global multi-agent runtime manifest. Read linked records on demand.',
55
+ '', '## Runtime', '',
56
+ `- Root: \`${manifest.runtimeRoot || (manifest.runtime && manifest.runtime.root) || ''}\``,
57
+ `- Manifest: \`${resolved.manifestPath}\``,
58
+ '', '## Document paths', ''
59
+ ];
60
+ for (const zone of ['decision', 'domain', 'architecture']) {
61
+ const entry = paths[zone];
62
+ if (entry) lines.push(`- **${zone}**: [${linkPath(workspace, entry.path)}](${linkTarget(workspace, entry.path)}) (${entry.source})`);
63
+ }
64
+ lines.push('', '## Selected specialists', '');
65
+ if (!selected.length) {
66
+ lines.push('- None selected. Do not claim that the external roster is complete.');
67
+ } else {
68
+ for (const agent of selected) {
69
+ if (typeof agent === 'string') lines.push(`- \`${agent}\``);
70
+ else lines.push(`- **${agent.name}** (${agent.division}) - \`${agent.slug}\``);
71
+ }
72
+ }
73
+ lines.push('', '## Handoff', '', `- [Structured handoff](${linkTarget(workspace, path.join(path.dirname(resolved.manifestPath), 'handoff.json'))})`, `- [Launcher](${linkTarget(workspace, path.join(path.dirname(resolved.manifestPath), 'launcher.md'))})`);
74
+ return `${lines.join('\n')}\n`;
75
+ }
76
+
77
+ function parseArgs(args) {
78
+ const workspace = option(args, '--workspace', '--root');
79
+ const manifest = option(args, '--manifest');
80
+ const output = option(args, '--output');
81
+ if (!output) throw new Error('--output requires a path; output location is never inferred from its depth');
82
+ return { workspace, manifest, output: path.resolve(output) };
83
+ }
84
+
85
+ function main() {
86
+ try {
87
+ const args = process.argv.slice(2);
88
+ const options = parseArgs(args);
89
+ const result = manifestFromArgs(args);
90
+ fs.mkdirSync(path.dirname(options.output), { recursive: true });
91
+ fs.writeFileSync(options.output, buildIndex({
92
+ workspace: result.workspace,
93
+ manifest: result.manifestPath,
94
+ manifestData: result.manifest
95
+ }), 'utf8');
96
+ console.log(`Memory index written to ${options.output}`);
97
+ } catch (error) {
98
+ console.error(`ERROR: ${error.message}`);
99
+ process.exitCode = 1;
100
+ }
101
+ }
102
+
103
+ if (require.main === module) main();
104
+ module.exports = { buildIndex, parseArgs, manifestFromArgs };
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ function canonicalizePath(value) {
7
+ let current = path.resolve(value);
8
+ const missing = [];
9
+ while (!fs.existsSync(current)) {
10
+ const parent = path.dirname(current);
11
+ if (parent === current) break;
12
+ missing.unshift(path.basename(current));
13
+ current = parent;
14
+ }
15
+ let existing = current;
16
+ try { existing = fs.realpathSync.native ? fs.realpathSync.native(current) : fs.realpathSync(current); }
17
+ catch { /* retain the nearest existing lexical ancestor */ }
18
+ return path.join(existing, ...missing);
19
+ }
20
+
21
+ function isWithin(root, target) {
22
+ const relative = path.relative(root, target);
23
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
24
+ }
25
+
26
+ function assertNoLinkComponents(root, target) {
27
+ const relative = path.relative(path.resolve(root), path.resolve(target));
28
+ if (relative.startsWith('..') || path.isAbsolute(relative)) return;
29
+ let current = path.resolve(root);
30
+ for (const component of relative ? relative.split(path.sep) : []) {
31
+ current = path.join(current, component);
32
+ let stat;
33
+ try { stat = fs.lstatSync(current); } catch { continue; }
34
+ if (stat.isSymbolicLink()) {
35
+ const error = new Error(`path contains a link component inside boundary: ${current}`);
36
+ error.code = 'LINK_COMPONENT_IN_BOUNDARY';
37
+ throw error;
38
+ }
39
+ }
40
+ }
41
+
42
+ function assertContainedPath(root, target) {
43
+ if (typeof root !== 'string' || typeof target !== 'string') {
44
+ const error = new TypeError('path boundary requires string root and target');
45
+ error.code = 'INVALID_BOUNDARY_PATH';
46
+ throw error;
47
+ }
48
+ assertNoLinkComponents(root, target);
49
+ const canonicalRoot = canonicalizePath(root);
50
+ const canonicalTarget = canonicalizePath(target);
51
+ if (!isWithin(canonicalRoot, canonicalTarget)) {
52
+ const error = new Error(`path escapes boundary: ${target}`);
53
+ error.code = 'PATH_OUTSIDE_BOUNDARY';
54
+ throw error;
55
+ }
56
+ return { root: canonicalRoot, target: canonicalTarget };
57
+ }
58
+
59
+ module.exports = { assertContainedPath };