docs(trekresearch): deep-research engine is operator-only from CC 2.1.218; document the real window
Claude Code 2.1.218 changed /deep-research to start only when invoked
manually; from there the Skill tool refuses a model invocation outright
with `disable-model-invocation` (measured in a real `--engine deep-research`
run 2026-09-01 18:32Z - the SC3 fallback to swarm held). The engine was
built against 2.1.196 and the prose still promised a path Claude Code has
removed ("requires Claude Code 2.1.154+").
The flag is KEPT as an additive opt-in that never hard-fails. Prose only:
no lib/ change, no adapter-contract change, no default change, no version
bump.
- commands/trekresearch.md: flag bullet states the closed window
`2.1.154 <= CC < 2.1.218`; the pre-gate gained an UPPER ceiling (still a
numeric comparison, not a string one) that skips straight to the fallback
with reason `disable-model-invocation`; step 3 names the Skill-tool
refusal as a known failure manifestation; step 4 lists the reason tokens.
- docs/command-modes.md + README.md: same window, one sentence each, on the
reference row itself.
- CHANGELOG.md: Unreleased/Docs entry.
Tests first (Iron Law): tests/lib/doc-consistency.test.mjs gained a pin
requiring 2.1.218 + disable-model-invocation on all three surfaces, on both
reference rows, and in both load-bearing regions of the command (flag
bullet + pre-gate). Seen red on all three surfaces before the prose change.
tests/commands/trekresearch-engine.test.mjs unchanged and green.
New baseline: 1024 tests, 1022 pass / 0 fail / 2 skip (was 1023: 1021/0/2).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
bcd2600918
commit
4e5523fb0a
5 changed files with 94 additions and 11 deletions
19
CHANGELOG.md
19
CHANGELOG.md
|
|
@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Docs
|
||||||
|
|
||||||
|
- **`/trekresearch --engine deep-research`: document the real version window.**
|
||||||
|
Claude Code **2.1.218** changed `/deep-research` to start only when the operator
|
||||||
|
invokes it; from there the Skill tool refuses a model invocation outright with
|
||||||
|
`disable-model-invocation` (measured in a real `--engine deep-research` run on
|
||||||
|
2026-09-01 — the SC3 fallback to `swarm` held). The engine was built against
|
||||||
|
2.1.196 and the prose still promised a path Claude Code has removed
|
||||||
|
("requires Claude Code 2.1.154+"). `commands/trekresearch.md` (flag bullet +
|
||||||
|
pre-gate + fallback reason tokens), `docs/command-modes.md` and `README.md` now
|
||||||
|
state the closed window `2.1.154 <= CC < 2.1.218` and name
|
||||||
|
`disable-model-invocation` as the expected fallback reason on any current CC.
|
||||||
|
The pre-gate gained an upper ceiling (still a numeric comparison, not a string
|
||||||
|
one). **The flag is kept** as an additive opt-in that never hard-fails; no
|
||||||
|
`lib/` change, no adapter-contract change, no default change, no version bump.
|
||||||
|
Pinned by `tests/lib/doc-consistency.test.mjs`.
|
||||||
|
|
||||||
## v5.10.0 — 2026-08-18 — STORM bounded research loop (default-off) + the Agent-tool `name` spawn defect
|
## v5.10.0 — 2026-08-18 — STORM bounded research loop (default-off) + the Agent-tool `name` spawn defect
|
||||||
|
|
||||||
Additive. Every new research mechanism ships **inert**: `VOYAGE_STORM_ENABLED` is
|
Additive. Every new research mechanism ships **inert**: `VOYAGE_STORM_ENABLED` is
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ Output:
|
||||||
| **External** | `/trekresearch --external <question>` | Only external research agents (skip codebase analysis) |
|
| **External** | `/trekresearch --external <question>` | Only external research agents (skip codebase analysis) |
|
||||||
| **Foreground** | `/trekresearch --fg <question>` | No-op alias (foreground is default since v2.4.0) |
|
| **Foreground** | `/trekresearch --fg <question>` | No-op alias (foreground is default since v2.4.0) |
|
||||||
| **Profile** | `/trekresearch --profile <name> <question>` | (v4.1.0) Pin model profile for the research phase. See [Profile system](#profile-system-v410). |
|
| **Profile** | `/trekresearch --profile <name> <question>` | (v4.1.0) Pin model profile for the research phase. See [Profile system](#profile-system-v410). |
|
||||||
| **Engine** | `/trekresearch --external --engine deep-research <question>` | Delegate the external phase to Claude Code's built-in `/deep-research` workflow; falls back to `swarm` if unavailable. Default `swarm`. |
|
| **Engine** | `/trekresearch --external --engine deep-research <question>` | Delegate the external phase to Claude Code's built-in `/deep-research` workflow. Only works on `2.1.154 <= CC < 2.1.218`; from **2.1.218** `/deep-research` is operator-invoked only (Skill tool: `disable-model-invocation`), so it always falls back to `swarm`. Never hard-fails. Default `swarm`. |
|
||||||
|
|
||||||
Flags combine: `--project <dir> --external`.
|
Flags combine: `--project <dir> --external`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,14 @@ Supported flags:
|
||||||
behavior). `swarm` runs Voyage's own external-research agent swarm;
|
behavior). `swarm` runs Voyage's own external-research agent swarm;
|
||||||
`deep-research` delegates the external phase to Claude Code's built-in
|
`deep-research` delegates the external phase to Claude Code's built-in
|
||||||
`/deep-research` dynamic workflow and adapts its report into the research-brief
|
`/deep-research` dynamic workflow and adapts its report into the research-brief
|
||||||
schema (requires Claude Code 2.1.154+ and dynamic workflows enabled; falls back
|
schema. **The delegation only works inside a closed version window:
|
||||||
to `swarm` and notes the fallback if unavailable — never hard-fails). Orthogonal
|
`2.1.154 <= CC < 2.1.218`** (dynamic workflows enabled). From Claude Code
|
||||||
to `--profile`/`phase_signals`; only affects the external phase. Set
|
**2.1.218** `/deep-research` starts only when the operator invokes it, and the
|
||||||
|
Skill tool refuses a model invocation outright (`disable-model-invocation`), so
|
||||||
|
on 2.1.218 or newer the engine **always** falls back to `swarm`. The flag is
|
||||||
|
kept as an additive opt-in and **never hard-fails**: outside the window it
|
||||||
|
degrades to `swarm` and logs the reason. Orthogonal to
|
||||||
|
`--profile`/`phase_signals`; only affects the external phase. Set
|
||||||
**engine = {swarm|deep-research}** (the *requested* engine).
|
**engine = {swarm|deep-research}** (the *requested* engine).
|
||||||
|
|
||||||
Flags can be combined:
|
Flags can be combined:
|
||||||
|
|
@ -328,9 +333,13 @@ changes nothing (SC1). Keep the native-swarm anchors intact ("in parallel",
|
||||||
|
|
||||||
1. **Coarse pre-gate (best-effort, NOT a trust signal).** `Bash: claude --version`;
|
1. **Coarse pre-gate (best-effort, NOT a trust signal).** `Bash: claude --version`;
|
||||||
parse the leading `X.Y.Z` (e.g. from `2.1.196 (Claude Code)`) and compare
|
parse the leading `X.Y.Z` (e.g. from `2.1.196 (Claude Code)`) and compare
|
||||||
numerically against `2.1.154` — split each on `.` and compare major, then minor,
|
numerically against **both ends** of the supported window
|
||||||
|
`2.1.154 <= version < 2.1.218` — split each on `.` and compare major, then minor,
|
||||||
then patch as integers (do NOT string-compare; lexical comparison mis-orders
|
then patch as integers (do NOT string-compare; lexical comparison mis-orders
|
||||||
multi-digit patch numbers). If the version is `< 2.1.154`, OR if
|
multi-digit patch numbers). If the version is `< 2.1.154` (below the
|
||||||
|
dynamic-workflows floor), OR `>= 2.1.218` (the ceiling: `/deep-research` starts
|
||||||
|
only when the operator invokes it, and the Skill tool refuses a model invocation
|
||||||
|
with `disable-model-invocation` — see step 4's reason token), OR if
|
||||||
`disableWorkflows: true` / `CLAUDE_CODE_DISABLE_WORKFLOWS=1` is set, skip to the
|
`disableWorkflows: true` / `CLAUDE_CODE_DISABLE_WORKFLOWS=1` is set, skip to the
|
||||||
fallback (step 4). **If `claude` is not on PATH inside the Bash tool (possible
|
fallback (step 4). **If `claude` is not on PATH inside the Bash tool (possible
|
||||||
under `claude -p`) or the version cannot be parsed, treat the pre-gate as
|
under `claude -p`) or the version cannot be parsed, treat the pre-gate as
|
||||||
|
|
@ -347,14 +356,18 @@ changes nothing (SC1). Keep the native-swarm anchors intact ("in parallel",
|
||||||
`/deep-research` report actually landed in context — substantive findings with
|
`/deep-research` report actually landed in context — substantive findings with
|
||||||
citations, not an empty/denied/errored turn and not bare error text. This check
|
citations, not an empty/denied/errored turn and not bare error text. This check
|
||||||
must be **robust to all failure manifestations** (workflow disabled, approval
|
must be **robust to all failure manifestations** (workflow disabled, approval
|
||||||
denied, runtime error, empty output), because the disabled-headless behavior is
|
denied, runtime error, empty output, or the Skill tool refusing with
|
||||||
undocumented: no recognizable cited report in context → fall back, regardless of
|
`disable-model-invocation` on CC 2.1.218+), because the disabled-headless
|
||||||
how the failure surfaces.
|
behavior is undocumented: no recognizable cited report in context → fall back,
|
||||||
|
regardless of how the failure surfaces.
|
||||||
|
|
||||||
4. **On no real report (fallback):** set `effective_engine = swarm`, run the swarm
|
4. **On no real report (fallback):** set `effective_engine = swarm`, run the swarm
|
||||||
blocks below, and **log the fallback at this decision point** — print
|
blocks below, and **log the fallback at this decision point** — print
|
||||||
`Engine: deep-research → swarm (fallback: <reason>)` and carry the reason into the
|
`Engine: deep-research → swarm (fallback: <reason>)` and carry the reason into the
|
||||||
Phase-8 Present summary and the brief's `## Executive Summary`. **NEVER fabricate
|
Phase-8 Present summary and the brief's `## Executive Summary`. Known reason
|
||||||
|
tokens: `disable-model-invocation` (CC >= 2.1.218 — the expected reason on any
|
||||||
|
current Claude Code), `version-below-floor`, `workflows-disabled`,
|
||||||
|
`no-cited-report`. **NEVER fabricate
|
||||||
or synthesize a substitute report** — a structurally-valid-but-invented brief
|
or synthesize a substitute report** — a structurally-valid-but-invented brief
|
||||||
passes the structure-only validator and silently poisons `/trekplan`; that is the
|
passes the structure-only validator and silently poisons `/trekplan`; that is the
|
||||||
worst outcome of this feature.
|
worst outcome of this feature.
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ Always interactive. Phase 3 is a section-driven completeness loop (no hard cap o
|
||||||
| `--gates {true\|false}` | (v3.4.0) Boolean autonomy-gate flag; present → gating on. Policy (`gates_mode`) detailed under `## Autonomy mode` in `docs/operations.md`. |
|
| `--gates {true\|false}` | (v3.4.0) Boolean autonomy-gate flag; present → gating on. Policy (`gates_mode`) detailed under `## Autonomy mode` in `docs/operations.md`. |
|
||||||
| `--min-brief-version <ver>` | (S18) Warn — never block — if an attached `--project` brief declares a version below `<ver>` (e.g. `2.2`), i.e. sidesteps framing enforcement |
|
| `--min-brief-version <ver>` | (S18) Warn — never block — if an attached `--project` brief declares a version below `<ver>` (e.g. `2.2`), i.e. sidesteps framing enforcement |
|
||||||
| `--profile <name>` | (v4.1.0) Model profile for the research phase. |
|
| `--profile <name>` | (v4.1.0) Model profile for the research phase. |
|
||||||
| `--engine {swarm\|deep-research}` | (deep-research-engine) Opt-in external-research engine; `deep-research` delegates the external phase to Claude Code's built-in `/deep-research` workflow (CC 2.1.154+), falls back to `swarm`. Default `swarm`. |
|
| `--engine {swarm\|deep-research}` | (deep-research-engine) Opt-in external-research engine; `deep-research` delegates the external phase to Claude Code's built-in `/deep-research` workflow, which only works on `2.1.154 <= CC < 2.1.218` — from **2.1.218** `/deep-research` is operator-invoked only (the Skill tool refuses with `disable-model-invocation`), so the engine always falls back to `swarm`. Never hard-fails. Default `swarm`. |
|
||||||
|
|
||||||
Flags combine: `--project <dir> --local`, `--external --quick`.
|
Flags combine: `--project <dir> --local`, `--external --quick`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1117,6 +1117,57 @@ test('deep-research-engine: --engine is documented + consistent across surfaces'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('deep-research-engine: the CC 2.1.218 operator-only ceiling is documented on every surface', () => {
|
||||||
|
// CC 2.1.218 changed /deep-research to "start only when invoked manually"; from
|
||||||
|
// there the Skill tool refuses a model invocation outright with
|
||||||
|
// `disable-model-invocation`. The flag stays (additive opt-in, always degrades to
|
||||||
|
// swarm), but no surface may keep promising a path Claude Code has removed, and
|
||||||
|
// none may leave `2.1.154+` standing alone as the engine's requirement.
|
||||||
|
const SURFACES = ['commands/trekresearch.md', 'docs/command-modes.md', 'README.md'];
|
||||||
|
for (const f of SURFACES) {
|
||||||
|
const body = read(f);
|
||||||
|
assert.ok(
|
||||||
|
body.includes('2.1.218'),
|
||||||
|
`${f} must document the CC 2.1.218 ceiling for the deep-research engine`,
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
body.includes('disable-model-invocation'),
|
||||||
|
`${f} must name disable-model-invocation as the fallback reason from CC 2.1.218`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The one-line reference rows carry the whole truth on their own line — an
|
||||||
|
// operator reading the flag table never scrolls to the command prose.
|
||||||
|
const ROWS = [
|
||||||
|
['docs/command-modes.md', /^.*`--engine \{swarm\\\|deep-research\}`.*$/m],
|
||||||
|
['README.md', /^\|\s*\*\*Engine\*\*.*$/m],
|
||||||
|
];
|
||||||
|
for (const [f, re] of ROWS) {
|
||||||
|
const m = read(f).match(re);
|
||||||
|
assert.ok(m, `${f} must still carry the --engine reference row`);
|
||||||
|
assert.ok(
|
||||||
|
m[0].includes('2.1.218') && m[0].includes('disable-model-invocation'),
|
||||||
|
`${f} --engine row must state the real window (2.1.218 + disable-model-invocation)`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both load-bearing regions of the command itself: the flag bullet and the
|
||||||
|
// pre-gate that decides whether the delegation is attempted at all.
|
||||||
|
const research = read('commands/trekresearch.md');
|
||||||
|
const bullet = research.match(/8\. `--engine <name>`[\s\S]*?Flags can be combined/);
|
||||||
|
assert.ok(bullet, 'trekresearch.md must still carry the --engine flag bullet');
|
||||||
|
assert.ok(
|
||||||
|
bullet[0].includes('2.1.218') && bullet[0].includes('disable-model-invocation'),
|
||||||
|
'trekresearch.md --engine bullet must state the real window, not just the 2.1.154 floor',
|
||||||
|
);
|
||||||
|
const pregate = research.match(/\*\*Coarse pre-gate[\s\S]*?authoritative guard\./);
|
||||||
|
assert.ok(pregate, 'trekresearch.md must still carry the deep-research pre-gate');
|
||||||
|
assert.ok(
|
||||||
|
pregate[0].includes('2.1.218'),
|
||||||
|
'the pre-gate must carry an upper ceiling at 2.1.218, not only the 2.1.154 floor',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// ── STORM bounded loop — env-vars documented across the four surfaces ──────
|
// ── STORM bounded loop — env-vars documented across the four surfaces ──────
|
||||||
// Same cross-doc shape as the --engine pin above. An operator-facing switch
|
// Same cross-doc shape as the --engine pin above. An operator-facing switch
|
||||||
// documented on one surface is a switch most operators never find; and the
|
// documented on one surface is a switch most operators never find; and the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue