Standalone CLI Tools for Post-Generation Enrichment & Evaluation
Three new CLI tools let you repair a finished memo without regenerating it: add citations to prose you already like, hyperlink every organization it mentions, or score the whole thing and see the breakdown.
Changelog - 2025-11-28 (#4)
Standalone CLI Tools for Post-Generation Enrichment & Evaluation
Type: New Feature Priority: HIGH
Summary
Added three new CLI tools for post-generation memo enhancement, plus improved title extraction in the export tool. These tools enable targeted improvements without regenerating the entire memo:
| Tool | Purpose | API |
cli/enrich_citations.py | Add citations to existing content (preserves text) | Perplexity Sonar Pro |
cli/enrich_links.py | Add organization + social profile hyperlinks | Claude + Tavily |
cli/evaluate_memo.py | Score memo quality with detailed breakdown | Claude |
cli/export_branded.py | Improved title/company extraction logic | - |
New Tool: Citation Enrichment (cli/enrich_citations.py)
Purpose
Add inline citations to a section WITHOUT rewriting the content. Uses Perplexity Sonar Pro to find authoritative sources for existing claims.
Key distinction from improve_section.py: This tool only adds citation markers ([^1], [^2]) to support existing text. It does NOT rewrite or expand content.
Usage
# By company name (finds latest version)
python -m cli.enrich_citations "Sava" "Market Context"
# Specific version
python -m cli.enrich_citations "Sava" "Market Context" --version v0.0.2
# Direct path
python -m cli.enrich_citations output/Sava-v0.0.2 "Market Context"
# Skip reassembly (just update section file)
python -m cli.enrich_citations "Sava" "Team" --no-reassembleFeatures
Preserves original content verbatim
Only adds citation markers where claims need sourcing
Automatically reassembles
4-final-draft.mdafter enrichmentShows citation count before/after
Supports all 10 direct investment + 10 fund commitment sections
Implementation Details
Uses
src/agents/citation_enrichment.enrich_section_with_citations()for API callDelegates final draft assembly to
cli/assemble_draft.assemble_final_draft()Requires
PERPLEXITY_API_KEYenvironment variable
New Tool: Link Enrichment (cli/enrich_links.py)
Purpose
Add hyperlinks to a section for organizations (investors, gov bodies, partners, competitors, universities) and social profiles (LinkedIn, Twitter/X) for people mentioned.
Usage
# Full enrichment (orgs + socials)
python -m cli.enrich_links "Sava" "Team"
# Organization links only
python -m cli.enrich_links "Sava" "Market Context" --orgs-only
# Social profile links only
python -m cli.enrich_links "Sava" "Team" --socials-only
# Specific version
python -m cli.enrich_links "Sava" "Team" --version v0.0.2Two-Stage Enrichment Process
Stage 1: Organization Links (Claude)
Uses Claude to identify and link organizations mentioned
Links investors, government bodies, partners, competitors, universities
Only links FIRST mention of each entity
Uses official websites (not Wikipedia/LinkedIn/Crunchbase)
Stage 2: Social Profile Links (Tavily)
Extracts people names from section (pattern matching)
Searches for LinkedIn profiles via Tavily
Also searches Twitter/X profiles
Adds links in format:
Name ([LinkedIn](url), [X](url))
People Extraction Patterns
The tool identifies team members using these patterns:
**Name – Role**(bold name with em-dash and role)CEO John Smith(role prefix pattern)John Smith (CEO)(name with role in parentheses)
Implementation Details
Requires
ANTHROPIC_API_KEYfor organization linksRequires
TAVILY_API_KEYfor social profile searchesClaude model:
claude-sonnet-4-5-20250929(configurable viaDEFAULT_MODEL)
New Tool: Memo Evaluation (cli/evaluate_memo.py)
Purpose
Evaluate the quality of each section in a memo, providing per-section scores, fact-checking, and improvement suggestions.
Usage
# Evaluate latest version
python -m cli.evaluate_memo "Sava"
# Specific version
python -m cli.evaluate_memo "Sava" --version v0.0.2
# Direct path
python -m cli.evaluate_memo output/Sava-v0.0.2
# Brief output (scores only)
python -m cli.evaluate_memo "Sava" --brief
# Custom output file
python -m cli.evaluate_memo "Sava" --output /path/to/eval.jsonEvaluation Criteria (0-10 Scale)
Each section is scored on four dimensions:
| Criterion | Weight | Description |
| Content Depth | 30% | Substantive analysis with specific details |
| Specificity | 25% | Concrete numbers vs vague language |
| Citation Quality | 25% | Factual claims properly sourced |
| Analytical Tone | 20% | Balanced, objective (not promotional) |
Scoring Guidelines:
0-3: Poor (generic, vague, unsourced, promotional)
4-6: Adequate (basic coverage, some specifics)
7-8: Good (relevant details, mostly specific, well-sourced)
9-10: Exceptional (rare - requires unique insights throughout)
Output
Console Output:
Section Scores
┌─────────────────────┬───────┬──────────┬───────┬─────────────┬──────────┬──────┬─────────┐
│ Section │ Words │ Citations│ Depth │ Specificity │ Citations│ Tone │ Overall │
├─────────────────────┼───────┼──────────┼───────┼─────────────┼──────────┼──────┼─────────┤
│ Executive Summary │ 245 │ 4 │ 7.0 │ 6.5 │ 8.0 │ 7.5 │ 7.2 │
│ Market Context │ 890 │ 12 │ 8.0 │ 7.5 │ 8.5 │ 8.0 │ 8.0 │
│ ... │ │ │ │ │ │ │ │
└─────────────────────┴───────┴──────────┴───────┴─────────────┴──────────┴──────┴─────────┘
Overall Score: 7.3/10 (B)JSON Output (evaluation.json):
Per-section scores and metrics
Strengths, issues, and suggestions per section
Claim analysis (total, cited, uncited, suspicious)
Top issues across all sections
Priority improvements (from lowest-scoring sections)
Letter grade (A through F)
Fact-Checking
The tool extracts factual claims that should be cited:
Metrics:
"500 customers","$2M ARR"Financial figures:
"$10M raised"Percentages:
"40% growth"Market sizes:
"$5B market"Growth rates:
"150% YoY"Dates:
"founded in 2020"
Claims without citations are flagged as potential issues.
Exit Codes
0: Overall score >= 6.01: Overall score < 6.0
Improvement: Export Title Extraction (cli/export_branded.py)
Problem
The extract_title_from_markdown() function was incorrectly extracting company names when the markdown file contained "Investment Memo" text later in the document (e.g., in section content).
Solution
Implemented priority-based extraction with explicit boundaries:
Priority Order:
Directory name pattern (most reliable):
{Company}-v{version}/4-final-draft.md→"Company Name"Explicit header (first 500 chars only):
Investment Memo: Companyat file startFirst H1 (first 1000 chars only):
# Titleheader near topFilename fallback: Clean up filename stem
Code Change
# Priority 1: Extract from parent directory name (most reliable)
parent_dir = md_path.parent.name
dir_match = re.match(r'^(.+?)-v\d+\.\d+\.\d+$', parent_dir)
if dir_match:
company = dir_match.group(1).replace('-', ' ')
return f"{company} - Investment Memo", company
# Priority 2: Look for "Investment Memo" at START of file only
first_500 = content[:500]
company_match = re.search(r'^Investment Memo[:\s]+(.+?)(?:\n|$)', first_500, ...)This prevents false matches from content deep in the document.
Files Changed
New Files (3)
| File | Lines | Purpose |
cli/enrich_citations.py | 213 | Citation-only enrichment tool |
cli/enrich_links.py | 426 | Organization + social link enrichment |
cli/evaluate_memo.py | 536 | Quality evaluation with scoring |
Modified Files (1)
| File | Change | Purpose |
cli/export_branded.py | +30 lines | Improved title/company extraction |
Section Name Mapping
All three new tools use consistent section name mapping:
Direct Investment (10 sections):
"Executive Summary" →
01-executive-summary.md"Business Overview" →
02-business-overview.md"Market Context" →
03-market-context.md"Team" →
04-team.md"Technology & Product" →
05-technology--product.md"Traction & Milestones" →
06-traction--milestones.md"Funding & Terms" →
07-funding--terms.md"Risks & Mitigations" →
08-risks--mitigations.md"Investment Thesis" →
09-investment-thesis.md"Recommendation" →
10-recommendation.md
Fund Commitment (additional sections):
"GP Background & Track Record" →
02-gp-background--track-record.md"Fund Strategy & Thesis" →
03-fund-strategy--thesis.md(etc.)
Workflow Integration
These tools are designed for post-generation refinement:
# 1. Generate initial memo
python -m src.main "Sava" --type direct --mode consider
# 2. Evaluate quality
python -m cli.evaluate_memo "Sava"
# Output: Overall Score: 6.2/10 (C+)
# Priority: [Team] Add specific metrics for team experience
# 3. Enrich weak sections
python -m cli.enrich_citations "Sava" "Team"
python -m cli.enrich_links "Sava" "Team"
# 4. Re-evaluate
python -m cli.evaluate_memo "Sava"
# Output: Overall Score: 7.4/10 (B)
# 5. Export
python -m cli.export_branded output/Sava-v0.0.1/4-final-draft.md --brand hypernovaDependencies
| Tool | Required API Keys |
enrich_citations.py | PERPLEXITY_API_KEY |
enrich_links.py | ANTHROPIC_API_KEY, TAVILY_API_KEY (optional for socials) |
evaluate_memo.py | ANTHROPIC_API_KEY |
Related Changes
This changelog is part of improvements made on 2025-11-28:
2025-11-28_01.md- Initial Sava memo generation2025-11-28_02.md- Entity disambiguation system2025-11-28_03.md- Canonical draft assembly tool2025-11-28_04.md- Standalone CLI tools (this file)
Contributors
Implementation by Claude Code (Anthropic) with user guidance.