Add "long answer opening with a conversational word is still recovered"
(regression guard); retarget the skipped-preamble case to the borderline band;
drop the external "#N" annotations in favor of self-explanatory comments.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- isSubstantiveAnswer: restore the original "≥200 chars ⇒ real answer"
unconditional accept (the preamble filter now applies only in the
borderline 80–200 band). Applying preambleRe regardless of length regressed
the recovery path: a long front-loaded answer opening with a conversational
word ("Sure,", "Let me explain:", "First,") was wrongly discarded
(flagged by glm-5.2 + claude-code/opus). The NVD-style planning-narration
case is already handled by the citation-dominance check, not this filter.
- citations dedup: compare with <url> angle-bracket wrappers stripped, so a
front-loaded turn that listed the same sources unwrapped still suppresses the
duplicate block.
- doc: spell out the citationLabelRe leading class members (+ list markers);
drop the stale "gated by preamble" note on recoverMinChars.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
finalOutput already recovered a front-loaded answer when the terminal
(no-tool-call) turn was empty or a short back-reference. But some models
(glm-5.2 via a "cite" tool) front-load the prose answer into an earlier
tool-call turn and close with a terminal turn that is ONLY their sources
("Sources: [pcprice.watch](url) (...), [ebay](url) (...)"). That list is
neither empty nor a back-reference, so it was returned verbatim and the real
answer was discarded (mort issue #1418: the user got a bare sources list; the
good answer was only visible in the trace).
Add isCitationsOnly: a terminal that OPENS with a sources/citations heading,
carries a link, and is dominated by that citation structure (once heading+links
are stripped, little prose remains). Unlike a back-reference the citations are
real content, so finalOutput recovers the prior substantive answer and APPENDS
the citations below it (deduped). The dominance check keeps a real prose answer
that merely opens with "Source: ... http://..." from being misclassified; the ^
anchor keeps an answer that ends with a Sources section from matching; the
citations branch is decoupled from the terminal-length ratio so a CONCISE
front-loaded answer is still recovered; and preambleRe now applies regardless of
length so planning narration is never recovered. Healthy terminal answers are
unchanged; zero extra model calls.
Tests: TestIsCitationsOnly (19 cases incl. bold/ATX/backref/prose negatives),
new TestFinalOutput cases (concise+long-citations, source-led-not-hijacked,
long-preamble-skipped, dedup), and end-to-end
TestRun_RecoversFrontLoadedAnswerWithCitations. Full agent suite green (-race).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>