From f8e28b53a6d68b53d2a718bb7f0cb500258e10b0 Mon Sep 17 00:00:00 2001 From: Bryan Matthew Simonson <7519963+bryanmatthewsimonson@users.noreply.github.com> Date: Sat, 18 Jul 2026 12:46:49 -0700 Subject: [PATCH] fix(synthesis): raise reduce output cap so the breadth brief finishes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The corpus-v3 breadth nudge (list EVERY holder, enumerate ALL cruxes) pushed the reduce for a large case (~125 members) past MAX_REDUCE_OUTPUT_TOKENS=16384 — runCorpusReducePass surfaced stop_reason: 'max_tokens' as "The synthesis hit its output limit before finishing." On Sonnet 5 it hit sooner: the reduce omits `thinking`, so adaptive thinking is on by default and its tokens share the same budget. Raise MAX_REDUCE_OUTPUT_TOKENS 16384 -> 32768 (far under every current model's 128k output ceiling) and CORPUS_REDUCE_TIMEOUT_MS 300000 -> 420000 so the now-larger brief can finish on the slower Opus tier instead of trading a token-cap failure for an abort. No prompt/tool/digest change, so no version bump — the cached map extracts and brief staleness keys are untouched. Co-Authored-By: Claude Opus 4.8 --- docs/JOURNAL.md | 26 ++++++++++++++++++++++++++ src/shared/corpus-prompts.js | 11 ++++++++++- src/shared/llm-client.js | 8 +++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/JOURNAL.md b/docs/JOURNAL.md index 3f0ebc9..129fc3c 100644 --- a/docs/JOURNAL.md +++ b/docs/JOURNAL.md @@ -19,6 +19,32 @@ or files, and the "so-what" for future readers. --- +## 2026-07-18 — Corpus reduce truncated on the breadth brief ("hit its output limit") + +**Tags:** bug, design + +After the corpus-v3 breadth nudge (list EVERY holder, enumerate ALL cruxes), +the reduce for a large case (~125 members) started failing with "The +synthesis hit its output limit before finishing" — `runCorpusReducePass` +seeing `stop_reason: 'max_tokens'` against `MAX_REDUCE_OUTPUT_TOKENS = +16384`. Two compounding causes: (1) the breadth brief legitimately runs +18-25k output tokens now (every position's holders as full 64-hex hashes, +all cruxes, load-bearing, the proposal queue); (2) the reduce omits the +`thinking` param, so on **Sonnet 5** adaptive thinking is ON by default and +its thinking tokens share the same `max_tokens` budget — Sonnet had *less* +room for the brief than the earlier (pre-nudge) Opus run that fit in 16384. + +Fix (surgical, no prompt change — preserves the graded breadth): +`MAX_REDUCE_OUTPUT_TOKENS` 16384 → 32768 (well under every current model's +128k output ceiling), and `CORPUS_REDUCE_TIMEOUT_MS` 300000 → 420000 so the +now-larger brief can finish on the slower Opus tier (~55 tok/s × ~22k tokens +≈ 400s) instead of trading a token-cap failure for an abort. The reduce is +the one long single fetch in the corpus flow; its pending sendResponse keeps +the MV3 SW alive. Deliberately NOT a prompt/tool/digest change → no +`MAP_PROMPT_VERSION`/`CORPUS_PROMPT_VERSION` bump → the ~100 cached map +extracts and brief-staleness keys are untouched. See +`src/shared/corpus-prompts.js`, `src/shared/llm-client.js`. + ## 2026-07-18 — A background re-render KILLED the running corpus analysis (token-scoped render guard) **Tags:** bug, pattern diff --git a/src/shared/corpus-prompts.js b/src/shared/corpus-prompts.js index 8b7ecb9..7da1fcd 100644 --- a/src/shared/corpus-prompts.js +++ b/src/shared/corpus-prompts.js @@ -52,7 +52,16 @@ export const HYPOTHESIS_EDGE_TOOL_NAME = 'propose_hypothesis_edges'; export const MAX_MEMBER_INPUT_CHARS = 60000; export const MAX_CLAIMS_DIGEST_CHARS = 4000; export const MAX_MAP_OUTPUT_TOKENS = 8192; -export const MAX_REDUCE_OUTPUT_TOKENS = 16384; +// The reduce emits the WHOLE-corpus brief: every position's holders, ALL +// cruxes, the load-bearing claims, and the proposal queue (the corpus-v3 +// breadth nudge above). For a large case (~125 members) that legitimately +// runs 18-25k output tokens, and on Sonnet 5 — where `thinking` is omitted +// so adaptive thinking is ON by default — those thinking tokens share this +// same budget. 16384 truncated it ("hit its output limit before finishing"); +// 32768 fits the breadth brief with headroom and stays far under every +// current model's 128k output ceiling. NOT a prompt/tool/digest change, so +// no version bump — the map cache and brief staleness are unaffected. +export const MAX_REDUCE_OUTPUT_TOKENS = 32768; export const MAX_HYPOTHESIS_EDGE_OUTPUT_TOKENS = 8192; // ------------------------------------------------------------------ diff --git a/src/shared/llm-client.js b/src/shared/llm-client.js index 0a36f83..bc18615 100644 --- a/src/shared/llm-client.js +++ b/src/shared/llm-client.js @@ -539,7 +539,13 @@ export async function runAuditModulePass(req = {}) { // ------------------------------------------------------------------ const CORPUS_MAP_TIMEOUT_MS = 120000; -const CORPUS_REDUCE_TIMEOUT_MS = 300000; +// The reduce is the ONE long single fetch in the corpus flow (the map phase +// is many short calls). With MAX_REDUCE_OUTPUT_TOKENS raised to 32768, a +// full breadth brief can generate ~20-25k tokens, which on the slower +// (Opus-tier) models runs past the old 300s cap — so give it 7 min rather +// than trade a token-cap failure for an abort. The pending sendResponse +// keeps the MV3 service worker alive for the duration. +const CORPUS_REDUCE_TIMEOUT_MS = 420000; /** Gating snapshot for the portal's "Analyze corpus" control. */ export async function getCorpusConfig() {