88b94576af
- 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>