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.
- package/LICENSE +21 -0
- package/NOTICE +108 -0
- package/README.md +134 -0
- package/canonical/HARVEST.yaml +858 -0
- package/canonical/PROVENANCE.yaml +740 -0
- package/canonical/agents/README.md +95 -0
- package/canonical/agents/agentic-architect.md +18 -0
- package/canonical/agents/database-reviewer.md +41 -0
- package/canonical/agents/explorer-ai-engineer-analyst.md +65 -0
- package/canonical/agents/pr-reviewer.md +96 -0
- package/canonical/agents/python-reviewer.md +55 -0
- package/canonical/agents/report-formatter.md +19 -0
- package/canonical/agents/security-reviewer.md +53 -0
- package/canonical/agents/test-writer.md +34 -0
- package/canonical/commands/fh-context.md +37 -0
- package/canonical/evals/promptfoo.redteam.yaml +108 -0
- package/canonical/hooks/cost-prices.json +14 -0
- package/canonical/hooks/freeharness-auto-memory.mjs +158 -0
- package/canonical/hooks/freeharness-config-guard.mjs +162 -0
- package/canonical/hooks/freeharness-context-monitor.mjs +198 -0
- package/canonical/hooks/freeharness-converge.mjs +227 -0
- package/canonical/hooks/freeharness-cost-tracker.mjs +1027 -0
- package/canonical/hooks/freeharness-memory-guard.mjs +57 -0
- package/canonical/hooks/freeharness-output-pruner.mjs +333 -0
- package/canonical/hooks/freeharness-precompact.mjs +323 -0
- package/canonical/hooks/freeharness-repeat-tool.mjs +208 -0
- package/canonical/hooks/freeharness-security-guidance.mjs +164 -0
- package/canonical/hooks/freeharness-session-start +583 -0
- package/canonical/hooks/hooks.auto-memory.claude-code.json +16 -0
- package/canonical/hooks/hooks.claude-code.json +17 -0
- package/canonical/hooks/hooks.config-guard.claude-code.json +16 -0
- package/canonical/hooks/hooks.context-monitor.claude-code.json +15 -0
- package/canonical/hooks/hooks.converge.claude-code.json +15 -0
- package/canonical/hooks/hooks.cost-tracker.claude-code.json +37 -0
- package/canonical/hooks/hooks.memory-guard.claude-code.json +16 -0
- package/canonical/hooks/hooks.output-pruner.claude-code.json +16 -0
- package/canonical/hooks/hooks.precompact.claude-code.json +15 -0
- package/canonical/hooks/hooks.repeat-tool.claude-code.json +25 -0
- package/canonical/hooks/hooks.security-guidance.claude-code.json +16 -0
- package/canonical/mcp/servers.json +20 -0
- package/canonical/openspec/config.base.yaml +89 -0
- package/canonical/openspec/schema.spec-driven.yaml +277 -0
- package/canonical/openspec/templates/data-contract.md +36 -0
- package/canonical/openspec/templates/design.md +84 -0
- package/canonical/openspec/templates/eval-plan.md +33 -0
- package/canonical/openspec/templates/follow-ups.md +2 -0
- package/canonical/openspec/templates/proposal.md +45 -0
- package/canonical/openspec/templates/spec.md +42 -0
- package/canonical/openspec/templates/tasks.md +38 -0
- package/canonical/profiles/local-llamacpp.LOCAL-MODELS.md +47 -0
- package/canonical/profiles/local-llamacpp.json +27 -0
- package/canonical/profiles/local-ollama.json +20 -0
- package/canonical/profiles/mcp.json +91 -0
- package/canonical/rules/CLAUDE.md +78 -0
- package/canonical/rules/project-CLAUDE.template.md +62 -0
- package/canonical/rules/routing.md +20 -0
- package/canonical/rules/safety.md +41 -0
- package/canonical/settings/settings.cache-hygiene.claude-code.json +5 -0
- package/canonical/skills/agent-evaluation/SKILL.md +102 -0
- package/canonical/skills/agent-evaluation/assets/evaluation_report_template.md +206 -0
- package/canonical/skills/agent-evaluation/evals/cases.yaml +106 -0
- package/canonical/skills/agent-evaluation/references/dataset-preparation.md +351 -0
- package/canonical/skills/agent-evaluation/references/scorers-constraints.md +165 -0
- package/canonical/skills/agent-evaluation/references/scorers.md +431 -0
- package/canonical/skills/agent-evaluation/references/setup-guide.md +252 -0
- package/canonical/skills/agent-evaluation/references/tracing-integration.md +164 -0
- package/canonical/skills/agent-evaluation/references/troubleshooting.md +514 -0
- package/canonical/skills/agent-evaluation/scripts/analyze_results.py +462 -0
- package/canonical/skills/agent-evaluation/scripts/create_dataset_template.py +382 -0
- package/canonical/skills/agent-evaluation/scripts/list_datasets.py +273 -0
- package/canonical/skills/agent-evaluation/scripts/run_evaluation_template.py +309 -0
- package/canonical/skills/agent-evaluation/scripts/setup_mlflow.py +353 -0
- package/canonical/skills/agent-evaluation/scripts/utils/__init__.py +27 -0
- package/canonical/skills/agent-evaluation/scripts/utils/env_validation.py +123 -0
- package/canonical/skills/agent-evaluation/scripts/utils/tracing_utils.py +108 -0
- package/canonical/skills/agent-evaluation/scripts/validate_agent_tracing.py +148 -0
- package/canonical/skills/agent-evaluation/scripts/validate_auth.py +240 -0
- package/canonical/skills/agent-evaluation/scripts/validate_environment.py +185 -0
- package/canonical/skills/agent-evaluation/scripts/validate_tracing_runtime.py +318 -0
- package/canonical/skills/agentic-architecture/SKILL.md +41 -0
- package/canonical/skills/agentic-architecture/evals/cases.yaml +94 -0
- package/canonical/skills/agentic-architecture/reference/context-engineering.md +75 -0
- package/canonical/skills/agentic-architecture/reference/patterns.md +76 -0
- package/canonical/skills/agentic-architecture/reference/reliability-observability.md +94 -0
- package/canonical/skills/agentic-architecture/reference/review-framework.md +59 -0
- package/canonical/skills/code-review/SKILL.md +52 -0
- package/canonical/skills/code-review/evals/cases.yaml +197 -0
- package/canonical/skills/git-workflow/SKILL.md +41 -0
- package/canonical/skills/git-workflow/evals/cases.yaml +92 -0
- package/canonical/skills/local-code/SKILL.md +24 -0
- package/canonical/skills/local-code/evals/cases.yaml +85 -0
- package/canonical/skills/local-code/scripts/query_llama.py +68 -0
- package/canonical/skills/report-formatting/SKILL.md +62 -0
- package/canonical/skills/report-formatting/evals/cases.yaml +83 -0
- package/canonical/skills/report-formatting/reference/ARCHITECTURE.md +135 -0
- package/canonical/skills/report-formatting/reference/HELPERS.md +120 -0
- package/canonical/skills/report-formatting/reference/PPTX.md +136 -0
- package/canonical/skills/report-formatting/reference/RELEASE.md +99 -0
- package/canonical/skills/report-formatting/reference/TEMPLATES.md +48 -0
- package/canonical/skills/report-formatting/reference/authoring.md +66 -0
- package/canonical/skills/report-formatting/scripts/architecture-template.md +271 -0
- package/canonical/skills/report-formatting/scripts/assets/claro-logo.png +0 -0
- package/canonical/skills/report-formatting/scripts/assets/claro-wordmark.svg +1 -0
- package/canonical/skills/report-formatting/scripts/build-architecture.js +57 -0
- package/canonical/skills/report-formatting/scripts/build-md-claro.js +224 -0
- package/canonical/skills/report-formatting/scripts/build-release.js +51 -0
- package/canonical/skills/report-formatting/scripts/check-env.js +58 -0
- package/canonical/skills/report-formatting/scripts/docmodel.js +283 -0
- package/canonical/skills/report-formatting/scripts/example-build.js +119 -0
- package/canonical/skills/report-formatting/scripts/example_build_ArchitectureReview_docx.js +195 -0
- package/canonical/skills/report-formatting/scripts/example_build_ExecutiveReport_docx.js +114 -0
- package/canonical/skills/report-formatting/scripts/package.json +17 -0
- package/canonical/skills/report-formatting/scripts/pptx/example_build_StatusReport_pptx.py +223 -0
- package/canonical/skills/report-formatting/scripts/pptx/example_build_WeeklyStatus_pptx.py +245 -0
- package/canonical/skills/report-formatting/scripts/pptx/pptx_office.py +144 -0
- package/canonical/skills/report-formatting/scripts/pptx/requirements.txt +7 -0
- package/canonical/skills/report-formatting/scripts/pptx/status_report_blocks.py +193 -0
- package/canonical/skills/report-formatting/scripts/pptx/theme_claro_pptx.py +473 -0
- package/canonical/skills/report-formatting/scripts/release-template.md +80 -0
- package/canonical/skills/report-formatting/scripts/render-mermaid.js +105 -0
- package/canonical/skills/report-formatting/scripts/theme-claro.js +403 -0
- package/canonical/skills/subagent-driven-development/SKILL.md +60 -0
- package/canonical/skills/subagent-driven-development/evals/cases.yaml +208 -0
- package/canonical/skills/subagent-driven-development/reference/brief.md +91 -0
- package/canonical/skills/subagent-driven-development/reference/handoff.md +118 -0
- package/canonical/skills/subagent-driven-development/scripts/validate-handoff.mjs +850 -0
- package/canonical/skills/systematic-debugging/SKILL.md +44 -0
- package/canonical/skills/systematic-debugging/evals/cases.yaml +90 -0
- package/canonical/skills/test-driven-development/SKILL.md +42 -0
- package/canonical/skills/test-driven-development/evals/cases.yaml +86 -0
- package/canonical/skills/test-driven-development/reference/writing-good-tests.md +52 -0
- package/canonical/skills/verification-before-completion/SKILL.md +53 -0
- package/canonical/skills/verification-before-completion/evals/cases.yaml +107 -0
- package/dist/adapters/content/language-lint.d.ts +46 -0
- package/dist/adapters/content/language-lint.js +191 -0
- package/dist/adapters/harness/claude-code.d.ts +57 -0
- package/dist/adapters/harness/claude-code.js +385 -0
- package/dist/adapters/harness/index.d.ts +3 -0
- package/dist/adapters/harness/index.js +17 -0
- package/dist/adapters/harness/opencode.d.ts +7 -0
- package/dist/adapters/harness/opencode.js +166 -0
- package/dist/adapters/harness/plugin.d.ts +22 -0
- package/dist/adapters/harness/plugin.js +257 -0
- package/dist/adapters/memory/doctor.d.ts +480 -0
- package/dist/adapters/memory/doctor.js +1217 -0
- package/dist/adapters/memory/vendored.d.ts +150 -0
- package/dist/adapters/memory/vendored.js +487 -0
- package/dist/adapters/package/node.d.ts +9 -0
- package/dist/adapters/package/node.js +20 -0
- package/dist/adapters/prompt/readline.d.ts +19 -0
- package/dist/adapters/prompt/readline.js +53 -0
- package/dist/adapters/sync/diff.d.ts +43 -0
- package/dist/adapters/sync/diff.js +380 -0
- package/dist/cli/cleanup.d.ts +86 -0
- package/dist/cli/cleanup.js +382 -0
- package/dist/cli/cost.d.ts +304 -0
- package/dist/cli/cost.js +501 -0
- package/dist/cli/doctor.d.ts +205 -0
- package/dist/cli/doctor.js +654 -0
- package/dist/cli/executor.d.ts +5 -0
- package/dist/cli/executor.js +48 -0
- package/dist/cli/plugin-validate.d.ts +37 -0
- package/dist/cli/plugin-validate.js +256 -0
- package/dist/cli/prefix.d.ts +68 -0
- package/dist/cli/prefix.js +218 -0
- package/dist/cli/profile.d.ts +170 -0
- package/dist/cli/profile.js +285 -0
- package/dist/cli/runner.d.ts +10 -0
- package/dist/cli/runner.js +27 -0
- package/dist/cli/uninstall.d.ts +65 -0
- package/dist/cli/uninstall.js +147 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +989 -0
- package/dist/infra/dogfood.d.ts +31 -0
- package/dist/infra/dogfood.js +51 -0
- package/dist/infra/fsutil.d.ts +40 -0
- package/dist/infra/fsutil.js +143 -0
- package/dist/infra/manifest.d.ts +76 -0
- package/dist/infra/manifest.js +92 -0
- package/dist/infra/paths.d.ts +19 -0
- package/dist/infra/paths.js +74 -0
- package/dist/infra/routing.d.ts +4 -0
- package/dist/infra/routing.js +7 -0
- package/node_modules/@freeharness/core/dist/context.d.ts +30 -0
- package/node_modules/@freeharness/core/dist/context.js +1 -0
- package/node_modules/@freeharness/core/dist/index.d.ts +5 -0
- package/node_modules/@freeharness/core/dist/index.js +6 -0
- package/node_modules/@freeharness/core/dist/planner.d.ts +13 -0
- package/node_modules/@freeharness/core/dist/planner.js +18 -0
- package/node_modules/@freeharness/core/dist/ports.d.ts +90 -0
- package/node_modules/@freeharness/core/dist/ports.js +1 -0
- package/node_modules/@freeharness/core/dist/registry.d.ts +41 -0
- package/node_modules/@freeharness/core/dist/registry.js +124 -0
- package/node_modules/@freeharness/core/dist/tiers.d.ts +30 -0
- package/node_modules/@freeharness/core/dist/tiers.js +99 -0
- package/node_modules/@freeharness/core/package.json +34 -0
- package/node_modules/@freeharness/sdd/PROVENANCE.yaml +175 -0
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.d.ts +2 -0
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.js +166 -0
- package/node_modules/@freeharness/sdd/dist/src/index.d.ts +14 -0
- package/node_modules/@freeharness/sdd/dist/src/index.js +11 -0
- package/node_modules/@freeharness/sdd/dist/src/init.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/src/init.js +190 -0
- package/node_modules/@freeharness/sdd/dist/src/root-resolver.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/src/root-resolver.js +32 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.d.ts +81 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.js +483 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/context.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/context.js +48 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.d.ts +57 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.js +279 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.d.ts +67 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.js +460 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/list.d.ts +5 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/list.js +95 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.js +150 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/schemas.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/schemas.js +23 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.d.ts +56 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.js +140 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/status.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/status.js +85 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.js +229 -0
- package/node_modules/@freeharness/sdd/dist/src/validate-change.d.ts +40 -0
- package/node_modules/@freeharness/sdd/dist/src/validate-change.js +114 -0
- package/node_modules/@freeharness/sdd/dist/src/validate.d.ts +24 -0
- package/node_modules/@freeharness/sdd/dist/src/validate.js +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.d.ts +130 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.js +981 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.d.ts +46 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.js +128 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.d.ts +26 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.js +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.d.ts +50 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.js +394 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.d.ts +15 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.js +49 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.d.ts +71 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.js +164 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.js +21 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.d.ts +102 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.js +230 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.d.ts +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.js +138 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.d.ts +82 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.js +333 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.js +110 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.js +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.d.ts +33 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.js +149 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.js +49 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.js +31 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.d.ts +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.js +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.js +26 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.d.ts +28 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.js +41 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.d.ts +23 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.js +25 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.d.ts +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.js +76 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.js +53 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.d.ts +62 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.js +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.d.ts +35 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.js +47 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.d.ts +33 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.js +55 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.js +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.d.ts +48 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.js +99 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.d.ts +19 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.js +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.d.ts +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.js +4 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.d.ts +19 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.js +207 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.js +409 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.js +673 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.js +230 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.js +550 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.js +107 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.js +228 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.js +147 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.js +571 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.js +322 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.d.ts +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.js +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.js +518 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.js +176 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.js +344 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.js +54 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.d.ts +35 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.js +171 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.d.ts +27 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.js +210 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.d.ts +14 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.js +48 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.d.ts +22 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.js +186 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.d.ts +65 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.js +409 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.d.ts +55 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.js +98 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.js +77 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.d.ts +44 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.js +116 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.js +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.d.ts +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.js +30 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.d.ts +3 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.js +3 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.js +14 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.js +114 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.d.ts +45 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.js +105 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.d.ts +15 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.js +56 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.js +1 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.d.ts +94 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.js +756 -0
- package/node_modules/@freeharness/sdd/package.json +57 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/LICENSE.upstream +22 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/schema.upstream.yaml +232 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/README.md +19 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-apply-change/SKILL.md +187 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-archive-change/SKILL.md +181 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-bulk-archive-change/SKILL.md +338 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-continue-change/SKILL.md +117 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-explore/SKILL.md +342 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-ff-change/SKILL.md +116 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-new-change/SKILL.md +76 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-onboard/SKILL.md +560 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-propose/SKILL.md +162 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-sync-specs/SKILL.md +261 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-update-change/SKILL.md +90 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-verify-change/SKILL.md +174 -0
- package/package.json +70 -0
- package/provenance/canonical.PROVENANCE.yaml +740 -0
- package/provenance/claude-mem.LICENSE.upstream +202 -0
- package/provenance/memory.PROVENANCE.yaml +399 -0
- package/provenance/sdd.PROVENANCE.yaml +175 -0
- package/vendor-licenses/caveman.LICENSE +27 -0
- package/vendor-licenses/deepseek-harness.LICENSE +21 -0
- package/vendor-licenses/ecc.LICENSE +21 -0
- package/vendor-licenses/pi.LICENSE +21 -0
- 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.
|