feat(voyage): W2 impl (S4) — gate resolver model, adopt native effort:, doc-truth
S4 of the 2.1.181 upgrade — implementation, not a gate. TDD: failing test written first for the resolver gate, then the fix; suite green throughout. - Resolver MAJOR (FIX): lib/profiles/phase-signal-resolver.mjs now imports BASE_ALLOWED_MODELS from profile-validator and gates `model` (if 'model' in entry && BASE_ALLOWED_MODELS.includes(entry.model)), mirroring the EFFORT_LEVELS gate one line up. Out-of-allowlist models (gpt-4, haiku) are dropped instead of handed to an agent spawn — defense-in-depth behind brief-validator's validation-time check. No circular import (brief-validator already imports the same symbol). +2 tests (drops-invalid / keeps-valid). - Native effort: (SHIP, static additive): effort: frontmatter on 8 agents — retrieval (task-finder, git-historian, dependency-tracer, architecture-mapper) = medium; adversarial-reasoning (plan-critic, risk-assessor, contrarian-researcher, review-coordinator) = high. The other 15 stay unset -> inherit Opus-4.8 default (high). This per-spawn REASONING effort is a different axis from brief phase_signals.effort (ORCHESTRATION shape) per the S3 decision. - Doc-truth + axis distinction: new canonical docs/profiles.md §Model & effort axes (opus->Opus 4.8 default-high; orchestration vs reasoning effort table; native-effort precedence; per-agent levels). Short notes in CLAUDE.md (after Agents table) and README.md (Cost profile), both pointing to profiles.md. - Open (non-blocking, unchanged): only STATIC effort shipped — the verified-safe minimum. Profile-driven DYNAMIC effort still needs verification of the per-spawn effort param or env-var injection. Matrix: new "S4 resolutions" section. Tests 582 total / 580 pass / 0 fail / 2 skip (was 578 pass; +2). claude plugin validate passes (only pre-existing root-CLAUDE.md warning). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LqBYc8Ltrk7LipyJmGxXiB
This commit is contained in:
parent
fbf83f2271
commit
fdd3ad80d7
14 changed files with 102 additions and 1 deletions
|
|
@ -108,6 +108,16 @@ S3 was a decision-gate. Two-track evidence (codebase map of `phase_signals`/`pha
|
|||
|
||||
**S4 scope (now unblocked):** (1) resolver MAJOR model-gate fix; (2) additive native `effort:` — verified-safe minimum is static per-agent frontmatter (retrieval agents `task-finder`/`git-historian`/`dependency-tracer`/`architecture-mapper` lower; reasoning agents `plan-critic`/`risk-assessor`/`contrarian-researcher`/`review-coordinator` stay high); (3) doc-truth model/effort updates; (4) document the effort-axis distinction. **Open (non-blocking):** profile-driven *dynamic* effort needs verification — per-spawn `effort` param is **unverified** (only `model` is documented per-spawn); dynamic would otherwise need env-var injection.
|
||||
|
||||
## S4 resolutions (W2 implementation — 2026-06-18)
|
||||
|
||||
S4 implemented the four scope items above. TDD: a failing test was written first for the resolver gate, then the fix; full suite green throughout.
|
||||
|
||||
- **Resolver MAJOR — FIXED.** `lib/profiles/phase-signal-resolver.mjs` now imports `BASE_ALLOWED_MODELS` from `profile-validator.mjs` and gates `model` (`if ('model' in entry && BASE_ALLOWED_MODELS.includes(entry.model))`), mirroring the `EFFORT_LEVELS` gate one line above. Out-of-allowlist models (e.g. `gpt-4`, `haiku`) are now dropped (treated as absent) instead of handed through to an agent spawn — defense-in-depth behind `brief-validator`'s validation-time check. 2 new tests in `tests/lib/phase-signal-resolver.test.mjs` (drops-invalid + keeps-valid). No circular import (`brief-validator` already imports the same symbol; `profile-validator` depends only on `util/`).
|
||||
- **Native `effort:` — SHIPPED (static, additive).** Added `effort:` frontmatter to the 8 named agents: retrieval (`task-finder`, `git-historian`, `dependency-tracer`, `architecture-mapper`) → `medium`; adversarial-reasoning (`plan-critic`, `risk-assessor`, `contrarian-researcher`, `review-coordinator`) → `high`. The other 15 agents stay unset → inherit Opus-4.8 default (`high`). `claude plugin validate` passes (effort is a valid frontmatter field; only the pre-existing root-CLAUDE.md warning remains).
|
||||
- **Doc-truth + axis distinction — DONE.** New canonical section `docs/profiles.md` §Model & effort axes (opus→Opus 4.8 default-`high`; orchestration `phase_signals.effort` vs native reasoning `effort:` table; native-effort precedence; which agents carry which level). Short note added to `CLAUDE.md` (after Agents table) and `README.md` (Cost profile section), both pointing to the profiles.md section.
|
||||
- **Open (non-blocking, unchanged).** Only *static* per-agent effort shipped — the verified-safe minimum. Profile-driven *dynamic* effort still needs verification of the per-spawn `effort` param (only `model` is documented per-spawn) or env-var injection (`CLAUDE_CODE_EFFORT_LEVEL`). Deferred to W2 profile design.
|
||||
- **Tests:** 582 total / 580 pass / 0 fail / 2 skip (was 578 pass; +2 new resolver tests).
|
||||
|
||||
## W1 — Orchestration architecture (multi-week, empirical)
|
||||
|
||||
| ID | Change (version) | Type | Voyage relevance | Decision | Rationale |
|
||||
|
|
|
|||
|
|
@ -26,6 +26,45 @@ runs (Step 17 calibration was deferred — see
|
|||
`tests/synthetic/profile-jaccard-calibration.md`). If you observe
|
||||
economy-plan quality regressions, fall back to `balanced`.
|
||||
|
||||
## Model & effort axes
|
||||
|
||||
`opus` and `sonnet` are model **aliases**, not pinned ids. As of Claude Code
|
||||
2.1.154 the `opus` alias resolves to **Opus 4.8**, whose default reasoning
|
||||
effort is **`high`**; `sonnet` resolves to Sonnet 4.6. The profile table above
|
||||
selects *which alias* runs each phase — it does not touch reasoning effort.
|
||||
|
||||
Two different things share the word "effort" in Voyage. They are **orthogonal
|
||||
axes** — same name, different mechanism:
|
||||
|
||||
| | **Orchestration effort** | **Reasoning effort (native)** |
|
||||
|---|---|---|
|
||||
| Where | brief `phase_signals.effort`, consumed by command prose | native Claude Code `effort:` in agent frontmatter |
|
||||
| Values | `low` / `standard` / `high` | `low` / `medium` / `high` / `xhigh` / `max` |
|
||||
| Controls | *which agents/passes/gates run* (swarm cardinality, gate strictness, sequential-vs-parallel) | *per-spawn reasoning-token budget* the harness gives one agent |
|
||||
| `low` means | "run fewer agents" (the `--quick`-equivalent code-path) | "think with a smaller budget" |
|
||||
| Applied by | Voyage command logic | the harness, at spawn time |
|
||||
|
||||
The `phase-signal-resolver.mjs` helper only reads the **orchestration** axis
|
||||
(`phase_signals.effort`, gated against `low/standard/high`) plus the optional
|
||||
per-phase `model` (gated against `['sonnet','opus']`). It never emits native
|
||||
`effort:`.
|
||||
|
||||
**Native `effort:` on agents.** Voyage sets the reasoning axis statically on
|
||||
selected agents, additively over the Opus-4.8 default:
|
||||
|
||||
- **Retrieval agents → `medium`:** `task-finder`, `git-historian`,
|
||||
`dependency-tracer`, `architecture-mapper` (structured discovery, not deep
|
||||
multi-step reasoning).
|
||||
- **Adversarial-reasoning agents → `high`:** `plan-critic`, `risk-assessor`,
|
||||
`contrarian-researcher`, `review-coordinator` (synthesis and stress-testing
|
||||
where reasoning depth pays off).
|
||||
- **All other agents:** unset → inherit the model default (Opus 4.8 = `high`).
|
||||
|
||||
Native-effort precedence (harness): env `CLAUDE_CODE_EFFORT_LEVEL` > frontmatter
|
||||
`effort:` > session setting > model default. `MAX_THINKING_TOKENS=0` (or
|
||||
`--thinking disabled`) overrides effort entirely. Enterprise `availableModels`
|
||||
constrains the *model* alias only — it does **not** bound effort.
|
||||
|
||||
## Decision tree
|
||||
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue