voyage/docs
Kjell Tore Guttormsen 7dc0add768 feat(research-loop-cap): give the discovery ceiling a reader, not just a sentence
The bounded-cost NFR asks for explicit ceilings on BOTH axes - max
conversation turns and max discovered dimensions. The turn axis got
MAX_CONV_TURNS, a ledger-backed reader and a PreToolUse enforcer. The
discovery axis got one sentence in Phase 4.5 prose ("append candidates only
while the whole list stays at or below maxDimensions: 8") with no constant
of its own, no reader, and no test that a run exceeding it is caught. That
is the brief_reviewer_iter_cap shape the operator decision warned about: a
cap nothing reads.

checkDimensionCeiling() is the reader, exposed on the CLI as
--check-dimensions N (exit 0 within, exit 1 rejected), and Phase 4.5 step 3
now calls it once the final list is settled instead of merely describing the
bound.

Three deliberate choices:

- The ceiling IS MAX_TOTAL_DIMENSIONS, the constant that sizes the turn
  budget. Both axes read one settings.json:16 value, so they cannot end up
  enforcing different numbers - a second constant is how that drift starts.
- An unreadable count is REJECTED ('abc', null, undefined, {}, -1, NaN,
  non-integers). A cost ceiling that waves through what it cannot measure is
  not a ceiling.
- --check-dimensions requires no run id, effort or VOYAGE_STORM_ENABLED.
  Phase 4.5 never calls the budget gate - that is why its skip-guard reads
  the flag directly - so the ceiling check must not inherit the gate's
  preconditions.

The mitigation the review already verified still holds and is unchanged:
MAX_TOTAL_DIMENSIONS bounds actual retrieval cost regardless of how many
dimensions discovery appends. What was missing was anything that FAILS on a
list over the bound, and now a run over it is rejected by exit code.

Review finding 96a3ee51152dfe72aca703f771843f2f3639e7b6 (MINOR).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuGhWAbWyRFBFeemfhxoVv
2026-08-12 23:09:11 +02:00
..
eval-corpus feat(eval): SKAL-1·4b offline gold-scored output eval 2026-06-30 09:00:33 +02:00
agent-description-token-trim-brief.md docs(voyage): track agent-description token-trim brief (M4 input) 2026-06-26 20:15:34 +02:00
architecture.md feat(research-loop-cap): give the discovery ceiling a reader, not just a sentence 2026-08-12 23:09:11 +02:00
balance-backlog-plan.md chore(voyage): S34 — V30 economy-profile self-declares experimental (uncalibrated Jaccard floor) 2026-06-20 10:18:38 +02:00
cc-upgrade-2.1.181-decision-matrix.md docs(voyage): S20 — CC-04/T3 verified clean (research-agent MCP degradation under --strict-mcp-config) 2026-06-19 14:08:51 +02:00
claudemd-token-trim-brief.md docs(claude-md): trim CLAUDE.md to invariants (always-loaded token trim, S53) 2026-06-29 14:49:32 +02:00
command-modes.md fix(research-loop-cap): floor the turn cap before the guard, not after 2026-08-12 22:46:35 +02:00
deep-research-engine-brief.md docs(research): resolve deep-research-engine topic-1 (/deep-research trigging) 2026-06-30 10:39:03 +02:00
deep-research-engine-research.md docs(research): remove literal keyword tripping verify SC1 2026-08-12 20:29:35 +02:00
devils-advocate-plan.md docs(voyage): plan S14 devil's-advocate audit via Dynamic Workflow 2026-06-18 18:30:05 +02:00
devils-advocate-results.md docs(voyage): S22 — happy-path dogfood results (blind spot #1/#4 measured) 2026-06-19 20:53:21 +02:00
HANDOVER-CONTRACTS.md docs(voyage): fable-aware allowlist prose in contracts, architecture, templates, CLAUDE.md 2026-07-02 17:14:35 +02:00
observability.md docs(observability): document token-usage schema + main-context v1 scope 2026-06-26 14:47:24 +02:00
operations.md docs(voyage): add fable profile row and correct model-allowlist prose 2026-07-02 17:13:15 +02:00
profiles.md docs(voyage): add fable profile row and correct model-allowlist prose 2026-07-02 17:13:15 +02:00
S22-happy-path-dogfood.md docs(voyage): S27 — close version-skew (S22 defect #4) as no-op 2026-06-19 22:11:25 +02:00
SLDC-AI.pdf fix(cap): fail closed when the ledger cannot be READ, in both modules 2026-08-12 22:49:08 +02:00
spike-pretooluse-subagent-reach.md fix(cap-hook): shrink the inherited deny window and print the way out of it 2026-08-12 23:06:47 +02:00
storm-measurement.md fix(storm-measure): check BOTH halves of the activation SC, not just the count delta 2026-08-12 23:01:59 +02:00
subagent-delegation-audit.md feat(voyage)!: bulk content rewrite ultra -> voyage/trek prose [skip-docs] 2026-05-05 15:08:20 +02:00
T1-cc26-delegated-orchestration.md docs(voyage): S7 (W1/CC-26 gate) — T1 feasibility probe + measurement design 2026-06-18 13:21:09 +02:00
T1-synthesis-poc-results.md feat(voyage): S12 — NW3 synthesis-agent built + measured → declined per measurement [skip-docs] 2026-06-18 17:58:39 +02:00
T2-bakeoff-results.md fix(voyage): S21 — close IPv4-mapped IPv6 SSRF bypass + security/safety audit (blind spot #2) 2026-06-19 20:02:56 +02:00
T2-cc27-workflow-substrate.md docs(voyage): S8 (W1/CC-27 gate) — T2 Workflow-substrate probe + measurement design 2026-06-18 13:34:05 +02:00
voyage-vs-cc-balance-analysis.md chore(voyage): S34 — V30 economy-profile self-declares experimental (uncalibrated Jaccard floor) 2026-06-20 10:18:38 +02:00
voyage-vs-cc-balance-charter.md docs(voyage): add Voyage-vs-CC balance-analysis charter (next-session launch spec) 2026-06-20 06:34:40 +02:00
W1-narrow-wins-plan.md docs(voyage): plan W1 narrow-wins implementation (NW1/NW2/NW3, S9->) 2026-06-18 13:41:20 +02:00