freeharness 0.4.1 → 0.4.2
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/README.md +8 -7
- package/canonical/HARVEST.yaml +25 -14
- package/canonical/PROVENANCE.yaml +1 -1
- package/canonical/agents/README.md +77 -36
- package/canonical/agents/agentic-architect.md +2 -1
- package/canonical/agents/database-reviewer.md +6 -8
- package/canonical/agents/explorer-ai-engineer-analyst.md +2 -6
- package/canonical/agents/implementer.md +30 -0
- package/canonical/agents/pr-reviewer.md +9 -11
- package/canonical/agents/python-reviewer.md +7 -9
- package/canonical/agents/report-formatter.md +7 -3
- package/canonical/agents/security-reviewer.md +7 -8
- package/canonical/agents/test-writer.md +5 -2
- package/canonical/hooks/cost-prices.json +11 -9
- package/canonical/hooks/freeharness-config-guard.mjs +8072 -87
- package/canonical/hooks/freeharness-context-monitor.mjs +88 -54
- package/canonical/hooks/freeharness-converge.mjs +78 -23
- package/canonical/hooks/freeharness-cost-tracker.mjs +1129 -218
- package/canonical/hooks/freeharness-memory-guard.mjs +20 -23
- package/canonical/hooks/freeharness-precompact.mjs +217 -87
- package/canonical/hooks/freeharness-quota-tap.mjs +173 -0
- package/canonical/hooks/freeharness-reload-context.mjs +197 -0
- package/canonical/hooks/freeharness-repeat-tool.mjs +1 -1
- package/canonical/hooks/freeharness-sdd-context.mjs +970 -0
- package/canonical/hooks/freeharness-session-start +297 -59
- package/canonical/hooks/hooks.claude-code.json +1 -1
- package/canonical/hooks/hooks.config-guard.claude-code.json +3 -2
- package/canonical/hooks/hooks.context-monitor.claude-code.json +1 -1
- package/canonical/hooks/hooks.converge.claude-code.json +1 -1
- package/canonical/hooks/hooks.memory-guard.claude-code.json +3 -2
- package/canonical/hooks/hooks.reload-context.claude-code.json +15 -0
- package/canonical/openspec/schema.spec-driven.yaml +29 -8
- package/canonical/openspec/templates/follow-ups.md +3 -2
- package/canonical/openspec/templates/proposal.md +1 -1
- package/canonical/openspec/templates/tasks.md +8 -0
- package/canonical/rules/CLAUDE.md +5 -4
- package/canonical/rules/routing.md +10 -9
- package/canonical/skills/agent-evaluation/SKILL.md +17 -6
- package/canonical/skills/agent-evaluation/evals/cases.yaml +38 -23
- package/canonical/skills/agentic-architecture/SKILL.md +4 -0
- package/canonical/skills/agentic-architecture/evals/cases.yaml +27 -0
- package/canonical/skills/code-review/SKILL.md +9 -2
- package/canonical/skills/code-review/evals/cases.yaml +1118 -27
- package/canonical/skills/git-workflow/SKILL.md +2 -0
- package/canonical/skills/local-code/SKILL.md +2 -2
- package/canonical/skills/local-code/evals/cases.yaml +1 -1
- package/canonical/skills/report-formatting/SKILL.md +10 -2
- package/canonical/skills/report-formatting/reference/ARCHITECTURE.md +3 -3
- package/canonical/skills/report-formatting/reference/HELPERS.md +10 -5
- package/canonical/skills/report-formatting/reference/RELEASE.md +1 -2
- package/canonical/skills/report-formatting/reference/TEMPLATES.md +3 -2
- package/canonical/skills/report-formatting/reference/authoring.md +25 -37
- package/canonical/skills/report-formatting/scripts/build-architecture.js +1 -1
- package/canonical/skills/report-formatting/scripts/build-md-claro.js +5 -8
- package/canonical/skills/report-formatting/scripts/check-env.js +0 -4
- package/canonical/skills/report-formatting/scripts/docmodel.js +3 -11
- package/canonical/skills/report-formatting/scripts/example-build.js +8 -10
- package/canonical/skills/report-formatting/scripts/example_build_ArchitectureReview_docx.js +8 -10
- package/canonical/skills/report-formatting/scripts/example_build_ExecutiveReport_docx.js +8 -10
- package/canonical/skills/report-formatting/scripts/theme-claro.js +39 -10
- package/canonical/skills/subagent-driven-development/SKILL.md +35 -28
- package/canonical/skills/subagent-driven-development/evals/cases.yaml +3496 -19
- package/canonical/skills/subagent-driven-development/reference/brief.md +185 -35
- package/canonical/skills/subagent-driven-development/reference/handoff.md +82 -2
- package/canonical/skills/subagent-driven-development/reference/loop.md +57 -0
- package/canonical/skills/subagent-driven-development/reference/trees.md +40 -0
- package/canonical/skills/subagent-driven-development/reference/workspace.md +31 -0
- package/canonical/skills/subagent-driven-development/scripts/validate-handoff.mjs +4771 -326
- package/dist/adapters/harness/claude-code.d.ts +19 -3
- package/dist/adapters/harness/claude-code.js +204 -39
- package/dist/adapters/harness/opencode.js +16 -2
- package/dist/adapters/harness/plugin.js +28 -17
- package/dist/adapters/memory/doctor.d.ts +174 -29
- package/dist/adapters/memory/doctor.js +758 -134
- package/dist/adapters/memory/migrate.d.ts +95 -0
- package/dist/adapters/memory/migrate.js +497 -0
- package/dist/adapters/memory/paths.d.ts +22 -0
- package/dist/adapters/memory/paths.js +85 -0
- package/dist/adapters/memory/vendored.d.ts +56 -29
- package/dist/adapters/memory/vendored.js +191 -154
- package/dist/adapters/sync/diff.js +4 -1
- package/dist/cli/cleanup-prompt.d.ts +35 -0
- package/dist/cli/cleanup-prompt.js +68 -0
- package/dist/cli/cleanup.d.ts +22 -24
- package/dist/cli/cleanup.js +182 -68
- package/dist/cli/cost-quota.d.ts +158 -0
- package/dist/cli/cost-quota.js +645 -0
- package/dist/cli/cost.d.ts +408 -46
- package/dist/cli/cost.js +1731 -57
- package/dist/cli/doctor.d.ts +52 -13
- package/dist/cli/doctor.js +193 -44
- package/dist/cli/hard-cleanup.d.ts +93 -0
- package/dist/cli/hard-cleanup.js +552 -0
- package/dist/cli/install-facts.d.ts +28 -0
- package/dist/cli/install-facts.js +66 -0
- package/dist/cli/json-key-edit.d.ts +18 -0
- package/dist/cli/json-key-edit.js +118 -0
- package/dist/cli/memory-import.d.ts +74 -0
- package/dist/cli/memory-import.js +469 -0
- package/dist/cli/plugin-validate.d.ts +12 -0
- package/dist/cli/plugin-validate.js +43 -0
- package/dist/cli/uninstall.d.ts +1 -1
- package/dist/cli/uninstall.js +2 -2
- package/dist/cli/upstream-launchers.d.ts +49 -0
- package/dist/cli/upstream-launchers.js +287 -0
- package/dist/index.js +247 -70
- package/dist/infra/fsutil.d.ts +31 -3
- package/dist/infra/fsutil.js +69 -6
- package/dist/infra/manifest.d.ts +2 -1
- package/dist/infra/manifest.js +3 -2
- package/dist/infra/prices.d.ts +18 -0
- package/dist/infra/prices.js +64 -0
- package/node_modules/@freeharness/core/dist/tiers.d.ts +10 -1
- package/node_modules/@freeharness/core/dist/tiers.js +24 -2
- package/node_modules/@freeharness/core/package.json +1 -1
- package/node_modules/@freeharness/sdd/PROVENANCE.yaml +279 -2
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.js +34 -8
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.d.ts +7 -6
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.js +72 -64
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.d.ts +48 -16
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.js +168 -70
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.d.ts +36 -6
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.js +110 -49
- package/node_modules/@freeharness/sdd/dist/src/shim/list.d.ts +1 -1
- package/node_modules/@freeharness/sdd/dist/src/shim/list.js +57 -14
- package/node_modules/@freeharness/sdd/dist/src/shim/nested-change.d.ts +7 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/nested-change.js +118 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.js +3 -1
- package/node_modules/@freeharness/sdd/dist/src/shim/proposal-capabilities.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/proposal-capabilities.js +94 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.js +182 -1
- package/node_modules/@freeharness/sdd/dist/src/shim/status.d.ts +2 -2
- package/node_modules/@freeharness/sdd/dist/src/shim/status.js +34 -5
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.js +49 -41
- package/node_modules/@freeharness/sdd/dist/src/shim/warnings.d.ts +21 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/warnings.js +66 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/line-endings.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/line-endings.js +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.js +95 -22
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.js +14 -6
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.d.ts +1 -1
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.js +1 -1
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.d.ts +3 -3
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.js +24 -4
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.js +4 -7
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.js +13 -1
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.js +21 -6
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.js +80 -19
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.js +42 -22
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/project-root.d.ts +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/project-root.js +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.js +16 -9
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.js +36 -1
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.js +65 -30
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.d.ts +1 -1
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.js +1 -1
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.d.ts +8 -13
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.js +79 -102
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.js +4 -9
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.d.ts +50 -10
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.js +165 -37
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.d.ts +24 -3
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.js +55 -8
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.js +4 -1
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.js +19 -9
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.d.ts +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.js +115 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.d.ts +3 -3
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.js +20 -20
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.js +75 -14
- package/node_modules/@freeharness/sdd/package.json +1 -1
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/schema.upstream.yaml +47 -7
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-apply-change/SKILL.md +25 -7
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-archive-change/SKILL.md +50 -11
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-bulk-archive-change/SKILL.md +48 -10
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-continue-change/SKILL.md +27 -7
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-explore/SKILL.md +25 -12
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-ff-change/SKILL.md +17 -5
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-new-change/SKILL.md +12 -1
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-onboard/SKILL.md +47 -33
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-propose/SKILL.md +17 -5
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-sync-specs/SKILL.md +29 -1
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-update-change/SKILL.md +31 -13
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-verify-change/SKILL.md +75 -27
- package/package.json +6 -4
- package/provenance/canonical.PROVENANCE.yaml +1 -1
- package/provenance/memory.PROVENANCE.yaml +458 -6
- package/provenance/sdd.PROVENANCE.yaml +279 -2
- package/canonical/hooks/freeharness-auto-memory.mjs +0 -158
- package/canonical/hooks/hooks.auto-memory.claude-code.json +0 -16
|
@@ -1,60 +1,67 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: subagent-driven-development
|
|
3
|
-
description: Use when executing an approved tasks.md from an OpenSpec change: one brief per task under .freeharness/sdd/<change>/, a fresh implementer per dispatch
|
|
3
|
+
description: Use when executing an approved tasks.md from an OpenSpec change: one small brief per task under .freeharness/sdd/<change>/, a fresh implementer per dispatch routed by class, tier and effort with a disjoint write scope and acceptance probes, a JSON handoff, the lead's own test run and diff review, one combined task reviewer, fix rounds only for blocking findings, a round-cap circuit breaker and one final branch review via code-review. Not for ad-hoc one-file edits.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Subagent-Driven Development Protocol
|
|
7
7
|
|
|
8
8
|
<orchestrator_directive>
|
|
9
|
-
The primary session is the lead: it dispatches, evaluates and rules; it never writes production code while
|
|
9
|
+
The primary session is the lead: it dispatches, evaluates and rules; it never writes production code while running `tasks.md`. A feature starts at `/opsx:propose`; this skill runs the approved `tasks.md` after `/opsx:apply`. Continuous execution: no "should I continue?" between tasks; only the stop conditions below pause it.
|
|
10
10
|
</orchestrator_directive>
|
|
11
11
|
|
|
12
12
|
<workspace>
|
|
13
|
-
- Artifacts live in `.freeharness/sdd/<change
|
|
14
|
-
- Templates: `reference/brief.md`, `reference/handoff.md
|
|
13
|
+
- Artifacts live in `.freeharness/sdd/<change>/`: `<task>.brief.md` and `<task>.review.md`, plus the ledger, state and round-base files. Files survive compaction; trust the review packages, `tasks.md` checkboxes and `git log`, never recollection.
|
|
14
|
+
- Templates: `reference/brief.md`, `reference/handoff.md`; the tier map is the emitted `reference/tiers.md`; the validator is `scripts/validate-handoff.mjs`. Read reference/workspace.md when the run starts or a validator subcommand's arguments are needed.
|
|
15
|
+
- Preflight, before task 1: scan pairs of tasks sharing a file or an interface and rule on conflicts in a `## Preflight` note of the first review package.
|
|
15
16
|
- Worker rules, restated in every brief: 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), and never dispatch a subagent.
|
|
16
|
-
-
|
|
17
|
+
- Lead context rules: run `name`, `briefs` and `budget` for a dispatch in one Bash call and every `openspec follow-up add` of a task close in one Bash call; per round read the `git diff --stat`, the guard output and the gate output only, and read the full task diff once, at acceptance; never paste a worker transcript or a full diff into the conversation when a file path serves; run `/compact` at a task boundary once the lead context passes 200,000 tokens; the workspace files carry the state.
|
|
17
18
|
</workspace>
|
|
18
19
|
|
|
19
20
|
<dispatch>
|
|
20
|
-
1. Brief:
|
|
21
|
-
2.
|
|
22
|
-
3.
|
|
23
|
-
4. Dispatch a fresh implementer with the brief path, the report path and the interfaces earlier tasks produced; nothing from the session history. The implementer follows `test-driven-development`; dispatch `test-writer` for the RED step when the failing tests are non-trivial. Record `Base:` (`git rev-parse HEAD`) before dispatching.
|
|
24
|
-
5.
|
|
25
|
-
6. Dispatch names follow `<role>-<task>[-r<round>][-<slug>]`: `impl-2_3`, `fix-2_3-r2`, `impl-
|
|
26
|
-
7. Budget: run `validate-handoff.mjs budget <ledger.jsonl> <task>` before every dispatch of a task, and again when its handoff is accepted
|
|
27
|
-
8. Rewrite the brief's `## Why and rulings` digest before every re-dispatch (a fix round, a re-brief after `partial` or `blocked`) so it still matches the current decisions; a deviation the handoff does not cite is a reviewer P0 tagged `why-digest`.
|
|
28
|
-
9. No nested subagents: a worker never dispatches helpers or reviewers; a worker-spawned reviewer is a defect
|
|
21
|
+
1. Brief: start `<task>.brief.md` with `validate-handoff.mjs brief-init <change> <task>` and fill every `<fill: ...>` placeholder it leaves (the template stays the source of the fixed parts; `briefs` refuses one left); one task id per brief and per dispatch, never a batch. Header `Spec:` is the OpenSpec change id, never a copied spec; `Tier:` is explicit on every dispatch. Route by `Class:`: `docs`, `extraction`, `exploration` and `mechanical` (documentation, extraction, exploration, mechanical edits such as matrix rows, renames, one-line values and transcription of complete plan text) run on standard or strong; `summary` on fast, standard or strong, and `extraction` also on fast; `security` (a task that changes a security boundary: a guard, a hook verdict, an auth or secret path, input validation of untrusted payloads) and `complex` (a parser or state machine, concurrency, a cross-file contract, or a task that reached the round cap before; a validator tokenizer or collector edit routes as `complex` unless it changes a verdict a legitimate worker command reaches; lead-written files owe no hostile-input tests) run on strong with `Effort: high` only; `code` (a code change that is neither `security` nor `complex`) runs on strong, or on standard only with `Route: C1-C7 - <reason>` per `reference/brief.md`; any other class, or none, runs on strong only. A fast brief's reading set stays under 100,000 tokens at 4 bytes per token; the validator checks the class, never that bound. A fix round's tier and effort are what `validate-handoff.mjs route <brief> --round <n> [--p0] [--security]` prints (`--p0` or `--security` for a round carrying such a finding), and `round-base` given the same flags refuses a brief below them. `Effort:` is `medium` (default) or `high`, `high` on strong only. Write scope names every file the worker may touch. Read reference/loop.md when a brief is written: the sizing bounds and the split rule, the fixture scope, the grep for statements pinning a changed value, and the class ceilings.
|
|
22
|
+
2. Probes and project rules: before the dispatch write `## Acceptance probes` (1 to 12 lines, `P<n>: <command, input or observable> -> <expected outcome>`) from the spec scenarios and the design's edge cases; a `security` or `complex` brief carries one probe expecting an allow or a pass and one corpus, fixture replay or generator probe. Fill `## Project rules` (1 to 20 lines) from the project CLAUDE.md invariants and protected boundaries that bear on the write scope plus the artifact rules; workers run without CLAUDE.md, so the section is their only copy. A probe of a guard or hook verdict runs the hook through node on a payload file (reference/brief.md).
|
|
23
|
+
3. Disjoint write scopes: run `validate-handoff.mjs briefs` over the dispatch; any overlap refuses the whole batch naming the file, so no two implementers in flight share a file.
|
|
24
|
+
4. Dispatch a fresh `implementer` agent with the brief path, the report path and the interfaces earlier tasks produced; nothing from the session history. On every implementer, test-writer and fix dispatch the per-dispatch model is the brief's `Tier:` resolved through `reference/tiers.md` (the alias the tier maps to; never a model name in this skill) and the per-dispatch effort is the brief's `Effort:` (`medium` when absent); the agent frontmatter is never the source of a brief's effort. An omitted per-dispatch model falls back to the implementer agent's tier. A per-dispatch effort overrides the frontmatter effort. A team dispatch inherits the session effort, except a plugin-defined agent spawned by name, which keeps its own; the agent frontmatter effort applies to plain subagent dispatches. The implementer follows `test-driven-development`; dispatch `test-writer` for the RED step when the failing tests are non-trivial. Record `Base:` (`git rev-parse HEAD`) before dispatching. Reviewers and implementers are never resumed: every review, re-review and fix round is a fresh dispatch. Dispatch every implementer, test-writer and reviewer through the Agent tool without `name`: the prompt's first line is `Dispatch: <dispatch-name>` and the Agent tool `description` repeats it. A named dispatch launches as a teammate when agent teams are enabled, at the session effort by the team rule above and with no SubagentStop until shutdown; without `name` it stays a plain subagent.
|
|
25
|
+
5. Band of implementers in flight: small, at most 4 (the default); medium, at most 8; large, at most 12, only on the user's ask recorded in the review package with the latest quota reading under 50%. Medium or large only when the median accepted-task duration in the ledger exceeds four times the lead's service time per task. At most 16 dispatches of any role in flight. Every implementer runs in its own worktree whenever more than one is in flight. Read reference/trees.md when more than one implementer is in flight.
|
|
26
|
+
6. Dispatch names follow `<role>-<task>[-r<round>][-<slug>]`: `impl-2_3`, `fix-2_3-r2`, `impl-2_4_1` (a sub-task), `review-final-r1` (the final review) and `review-final-r1-security` (one of that round's parallel reviewers, the slug naming its lens). The name goes in the prompt and the `description` (rule 4), never in the `name` parameter. Write `_` for `.`. The lens slug is lowercase letters, digits and hyphens. Before every dispatch, run `validate-handoff.mjs name <dispatch-name>` and use the printed corrected form. Read reference/loop.md when the printed form differs from the name.
|
|
27
|
+
7. Budget: run `validate-handoff.mjs budget <ledger.jsonl> <task>` before every dispatch of a task, and again when its handoff is accepted.
|
|
28
|
+
8. Rewrite the brief's `## Why and rulings` digest before every re-dispatch (a fix round, a re-brief after `partial` or `blocked`) so it still matches the current decisions; a deviation the handoff does not cite is a reviewer P0 tagged `why-digest`. A `[base]`, `hardening` or follow-up finding never enters a later brief's digest or write scope.
|
|
29
|
+
9. No nested subagents: a worker never dispatches helpers or reviewers; a worker-spawned reviewer is a defect.
|
|
30
|
+
10. Frontier: the lead passes the `frontier` model (the alias `frontier` maps to in `reference/tiers.md`) on every `agentic-architect` dispatch (a design, a design review, an architecture review) at effort `high`, or `medium` for a review scoped to one capability or one design decision, and records `Frontier: agentic-architect - <effort> - <reason>` in the review package (planning records: `agentic-architecture`); implementers, test-writers and reviewers never run on `frontier`; under a local-model profile `frontier` is unavailable and `agentic-architect` runs on its frontmatter tier and effort (`strong`, `xhigh`).
|
|
29
31
|
</dispatch>
|
|
30
32
|
|
|
31
33
|
<handoff>
|
|
32
|
-
The worker returns only the JSON block (schema in `reference/handoff.md`): `task`, `status: completed|partial|blocked`, `files_changed`, `tests_run
|
|
33
|
-
|
|
34
|
+
The worker returns only the JSON block (schema in `reference/handoff.md`): `task`, `status: completed|partial|blocked`, `files_changed`, `tests_run`, `evidence` (one line per Verify item and per probe id), `partial_output` (required when partial), `blocked_reason` (stop token first; required when blocked), `concerns`. Stop tokens end the dispatch at the first one: `too-big`, `needs-confirm`, `ambiguous`, `regressed`, `scope`. Handle: `partial` -> re-dispatch with the label as the task; `blocked` -> fix the cause (context, tier, split, ruling) and re-dispatch; never re-run the same dispatch unchanged. A guard `needs-confirm` on a line naming no guarded path: reference/loop.md.
|
|
35
|
+
Every report ends with `## Checkpoint` (reference/handoff.md). The task's working state `<task>.state.md` is written by the SDD context hook at SubagentStop when installed, otherwise run `validate-handoff.mjs state <report> <task>.state.md`.
|
|
36
|
+
On a missing, empty or block-less reply the first step is `validate-handoff.mjs recover <transcript.jsonl> <report>` over `~/.claude/projects/<project>/<session>/subagents/agent-<id>.jsonl`, never a re-dispatch (reference/handoff.md).
|
|
34
37
|
</handoff>
|
|
35
38
|
|
|
36
39
|
<acceptance>
|
|
37
|
-
- Worker reports are not acceptance. The lead reviews the final diff (`git diff <base>..HEAD`) and runs the Verify commands itself, then appends `## Lead evaluation` to the review package with the commands and their summary lines. A task with only the worker's claim is never marked done.
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
+
- Worker reports are not acceptance. The lead reviews the final diff (`git diff <base>..HEAD`) once and runs the Verify commands itself, every probe included, then appends `## Lead evaluation` to the review package with the commands and their summary lines. A task with only the worker's claim is never marked done. A handoff whose `tests_run` holds no test command (a build alone) is `partial`, and the lead's run covers every test file that exercises an edited source, not only the files the brief names. A `Verify` list holds the task's tests plus the affected tests the changed-term check found, and implementers run only the Verify commands; the lead alone runs the full suite (the brief's `Suite:` command), at most one run at a time, after each accepted wave of parallel tasks and at the whole-change gate (reference/loop.md, "Test tiers and waves").
|
|
41
|
+
- Budget gate: run `validate-handoff.mjs budget <ledger.jsonl> <task>` again when the handoff is accepted; `FAIL ceiling reached` stops dispatching the task and requires the same `## Controller ruling` as the circuit breaker.
|
|
42
|
+
- Guards before the reviewer: run `validate-handoff.mjs handoff <report> --base <Base> --brief <brief.md> --agent <agent_id>`, adding `--in-flight <brief.md>` for every other brief still running and `--lead <path>` for the lead's own paths; every guard failure returns to the worker as findings (a round), never straight to the reviewer. Read reference/loop.md when a guard fails.
|
|
43
|
+
- One combined task reviewer per task (spec compliance + code quality in one dispatch, tier explicit) reads the brief, the review package and the diff file; it treats the report as unverified claims, checks the brief's probes first (running each) and only then reviews the diff against the spec; a probe the reviewer adds after the dispatch is a finding judged by the blocking rule, never a silent new bar. A reviewer never writes to, reverts or checks out files in the shared working tree and proves a test RED only against a temporary copy outside it. Findings follow the reviewer contract: `path:line: P0|P1|P2 <type>: problem. fix.` with `<type>` one of `defect|hardening|refactor|test-gap|docs|design`, `defect` only when the current behavior violates a spec requirement, a documented contract or a behavior the owner has stated; a follow-up's own `Expected:` line alone never makes it a defect. At most 3 reviewer dispatches per round; a fourth waits for a second round unless a user ask for more is recorded in the review package.
|
|
44
|
+
- Review tier: the lead picks each review dispatch's model (task reviewer, scoped re-reviews, the final branch review's reviewers), standard being the default: it runs `validate-handoff.mjs route <brief> --review --base <Base> [--round <n>] [--p0] [--final-spec] [--probed]` (`--final-spec` for the final branch review's spec-compliance pass, `--probed` (S4) for a scoped re-review whose every finding has a reproducing probe) and writes the printed `Review tier: <tier> - S<n> <reason>` line to the review package before the dispatch.
|
|
40
45
|
- No finding suppression: never tell a reviewer what not to flag, never downgrade a finding for a stated rationale, never drop a finding silently; disagreement is a written ruling.
|
|
41
46
|
- `test-driven-development` proof (failing run, then passing run) is part of the evidence; coverage numbers are not.
|
|
42
47
|
</acceptance>
|
|
43
48
|
|
|
44
49
|
<fix_loop>
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
50
|
+
- Blocking: a finding is blocking when it is a P0, or a P1 `defect` introduced by the task's diff (it does not reproduce at the task's `Base:` for a task review, or at the round base for a re-review) or one that fails a brief probe or a spec scenario, or, on a `security` or `complex` task, a P1 of any type introduced by the diff that fails a brief probe, a spec scenario or the corpus probe against the base. The reviewer tags a P1 `defect` that reproduces at the base `[base]`; a `[base]` finding is never blocking. Only blocking findings open a fix round; every other finding is a follow-up recorded at task close. A non-blocking `docs` or `test-gap` finding, or a comment fix, may ride round 1 when a blocking finding opened it and the fix stays inside the write scope, never a later round. A blocking finding whose fix lies outside the write scope gets a controller ruling and a new brief, never a round. The lead retypes a finding only through a written ruling line. The gate cannot tell that a finding meets the evidence test (reference/loop.md): on a `security` or `complex` task the lead retypes such a P1 to `defect` through a written ruling line before running `gate`, so it blocks.
|
|
51
|
+
- Ledger and gate: `<task>.findings.md` holds one line per finding, `F<n> <open|fixed|rejected|follow-up> r<round>: <reviewer contract line>`, written only by the lead. After every review run `validate-handoff.mjs gate <findings.md>`: it prints each `open` line as `blocking` or `follow-up` with the reason and exits non-zero when any is blocking; with no blocking line the task is accepted.
|
|
52
|
+
- A fix round = one fix dispatch + one scoped re-review. Before each fix dispatch run `validate-handoff.mjs round-base <brief.md> <n>`, the round-cap check (it refuses `round-cap <n> over <cap>`), which copies the write-scope files under `rounds/<task>-r<n>/`. Every round dispatches a fresh `implementer` given the brief, the review package and `<task>.findings.md` (the ledger), on the tier and effort `route` prints for the round (dispatch rule 1; strong from round 3 on, never frontier, which is reserved for the agentic-architect role (dispatch rule 10)). Read reference/loop.md when a fix dispatch is written: the fix prompt order and the task state.
|
|
53
|
+
- Re-review: a fresh re-reviewer is given only the ledger, the output of `validate-handoff.mjs round-diff <brief.md> <n>` and the probes; it returns a status for each open id and any new findings (from round 2 on only a P0 with a reproducer on the round diff; any other is a follow-up), and judges only the round diff: a finding on code the round diff does not change is a follow-up unless it is a P0.
|
|
54
|
+
- Circuit breaker: at the round cap (3, or the run authorization's `Rounds:`; `round-base` refuses `round-cap`) with blocking findings still open, stop dispatching. Write `## Controller ruling` to the review package for every open finding (reference/loop.md). Then ask the user before the next task, unless every open finding is ruled "remove the addition". Second breaker: the class ceiling (reference/loop.md). At `FAIL ceiling reached` stop dispatching the task and write the same ruling, each with an `R:<task>.<n>` id the next brief's digest can cite.
|
|
55
|
+
- Every round appends `round <n>/<cap>: <addressed>/<open blocking>` to the review package. The lead never fixes findings itself.
|
|
49
56
|
</fix_loop>
|
|
50
57
|
|
|
51
58
|
<completion>
|
|
52
|
-
- Per task: lead evaluation present,
|
|
53
|
-
- After the last task: one final branch review via `code-review` over `git merge-base` to HEAD
|
|
54
|
-
- Every deferred item (a
|
|
55
|
-
- Final message lists every ruling made (what, why, cost if wrong) and the `validate-handoff.mjs ledger <change-dir>` summary of dispatches and cache-read spend per task
|
|
59
|
+
- Per task: lead evaluation present, gate clean (or rulings written at the cap), `verification-before-completion` evidence recorded, then tick `[x]` in `tasks.md`, then commit the task with `validate-handoff.mjs commit <report> [<report>...] -F <message-file> --lead <tasks.md>`, listing every report of the task, adding `--tree <Tree> --base <sha>` for a tree task (the lead writes the message file; the tick rides in the same commit). Every accepted task is committed this way, never by `git add` plus `git commit`. Read reference/loop.md when a task is committed.
|
|
60
|
+
- After the last task: one final branch review via `code-review` over `git merge-base` to HEAD. Read reference/loop.md when the final branch review starts. Before the first final-review dispatch, write `final.brief.md` in the change workspace (header `Task: final`, the change's other headers, `Tier: strong`), since the cost tracker writes no ledger line for a dispatch whose task no in-flight brief declares; the lead writes it from the template, the fix dispatch reads it, and `validate-handoff.mjs briefs` checks it like any brief. Then `git-workflow` for commit and PR; `/opsx:archive` when the change is done, with its compound step (retrospective line, telemetry file, rules or skill delta, memory observation).
|
|
61
|
+
- Every deferred item (a non-blocking finding, a parked ruling, a machine-only measurement) is recorded with `openspec follow-up add <change-id> '<text>' --type <type> --expected '<...>' --current '<...>' --impact '<...>' --from <task>`, never as prose, the type and the expected, current and impact context taken from the finding, plus `owner-step` for a machine or owner measurement and `upstream` for an item owed upstream; the lead passes every value single-quoted (a `'` written as `'\''`) because finding text may quote shell syntax that double quotes would expand; archive prints the unclaimed items.
|
|
62
|
+
- Final message lists every ruling made (what, why, cost if wrong) and the `validate-handoff.mjs ledger <change-dir>` summary of dispatches and cache-read spend per task.
|
|
56
63
|
</completion>
|
|
57
64
|
|
|
58
65
|
<stop_conditions>
|
|
59
|
-
Stop and ask the user only for: an irreversible or destructive operation; a security-sensitive action; a
|
|
66
|
+
Stop and ask the user only for: an irreversible or destructive operation; a security-sensitive action; a merge or push outside the change branch, or a publish; a task flagged "Ask first" in the proposal; the round cap or the class ceiling of the run authorization (the circuit breaker); a plan so broken that every path forward is a guess. Ceilings and the round cap come only from the owner (proposal.md `## Run authorization`, or `--ceiling`); the lead never raises them, and stops for neither below them. A cap with every finding ruled "remove the addition" is no stop. Everything else is a ruling, written down, and the run continues.
|
|
60
67
|
</stop_conditions>
|