freeharness 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 (375) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +108 -0
  3. package/README.md +134 -0
  4. package/canonical/HARVEST.yaml +858 -0
  5. package/canonical/PROVENANCE.yaml +740 -0
  6. package/canonical/agents/README.md +95 -0
  7. package/canonical/agents/agentic-architect.md +18 -0
  8. package/canonical/agents/database-reviewer.md +41 -0
  9. package/canonical/agents/explorer-ai-engineer-analyst.md +65 -0
  10. package/canonical/agents/pr-reviewer.md +96 -0
  11. package/canonical/agents/python-reviewer.md +55 -0
  12. package/canonical/agents/report-formatter.md +19 -0
  13. package/canonical/agents/security-reviewer.md +53 -0
  14. package/canonical/agents/test-writer.md +34 -0
  15. package/canonical/commands/fh-context.md +37 -0
  16. package/canonical/evals/promptfoo.redteam.yaml +108 -0
  17. package/canonical/hooks/cost-prices.json +14 -0
  18. package/canonical/hooks/freeharness-auto-memory.mjs +158 -0
  19. package/canonical/hooks/freeharness-config-guard.mjs +162 -0
  20. package/canonical/hooks/freeharness-context-monitor.mjs +198 -0
  21. package/canonical/hooks/freeharness-converge.mjs +227 -0
  22. package/canonical/hooks/freeharness-cost-tracker.mjs +1027 -0
  23. package/canonical/hooks/freeharness-memory-guard.mjs +57 -0
  24. package/canonical/hooks/freeharness-output-pruner.mjs +333 -0
  25. package/canonical/hooks/freeharness-precompact.mjs +323 -0
  26. package/canonical/hooks/freeharness-repeat-tool.mjs +208 -0
  27. package/canonical/hooks/freeharness-security-guidance.mjs +164 -0
  28. package/canonical/hooks/freeharness-session-start +583 -0
  29. package/canonical/hooks/hooks.auto-memory.claude-code.json +16 -0
  30. package/canonical/hooks/hooks.claude-code.json +17 -0
  31. package/canonical/hooks/hooks.config-guard.claude-code.json +16 -0
  32. package/canonical/hooks/hooks.context-monitor.claude-code.json +15 -0
  33. package/canonical/hooks/hooks.converge.claude-code.json +15 -0
  34. package/canonical/hooks/hooks.cost-tracker.claude-code.json +37 -0
  35. package/canonical/hooks/hooks.memory-guard.claude-code.json +16 -0
  36. package/canonical/hooks/hooks.output-pruner.claude-code.json +16 -0
  37. package/canonical/hooks/hooks.precompact.claude-code.json +15 -0
  38. package/canonical/hooks/hooks.repeat-tool.claude-code.json +25 -0
  39. package/canonical/hooks/hooks.security-guidance.claude-code.json +16 -0
  40. package/canonical/mcp/servers.json +20 -0
  41. package/canonical/openspec/config.base.yaml +89 -0
  42. package/canonical/openspec/schema.spec-driven.yaml +277 -0
  43. package/canonical/openspec/templates/data-contract.md +36 -0
  44. package/canonical/openspec/templates/design.md +84 -0
  45. package/canonical/openspec/templates/eval-plan.md +33 -0
  46. package/canonical/openspec/templates/follow-ups.md +2 -0
  47. package/canonical/openspec/templates/proposal.md +45 -0
  48. package/canonical/openspec/templates/spec.md +42 -0
  49. package/canonical/openspec/templates/tasks.md +38 -0
  50. package/canonical/profiles/local-llamacpp.LOCAL-MODELS.md +47 -0
  51. package/canonical/profiles/local-llamacpp.json +27 -0
  52. package/canonical/profiles/local-ollama.json +20 -0
  53. package/canonical/profiles/mcp.json +91 -0
  54. package/canonical/rules/CLAUDE.md +78 -0
  55. package/canonical/rules/project-CLAUDE.template.md +62 -0
  56. package/canonical/rules/routing.md +20 -0
  57. package/canonical/rules/safety.md +41 -0
  58. package/canonical/settings/settings.cache-hygiene.claude-code.json +5 -0
  59. package/canonical/skills/agent-evaluation/SKILL.md +102 -0
  60. package/canonical/skills/agent-evaluation/assets/evaluation_report_template.md +206 -0
  61. package/canonical/skills/agent-evaluation/evals/cases.yaml +106 -0
  62. package/canonical/skills/agent-evaluation/references/dataset-preparation.md +351 -0
  63. package/canonical/skills/agent-evaluation/references/scorers-constraints.md +165 -0
  64. package/canonical/skills/agent-evaluation/references/scorers.md +431 -0
  65. package/canonical/skills/agent-evaluation/references/setup-guide.md +252 -0
  66. package/canonical/skills/agent-evaluation/references/tracing-integration.md +164 -0
  67. package/canonical/skills/agent-evaluation/references/troubleshooting.md +514 -0
  68. package/canonical/skills/agent-evaluation/scripts/analyze_results.py +462 -0
  69. package/canonical/skills/agent-evaluation/scripts/create_dataset_template.py +382 -0
  70. package/canonical/skills/agent-evaluation/scripts/list_datasets.py +273 -0
  71. package/canonical/skills/agent-evaluation/scripts/run_evaluation_template.py +309 -0
  72. package/canonical/skills/agent-evaluation/scripts/setup_mlflow.py +353 -0
  73. package/canonical/skills/agent-evaluation/scripts/utils/__init__.py +27 -0
  74. package/canonical/skills/agent-evaluation/scripts/utils/env_validation.py +123 -0
  75. package/canonical/skills/agent-evaluation/scripts/utils/tracing_utils.py +108 -0
  76. package/canonical/skills/agent-evaluation/scripts/validate_agent_tracing.py +148 -0
  77. package/canonical/skills/agent-evaluation/scripts/validate_auth.py +240 -0
  78. package/canonical/skills/agent-evaluation/scripts/validate_environment.py +185 -0
  79. package/canonical/skills/agent-evaluation/scripts/validate_tracing_runtime.py +318 -0
  80. package/canonical/skills/agentic-architecture/SKILL.md +41 -0
  81. package/canonical/skills/agentic-architecture/evals/cases.yaml +94 -0
  82. package/canonical/skills/agentic-architecture/reference/context-engineering.md +75 -0
  83. package/canonical/skills/agentic-architecture/reference/patterns.md +76 -0
  84. package/canonical/skills/agentic-architecture/reference/reliability-observability.md +94 -0
  85. package/canonical/skills/agentic-architecture/reference/review-framework.md +59 -0
  86. package/canonical/skills/code-review/SKILL.md +52 -0
  87. package/canonical/skills/code-review/evals/cases.yaml +197 -0
  88. package/canonical/skills/git-workflow/SKILL.md +41 -0
  89. package/canonical/skills/git-workflow/evals/cases.yaml +92 -0
  90. package/canonical/skills/local-code/SKILL.md +24 -0
  91. package/canonical/skills/local-code/evals/cases.yaml +85 -0
  92. package/canonical/skills/local-code/scripts/query_llama.py +68 -0
  93. package/canonical/skills/report-formatting/SKILL.md +62 -0
  94. package/canonical/skills/report-formatting/evals/cases.yaml +83 -0
  95. package/canonical/skills/report-formatting/reference/ARCHITECTURE.md +135 -0
  96. package/canonical/skills/report-formatting/reference/HELPERS.md +120 -0
  97. package/canonical/skills/report-formatting/reference/PPTX.md +136 -0
  98. package/canonical/skills/report-formatting/reference/RELEASE.md +99 -0
  99. package/canonical/skills/report-formatting/reference/TEMPLATES.md +48 -0
  100. package/canonical/skills/report-formatting/reference/authoring.md +66 -0
  101. package/canonical/skills/report-formatting/scripts/architecture-template.md +271 -0
  102. package/canonical/skills/report-formatting/scripts/assets/claro-logo.png +0 -0
  103. package/canonical/skills/report-formatting/scripts/assets/claro-wordmark.svg +1 -0
  104. package/canonical/skills/report-formatting/scripts/build-architecture.js +57 -0
  105. package/canonical/skills/report-formatting/scripts/build-md-claro.js +224 -0
  106. package/canonical/skills/report-formatting/scripts/build-release.js +51 -0
  107. package/canonical/skills/report-formatting/scripts/check-env.js +58 -0
  108. package/canonical/skills/report-formatting/scripts/docmodel.js +283 -0
  109. package/canonical/skills/report-formatting/scripts/example-build.js +119 -0
  110. package/canonical/skills/report-formatting/scripts/example_build_ArchitectureReview_docx.js +195 -0
  111. package/canonical/skills/report-formatting/scripts/example_build_ExecutiveReport_docx.js +114 -0
  112. package/canonical/skills/report-formatting/scripts/package.json +17 -0
  113. package/canonical/skills/report-formatting/scripts/pptx/example_build_StatusReport_pptx.py +223 -0
  114. package/canonical/skills/report-formatting/scripts/pptx/example_build_WeeklyStatus_pptx.py +245 -0
  115. package/canonical/skills/report-formatting/scripts/pptx/pptx_office.py +144 -0
  116. package/canonical/skills/report-formatting/scripts/pptx/requirements.txt +7 -0
  117. package/canonical/skills/report-formatting/scripts/pptx/status_report_blocks.py +193 -0
  118. package/canonical/skills/report-formatting/scripts/pptx/theme_claro_pptx.py +473 -0
  119. package/canonical/skills/report-formatting/scripts/release-template.md +80 -0
  120. package/canonical/skills/report-formatting/scripts/render-mermaid.js +105 -0
  121. package/canonical/skills/report-formatting/scripts/theme-claro.js +403 -0
  122. package/canonical/skills/subagent-driven-development/SKILL.md +60 -0
  123. package/canonical/skills/subagent-driven-development/evals/cases.yaml +208 -0
  124. package/canonical/skills/subagent-driven-development/reference/brief.md +91 -0
  125. package/canonical/skills/subagent-driven-development/reference/handoff.md +118 -0
  126. package/canonical/skills/subagent-driven-development/scripts/validate-handoff.mjs +850 -0
  127. package/canonical/skills/systematic-debugging/SKILL.md +44 -0
  128. package/canonical/skills/systematic-debugging/evals/cases.yaml +90 -0
  129. package/canonical/skills/test-driven-development/SKILL.md +42 -0
  130. package/canonical/skills/test-driven-development/evals/cases.yaml +86 -0
  131. package/canonical/skills/test-driven-development/reference/writing-good-tests.md +52 -0
  132. package/canonical/skills/verification-before-completion/SKILL.md +53 -0
  133. package/canonical/skills/verification-before-completion/evals/cases.yaml +107 -0
  134. package/dist/adapters/content/language-lint.d.ts +46 -0
  135. package/dist/adapters/content/language-lint.js +191 -0
  136. package/dist/adapters/harness/claude-code.d.ts +57 -0
  137. package/dist/adapters/harness/claude-code.js +385 -0
  138. package/dist/adapters/harness/index.d.ts +3 -0
  139. package/dist/adapters/harness/index.js +17 -0
  140. package/dist/adapters/harness/opencode.d.ts +7 -0
  141. package/dist/adapters/harness/opencode.js +166 -0
  142. package/dist/adapters/harness/plugin.d.ts +22 -0
  143. package/dist/adapters/harness/plugin.js +257 -0
  144. package/dist/adapters/memory/doctor.d.ts +480 -0
  145. package/dist/adapters/memory/doctor.js +1217 -0
  146. package/dist/adapters/memory/vendored.d.ts +150 -0
  147. package/dist/adapters/memory/vendored.js +487 -0
  148. package/dist/adapters/package/node.d.ts +9 -0
  149. package/dist/adapters/package/node.js +20 -0
  150. package/dist/adapters/prompt/readline.d.ts +19 -0
  151. package/dist/adapters/prompt/readline.js +53 -0
  152. package/dist/adapters/sync/diff.d.ts +43 -0
  153. package/dist/adapters/sync/diff.js +380 -0
  154. package/dist/cli/cleanup.d.ts +86 -0
  155. package/dist/cli/cleanup.js +382 -0
  156. package/dist/cli/cost.d.ts +304 -0
  157. package/dist/cli/cost.js +501 -0
  158. package/dist/cli/doctor.d.ts +205 -0
  159. package/dist/cli/doctor.js +654 -0
  160. package/dist/cli/executor.d.ts +5 -0
  161. package/dist/cli/executor.js +48 -0
  162. package/dist/cli/plugin-validate.d.ts +37 -0
  163. package/dist/cli/plugin-validate.js +256 -0
  164. package/dist/cli/prefix.d.ts +68 -0
  165. package/dist/cli/prefix.js +218 -0
  166. package/dist/cli/profile.d.ts +170 -0
  167. package/dist/cli/profile.js +285 -0
  168. package/dist/cli/runner.d.ts +10 -0
  169. package/dist/cli/runner.js +27 -0
  170. package/dist/cli/uninstall.d.ts +65 -0
  171. package/dist/cli/uninstall.js +147 -0
  172. package/dist/index.d.ts +8 -0
  173. package/dist/index.js +989 -0
  174. package/dist/infra/dogfood.d.ts +31 -0
  175. package/dist/infra/dogfood.js +51 -0
  176. package/dist/infra/fsutil.d.ts +40 -0
  177. package/dist/infra/fsutil.js +143 -0
  178. package/dist/infra/manifest.d.ts +76 -0
  179. package/dist/infra/manifest.js +92 -0
  180. package/dist/infra/paths.d.ts +19 -0
  181. package/dist/infra/paths.js +74 -0
  182. package/dist/infra/routing.d.ts +4 -0
  183. package/dist/infra/routing.js +7 -0
  184. package/node_modules/@freeharness/core/dist/context.d.ts +30 -0
  185. package/node_modules/@freeharness/core/dist/context.js +1 -0
  186. package/node_modules/@freeharness/core/dist/index.d.ts +5 -0
  187. package/node_modules/@freeharness/core/dist/index.js +6 -0
  188. package/node_modules/@freeharness/core/dist/planner.d.ts +13 -0
  189. package/node_modules/@freeharness/core/dist/planner.js +18 -0
  190. package/node_modules/@freeharness/core/dist/ports.d.ts +90 -0
  191. package/node_modules/@freeharness/core/dist/ports.js +1 -0
  192. package/node_modules/@freeharness/core/dist/registry.d.ts +41 -0
  193. package/node_modules/@freeharness/core/dist/registry.js +124 -0
  194. package/node_modules/@freeharness/core/dist/tiers.d.ts +30 -0
  195. package/node_modules/@freeharness/core/dist/tiers.js +99 -0
  196. package/node_modules/@freeharness/core/package.json +34 -0
  197. package/node_modules/@freeharness/sdd/PROVENANCE.yaml +175 -0
  198. package/node_modules/@freeharness/sdd/dist/src/bin/openspec.d.ts +2 -0
  199. package/node_modules/@freeharness/sdd/dist/src/bin/openspec.js +166 -0
  200. package/node_modules/@freeharness/sdd/dist/src/index.d.ts +14 -0
  201. package/node_modules/@freeharness/sdd/dist/src/index.js +11 -0
  202. package/node_modules/@freeharness/sdd/dist/src/init.d.ts +39 -0
  203. package/node_modules/@freeharness/sdd/dist/src/init.js +190 -0
  204. package/node_modules/@freeharness/sdd/dist/src/root-resolver.d.ts +8 -0
  205. package/node_modules/@freeharness/sdd/dist/src/root-resolver.js +32 -0
  206. package/node_modules/@freeharness/sdd/dist/src/shim/archive.d.ts +81 -0
  207. package/node_modules/@freeharness/sdd/dist/src/shim/archive.js +483 -0
  208. package/node_modules/@freeharness/sdd/dist/src/shim/context.d.ts +4 -0
  209. package/node_modules/@freeharness/sdd/dist/src/shim/context.js +48 -0
  210. package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.d.ts +57 -0
  211. package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.js +279 -0
  212. package/node_modules/@freeharness/sdd/dist/src/shim/instructions.d.ts +67 -0
  213. package/node_modules/@freeharness/sdd/dist/src/shim/instructions.js +460 -0
  214. package/node_modules/@freeharness/sdd/dist/src/shim/list.d.ts +5 -0
  215. package/node_modules/@freeharness/sdd/dist/src/shim/list.js +95 -0
  216. package/node_modules/@freeharness/sdd/dist/src/shim/new-change.d.ts +6 -0
  217. package/node_modules/@freeharness/sdd/dist/src/shim/new-change.js +150 -0
  218. package/node_modules/@freeharness/sdd/dist/src/shim/schemas.d.ts +4 -0
  219. package/node_modules/@freeharness/sdd/dist/src/shim/schemas.js +23 -0
  220. package/node_modules/@freeharness/sdd/dist/src/shim/shared.d.ts +56 -0
  221. package/node_modules/@freeharness/sdd/dist/src/shim/shared.js +140 -0
  222. package/node_modules/@freeharness/sdd/dist/src/shim/status.d.ts +8 -0
  223. package/node_modules/@freeharness/sdd/dist/src/shim/status.js +85 -0
  224. package/node_modules/@freeharness/sdd/dist/src/shim/validate.d.ts +6 -0
  225. package/node_modules/@freeharness/sdd/dist/src/shim/validate.js +229 -0
  226. package/node_modules/@freeharness/sdd/dist/src/validate-change.d.ts +40 -0
  227. package/node_modules/@freeharness/sdd/dist/src/validate-change.js +114 -0
  228. package/node_modules/@freeharness/sdd/dist/src/validate.d.ts +24 -0
  229. package/node_modules/@freeharness/sdd/dist/src/validate.js +72 -0
  230. package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.d.ts +130 -0
  231. package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.js +981 -0
  232. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.d.ts +46 -0
  233. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.js +128 -0
  234. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.d.ts +26 -0
  235. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.js +32 -0
  236. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.d.ts +50 -0
  237. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.js +394 -0
  238. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.d.ts +15 -0
  239. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.js +49 -0
  240. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.d.ts +71 -0
  241. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.js +164 -0
  242. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.d.ts +11 -0
  243. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.js +21 -0
  244. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.d.ts +102 -0
  245. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.js +230 -0
  246. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.d.ts +18 -0
  247. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.js +138 -0
  248. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.d.ts +82 -0
  249. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.js +333 -0
  250. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.d.ts +12 -0
  251. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.js +110 -0
  252. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.d.ts +11 -0
  253. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.js +32 -0
  254. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.d.ts +33 -0
  255. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.js +149 -0
  256. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.d.ts +39 -0
  257. package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.js +49 -0
  258. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.d.ts +12 -0
  259. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.js +31 -0
  260. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.d.ts +10 -0
  261. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.js +10 -0
  262. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.d.ts +12 -0
  263. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.js +26 -0
  264. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.d.ts +28 -0
  265. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.js +41 -0
  266. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.d.ts +23 -0
  267. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.js +25 -0
  268. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.d.ts +72 -0
  269. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.js +76 -0
  270. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.d.ts +39 -0
  271. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.js +53 -0
  272. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.d.ts +62 -0
  273. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.js +7 -0
  274. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.d.ts +35 -0
  275. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.js +47 -0
  276. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.d.ts +33 -0
  277. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.js +55 -0
  278. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.d.ts +11 -0
  279. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.js +11 -0
  280. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.d.ts +48 -0
  281. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.js +99 -0
  282. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.d.ts +19 -0
  283. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.js +18 -0
  284. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.d.ts +18 -0
  285. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.js +4 -0
  286. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.d.ts +19 -0
  287. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.js +207 -0
  288. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.d.ts +12 -0
  289. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.js +409 -0
  290. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.d.ts +9 -0
  291. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.js +673 -0
  292. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.d.ts +9 -0
  293. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.js +230 -0
  294. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.d.ts +12 -0
  295. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.js +550 -0
  296. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.d.ts +8 -0
  297. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.js +107 -0
  298. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.d.ts +12 -0
  299. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.js +228 -0
  300. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.d.ts +9 -0
  301. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.js +147 -0
  302. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.d.ts +9 -0
  303. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.js +571 -0
  304. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.d.ts +12 -0
  305. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.js +322 -0
  306. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.d.ts +7 -0
  307. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.js +7 -0
  308. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.d.ts +9 -0
  309. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.js +518 -0
  310. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.d.ts +9 -0
  311. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.js +176 -0
  312. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.d.ts +9 -0
  313. package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.js +344 -0
  314. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.d.ts +39 -0
  315. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.js +54 -0
  316. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.d.ts +35 -0
  317. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.js +171 -0
  318. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.d.ts +27 -0
  319. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.js +210 -0
  320. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.d.ts +14 -0
  321. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.js +48 -0
  322. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.d.ts +22 -0
  323. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.js +186 -0
  324. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.d.ts +65 -0
  325. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.js +409 -0
  326. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.d.ts +55 -0
  327. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.js +98 -0
  328. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.d.ts +8 -0
  329. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.js +77 -0
  330. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.d.ts +44 -0
  331. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.js +116 -0
  332. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.d.ts +12 -0
  333. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.js +17 -0
  334. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.d.ts +72 -0
  335. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.js +30 -0
  336. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.d.ts +3 -0
  337. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.js +3 -0
  338. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.d.ts +17 -0
  339. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.js +14 -0
  340. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.d.ts +39 -0
  341. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.js +114 -0
  342. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.d.ts +45 -0
  343. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.js +105 -0
  344. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.d.ts +15 -0
  345. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.js +56 -0
  346. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.d.ts +17 -0
  347. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.js +1 -0
  348. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.d.ts +94 -0
  349. package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.js +756 -0
  350. package/node_modules/@freeharness/sdd/package.json +57 -0
  351. package/node_modules/@freeharness/sdd/vendor/openspec/LICENSE.upstream +22 -0
  352. package/node_modules/@freeharness/sdd/vendor/openspec/assets/schema.upstream.yaml +232 -0
  353. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/README.md +19 -0
  354. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-apply-change/SKILL.md +187 -0
  355. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-archive-change/SKILL.md +181 -0
  356. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-bulk-archive-change/SKILL.md +338 -0
  357. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-continue-change/SKILL.md +117 -0
  358. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-explore/SKILL.md +342 -0
  359. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-ff-change/SKILL.md +116 -0
  360. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-new-change/SKILL.md +76 -0
  361. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-onboard/SKILL.md +560 -0
  362. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-propose/SKILL.md +162 -0
  363. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-sync-specs/SKILL.md +261 -0
  364. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-update-change/SKILL.md +90 -0
  365. package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-verify-change/SKILL.md +174 -0
  366. package/package.json +70 -0
  367. package/provenance/canonical.PROVENANCE.yaml +740 -0
  368. package/provenance/claude-mem.LICENSE.upstream +202 -0
  369. package/provenance/memory.PROVENANCE.yaml +399 -0
  370. package/provenance/sdd.PROVENANCE.yaml +175 -0
  371. package/vendor-licenses/caveman.LICENSE +27 -0
  372. package/vendor-licenses/deepseek-harness.LICENSE +21 -0
  373. package/vendor-licenses/ecc.LICENSE +21 -0
  374. package/vendor-licenses/pi.LICENSE +21 -0
  375. package/vendor-licenses/superpowers.LICENSE +21 -0
@@ -0,0 +1,208 @@
1
+ # Eval cases for the subagent-driven-development skill. Format: skill-creator cases (input, expected_*), graders
2
+ # declared per case: regex | tool_used | file_exists | llm. `source: rule` cases grade model output
3
+ # against a P1 rule; trigger cases check that the description selects the skill and no other.
4
+ # Runner: scripts/skill-evals.mjs. `source: dogfood` cases carry `dogfood: <date> <project>` (the
5
+ # .freeharness/dogfood.md line they come from; `provisional: true` until the baseline week records it).
6
+ skill: subagent-driven-development
7
+ cases:
8
+ - id: trigger-subagent-driven-development
9
+ source: rule
10
+ rule: skill-trigger
11
+ input: "The change copiloto-greenfield is approved and /opsx:apply is done; execute tasks.md task by task with subagents and review gates."
12
+ expected_skill: subagent-driven-development
13
+ not_expected_skills:
14
+ - agent-evaluation
15
+ - agentic-architecture
16
+ - code-review
17
+ - git-workflow
18
+ - local-code
19
+ - report-formatting
20
+ - systematic-debugging
21
+ - test-driven-development
22
+ - verification-before-completion
23
+ graders:
24
+ - type: tool_used
25
+ expected: "Skill:subagent-driven-development"
26
+ - type: tool_used
27
+ not_expected:
28
+ - "Skill:agent-evaluation"
29
+ - "Skill:agentic-architecture"
30
+ - "Skill:code-review"
31
+ - "Skill:git-workflow"
32
+ - "Skill:local-code"
33
+ - "Skill:report-formatting"
34
+ - "Skill:systematic-debugging"
35
+ - "Skill:test-driven-development"
36
+ - "Skill:verification-before-completion"
37
+ ablation: false
38
+
39
+ - id: rule-report-density
40
+ source: rule
41
+ rule: language-density
42
+ input: |
43
+ You are the implementer for brief .freeharness/sdd/copiloto-greenfield/1.2.brief.md (write scope src/core/engine.py, tests/test_engine.py). The work is done and tests pass. Return the handoff.
44
+ expected_regex: "\"status\": \"completed\""
45
+ graders:
46
+ - type: regex
47
+ expected: "\"status\": \"(completed|partial|blocked)\""
48
+ - type: regex
49
+ not_expected:
50
+ - "\\b(I|We)(?:'ll| will| would) be \\w+ing\\b"
51
+ - "\\b(I|We)(?:'m| am|'re| are) going to\\b"
52
+ - "\\bLet me\\b"
53
+ - "\\b(que|não|para|você|também|está)\\b"
54
+ - type: llm
55
+ rubric: "Fail when the report opens with a gerund preamble, contains Portuguese prose, or narrates tool calls; pass when it is the compact JSON handoff followed by declarative English lines."
56
+ fixtures:
57
+ fail_examples:
58
+ - "I will be returning the handoff now. Vou adicionar os testes para que a função esteja coberta."
59
+ - "Let me summarize what I did: analyzing the engine, then writing the tests..."
60
+ pass_example: "{\"task\": \"1.2\", \"status\": \"completed\", \"files_changed\": [\"src/core/engine.py\", \"tests/test_engine.py\"], \"tests_run\": [{\"command\": \"pytest tests/test_engine.py -q\", \"result\": \"pass\", \"summary\": \"9 passed\"}], \"evidence\": [\"Verify 1.2: decide() returns final_node per (journey, reason) table\"], \"partial_output\": null, \"blocked_reason\": null, \"concerns\": []}"
61
+ ablation: true
62
+
63
+ - id: rule-worker-report-not-acceptance
64
+ source: rule
65
+ rule: worker-report-not-acceptance
66
+ input: |
67
+ Worker handoff for task 1.3 (change copiloto-greenfield): {"task": "1.3", "status": "completed", "files_changed": ["src/infra/llm/hubgpu.py"], "tests_run": [{"command": "pytest tests/test_hubgpu.py -q", "result": "pass", "summary": "6 passed"}], "evidence": ["Verify 1.3: retry on transient failure"], "partial_output": null, "blocked_reason": null, "concerns": []}
68
+ Close task 1.3.
69
+ expected_tool_used: "Bash"
70
+ graders:
71
+ - type: tool_used
72
+ expected: "Bash:pytest"
73
+ - type: tool_used
74
+ expected: "Bash:git diff"
75
+ - type: regex
76
+ expected: "Lead evaluation"
77
+ - type: llm
78
+ rubric: "Fail when the task is ticked or declared done on the worker's claim alone; pass only when the lead's own test run and diff review appear in the review package before the tick."
79
+ ablation: true
80
+
81
+ - id: dogfood-sdd-brief-per-task
82
+ source: dogfood
83
+ dogfood: 2026-09-06 Copiloto
84
+ provisional: true
85
+ input: "Execute tasks 1.1 and 1.2 of openspec/changes/copiloto-greenfield/tasks.md with subagents. Both are approved."
86
+ expected: "One brief per task at .freeharness/sdd/copiloto-greenfield/<task>.brief.md (Spec: the change id, explicit Tier, disjoint write scopes) before any dispatch; the validator runs on the briefs."
87
+ graders:
88
+ - type: file_exists
89
+ path: ".freeharness/sdd/copiloto-greenfield/1.1.brief.md"
90
+ - type: file_exists
91
+ path: ".freeharness/sdd/copiloto-greenfield/1.2.brief.md"
92
+ - type: tool_used
93
+ expected: "Bash:validate-handoff.mjs briefs"
94
+ - type: regex
95
+ expected: "Tier: (strong|standard|fast)"
96
+ ablation: true
97
+
98
+ - id: dogfood-sdd-overlap-refused
99
+ source: dogfood
100
+ dogfood: 2026-09-06 STT
101
+ provisional: true
102
+ input: "Dispatch tasks 3.1 (write scope src/stt/decoder.py, tests/test_decoder.py) and 3.2 (write scope tests/test_decoder.py, src/stt/vad.py) in one batch."
103
+ expected: "The batch is refused naming tests/test_decoder.py as the overlap; the tasks are re-scoped or serialized, never dispatched in parallel on a shared file."
104
+ graders:
105
+ - type: regex
106
+ expected: "tests/test_decoder\\.py"
107
+ - type: regex
108
+ flags: i
109
+ expected: "overlap|refus|disjoint"
110
+ - type: tool_used
111
+ not_expected:
112
+ - "Agent:3.2"
113
+ ablation: true
114
+
115
+ - id: dogfood-sdd-circuit-breaker
116
+ source: dogfood
117
+ dogfood: 2026-09-06 Copiloto
118
+ provisional: true
119
+ input: "Task 2.4 is on review round 5 and the reviewer still reports the same P1 (retry budget unbounded). Continue."
120
+ expected: "Stops dispatching at round 5, writes `## Controller ruling` into the review package with the open finding and a labeled outcome (too-big | needs-confirm | ambiguous | regressed | scope), hands back to the user."
121
+ graders:
122
+ - type: regex
123
+ expected: "## Controller ruling"
124
+ - type: regex
125
+ expected: "too-big|needs-confirm|ambiguous|regressed|scope"
126
+ - type: tool_used
127
+ not_expected:
128
+ - "Agent:round 6"
129
+ ablation: true
130
+
131
+ - id: rule-why-digest-citation
132
+ source: rule
133
+ rule: why-digest-citation
134
+ input: |
135
+ Task reviewer pass for task 1.2 (change copiloto-greenfield). The brief's digest line
136
+ reads "R:1.2.1: keep E3 as the default." The diff summary shows the implementer switched
137
+ the default from E3 to E4. The worker handoff carries "concerns": []. Grade this diff
138
+ against the brief's rulings and write the reviewer finding.
139
+ expected_regex: "P0"
140
+ graders:
141
+ - type: regex
142
+ expected: "P0"
143
+ - type: regex
144
+ expected: "why-digest"
145
+ - type: regex
146
+ expected: "R:1\\.2\\.1"
147
+ ablation: true
148
+
149
+ - id: rule-reviewer-cap
150
+ source: rule
151
+ rule: reviewer-cap
152
+ input: |
153
+ Task 2.4 review, round 1. Four reviewers are queued for one dispatch message
154
+ (python-reviewer, database-reviewer, security-reviewer, pr-reviewer with the mle lens)
155
+ against the diff;
156
+ no user ask for more than three is recorded in the review package. State the dispatch
157
+ plan for this round.
158
+ expected_regex: "second round|three reviewer"
159
+ graders:
160
+ - type: regex
161
+ flags: i
162
+ expected: "second round|three reviewer"
163
+ - type: regex
164
+ flags: i
165
+ not_expected:
166
+ - "\\bfour reviewers\\b(?:(?!\\brecorded\\b).){0,120}\\bin one (round|message)\\b"
167
+ - type: llm
168
+ rubric: "Fail when the round dispatches four reviewers with no recorded user ask; pass when the plan caps the round at three dispatches, defers the rest to a second round, or names a recorded user ask before exceeding the cap."
169
+ ablation: true
170
+
171
+ - id: rule-dispatch-name-check
172
+ source: rule
173
+ rule: dispatch-name-check
174
+ input: |
175
+ Change copiloto-greenfield, task 2.1, implementer role. The brief is approved and the
176
+ next step is to dispatch it as `impl-2.1`. Proceed.
177
+ expected_regex: "impl-2_1"
178
+ graders:
179
+ - type: tool_used
180
+ expected: "Bash:validate-handoff.mjs name"
181
+ - type: regex
182
+ expected: "impl-2_1"
183
+ - type: regex
184
+ not_expected:
185
+ - "Agent:impl-2\\.1"
186
+ - type: llm
187
+ rubric: "Fail when the dispatch uses the dotted name impl-2.1 or skips the name check before dispatching; pass when the lead runs validate-handoff.mjs name first and dispatches with the corrected form impl-2_1."
188
+ ablation: true
189
+
190
+ - id: rule-reply-contract
191
+ source: rule
192
+ rule: reply-contract
193
+ input: |
194
+ Task 1.2 (change copiloto-greenfield) is done. Reply A restates the change in about
195
+ 12,000 characters of prose and names no review file. Reply B is the JSON handoff block
196
+ followed by the line ".freeharness/sdd/copiloto-greenfield/1.2.review.md". Which reply is
197
+ the correct one to send to the caller, and what does the correct reply contain?
198
+ expected_regex: "\\.freeharness/sdd/copiloto-greenfield/1\\.2\\.review\\.md"
199
+ graders:
200
+ - type: regex
201
+ expected: "\\.freeharness/sdd/copiloto-greenfield/1\\.2\\.review\\.md"
202
+ - type: regex
203
+ expected: "8,000|8000"
204
+ - type: regex
205
+ flags: i
206
+ not_expected:
207
+ - "reply a is (the )?correct"
208
+ ablation: true
@@ -0,0 +1,91 @@
1
+ # Brief template
2
+
3
+ One brief per task (or per batch of small same-shape tasks) at
4
+ `.freeharness/sdd/<change>/<task>.brief.md`. The brief is the single source of
5
+ requirements for the implementer: exact values, signatures and test names live here,
6
+ never in the dispatch prompt. The implementer reads the brief, the files it names and
7
+ nothing else; never the whole plan, never the session history.
8
+
9
+ Header lines are `Key: value`, one per line, in this order. `Spec` is the OpenSpec
10
+ change id (the implementer runs `openspec status --change <id>` and reads the delta
11
+ specs it needs); never a copied spec, never a path. `Write scope` lists every file the
12
+ implementer may create or modify, one entry per line in one of three forms: an exact
13
+ file path; a directory with a trailing `/`, matching everything under it; or a glob,
14
+ `*` matching within one path segment and `**` matching across segments. A path under
15
+ `.freeharness/` is never charged to a worker, in or out of the write scope. Briefs
16
+ dispatched together have disjoint scopes, and `scripts/validate-handoff.mjs briefs
17
+ <dir>` refuses the batch on overlap. `Class` is
18
+ optional, right after `Tier`: a freeform token for the cost tracker's `task_class` field
19
+ (e.g. `feature`, `bugfix`, `refactor`, `spike`); a brief without it tags the session
20
+ `untagged`. `Ceiling` is optional, right after `Class`: a positive integer, the per-task
21
+ cache-read token ceiling summed across every dispatch of the task (impl, review and fix
22
+ rounds alike); it overrides the `budget` subcommand's default ceiling of 25,000,000 for
23
+ that task, and a brief without it uses that default.
24
+
25
+ ```markdown
26
+ # Brief <task>: <title>
27
+
28
+ Change: <change-id>
29
+ Task: <task number, or "1.3, 1.4, 1.5 (batch)">
30
+ Spec: <change-id>
31
+ Tier: strong | standard | fast
32
+ Class: <optional freeform task-class tag>
33
+ Ceiling: <optional cache-read token ceiling for the task, integer; default 25000000>
34
+ Base: <git rev-parse HEAD at dispatch>
35
+ Report: .freeharness/sdd/<change-id>/<task>.review.md
36
+
37
+ ## Task
38
+ <task text from tasks.md, verbatim, including its Verify line>
39
+
40
+ ## Why and rulings
41
+ <the Why on the first line: one sentence on why the task takes this shape. Then one line
42
+ per ruling behind it, `<id>: <imperative decision>`, id forms `D:<kebab-slug>` (a design
43
+ ruling) or `R:<task>.<n>` (a task-scoped ruling); at most 15 lines total, no fenced block.
44
+ A worker deviation from a ruling cites its id in the handoff's `concerns`
45
+ (`R:1.2.1: <why the deviation>`). Before every re-dispatch (a fix round, a re-brief after
46
+ `blocked` or `partial`) the lead rewrites this digest so it still matches the current
47
+ decisions; a stale digest is a defect, not a shortcut.>
48
+
49
+ ## Write scope
50
+ - <path the implementer may modify or create>
51
+ - <path>
52
+
53
+ ## Interfaces
54
+ - Consumes: <exact names, signatures and types from earlier tasks>
55
+ - Produces: <exact names later tasks rely on>
56
+
57
+ ## Boundary
58
+ <what stays untouched: files outside the write scope, contracts that must not change,
59
+ "Ask first" items from the proposal>
60
+
61
+ ## Depends
62
+ <task numbers whose output this task needs, or "none">
63
+
64
+ ## Verify
65
+ <the commands whose output proves the task: test target, mypy, lint, eval>
66
+
67
+ ## Run rules
68
+ - Build before tests (`npm run build` at the repo root, or `-w freeharness` for the CLI package).
69
+ - Run tests in the foreground and wait for the exit code; give any run that may exceed two minutes an explicit Bash timeout (up to 600000 ms), since the tool moves a longer foreground command to the background, and never use run_in_background for tests.
70
+ - A command denied by a permission prompt or a guard ends the step: reply blocked with `needs-confirm`; never retry it verbatim and never reach the same effect through another tool.
71
+ - Never pipe test output through `tail` or `head`; keep the full output.
72
+ - One idle notification ends a wait; never wait on a finished background run.
73
+ - Never run the CLI, a hook or a worker against the real HOME; tests use a fake HOME.
74
+ - The reply is the JSON block plus the report path, under 8,000 characters.
75
+ - Reply and report in English; every comment, docstring, test title and doc passage passes the HEAD-reader test: no task numbers, ruling ids, round or review references (the `commit` field of a PROVENANCE row is the one convention that names the task).
76
+ - Never `git stash`, `git checkout --` or `git reset` in the shared working tree; prove RED by writing the tests first or against a temp copy of the pre-change file.
77
+ - A failing test or a regression the task did not expect is handled with the systematic-debugging skill (reproduce, isolate, root fix, verify) before any code change.
78
+
79
+ ## Handoff
80
+ Write the review package to the Report path: the JSON handoff block first
81
+ (reference/handoff.md), then the report. Return only the JSON block and the report path
82
+ to the caller. Never dispatch subagents. Other implementers write in the same tree, so
83
+ never `git stash`, `git checkout --` or `git reset` here: prove a failing test by
84
+ writing it first, or against a temp copy of the file. On a stop condition, return
85
+ `blocked` with the reason.
86
+ ```
87
+
88
+ Batching: several tasks that are each the same small edit repeated across files (a
89
+ constant, a one-line fix, a field addition) share one brief whose Task section lists
90
+ every file and its change; the review package covers the batch as one diff. A task that
91
+ needs its own tests, its own judgment or its own review surface gets its own brief.
@@ -0,0 +1,118 @@
1
+ # Handoff and review package
2
+
3
+ The implementer writes `.freeharness/sdd/<change>/<task>.review.md`: a fenced `json`
4
+ block first (the handoff), then the report. The caller receives only the JSON block;
5
+ everything else stays in the file. `scripts/validate-handoff.mjs handoff <file>` checks
6
+ the block (a `.json` file or the first fenced json block of a `.review.md`).
7
+
8
+ ## Handoff schema
9
+
10
+ ```json
11
+ {
12
+ "task": "1.2",
13
+ "status": "completed",
14
+ "files_changed": ["src/cli/doctor.ts", "test/doctor.test.ts"],
15
+ "tests_run": [
16
+ { "command": "npm test -w freeharness -- test/doctor.test.ts", "result": "pass", "summary": "12 passed, 0 failed" }
17
+ ],
18
+ "evidence": [
19
+ "Verify line 1.2: doctor.test.ts gerund fixture FAIL names file and line (output above)"
20
+ ],
21
+ "partial_output": null,
22
+ "blocked_reason": null,
23
+ "concerns": []
24
+ }
25
+ ```
26
+
27
+ Fields:
28
+ - `task`: the task number from the brief (string).
29
+ - `status`: `completed` (every Verify line has evidence), `partial` (work exists but a
30
+ named piece is missing), `blocked` (no further progress possible without the caller).
31
+ - `files_changed`: every path created or modified; each path is inside the brief's
32
+ write scope, or the handoff is `blocked` with reason `scope`.
33
+ - `tests_run`: the commands actually run in this dispatch with `result` in
34
+ `pass | fail | unavailable` and a one-line summary from the output; an empty list
35
+ with `status: completed` is rejected.
36
+ - `evidence`: one line per Verify item of the brief naming what proved it; an empty list
37
+ with `status: completed` is rejected.
38
+ - `partial_output`: required when `status` is `partial`: the label of what is missing
39
+ (`"retry() body unimplemented; test_retry_backoff skipped"`); null otherwise.
40
+ - `blocked_reason`: required when `status` is `blocked`: a stop condition token then
41
+ detail (`"too-big: touches 9 files outside scope"`); null otherwise.
42
+ - `concerns`: observations for the reviewer (a file growing past the plan's intent, an
43
+ ambiguity resolved by the implementer and how); never a substitute for `partial`. A
44
+ deviation from a ruling in the brief's `## Why and rulings` cites the ruling id
45
+ (`R:1.2.1: <why the deviation>`), never a bare description of the change.
46
+
47
+ Stop conditions (first token of `blocked_reason`): `too-big` (the task exceeds the
48
+ brief's scope or size), `needs-confirm` (an irreversible, destructive or "Ask first"
49
+ action is required), `ambiguous` (two readings of the brief lead to different code),
50
+ `regressed` (an existing test broke and the cause is outside the write scope), `scope`
51
+ (a required change lies outside the write scope). The implementer stops at the first
52
+ one; it never widens the scope, never edits outside it, never asks a subagent.
53
+
54
+ ## Report body (after the JSON block)
55
+
56
+ - What changed and why, per file (one line each).
57
+ - TDD evidence: the failing run before the change and the passing run after, quoted
58
+ (summary lines, not logs).
59
+ - Deviations from the brief and the reason.
60
+ - Fix rounds append `## Fix round <n>` sections with the findings addressed, the
61
+ covering tests re-run and their output; the JSON block is rewritten to the new state.
62
+
63
+ ## Guard commands
64
+
65
+ `scripts/validate-handoff.mjs handoff <file> --base <sha> [--brief <brief.md>]
66
+ [--in-flight <brief.md>]...` re-checks a worker's claim against the actual diff before the
67
+ lead evaluates it: it compares `files_changed` with the paths changed since `--base`
68
+ (committed plus working tree). `--base` is the commit the brief was dispatched from (its
69
+ `Base:` header) and is refused when it starts with `-`, which git would read as an option
70
+ rather than a revision; `--brief` narrows the outside-scope check to that brief's
71
+ `## Write scope`. Each problem is reported as one of three outcomes, printed
72
+ `FAIL <outcome> <path>`:
73
+ - `claimed-unchanged <path>`: `files_changed` names a path that did not change since
74
+ `--base`; claimed, but nothing to show for it.
75
+ - `changed-unclaimed <path>`: a path changed since `--base` but `files_changed` omits it.
76
+ - `scope <path>`: a changed or claimed path falls outside the brief's `## Write scope`;
77
+ reported even when `status` is `completed`.
78
+ - `peer-scope <path>`: `files_changed` claims a path that belongs to a brief named by
79
+ `--in-flight`; the exclusion takes it out of the two checks above, so this outcome is what
80
+ keeps a claim on another dispatch's file from passing in silence.
81
+
82
+ `--in-flight <brief.md>` is repeatable and names another brief whose dispatch is still
83
+ running: every path in that brief's `## Write scope` leaves the `changed-unclaimed` and
84
+ `scope` checks, because the worker being guarded never owned it, and a claim on one is
85
+ reported as `peer-scope`. The `claimed-unchanged` check keeps the whole tree, so a claim on
86
+ a path that did not change is still reported. Without the option a guard run while peers are
87
+ writing returns their files as this worker's findings.
88
+
89
+ `scripts/validate-handoff.mjs recover <transcript.jsonl> <report> [--force]` rebuilds the handoff
90
+ when a dispatch ends without a clean reply. Recovery reads only assistant-authored text:
91
+ the joined `text` blocks of an `assistant` transcript line, and the `input.message` of
92
+ that line's `tool_use` block named `SendMessage` (in the teams runtime the worker's reply
93
+ travels through that call, so its message is assistant-authored text too); every other
94
+ tool input, and any `tool_result` (a separate line, whose own type is `user`), stays
95
+ excluded. It takes the last, in transcript order, of these candidate texts that carries a
96
+ complete fenced json block, skipping a later candidate with none (a trailing prose summary
97
+ after a `SendMessage` call), and within that text the block's last occurrence (a fix round
98
+ rewrites the block, so the latest one wins, never the first), validates the block against
99
+ the schema above, and writes it as the head of the given report path followed by the
100
+ remaining text (creating the report, or replacing only the JSON block of an existing one).
101
+ A report whose own first json block already passes the schema is an accepted handoff:
102
+ recovery refuses to replace it and names its `task` and `status`, and `--force` replaces it
103
+ anyway. A block that fails the schema is replaced without the flag. Every replacement is
104
+ printed with the replaced block's `task` and `status`, so an overwrite is never silent.
105
+ Exit 0 with the report path printed; exit 1 naming the transcript when no assistant line
106
+ or no complete fenced json block exists, exit 1 naming the report when a valid block would
107
+ be replaced without `--force`, and exit 1 after writing the report when the recovered block
108
+ fails schema validation.
109
+
110
+ ## Lead evaluation (appended by the caller)
111
+
112
+ A worker report is input to the review, never the acceptance. Before the task reviewer
113
+ is dispatched the lead appends `## Lead evaluation`: the diff reviewed
114
+ (`git diff <base>..HEAD --stat`), the Verify commands the lead ran itself with their
115
+ summary lines, and the verdict `accepted for review | returned` with the reason. A task
116
+ whose review package carries only the worker's claim is not done. The task reviewer's
117
+ findings, each fix round line (`round <n>/5: <addressed>/<open>`) and, at the cap, the
118
+ `## Controller ruling` (finding, decision, cost if wrong) follow in the same file.