Commit 2785fcf
feat: add multi-persona academic critique system (critique.py)
Adds researchclaw/critique.py providing a configurable multi-persona
review panel for Stage 18 (PEER_REVIEW).
Four complementary review voices:
- board (default): scathing academic panel, terse imperatives, zero
hedging tolerance, grounded in Bourne's Rules and CASP methodology
- balanced: three-perspective reviewer (methodology, domain, statistics),
constructive and thorough; good for first-pass review
- tank: Silicon Valley VC panel evaluating commercialization, IP
defensibility, and impact potential
- bros: tech-bro startup CEO voice translating academic rigor into
venture-speak with the same technical precision
All personas share CRITIQUE_FRAMEWORK (Bourne + CASP + tagging rules)
and emit machine-parseable tags for cross-run learning:
[FATAL], [EVIDENCE?], [HEDGE], [POLISH].
Public API:
- build_critique_prompt(draft, evidence, prior_critiques, persona)
- build_panel_prompt(draft, evidence, prior_critiques, personas)
- format_critique_lessons(reviews) -> list[str] for prompt injection
- available_personas() -> {name: description}
Bug fixes addressed in review:
- build_panel_prompt(): framework suffix stripped via rsplit(CRITIQUE_FRAMEWORK, 1)
instead of .replace() to avoid removing all occurrences and leaving partial
whitespace artifacts.
- build_panel_prompt(): builds included_personas list first; uses its length
in the user prompt (not len(personas) before filtering); raises ValueError
if all provided persona names are unknown.
- format_critique_lessons(): payload normalized (CRLF collapsed, trailing
punctuation stripped) so "issue." and "issue" don't produce duplicate
lessons; empty payloads filtered; order-preserving deduplication added
for panels that emit the same tag across multiple reviewer voices.
- PERSONA_DESCRIPTIONS comment corrected (no false claim about lazy imports).
Note: format_critique_lessons() returns list[str] for prompt injection via
PriorRunContext.prior_critique_lessons, not list[LessonEntry] for
EvolutionStore. Callers that need EvolutionStore persistence should wrap
the strings in LessonEntry(stage_name="peer_review", stage_num=18, ...).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>1 parent 78bcab4 commit 2785fcf
1 file changed
Lines changed: 431 additions & 0 deletions
0 commit comments