$npx -y skills add WILLOSCAR/research-units-pipeline-skills --skill citation-diversifierRaise citation diversity/density (NO NEW FACTS): generate an in-scope “citation budget” plan per H3 so drafts stop failing the global unique-citation gate and stop looking under-cited. Trigger: cite boost, citation budget, unique citations too low, add more citations, improve
| 1 | # Citation Diversifier (budget-as-constraints) [NO NEW FACTS] |
| 2 | |
| 3 | Purpose: fix a common survey failure mode: |
| 4 | - the draft reads under-cited (or reuses the same few citations everywhere) |
| 5 | - the pipeline fails the **global unique-citation** gate |
| 6 | |
| 7 | This skill does **not** change prose by itself. |
| 8 | It produces a constraint sheet: `output/CITATION_BUDGET_REPORT.md`. |
| 9 | |
| 10 | ## Inputs |
| 11 | |
| 12 | - `output/DRAFT.md` |
| 13 | - `outline/outline.yml` (H3 ids/titles; used to allocate budgets per subsection) |
| 14 | - `outline/writer_context_packs.jsonl` (source of `allowed_bibkeys_{selected,mapped,chapter,global}` per H3) |
| 15 | - `citations/ref.bib` |
| 16 | |
| 17 | ## Output |
| 18 | |
| 19 | - `output/CITATION_BUDGET_REPORT.md` |
| 20 | |
| 21 | ## Non-negotiables (NO NEW FACTS) |
| 22 | |
| 23 | - Only propose citation keys that exist in `citations/ref.bib`. |
| 24 | - Only propose keys that are **in-scope** for the target H3 (prefer subsection-first scope; use chapter/global only when truly cross-cutting). |
| 25 | - Do not propose “padding citations” that would require adding new claims or new numbers. |
| 26 | |
| 27 | ## What a good budget report looks like (contract) |
| 28 | |
| 29 | The report should feel like a *constraint sheet*, not a random list: |
| 30 | - It states the **blocking policy target** and the **gap-to-target** (how many unique keys are missing; policy default is `recommended`). |
| 31 | - For each H3, it proposes a scope-safe budget sized to actually close the gap: |
| 32 | - small gaps: 3-6 keys / H3 is often enough |
| 33 | - `course_paper`: cap suggestions at 3-6 keys / H3 and target the profile's 24/32 global budget |
| 34 | - A150++ gaps: plan for ~6-12 keys / H3 (and avoid duplicates across H3 budgets) |
| 35 | - It gives placement guidance (where in the subsection those keys can be embedded without adding new facts). |
| 36 | |
| 37 | Canonical (parseable) lines required (downstream validators depend on these): |
| 38 | - The target is derived from `queries.md:citation_target` (`recommended` by default for A150++). |
| 39 | - `- Global target (policy; blocking): >= <N> ...` |
| 40 | - `- Gap: <K>` (gap-to-target; if `0`, injection can be a no-op PASS) |
| 41 | |
| 42 | Optional (always reported; may be blocking depending on `citation_target`): |
| 43 | - `- Global recommended target: >= <N> ...` |
| 44 | - `- Gap to recommended: <K>` |
| 45 | |
| 46 | Recommended prioritization (scope-safe): |
| 47 | - `allowed_bibkeys_selected` → `allowed_bibkeys_mapped` → `allowed_bibkeys_chapter` |
| 48 | - Use `allowed_bibkeys_global` only for: |
| 49 | - benchmarks/protocol papers |
| 50 | - widely-used datasets/suites |
| 51 | - cross-cutting surveys/method papers referenced across chapters |
| 52 | |
| 53 | ## How this connects to writing (LLM-first) |
| 54 | |
| 55 | After you generate the budget report: |
| 56 | - Apply it using `citation-injector` (LLM edits to `output/DRAFT.md`, NO NEW FACTS). |
| 57 | - Then run `draft-polisher` to remove any “budget dump voice” while keeping citation keys unchanged. |
| 58 | |
| 59 | Important: `citation-injector` is **LLM-first**. Its script is validation-only. |
| 60 | |
| 61 | ## Workflow |
| 62 | |
| 63 | 1) Diagnose the global situation |
| 64 | - Read `output/DRAFT.md` and estimate the “unique-key gap” (or use `pipeline-auditor`’s FAIL reason). |
| 65 | |
| 66 | 2) Allocate budgets per H3 (scope-first) |
| 67 | - Use `outline/outline.yml` to enumerate H3s in paper order. |
| 68 | - For each H3, read its allowed key sets from `outline/writer_context_packs.jsonl`. |
| 69 | - Pick a small set of *unused* keys that strengthen positioning without requiring new claims. |
| 70 | |
| 71 | 3) Write `output/CITATION_BUDGET_REPORT.md` |
| 72 | Required structure: |
| 73 | - `- Status: PASS|FAIL` |
| 74 | - `- Global target (policy; blocking): >= <N> ...` |
| 75 | - `- Gap: <K>` |
| 76 | - `## Summary` (gap + strategy) |
| 77 | - `## Per-subsection budgets` (H3 id/title → suggested keys → placement hint) |
| 78 | |
| 79 | ## Script (optional; deterministic report generator) |
| 80 | |
| 81 | If you want a deterministic first-pass budget report, run the helper script. Treat it as a baseline and refine the plan as needed. |
| 82 | |
| 83 | ### Quick Start |
| 84 | |
| 85 | - `uv run python .codex/skills/citation-diversifier/scripts/run.py --help` |
| 86 | - `uv run python .codex/skills/citation-diversifier/scripts/run.py --workspace <workspace>` |
| 87 | |
| 88 | ### All Options |
| 89 | |
| 90 | - `--workspace <dir>` |
| 91 | - `--unit-id <U###>` (optional) |
| 92 | - `--inputs <semicolon-separated>` (rare override; prefer defaults) |
| 93 | - `--outputs <semicolon-separated>` (rare override; default writes `output/CITATION_BUDGET_REPORT.md`) |
| 94 | - `--checkpoint <C#>` (optional) |
| 95 | |
| 96 | ### Examples |
| 97 | |
| 98 | - Default IO: |
| 99 | - `uv run python .codex/skills/citation-diversifier/scripts/run.py --workspace <workspace>` |
| 100 | |
| 101 | ## Done criteria |
| 102 | |
| 103 | - `output/CITATION_BUDGET_REPORT.md` exists and has actionable, in-scope budgets. |
| 104 | - After applying the plan via `citation-injector`, `pipeline-auditor` no longer FAILs on global unique citations. |