Naming the Gap Between Enrichment and Coverage
Yesterday's v0.0.10 run made a problem legible: 33 hand-curated URLs went into the writer, 7 came out cited in the prose, 26 sat untouched. The fix wanted to be a new agent, and the first instinct was to name it 'Citation Diversity Enricher' and slot it between the writer and the existing 'cite' node. Today's planning work landed somewhere different — the existing cite node runs upstream of the writer (not after), the new agent's job is genuinely orthogonal to enrichment, and the right name is Citation Coverage Promoter. No code shipped; a plan got corrected before it generated a confused agent.
plan(citations): rename Citation Diversity Enricher → Citation Coverage Promoter
plan(citations): correct upstream/downstream placement of citation_enrichment in workflow
plan(citations): document that no existing agent does the proposed job
One file moved, one plan substantively edited. No agent code yet —
the planning pass produced a corrected understanding that's load-bearing
for whoever (next session, next person) writes the agent.
* apps/memopop-orchestrator/context-v/plans/Citation-Coverage-Promoter.md
(renamed from Citation-Diversity-Enricher.md) — title, h1, all in-file
references, function name, and workflow integration diagram updated.
Added a "Naming note" explaining the distinction from the existing
citation_enrichment family.Changelog - 2026-05-23_01
Naming the Gap Between Enrichment and Coverage
Yesterday's ChromaDB v0.0.10 run was the first end-to-end demonstration of codified-source mode, and it surfaced a number that wouldn't go away: 33 curated URLs in, 7 distinct sources cited across 98 inline references in the final memo, 26 sources never referenced at all. The writer's pattern of citing a handful of sources heavily and ignoring the rest had been visible across prior memos, but codified mode is what made it measurable — the corpus is a closed set, so coverage is a fraction with a known denominator.
The instinct was to write a new agent for the post-writer band. The plan was drafted as "Citation Diversity Enricher," to sit between the writer and the existing citation_enrichment node ("cite"). Today's pass over the codebase corrected three things about that framing before any agent code got written.
What Got Corrected
1. citation_enrichment runs upstream of the writer, not downstream
The original plan's narrative described citation_enrichment_agent as a post-writer pass on 2-sections/ artifacts. That's not what it does. From src/agents/citation_enrichment.py:1-16 and the actual node ordering in src/workflow.py:529-548:
... → competitive_evaluator → cite → cleanup_research → aggregate_sources → draft
→ inject_deck_images → enrich_trademark → enrich_socials → enrich_links
→ generate_tables → generate_diagrams → enrich_visualizations
→ revise_summaries → cleanup_sections → assemble_citations → ...cite fires on 1-research/ files before the writer composes prose. Its job is to use Perplexity Sonar Pro to add new external URLs to the research material the writer will subsequently consume. By the time the writer runs, that enrichment has already happened.
A "diversity enricher" slotted between draft and cite doesn't exist as a location in the graph. The correct slot for the new agent is between enrich_visualizations and revise_summaries:
After
enrich_visualizations: all section-prose enrichment is done; no later agent will add new sentences for coverage to attach to.Before
revise_summaries: the revision agent rewrites exec summary + closing from the body, so coverage should be settled first.Before
cleanup_sections: any inserted[^N]markers get the verdict-ladder validation for free.Before
assemble_citations: renumbering picks up the new citations naturally.
2. The two jobs are genuinely distinct — don't repurpose the existing agent
The temptation when "we already have a citation enrichment agent" is to extend it. Today's reading made the case that the two jobs are not the same shape:
citation_enrichment (existing) | citation_coverage_promoter (new) | |
| When | Pre-writer | Post-writer, pre-revise-summaries |
| Operates on | 1-research/*.md | 2-sections/*.md |
| Source of new citations | Perplexity Sonar Pro (external) | Existing curated corpus (fixed) |
| What it adds | New external URLs | [^N] markers to existing prose |
| Whether prose changes | N/A (research files) | No — additive only |
| Active in codified mode? | Should be gated off (it'll invent URLs outside the analyst's set) | Always-on in codified mode |
One widens the corpus. The other redistributes attention within a fixed corpus. Conflating them would muddy two clean responsibilities and force one prompt to do work that two prompts can do cleanly. The rule is from the Separating Retrieval from Generation exploration, applied at finer grain: keep agents bounded.
3. The name "enrichment" is overloaded; "coverage promoter" reads cleaner
The agents directory already has: citation_enrichment, citation_assembly, citation_corrector, citation_validator, citation_spacing. Plus enrich_trademark, enrich_socials, enrich_links, enrich_visualizations. "Enrichment" is the most-used verb in the post-writer band, and it means several different things depending on which agent owns it.
The new agent's job — find sources tagged for this section that aren't yet cited, insert [^N] markers at sentences they naturally support, never rewrite prose — is best described by promotion (from "tagged but uncited" to "cited at the right sentence") of coverage (the analyst's full curated corpus). Hence citation_coverage_promoter.py with function citation_coverage_promoter_agent.
The plan file itself was renamed Citation-Diversity-Enricher.md → Citation-Coverage-Promoter.md and all in-file references were updated.
Why This Is a Changelog Entry Even With No Code Shipped
The mistake-shape this catches is the most expensive one in this codebase: writing a new agent without first reading the agents already there. The result is usually an agent whose job overlaps 60% with one that already exists, named in a way that obscures the overlap, sitting in the wrong slot in the graph because the author imagined a workflow that doesn't match the actual add_edge list. We've shipped that before and paid for it in cleanup passes.
Catching it at the plan stage cost about twenty minutes of grep + read. The acknowledgement isn't "we wrote a plan"; it's "we corrected a plan before it generated a confused agent." That belongs in the log even though git diff shows one renamed file and one substantive edit.
What Phase 1 Still Says
Independent of the rename, the plan's recommendation remains: ship Phase 1 alone first. Three prompt-level edits, no new agent, no new API spend:
Add diversity guidance to the writer's system prompt (cite each provided source at least once if reasonably relevant; prefer higher-rank sources).
Label each source block in the codified researcher's output with its rank, and tell the writer that rank-1 sources are the analyst's primary picks per section.
Soft cap on per-source citation density (no single source should account for >40% of a section's citations).
Re-run v0.0.10 with those tweaks; measure coverage and per-source distribution. If the gap closes from 7-of-33 to 15+-of-33 on prompts alone, Phase 2 (the new agent) is deferred indefinitely. The point of Phase 2 is to close the remaining gap — not to be ambitious.
What's Next
Phase 1: three writer-prompt edits + the rank-labeling change in
codified_section_researcher._synthesize_via_claude. Then a fresh v0.0.11 run on ChromaDB to measure coverage delta from prompts alone.If Phase 1 doesn't close the gap to ~15-of-33, build
citation_coverage_promoter_agentper the corrected plan, wire it betweenenrich_visualizationsandrevise_summaries, and re-measure.Independently, Decision Point #2 from the plan: gate
citation_enrichment_agentonis_codified()so that in codified mode it does NOT invent URLs outside the analyst's approved set. This is a separate edit on the upstream agent and can ship without waiting on the new agent.
References
[[Citation-Coverage-Promoter]] — the plan, now correctly named
[[2026-05-22_02|The Analyst Gets the Pencil]] — yesterday's entry; names the 7-of-33 problem as the next-iteration item
[[Trustworthy-Citations-Source-Harvester-Rollout]] — the parent rollout plan
[[Separating-Retrieval-from-Generation-in-Agent-Pipelines]] — the architectural rule that says keep agents bounded; applied here at finer grain
src/agents/citation_enrichment.py— the existing agent whose role got correctly described todaysrc/workflow.py:524-549— the actual node ordering, source of truth
