feat(#2481): add a negotiated effortSurface axis and wire invocation-time effort

ADR-1239 gains a ninth negotiated axis, effortSurface (argv | none), declaring how
a host accepts reasoning effort. ADR-443 is amended in the same change because its
recorded deferral is what the axis resolves: its Unblock condition offered paths
(a) and (b) and stated the choice was 'a maintainer call this file records but does
not make'. Path (a) is selected and satisfied here.

Before this, effort reached a runtime only through install-time channels
(EFFORT_RENDERING's frontmatter/api), so reviewer CLIs spawned as subprocesses
silently inherited whatever effort sat in the user's own global CLI config. The
review lane now resolves one universal effort through the ADR-443 cascade and
renders it per host through the negotiated descriptor.

Every per-host value is documentation-sourced, never inferred:
- claude   argv  -- verified via 'claude --help' (--effort <level>)
- opencode argv  -- verified via 'opencode run --help' (--variant)
- codex    argv  -- codex-rs/exec/src/cli.rs: model_reasoning_effort is NOT a CLI
                    flag (config.toml key only), so the global -c override is the
                    only argv route
- 15 hosts undocumented -- their docs state no reasoning setting; the sentinel
                    fails closed rather than inheriting a profile baseline

No config-file vocabulary member: the only host that ever had one (Gemini CLI's
thinkingConfig) was removed as a sunset runtime by 8f2ebbe9b (#1928, PR #1996),
and neither Antigravity CLI nor ZCode documents a reasoning setting.

Closes #2481

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-07-21 09:12:32 -04:00
parent c19d3d7bda
commit 09b535ac00
51 changed files with 863 additions and 100 deletions

View File

@@ -1342,6 +1342,36 @@ The model-catalog's `reasoning_effort` per-tier hint is a legacy field kept for
Valid effort values: `minimal`, `low`, `medium`, `high`, `xhigh`, `max`.
#### Where effort actually reaches — added in v1.8.0
Effort resolved from the cascade above reaches a runtime through one of two channels.
**Install-time.** The value is baked into the artifacts the installer generates — the
`effort:` frontmatter key on a Claude subagent, `model_reasoning_effort` in a generated
Codex `.toml`. This is fixed at install and changes only on reinstall or sync.
**Invocation-time.** When GSD spawns another CLI as a subprocess — the cross-AI reviewers
in `/gsd:review` — the effort is appended to that CLI's own command line. Whether a host
can receive effort this way is a declared capability (`effortSurface`, ADR-1239), not an
assumption:
| Reviewer CLI | Receives effort as |
|---|---|
| `claude` | `--effort <level>` |
| `opencode` | `--variant <level>` |
| `codex` | `-c model_reasoning_effort=<level>` |
A host whose documentation states no reasoning setting is left **untouched** — no flag is
guessed, and GSD never writes into your own CLI's config file to set one. Levels a given
CLI does not accept are clamped to its nearest supported value (`minimal` → `low` for
Claude, `max` → `xhigh` for Codex), so a cross-provider value never produces an invalid
argument.
Before this, a review run inherited whatever effort happened to be configured in your
personal CLI config, which is why the same project could produce very different review
times on two machines. Setting `effort.default` (or an agent/tier override) now controls
review runs too.
---
### Fast Mode (`fast_mode`) — added in v1.42