Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/JOURNAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 10 additions & 1 deletion src/shared/corpus-prompts.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

// ------------------------------------------------------------------
Expand Down
8 changes: 7 additions & 1 deletion src/shared/llm-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
Loading