fix(review): scope per-trigger effort to the backend that can honour it #80

Merged
crenshawdev merged 1 commit from cadence/64-per-trigger-effort into main 2026-07-28 19:34:42 +00:00
crenshawdev commented 2026-07-28 19:33:57 +00:00 (Migrated from github.com)

fire() resolved {gate, tier, effort} and consumed effort only on the cross-model arm. The claude-subagent arm dispatches cad-reviewer through spawn-agent, whose surface is (agent_name, prompt, model?), so the value was read, resolved, and dropped with nothing said. On a stock install (reviewers: ["claude-subagent"], diff.effort: medium) that is every trigger, every fire.

Wiring it through is not available

Re-verified against the host docs during this work: on the Agent/Task dispatch path Cadence uses, effort is a subagent definition field only. There is no tool parameter, env var, or setting that varies it per dispatch. Varying it needs per-rung reviewer agent files, which is #63's proposal, and half-building that here would have been worse than the defect.

So this scopes the key rather than wiring it, on the principle the issue states: either the configured value reaches the backend, or the key does not claim it does. A key read, resolved and silently dropped is the worst of the three.

What changed

  • review-triggers.md — step 1 states which fields reach which backend. Step 4's claude-subagent branch says trigger.effort is not passed and cannot be, names the seam surface, and requires one visible line per fire when the configured effort differs from cad-reviewer's pinned high. Same "name the degradation" discipline the cross-model ok:false drop already uses.
  • config.schema.json — the five review.triggers.*.effort purposes and review.decision_review.effort now say the key is cross-model only. This is what feeds the /cad-config menu, so it lands at the point of setting. review.consult.effort untouched, since consult has no subagent arm by design.
  • workflows/config.md — catalog row scoped.
  • DESIGN.md — a dated ⚠️ SCOPED bullet under "Per-trigger cognitive fit" recording that this is scopable, not wirable, and that the real dial needs #63.
  • route.test.mjs — two tests so the new claim cannot drift: every role's base_effort matches the frontmatter of the agent file that runs it, and each escalate_effort_variant really carries the high that route.mjs hardcodes.

Nothing in route-table.json tiers or the profile matrix was touched.

Rebase note

Rebased onto #79. Both branches grew cadence-core/workflows/config.md, so the shared weight-budgets.json entry conflicted. Resolved to 16681, which is the combined size of both additions and matches the file exactly; self-verify enforces it as a ceiling and passes.

Verification (post-rebase)

  • node --test cadence-core/bin/*.test.mjs → 739 pass, 0 fail
  • node cadence-core/bin/self-verify.mjs{"ok":true,...,"problems":[]}

Follow-up

The same silent-drop shape exists in two more places, filed as #78 rather than folded in here.

Closes #64

`fire()` resolved `{gate, tier, effort}` and consumed `effort` only on the cross-model arm. The `claude-subagent` arm dispatches `cad-reviewer` through spawn-agent, whose surface is `(agent_name, prompt, model?)`, so the value was read, resolved, and dropped with nothing said. On a stock install (`reviewers: ["claude-subagent"]`, `diff.effort: medium`) that is every trigger, every fire. ## Wiring it through is not available Re-verified against the host docs during this work: on the Agent/Task dispatch path Cadence uses, `effort` is a subagent definition field only. There is no tool parameter, env var, or setting that varies it per dispatch. Varying it needs per-rung reviewer agent files, which is #63's proposal, and half-building that here would have been worse than the defect. So this scopes the key rather than wiring it, on the principle the issue states: either the configured value reaches the backend, or the key does not claim it does. A key read, resolved and silently dropped is the worst of the three. ## What changed - **`review-triggers.md`** — step 1 states which fields reach which backend. Step 4's claude-subagent branch says `trigger.effort` is not passed and cannot be, names the seam surface, and requires one visible line per fire when the configured effort differs from `cad-reviewer`'s pinned `high`. Same "name the degradation" discipline the cross-model `ok:false` drop already uses. - **`config.schema.json`** — the five `review.triggers.*.effort` purposes and `review.decision_review.effort` now say the key is cross-model only. This is what feeds the `/cad-config` menu, so it lands at the point of setting. `review.consult.effort` untouched, since consult has no subagent arm by design. - **`workflows/config.md`** — catalog row scoped. - **`DESIGN.md`** — a dated `⚠️ SCOPED` bullet under "Per-trigger cognitive fit" recording that this is scopable, not wirable, and that the real dial needs #63. - **`route.test.mjs`** — two tests so the new claim cannot drift: every role's `base_effort` matches the frontmatter of the agent file that runs it, and each `escalate_effort_variant` really carries the `high` that `route.mjs` hardcodes. Nothing in `route-table.json` tiers or the profile matrix was touched. ## Rebase note Rebased onto #79. Both branches grew `cadence-core/workflows/config.md`, so the shared `weight-budgets.json` entry conflicted. Resolved to 16681, which is the combined size of both additions and matches the file exactly; self-verify enforces it as a ceiling and passes. ## Verification (post-rebase) - `node --test cadence-core/bin/*.test.mjs` → 739 pass, 0 fail - `node cadence-core/bin/self-verify.mjs` → `{"ok":true,...,"problems":[]}` ## Follow-up The same silent-drop shape exists in two more places, filed as #78 rather than folded in here. Closes #64
Sign in to join this conversation.
No description provided.