feat(agents): pin explicit reasoning effort on every agent and workflow call
Effort joins model as a mandatory pin: an omitted field inherits the session effort, coupling every dispatch's thinking budget to whatever the user happens to be chatting at (often xhigh) — the same session-state coupling the model pin removes. The assignment follows the model split: - xhigh on every opus agent (judgement roles are the pipeline's quality floor and must not degrade with the session); - high on every sonnet agent (tightly-scoped plan execution gains little from xhigh but pays its latency per dispatch, and these are the per-task in-loop roles — wall-clock is the efficiency metric; not lower than high, since re-loops cost more than saved thinking); - medium inline in the workflow scripts for schema-bound extraction/verification stages that author no code (preflight, plan-extract, mini-verify, tree-check, finalize, build/suite verify). Workflow agent() calls pass effort explicitly on every call — whether frontmatter effort propagates through an agentType dispatch is undocumented, so the scripts do not rely on it. Policy documented in docs/agent-template.md § effort, mirroring § model.
This commit is contained in:
@@ -3,6 +3,7 @@ name: architect
|
||||
description: Read-only architecture reviewer. Checks at cycle close whether the codebase still matches the project's design ledger and CLAUDE.md, identifies drift and technical debt with paths and short justifications, and recommends one direction for the next iteration. Names problems; does NOT propose implementations.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# architect
|
||||
|
||||
@@ -3,6 +3,7 @@ name: bencher
|
||||
description: Hypothesis-driven performance benchmarker. Designs workloads, runs measurements, interprets results to answer "is X better than Y?" — not "is X fast in absolute terms?". Reports evidence including the limitations of the bench design. Does NOT ship features.
|
||||
tools: Read, Write, Edit, Glob, Grep, Bash
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# bencher
|
||||
|
||||
@@ -3,6 +3,7 @@ name: synthetic-user
|
||||
description: Read-only synthetic design-stance respondent for the brainstorm swarm. Answers the orchestrator's enumerated design forks from ONE fixed adversarial stance, grounded in the project's audience / design ledger / glossary, with a mandatory source citation per answer. Does NOT decide and does NOT author approaches; the convergence vs divergence of many stances is the orchestrator's fork-triage evidence.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
model: sonnet
|
||||
effort: high
|
||||
---
|
||||
|
||||
> Violating the letter of these rules is violating the spirit.
|
||||
|
||||
@@ -3,6 +3,7 @@ name: debugger
|
||||
description: Diagnoses bugs in the project. Reproduces, finds the root cause, writes a RED test that pins down the symptom, and hands off to implement mini-mode for the GREEN side. Does NOT apply the fix itself.
|
||||
tools: Read, Edit, Write, Bash, Glob, Grep
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# debugger
|
||||
|
||||
@@ -13,6 +13,7 @@ name: <agent-slug>
|
||||
description: <third-person, "Use when…" or role description>
|
||||
tools: <comma-separated tool list>
|
||||
model: <opus | sonnet>
|
||||
effort: <xhigh | high>
|
||||
---
|
||||
|
||||
> Violating the letter of these rules is violating the spirit.
|
||||
@@ -137,6 +138,34 @@ The same rule binds Workflow scripts: every `agent()` call passes an
|
||||
explicit `model:` option (see the model-policy header comments in
|
||||
`implement/workflows/*.js`).
|
||||
|
||||
### `effort`
|
||||
|
||||
Mandatory. Every agent pins an explicit reasoning effort — one of the
|
||||
harness levels `low | medium | high | xhigh | max`, of which the plugin
|
||||
uses two. An omitted field means the agent inherits the *session*
|
||||
effort, coupling every dispatch's thinking budget to whatever the user
|
||||
happens to be chatting at — the same session-state coupling the `model`
|
||||
pin exists to remove. Effort follows the model split:
|
||||
|
||||
- **`xhigh` on every `opus` agent.** The judgement roles are the
|
||||
pipeline's quality floor; their thinking budget must not silently
|
||||
degrade because the session runs lower.
|
||||
- **`high` on every `sonnet` agent.** Tightly-scoped execution of a
|
||||
pre-made plan gains little from `xhigh` but pays its latency on
|
||||
every dispatch — and these are exactly the roles dispatched
|
||||
per-task inside loops (wall-clock is the pipeline's efficiency
|
||||
metric). Not lower than `high`: a sloppy in-loop step triggers
|
||||
re-loops that cost more wall-clock than the saved thinking.
|
||||
|
||||
Workflow scripts pin a third tier inline: schema-bound
|
||||
extraction/verification stages that author no code (preflight,
|
||||
plan-extract, mini-verify, tree-check, finalize, build/suite verify)
|
||||
run `medium` via the `agent()` call's `effort:` option. As with
|
||||
`model:`, every `agent()` call passes `effort:` explicitly — whether
|
||||
frontmatter effort propagates through an `agentType` dispatch is
|
||||
undocumented, so the scripts do not rely on it (see the policy header
|
||||
comments in `implement/workflows/*.js`).
|
||||
|
||||
## Sections in detail
|
||||
|
||||
### Spirit-letter lead-in
|
||||
|
||||
@@ -3,6 +3,7 @@ name: docwriter
|
||||
description: Writes and maintains API documentation for the project's source. Brings top-level, module-level, and public-item docs up to a level where a newcomer can navigate the generated docs without having read the design ledger first. NOT for changing APIs, NOT for editing files under the project's design or specs directories.
|
||||
tools: Read, Edit, Write, Bash, Glob, Grep
|
||||
model: sonnet
|
||||
effort: high
|
||||
---
|
||||
|
||||
# docwriter
|
||||
|
||||
@@ -3,6 +3,7 @@ name: fieldtester
|
||||
description: Implements 2-4 real-world tasks against the project as a downstream consumer would, runs them, and reports friction, bugs, and spec gaps as a structured spec. Simulates a downstream user who has only the public interface (the project's design ledger, READMEs, public docs, and example corpus) — never the implementation source. Does NOT fix bugs.
|
||||
tools: Read, Edit, Write, Bash, Glob, Grep
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# fieldtester
|
||||
|
||||
@@ -3,6 +3,7 @@ name: glossary-extractor
|
||||
description: Read-only per-slice prose extractor for glossary bootstrap. Sweeps one slice of a project's prose surface and reports the recurring domain-concept terms and their competing synonyms as actually written, with frequencies and locations. Coins nothing; dispatched fan-out by the glossary skill's bootstrap procedure.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
model: sonnet
|
||||
effort: high
|
||||
---
|
||||
|
||||
> Violating the letter of these rules is violating the spirit.
|
||||
|
||||
@@ -3,6 +3,7 @@ name: implementer
|
||||
description: Carries out a tightly scoped implementation task. Reads the task extract handed by the controller, implements, builds, tests, reports a structured status with the diff. NOT for architecture decisions, NOT for self-curated scope; this agent executes a plan that has already been made.
|
||||
tools: Read, Edit, Write, Bash, Glob, Grep
|
||||
model: sonnet
|
||||
effort: high
|
||||
---
|
||||
|
||||
# implementer
|
||||
|
||||
@@ -3,6 +3,7 @@ name: quality-reviewer
|
||||
description: Read-only code-quality reviewer for project diffs. Reports Strengths, Issues by severity (Important / Minor / Nit), and a Recommendation. Runs after spec-reviewer is green; spec-compliance is NOT this agent's concern. Does NOT propose fixes.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# quality-reviewer
|
||||
|
||||
@@ -3,6 +3,7 @@ name: spec-reviewer
|
||||
description: Read-only spec-compliance reviewer. Compares a recent diff against the task text from a plan under docs/plans handed by the controller. Reports missing requirements and unrequested extras. Does NOT review code quality (that is quality-reviewer's job) and does NOT propose fixes (the implementer fixes; the orchestrator coordinates).
|
||||
tools: Read, Glob, Grep, Bash
|
||||
model: sonnet
|
||||
effort: high
|
||||
---
|
||||
|
||||
# spec-reviewer
|
||||
|
||||
@@ -3,6 +3,7 @@ name: tester
|
||||
description: Writes new fixtures and E2E tests after a cycle or feature ships. Verifies a feature works from build through to observable output. Each test protects a named property; tests check observable behaviour, not implementation internals.
|
||||
tools: Read, Edit, Write, Bash, Glob, Grep
|
||||
model: sonnet
|
||||
effort: high
|
||||
---
|
||||
|
||||
# tester
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
// session-model inherit (which could route to an unintended tier, e.g. fable —
|
||||
// banned for all plugin agents and workflows). Both phases here are mechanical
|
||||
// (compiler-enumerated propagation, build/suite re-run), so both run sonnet.
|
||||
// Effort policy mirrors it: every call pins an explicit effort — the edit
|
||||
// (real code work) runs high, the build/suite verify (schema-bound check)
|
||||
// runs medium. See docs/agent-template.md § effort.
|
||||
//
|
||||
// Carrier — Workflow `args`:
|
||||
// edit_description: what type/signature change to make
|
||||
@@ -125,7 +128,7 @@ const edit = await agent(
|
||||
'Then run the project build and report: is the build clean, does any hole need a decision (with detail + bounce_to), ' +
|
||||
'how many sites were touched, and — checked against `git status --porcelain` / `git diff HEAD`, NOT from memory — ' +
|
||||
'whether the working tree actually changed (applied_changes).',
|
||||
{ agentType: 'implementer', model: 'sonnet', label: 'edit+propagate', phase: 'Edit + propagate', schema: EDIT_SCHEMA },
|
||||
{ agentType: 'implementer', model: 'sonnet', effort: 'high', label: 'edit+propagate', phase: 'Edit + propagate', schema: EDIT_SCHEMA },
|
||||
)
|
||||
if (!edit) return { status: 'BLOCKED', reason: 'edit agent did not return' }
|
||||
if (edit.hole_needs_decision) {
|
||||
@@ -167,7 +170,7 @@ const verify = await agent(
|
||||
'every test passes and NO test was added, removed, or weakened versus the pre-edit baseline (compare `git diff ' +
|
||||
'HEAD` for test-file changes). Also report working_tree_dirty — whether `git status --porcelain` / `git diff HEAD` ' +
|
||||
'shows ANY change at all (a clean tree means no edit landed). Do NOT edit anything; do NOT commit.',
|
||||
{ model: 'sonnet', label: 'verify(build+suite)', phase: 'Verify', schema: VERIFY_SCHEMA },
|
||||
{ model: 'sonnet', effort: 'medium', label: 'verify(build+suite)', phase: 'Verify', schema: VERIFY_SCHEMA },
|
||||
)
|
||||
|
||||
// ---- Phase 3 — verdict --------------------------------------------------
|
||||
|
||||
@@ -47,6 +47,11 @@
|
||||
// fable — banned for all plugin agents and workflows). Mechanical and
|
||||
// in-loop steps run sonnet; the quality gate is the one deliberate opus
|
||||
// call (last correctness check before a task is marked DONE).
|
||||
// • Effort policy mirrors the model policy: every agent() call pins an
|
||||
// explicit effort — never the session inherit. Code-writing and review
|
||||
// steps run high, the opus quality gate runs xhigh, and schema-bound
|
||||
// extraction/check steps (preflight, plan-extract, mini-verify,
|
||||
// tree-check, finalize) run medium. See docs/agent-template.md § effort.
|
||||
//
|
||||
// Carrier — passed as the Workflow `args` object by the orchestrator:
|
||||
// mode: 'standard' | 'mini'
|
||||
@@ -250,7 +255,7 @@ const pre = await agent(
|
||||
'Run `git status --porcelain`, `git rev-parse HEAD`, and `git rev-parse --abbrev-ref HEAD`. ' +
|
||||
'Report whether the tree is clean (no porcelain output), the HEAD sha, the branch, and any dirty paths. ' +
|
||||
'Do NOT modify anything, do NOT commit. The HEAD sha is an informational anchor only — never a reset target.',
|
||||
{ model: 'sonnet', label: 'preflight', phase: 'Preflight', schema: PREFLIGHT_SCHEMA },
|
||||
{ model: 'sonnet', effort: 'medium', label: 'preflight', phase: 'Preflight', schema: PREFLIGHT_SCHEMA },
|
||||
)
|
||||
if (!pre) return { status: 'BLOCKED', iter_id, reason: 'infra: preflight agent did not return' }
|
||||
if (!pre.clean) {
|
||||
@@ -281,7 +286,7 @@ if (mode === 'mini') {
|
||||
`${STANDING}\n\nRead the plan at ${plan_path}. Extract ` +
|
||||
(task_range ? `tasks ${task_range[0]}..${task_range[1]} (inclusive, 1-based)` : 'every task') +
|
||||
', each as its VERBATIM block with the task id and a one-line title. Do not summarise or reorder. Do not edit anything.',
|
||||
{ model: 'sonnet', label: 'plan-extract', phase: 'Per-task loop', schema: TASKS_SCHEMA },
|
||||
{ model: 'sonnet', effort: 'medium', label: 'plan-extract', phase: 'Per-task loop', schema: TASKS_SCHEMA },
|
||||
)
|
||||
if (!extracted || !extracted.tasks || extracted.tasks.length === 0) {
|
||||
return { status: 'NEEDS_CONTEXT', iter_id, reason: `no tasks extracted from ${plan_path}` }
|
||||
@@ -299,7 +304,7 @@ async function runTask(task) {
|
||||
'inner-loop discipline — add the failing test inline even if the task text forgot to script it). ' +
|
||||
'Build and test must be green before you report DONE. Leave all edits UNSTAGED; never commit.\n\n' +
|
||||
`mode: ${mode}\niter_id: ${iter_id}\n\nTASK ${task.id} — ${task.title}\n${task.text}`,
|
||||
{ agentType: 'implementer', model: 'sonnet', label: `impl:${task.id}`, phase: 'Per-task loop', schema: IMPL_SCHEMA },
|
||||
{ agentType: 'implementer', model: 'sonnet', effort: 'high', label: `impl:${task.id}`, phase: 'Per-task loop', schema: IMPL_SCHEMA },
|
||||
)
|
||||
if (!impl) return { id: task.id, title: task.title, outcome: 'BLOCKED', reason: 'implementer agent did not return' }
|
||||
if (impl.status === 'BLOCKED') return { id: task.id, title: task.title, outcome: 'BLOCKED', reason: impl.reason || 'worker-blocked' }
|
||||
@@ -318,7 +323,7 @@ async function runTask(task) {
|
||||
`${STANDING}\n\nSpec-compliance review of task ${task.id}. Compare \`git diff HEAD\` against the task ` +
|
||||
'text ONLY — list missing requirements and unrequested extras. No quality opinions, no fix proposals. ' +
|
||||
`Focus on the files this task claims to touch.\n\nTASK ${task.id} — ${task.title}\n${task.text}`,
|
||||
{ agentType: 'spec-reviewer', model: 'sonnet', label: `spec:${task.id}`, phase: 'Per-task loop', schema: SPEC_SCHEMA },
|
||||
{ agentType: 'spec-reviewer', model: 'sonnet', effort: 'high', label: `spec:${task.id}`, phase: 'Per-task loop', schema: SPEC_SCHEMA },
|
||||
)
|
||||
if (spec && spec.status === 'compliant') break
|
||||
if (spec && spec.status === 'unclear') return { id: task.id, title: task.title, outcome: 'BLOCKED', reason: 'spec-ambiguous', detail: spec.ambiguity }
|
||||
@@ -328,7 +333,7 @@ async function runTask(task) {
|
||||
`${STANDING}\n\nRepair task ${task.id} to satisfy the spec-compliance review. Address EACH finding; ` +
|
||||
'do not widen scope. Keep build + tests green; leave edits unstaged.\n\n' +
|
||||
`TASK ${task.id} — ${task.title}\n${task.text}\n\nFINDINGS:\n- ${(spec?.findings || ['(none reported)']).join('\n- ')}`,
|
||||
{ agentType: 'implementer', model: 'sonnet', label: `impl-fix-spec:${task.id}`, phase: 'Per-task loop', schema: IMPL_SCHEMA },
|
||||
{ agentType: 'implementer', model: 'sonnet', effort: 'high', label: `impl-fix-spec:${task.id}`, phase: 'Per-task loop', schema: IMPL_SCHEMA },
|
||||
)
|
||||
if (specFix && specFix.applied_changes === true) wroteAnyFile = true
|
||||
}
|
||||
@@ -353,7 +358,7 @@ async function runTask(task) {
|
||||
'The loop compares it across rounds to detect a no-op/cyclic repair.',
|
||||
// opus by design: the loop's last correctness gate (spec-reviewer only checks
|
||||
// task-text correspondence) — real-bug finding is the documented opus strength.
|
||||
{ agentType: 'quality-reviewer', model: 'opus', label: `qual:${task.id}`, phase: 'Per-task loop', schema: QUAL_SCHEMA },
|
||||
{ agentType: 'quality-reviewer', model: 'opus', effort: 'xhigh', label: `qual:${task.id}`, phase: 'Per-task loop', schema: QUAL_SCHEMA },
|
||||
)
|
||||
if (qual && qual.status === 'approved') break
|
||||
// No-op / cyclic-repair backstop: a changes_requested verdict over a diff-state already reviewed-and-flagged
|
||||
@@ -387,7 +392,7 @@ async function runTask(task) {
|
||||
'A finding whose only remedy is to diverge from the ratified plan must be held or escalated, never chased ' +
|
||||
'into a deviation the next review flags.\n\n' +
|
||||
`TASK ${task.id} — ${task.title}\n${task.text}\n\nISSUES:\n- ` + (qual?.issues || ['(none reported)']).join('\n- '),
|
||||
{ agentType: 'implementer', model: 'sonnet', label: `impl-fix-qual:${task.id}`, phase: 'Per-task loop', schema: IMPL_SCHEMA },
|
||||
{ agentType: 'implementer', model: 'sonnet', effort: 'high', label: `impl-fix-qual:${task.id}`, phase: 'Per-task loop', schema: IMPL_SCHEMA },
|
||||
)
|
||||
if (fix && fix.applied_changes === true) wroteAnyFile = true
|
||||
if (fix && (fix.status === 'BLOCKED' || fix.status === 'NEEDS_CONTEXT')) {
|
||||
@@ -471,7 +476,7 @@ if (mode === 'mini' && outcome === 'DONE') {
|
||||
'fix). Then run the full suite and confirm it is green (no regression). Also report working_tree_dirty — ' +
|
||||
'whether `git status --porcelain` (NOT `git diff HEAD`, which misses new untracked files) shows any change at ' +
|
||||
'all (a clean tree means no fix landed). Do NOT edit anything; do NOT commit.',
|
||||
{ model: 'sonnet', label: 'mini-verify', phase: 'Verify', schema: MINI_VERIFY_SCHEMA },
|
||||
{ model: 'sonnet', effort: 'medium', label: 'mini-verify', phase: 'Verify', schema: MINI_VERIFY_SCHEMA },
|
||||
)
|
||||
if (!miniVerify || !miniVerify.red_test_now_green || !miniVerify.suite_green || !miniVerify.working_tree_dirty) {
|
||||
outcome = 'BLOCKED'
|
||||
@@ -498,7 +503,7 @@ if (mode === 'mini' && outcome === 'DONE') {
|
||||
'`git status --porcelain` and report files_touched = its line count (every changed, added, or untracked ' +
|
||||
'path). Use `git status --porcelain`, NOT `git diff`, so brand-new untracked files are counted. Do NOT edit, ' +
|
||||
'do NOT commit.',
|
||||
{ model: 'sonnet', label: 'tree-check', phase: 'Verify', schema: TREE_SCHEMA },
|
||||
{ model: 'sonnet', effort: 'medium', label: 'tree-check', phase: 'Verify', schema: TREE_SCHEMA },
|
||||
)
|
||||
if (!treeState || treeState.files_touched === 0) {
|
||||
outcome = 'BLOCKED'
|
||||
@@ -526,7 +531,7 @@ if (mode === 'standard' && outcome === 'DONE') {
|
||||
'E2E fixtures for them in the project\'s canonical fixture form; each test\'s doc comment names the property ' +
|
||||
'it protects. Run the project\'s test command — all green. Leave edits unstaged; never commit.\n\n' +
|
||||
`iter_id: ${iter_id}\nshipped: ${completed.map((c) => `#${c.id} ${c.title}`).join('; ')}`,
|
||||
{ agentType: 'tester', model: 'sonnet', label: 'e2e', phase: 'E2E coverage', schema: E2E_SCHEMA },
|
||||
{ agentType: 'tester', model: 'sonnet', effort: 'high', label: 'e2e', phase: 'E2E coverage', schema: E2E_SCHEMA },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -582,7 +587,7 @@ const fin = await agent(
|
||||
'and `## Files touched` (from `git status --porcelain`).\n') +
|
||||
'Report the stats path and whether you wrote BLOCKED.md. Do NOT commit anything.\n\nAGGREGATE:\n' +
|
||||
JSON.stringify(aggregate, null, 2),
|
||||
{ model: 'sonnet', label: 'finalize', phase: 'Report', schema: FINALIZE_SCHEMA },
|
||||
{ model: 'sonnet', effort: 'medium', label: 'finalize', phase: 'Report', schema: FINALIZE_SCHEMA },
|
||||
)
|
||||
|
||||
// The no-op verdict was already taken before finalize (the tree-check / mini-verify
|
||||
|
||||
@@ -3,6 +3,7 @@ name: plan-recon
|
||||
description: Read-only code-and-doc-recon agent for plan writing. Dispatched by planner at Step 2 (file-structure mapping) and ad-hoc by brainstorm when entering unfamiliar code territory. Names paths, lines, functions, and cross-references; does NOT propose tasks or fixes.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# plan-recon
|
||||
|
||||
@@ -3,6 +3,7 @@ name: grounding-check
|
||||
description: Read-only grounding-check reviewer for spec drafts. Dispatched by the specify skill in Step 5, between linguistic self-review and user-approval. Reads the draft with fresh context, extracts its load-bearing assumptions about current codebase behaviour, and for each one searches the workspace for a currently-green test that ratifies it. Reports PASS or BLOCK. Does NOT propose fixes, does NOT edit files.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# grounding-check — spec grounding-check agent
|
||||
|
||||
@@ -3,6 +3,7 @@ name: spec-skeptic
|
||||
description: Read-only adversarial bias-breaker the orchestrator pulls ad hoc when deciding a load-bearing fork under `/boss` — one lens (or a few) of criterion, grounding, scope-fork, ambiguity, plan-readiness. Tries to REFUTE the spec/decision along its single lens and reports SOUND or BLOCK. The finding feeds the orchestrator's decision; it is NOT a gate and NOT a veto. Does NOT propose fixes, does NOT edit files.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# spec-skeptic — ad-hoc adversarial bias-breaker
|
||||
|
||||
@@ -3,6 +3,7 @@ name: tdd-author
|
||||
description: Turns a test-specifiable feature description or issue into a single minimal, autonomous RED executable-spec test ("how it should work"), then hands the GREEN side to implement mini-mode. On a design fork (behaviour not test-specifiable) it bounces to brainstorm; on a GREEN one iteration can't reach, it decomposes the headline into BLOCKER sub-tests. Does NOT implement the feature.
|
||||
tools: Read, Edit, Write, Bash, Glob, Grep
|
||||
model: opus
|
||||
effort: xhigh
|
||||
---
|
||||
|
||||
# tdd-author
|
||||
|
||||
Reference in New Issue
Block a user