feat: IMAP mail sync with thread-to-contact matching (PRD §6.1)

Real IMAP connection via imapflow library:
- Connects to IMAP server (IMAPFlow, TLS on port 993)
- Fetches recent messages (configurable limit, default 20)
- Extracts: from, fromEmail, subject, date, snippet (200 chars)
- Thread-to-contact matching (PRD §6.1):
  1. Match sender email against persons table
  2. If no person match, extract domain and match against company.website
  3. Returns matchedCompany + matchedPerson for each email
- Audit-logged (action: crm.mailsync:imap)
- Zod validated (host, port, user, password, folder, limit)
- 502 on IMAP connection failure with detail
- 400 on validation failure

Tested: invalid creds → 502 'IMAP connection failed', missing host → 400
This commit is contained in:
Z User committed 2026-10-27 22:50:50 +00:00
1 parent 7acc0c5451
commit e45b68bb8b
1089 files changed
+260614

No files matched your search

+156
View File
@@ -0,0 +1,156 @@
---
name: literature-survey
description: Use when the user wants a comprehensive literature survey on a specific research topic. Outputs a complete PDF survey (6–20 pages, 60+ real citations, 100+ recommended) with LaTeX source, taxonomy figures, and a classified literature table. Single-stage, no Python runtime.
---
# Literature Survey
## Overview
End-to-end literature survey builder. **Single stage, full quality from the start.** The agent (Claude Code / Cursor / Aider / Codex / …) does the entire build using its own tools (WebFetch, WebSearch, Write, Bash). This SKILL is procedure + reference playbooks + LaTeX template — no Python runtime, no LLM SDK.
The substantive work is decomposed into reference playbooks under `references/`:
| Reference | Topic |
|---|---|
| `references/00-incremental-execution.md` | how to actually do this without losing work: batch sizes, persistence, resume — **read first** |
| `references/01-bibliography-expansion.md` | grow `bibliography.bib` to 60+ real entries (100+ recommended) via WebFetch (no memory) |
| `references/02-survey-figures.md` | taxonomy / timeline / coverage-matrix / area-map figures |
| `references/03-survey-section-playbook.md` | per-section structure for survey-shaped papers |
| `references/04-layout-discipline.md` | tables, figures, floats, cross-refs, author + disclosure footnote |
| `references/05-quality-gate.md` | self-check before delivery |
**Read the relevant reference _before_ writing, not after.** The full pass does not fit in a single turn — `references/00-incremental-execution.md` is the only execution mode that completes.
## When to Use
- User asks for a "survey" / "review" on a specific topic.
- User has a research topic and wants a structured map of the field with citations.
- User needs background reading curated for a thesis chapter or grant section.
## When NOT to Use
- User wants original research with experiments → `paper-writer`.
- User wants only an outline / topic exploration → `research-explorer`.
- User wants experiment code → `experiment-suite`.
- Topic is too broad (e.g., "all of AI") — narrow it before starting.
## Workflow
### Step 1 — Understand the topic and scope
Confirm with the user:
- **Topic** — specific research area (e.g., "federated learning in healthcare"). If too broad, narrow it first.
- **Scope** — broad survey of a field vs. focused review of a sub-area.
- **Citation budget** — minimum 60 unique entries; aim for 100+ (push higher for a broad survey).
- **Language** — default Chinese in conversation; the LaTeX paper is English unless requested otherwise.
Always tell the user that human review by a domain expert is recommended before publication or production use.
### Step 2 — Set up the run directory
```bash
TOPIC="<topic>"
SLUG=$(python3 -c "import re,hashlib,sys; t=sys.argv[1]; n=re.sub(r'[\\s_]+','-',re.sub(r'[^\\w\\s-]','',t.lower().strip())).strip('-')[:40].rstrip('-'); h=hashlib.sha1(t.encode()).hexdigest()[:8]; print(f'{n}-{h}')" "$TOPIC")
TS=$(date +%Y-%m-%d_%H%M%S)
RUN=output/literature-survey/$SLUG/$TS/survey_paper
mkdir -p "$RUN/sections" "$RUN/figures"
cp -r literature-survey/templates/survey/. "$RUN/"
ln -sfn "$TS" "output/literature-survey/$SLUG/latest"
```
In commands below `$RUN` = `output/literature-survey/<slug>/latest/survey_paper`.
### Step 3 — Build the survey (REQUIRED — this is the whole job)
Open `references/00-incremental-execution.md` first. Then carry out the five tracks below across many turns, persisting state to `$RUN/` after every batch.
#### 3.1 Bibliography — 60+ real entries (100+ recommended)
**Open:** `references/01-bibliography-expansion.md`.
**First (§0 of that reference): read the topic's temporal/scope intent and pick a search posture.** If the topic names a year or says "latest/recent" (e.g. "OpenSource LLM **2026**"), go *recency-led* — date-sorted arXiv queries carrying the explicit year, canon only as context. Otherwise span the timeline. This is what prevents "asked for 2026, got all 2024".
Then plan **12–20** query angles, weighted by the posture. For each angle, use **AMiner academic search first, web search as supplement**:
- **AMiner `search_papers`** — Use this FIRST for every query angle. It returns
papers with structured metadata (title, authors, year, venue, DOI, citations,
abstract) that is far more reliable than web-scraped results. Example:
`search_papers(query="federated learning survey", max_results=20, sort_by_citation=true)`.
- **AMiner `get_paper_details`** — For key papers, fetch full details (abstract,
citations, references) by their AMiner IDs.
- **`web_search`** — Use when AMiner returns insufficient results, or for
non-academic sources (blogs, benchmarks, datasets, tool documentation).
For each kept candidate: extract canonical title/authors/year/venue/url/citations
from the AMiner response directly. For web-search-only results, WebFetch the
abstract URL to extract metadata. Append a BibTeX entry to
`$RUN/bibliography.bib`. **Every entry must originate from a URL fetched in this
session or from an AMiner search result.** Memory entries forbidden.
**Hard stop:** do not draft prose until `grep -c "^@" $RUN/bibliography.bib` ≥ 60 (aim for 100+).
#### 3.2 Figures — 6–10 survey-shaped
**Open:** `references/02-survey-figures.md`.
A survey is defined by how well it organises a field; figures carry that organisation:
- 1 taxonomy / classification diagram (TikZ hierarchy)
- 1 chronological timeline of major works
- 1 area / capability matrix (coverage heatmap)
- 1–2 representative architecture / mechanism diagrams
- 1–2 quantitative trend plots (matplotlib publication style)
- Optional: citation network, paradigm comparison
Save each into `$RUN/figures/` with reproducible source alongside.
#### 3.3 Sections — survey-shaped prose
**Open:** `references/03-survey-section-playbook.md`.
Survey sections differ in shape from research-paper sections. Order: introduction → background → methods (themed survey) → discussion → conclusion → related work → **abstract last**.
#### 3.4 Layout discipline
**Open:** `references/04-layout-discipline.md`.
Wrap every table in `\begin{table}[!t]` with booktabs; every figure in `\begin{figure}[!t]`. Use `~\cite{}` and `~\ref{}`. Set `\author{AI4S Agent}` with a `\thanks` footnote that **always** recommends human review. Surveys carry no simulated numerical experiments, so do **not** include a simulated clause.
#### 3.5 Compile + quality gate
```bash
cd "$RUN"
pdflatex -interaction=nonstopmode main.tex
bibtex main
pdflatex -interaction=nonstopmode main.tex
pdflatex -interaction=nonstopmode main.tex
```
**Open:** `references/05-quality-gate.md`. Survey-specific targets: ≥ 60 bib entries (100+ recommended), ≥ 6 pages, ≥ 1 taxonomy figure, ≥ 1 timeline.
If a gate cannot honestly be met (e.g., the field is genuinely small), say so explicitly. Do not pad.
### Step 4 — Deliver
Report:
1. `output/literature-survey/<slug>/latest/survey_paper/main.pdf`
2. `output/literature-survey/<slug>/latest/survey_paper/` — complete LaTeX project (reproducible)
3. `output/literature-survey/<slug>/latest/literature_table.md` — classified literature table (write this alongside the bib build)
4. Stats per the report format in `references/05-quality-gate.md`.
## Cross-skill data flow (path convention)
A downstream skill (e.g., `paper-writer`) computing the same slug for the same topic will look here:
- `output/literature-survey/<slug>/latest/survey_paper/bibliography.bib` — bib starting point.
## Important rules
- **No LLM SDK in this skill.** No `import anthropic` / `import openai`. The skill is SKILL.md + references + LaTeX template only.
- **No fabricated citations.** Every BibTeX entry must trace back to a URL fetched this session. Real or weaker claim — never fake reference.
- **Honest stop > padding.** If the field is too small for 60 real citations, say so to the user instead of inventing entries.
- **Survey scope** is 6–20 pages with 60–150 references (100+ recommended). For longer or shorter formats, adjust scope explicitly with the user up front.
@@ -0,0 +1,153 @@
# Incremental Execution — How a Survey Actually Gets Built
## Why this exists
A survey with 100+ references and 7 multi-paragraph sections does not fit into a single LLM tool call. WebSearch returns ~10 useful candidates per query, not 100. A single message can write one solid section, not seven. If you treat the build as "do it all in one shot", you will hit context limits, fail mid-task, and have nothing to recover.
This reference defines the only execution mode that works: **incremental, file-persisted, resumable**. Every other reference (`01`–`05`) describes *what* to produce; this one describes *how* to produce it without losing work.
## The three invariants
### Invariant 1 — Filesystem is the source of truth
Every intermediate result is written to disk **immediately**. A new BibTeX entry is appended to `bibliography.bib` the moment it is extracted from a WebFetch result, not after the batch finishes. A rewritten section is Written to `sections/<name>.tex` the moment it is drafted, not after all seven are drafted. A generated figure is committed to `figures/fig_NN_<name>.pdf` and the matching script is saved alongside.
If the conversation context fills, the agent crashes, or the user pivots, **the files survive**. Resumption reads the files and continues.
### Invariant 2 — Progress is observable via filesystem, not memory
```bash
cd output/literature-survey/<slug>/survey_paper
grep -c "^@" bibliography.bib # bib entries so far
ls figures/*.pdf | wc -l # figures so far
for f in sections/*.tex; do
echo "$(basename "$f"): $(wc -w < "$f") words"
done # per-section drafted size
```
If the count does not match the target, do another batch. Don't rely on remembering what you did.
### Invariant 3 — Each batch is small enough to succeed, atomic enough to retry
A "batch" is one WebSearch+WebFetch cycle, or one section's prose, or one figure's script+render. Failure → redo just that batch. Success → write to disk and move on.
## Batch sizes that work
| Operation | Batch size per turn | Total batches | Persistence |
|---|---|---|---|
| Bibliography expansion | 1 WebSearch query → triage → ~5–15 WebFetch'd entries | 10–15 batches to reach 100+ | Append to `bibliography.bib` after each |
| Section drafting | 1 section per turn | 7 batches total | Write each `sections/<name>.tex` immediately |
| Figure generation | 1 figure per turn (TikZ inline or matplotlib script + render) | 6–10 batches | Save script + render alongside |
| Compile + check | 1 cycle after major artefact | Several | `main.log` + grep |
A turn that tries to do 5 sections produces shallow prose and probably truncates. A turn that tries to "WebSearch all 15 queries at once" hits tool budgets. One per turn is the rhythm.
## Bibliography expansion — incremental loop
```
read existing bibliography.bib
n_entries = grep -c "^@" bibliography.bib
target = 110 # aim above the 100 recommended floor (hard gate 60)
query_plan = [...] # 12–20 angles from 01-bibliography-expansion.md
already_run = read_state(.bib_progress) # set of executed query strings
seen_urls = extract_urls_from_bib() # already-cited URLs
for q in query_plan:
if q in already_run: continue
candidates = WebSearch(q) # ~5–15 hits
for c in triage(candidates): # filter by venue, dedup
if c.url in seen_urls: continue
meta = WebFetch(c.url) # canonical title/authors/year/venue
if meta is bad: continue
append_bibtex(meta, bibliography.bib)
seen_urls.add(c.url)
append(.bib_progress, q) # persist that query was run
if grep -c "^@" bibliography.bib >= target: break
```
In Claude Code execution this is **one WebSearch + one or more WebFetch + Edit/Write per turn** for ~15 turns. If turn 7 fails, turn 8 reads the progress file, sees queries 1–6 are done, restarts from 7. **No work lost.**
## Section drafting — one section per turn
Order: introduction → background → methods (themed survey) → discussion → conclusion → related work → abstract.
For each section:
1. Read `references/03-survey-section-playbook.md` rules for that section (open it fresh — don't trust cached recollection).
2. Read `bibliography.bib` and pick relevant keys for this section.
3. Draft the section in one go (one section is 600–1500 words for a survey; a single LLM turn can comfortably produce that).
4. **Immediately** Write the result to `sections/<name>.tex`.
5. Compile (`pdflatex` once + `bibtex` + `pdflatex` ×2). Check `main.log` for new undefined citations.
6. Fix errors before moving to the next section.
### "Abstract last" rule
The abstract names the field's structure as you have organised it. Until you have actually organised it (in Background through Discussion), you can't write a good abstract. Drafting it last takes 5 minutes; drafting it first wastes 30.
## Figure generation — one figure per turn
For each figure (6–10 total):
1. Open `references/02-survey-figures.md` for the family that fits this figure (taxonomy / timeline / matrix / architecture / quantitative).
2. Decide what the figure *answers* in the survey. That answer becomes the caption.
3. Write the figure (TikZ inline in the relevant `sections/*.tex`, or a `figures/make_fig_NN_*.py` script).
4. Render (TikZ compiles via main.tex; matplotlib via `cd figures && python make_fig_NN_*.py`).
5. Verify the PDF exists and is non-trivial.
6. Reference it from the appropriate section with a caption.
7. Recompile and check.
## Recovery — what to do when a session resumes mid-task
```bash
cd output/literature-survey/<slug>/survey_paper
grep -c "^@" bibliography.bib # bib progress
cat .bib_progress.txt 2>/dev/null | wc -l # queries executed
for f in sections/*.tex; do
echo "$(basename "$f"): $(wc -w < "$f") words"
done # which sections drafted
ls figures/*.pdf 2>/dev/null
ls -la main.pdf
grep -c "Citation .* undefined" main.log
```
Resume the sub-step that's incomplete. **Never** redo work that's already on disk; only fill in what's missing.
## Checkpoint files
Three small bookkeeping files in the survey paper directory:
- `.bib_progress.txt` — one line per executed query string
- `.section_progress.txt` — one line per drafted section
- `.figure_progress.txt` — one line per generated figure id
```bash
echo "transformer time series Informer Autoformer" >> .bib_progress.txt
```
## Atomic write rule
Use Write/Edit tools (atomic). Never stream partial content via `python -c "open(...).write(...)"`. Don't parallelize bib appends — they must serialise.
## Sanity check before delivery
```bash
ls -la sections/ # all 7 .tex files non-trivial?
ls -la figures/*.pdf # 6+ figure PDFs present?
test -s main.pdf
grep -c "^@" bibliography.bib # ≥ 60 (100+ recommended)
total=0; for f in sections/*.tex; do
total=$((total + $(grep -o "\\\\cite{" "$f" | wc -l)))
done
echo "TOTAL cites: $total" # ≥ 60 across all sections
```
## Quick checklist
- [ ] Bibliography assembled in **12+ small WebSearch+WebFetch batches**, one query per turn
- [ ] Sections written **one per turn**, abstract last
- [ ] Figures generated **one per turn**
- [ ] Three checkpoint files maintained
- [ ] Compile+verify after each major artefact
- [ ] Never tried to "do it all in one turn"
@@ -0,0 +1,173 @@
# Bibliography Expansion for a Survey — 60+ Real Entries (100+ recommended) via WebFetch
## Why this exists
A survey paper is largely *defined* by its bibliography: the breadth of coverage, how recent the most-recent works are, and how foundational the oldest works are determine whether the survey is useful or junk. There is no Python-side fetching: the entire bibliography is built by the orchestrating agent using the **WebSearch** and **WebFetch** tools, in one continuous pass before drafting begins.
**Hard minimum:** **60 unique, real, properly-attributed entries** before drafting prose; **100+ recommended**. Aim for ~120 as headroom for organic citation needs.
## The non-negotiable rule
> **Every BibTeX entry must originate from a URL the agent fetched in this session.** No entries from training-data memory. No "I know this paper exists" shortcuts. If it's not backed by a fetched URL, it does not go in the bib.
For surveys this is especially important: a survey is judged on how completely and accurately it maps a field. A fabricated entry (wrong author, wrong year, hallucinated paper) ends the survey's usefulness instantly.
## Tools and when
| Tool | Use for | Output |
|---|---|---|
| **WebSearch** | Discovering papers per query angle | List of titles + URLs + snippets |
| **WebFetch** | Pulling canonical metadata from a discovered URL | Page content; you parse title/authors/year/venue |
Pattern: WebSearch first to find candidates, then WebFetch the most promising URLs.
Reliable URL templates:
- arXiv abstract: `https://arxiv.org/abs/<id>`
- arXiv API (bulk): `http://export.arxiv.org/api/query?search_query=...&max_results=N` (Atom XML)
- Semantic Scholar: `https://www.semanticscholar.org/paper/<slug>/<id>` and the `https://api.semanticscholar.org/graph/v1/paper/...` API (JSON)
- OpenReview: `https://openreview.net/forum?id=<id>`
- NeurIPS proceedings: `https://papers.nips.cc/paper_files/paper/<year>/...`
## Process
### 0. Read the topic's scope & temporal intent FIRST (adaptive search)
Before planning a single query, read the user's topic the way a librarian would and pick a **search posture**. This is the step that was missing when a topic like "OpenSource LLM **2026**" came back with zero 2026 papers — the year in the topic *is* an instruction, not decoration. There is no fixed rule here; you infer the posture from the signals, then let it shape every later query.
| Signal in the topic / request | Posture | What it means for search |
|---|---|---|
| Names a specific recent/current/future year ("… 2026"), or says "latest / recent / emerging / state of the art / this year / past 12 months" | **Recency-led** | The named timeframe is a **hard filter**. Most queries (≳ 70%) carry that year/range and lead with date-sorted sources (see §3.5). Canon/foundational works appear only as *supporting context* (≤ ~30%), explicitly framed as "prior to the surveyed window". **Do not draft until the bib actually contains real entries from the named window.** |
| Says "history / evolution / development / foundations / comprehensive / from X to Y" | **Timeline-spanning** | Span earliest seminal work → newest. The "cover the canon" guidance below applies in full. |
| No temporal signal at all | **Balanced (default)** | Mix foundational + recent, but always include the **most recent 12 months** so the survey isn't stale. |
Write the chosen posture and the parsed timeframe as the first line of `.bib_progress.txt`, e.g. `POSTURE: recency-led | window: 2025-09 .. now | canon cap: 30%`. Every later query-planning and gate decision refers back to it.
> **Why the old behaviour failed:** the model reaches for the famous papers it already knows (all 2–3 years old), and the "span the timeline / a bib that's all-2023+ is a snapshot" guidance below *reinforced* that pull. Under a recency-led posture that guidance is **suspended** — there, an all-old bib is the failure, not the goal.
### 1. Start with an empty bibliography
`$RUN/bibliography.bib` starts empty after Step 2 of the skill. Build it up to ≥ 60 entries (100+ recommended) below before drafting any prose. Optionally also maintain a `$RUN/papers.json` index alongside.
### 2. Plan a query expansion (12–20 angles)
Decompose the topic into angles spanning multiple axes simultaneously. For a survey, breadth matters more than for a research paper.
Recommended angle types (pick 12–20 across these):
- **Foundational classics**: pre-2015 / pre-2010 papers that defined the field.
- **Method families**: each named architectural / technical family (one query per family).
- **Application domains**: each major domain (one query per domain).
- **Adjacent paradigms**: rival or sibling families (e.g., for a Transformer survey: linear models, MLP-only, state-space).
- **Empirical & benchmark studies**: dataset and benchmark papers, evaluation studies.
- **Theoretical analyses**: convergence, expressivity, identifiability, scaling laws.
- **Surveys**: prior surveys / reviews on the same or adjacent topics.
- **Recent advances**: queries carrying the **explicit year/window from §0** (not a placeholder) to capture the frontier. Under a *recency-led* posture this is the majority of your angles, not one of twenty.
- **Open problems / critiques**: papers that argue against received wisdom.
- **Tooling / libraries**: framework papers (when relevant to the field).
Track the plan in `.bib_progress.txt`.
### 3. Per query: WebSearch → triage → WebFetch → extract → append
For each query in the plan:
1. **WebSearch** with the query string. Result: list of links + titles + snippets.
2. **Triage** — for each candidate, decide whether to keep:
- Keep peer-reviewed venue papers and authoritative arXiv preprints.
- Skip blog posts, marketing pages, vendor pages, Medium articles, lecture slides.
- Deduplicate against entries already in `bibliography.bib`.
3. **WebFetch** the abstract URL to obtain canonical metadata (title, full author list, year, venue).
4. **Append** the BibTeX entry to `bibliography.bib` immediately, and append the query to `.bib_progress.txt`.
For arXiv specifically, the export.arxiv.org Atom endpoint returns 10–30 entries from one fetch — preferred for bulk loading.
### 3.5. Date-filtered search (use whenever recency matters)
A plain WebSearch ranks by relevance/popularity, which skews toward *older, more-cited* papers — exactly why a "2026" topic returns 2023–2024 results. When the posture from §0 is **recency-led** (or balanced, for the recent-12-months slice), don't rely on the model's prior knowledge; **fetch a date-sorted feed and read what's actually new**:
- **arXiv, sorted by date (primary recency tool).** The Atom API takes `sortBy=submittedDate&sortOrder=descending` — the top results are the newest papers, regardless of citation count:
```
https://export.arxiv.org/api/query?search_query=all:%22open%20source%20large%20language%20model%22&sortBy=submittedDate&sortOrder=descending&max_results=40
```
WebFetch this URL (use **https** — the plain-`http` host can return empty through some proxies), then keep entries whose `<published>` year falls inside the §0 window. Repeat per sub-topic (architectures, alignment, evaluation, …) so each theme has fresh coverage. (Verified: a date-sorted query like this returns current-month arXiv papers, exactly the frontier a relevance-ranked search misses.)
- **WebSearch with the year embedded and time-scoped phrasing.** Put the explicit year in the query and add words that bias toward new work: `open source LLM 2026 release`, `... announced 2026`, `... arxiv 2026`. Avoid model-name lists (`Llama Mistral Qwen …`) under a recency-led posture — they pull the search back to the known canon.
- **Cross-check the frontier you can't know.** Your training data does not contain the newest papers. Treat any "I already know the key 2026 papers" impulse as a red flag: if it's not from a URL fetched this session via a date-sorted query, it isn't recent enough to trust.
Record in `.bib_progress.txt` which queries were date-sorted, so the §0 window is auditable.
### 4. BibTeX entry format
```bibtex
@inproceedings{lastname2023key,
title={Exact title from the source page},
author={Lastname, Firstname and Other, Author},
booktitle={Venue Name},
year={2023},
url={https://arxiv.org/abs/2305.12345},
}
@article{lastname2024arxiv,
title={Exact title from the source page},
author={Lastname, Firstname},
journal={arXiv preprint arXiv:2401.12345},
year={2024},
url={https://arxiv.org/abs/2401.12345},
}
```
Always include `url=` so a reviewer can audit. Use `@inproceedings` with `booktitle={...}` for conferences, `@article` with `journal={...}` for journals. arXiv preprints are `@article` with `journal={arXiv preprint arXiv:<id>}`.
**bib_key convention:** `<firstauthorlastname><year><firstmeaningfulword>`, lowercase, alphanumeric. Disambiguate collisions with a single suffix letter.
**Acronyms in titles**: wrap with `{}` to preserve case — `{T}ransformers`, `{FED}former`, `{N-BEATS}`. Escape `&`, `%`, `$`, `_`, `#`.
### 5. Sync to `papers.json` (recommended)
Append a JSON record per BibTeX entry to `papers.json` so the manifest stays consistent. Minimum fields: `title`, `authors`, `year`, `bib_key`, `url`, `dimension` (which query angle discovered it).
The `dimension` field powers the literature table later: papers grouped by sub-area become a classified inventory the survey reader can use as a starting point.
### 6. Validate before drafting
```bash
cd output/literature-survey/<slug>/survey_paper
grep -c "^@" bibliography.bib # should be ≥ 60 (100+ recommended)
```
Run a `pdflatex + bibtex + pdflatex × 2` pass on the template `main.tex` with the new bib. If `main.bbl` doesn't list everything you expect, the bib has a syntax problem; fix before drafting prose.
### 7. As you draft, audit cite resolution
After every section, recompile and grep `main.log` for `Citation .* undefined`. Each undefined citation is either a typo or a missing bib entry. Fix immediately.
## Survey-specific bib quality
A survey bibliography should also satisfy (read these **through the §0 posture** — the timeline rule below is for *timeline-spanning / balanced* surveys; a *recency-led* survey deliberately concentrates in its window):
- **Span the timeline** *(timeline-spanning / balanced postures)*. Papers should range from the earliest seminal work to the last 6 months. A bib that's all 2023+ is a snapshot, not a survey. **Under a recency-led posture this is inverted:** the bib should concentrate in the named window, with older works cited only as the lineage that leads up to it.
- **Cover the canon.** Every named technique in your taxonomy should be cited via its primary source — the paper that introduced it.
- **Include critiques.** If the field has a debate (e.g., "are X effective?"), cite both sides; a one-sided survey is a position paper.
- **Cite prior surveys.** Every prior survey on the same / adjacent topic must be cited, and its scope contrasted with yours in the introduction.
## Anti-patterns
- **Memory-sourced entries.** Forbidden. WebFetch first or omit.
- **Fabricated entries.** Catastrophic. Real or weaker claim, never fake reference.
- **One paper, 30 cites.** Each `\cite{}` should advance the argument. Density comes from prose density, not paper repetition.
- **Citation dump.** `\cite{a, b, c, d, e, f, g, h}` covering 8 papers at once means you didn't read them. Group thematically and cite 2–4 per claim with prose distinguishing them.
- **Stopping at the 60 floor.** 60 is the minimum, not the target — aim for 100+.
- **Skipping `url=`.** Without the URL the entry is unverifiable.
## Quick checklist
- [ ] Picked a search posture from §0 (recency-led / timeline-spanning / balanced) and wrote it + the parsed window to `.bib_progress.txt`
- [ ] If recency matters: ran date-sorted arXiv queries (§3.5), not just relevance-ranked WebSearch
- [ ] Planned query angles spanning timeline / family / domain / paradigm / theory / surveys / recent / critiques — weighted by the posture
- [ ] Each entry backed by a URL fetched in this session (not from memory)
- [ ] `grep -c "^@" bibliography.bib` ≥ 60 (100+ recommended)
- [ ] Every entry has `title`, `author`, `year`, venue, `url`
- [ ] `papers.json` records `dimension` per entry for the classified table
- [ ] `.bib_progress.txt` records executed queries
- [ ] First test compile shows zero "Citation undefined" warnings against the template
+320
View File
@@ -0,0 +1,320 @@
# Survey Figures Playbook
## Why this exists
A research paper's figures tend to be experimental: tables of numbers, training curves, confusion matrices. A survey's figures are *organisational*: how is the field structured, when did things happen, who works on what. They are how a reader navigates the survey. Without good figures a survey is a long list of references; with them it becomes a map.
**Hard targets:** **6–10 figures** spanning these families:
- **At least 1 taxonomy / classification diagram** (TikZ tree or hierarchy)
- **At least 1 chronological timeline** of major works
- **At least 1 area / capability matrix** (coverage heatmap)
- **1–2 representative architecture / mechanism diagrams** (TikZ)
- **1–2 quantitative trend plots** (matplotlib publication style)
- Optional: paradigm comparison, citation-co-occurrence map, geographic / institutional map
## Design figures for THIS research — aim at the Nature/Science bar
Two real failures this playbook used to cause. Read both before you draw anything.
**1. Template leakage (the worst over-fitting).** The worked examples below were written about *time-series Transformers*. A real "open-source LLM" survey produced from this playbook shipped a taxonomy whose leaves were `Informer`, `Autoformer`, `PatchTST`, `iTransformer`, `Moirai` — time-series forecasting models, completely off-topic — because the agent copied the *sample's content*, not just its shape. **Every code block here is a worked example of a principle, never content to reuse.** Replace 100% of the labels, branches, palette, and composition with what *your* topic and *your* gathered papers actually require. If a reader could guess which sample you started from, you over-templated. The figure should look like it was designed for this survey and no other.
**2. Generic look.** Default LaTeX/matplotlib output (Computer Modern *serif*, boxed axes, rainbow colours, one chart per figure) reads as a class assignment, not a journal. The target is **Nature / Science**: figures that are *designed*, not decorated.
### What "Nature/Science" concretely means (not vibes)
- **A figure is a composition, not a lone chart.** Top journals compose multi-panel figures (**a**, **b**, **c** …), each panel one sub-claim, together telling one story. Use `subfigure` / matplotlib `subplots`, with **bold lowercase panel labels in the top-left corner** of each panel.
- **Sans-serif type.** Helvetica/Arial (both installed here), ~7 pt floor — never Computer Modern serif. matplotlib: `font.family:"sans-serif"`. TikZ/LaTeX diagrams: `\usepackage[scaled]{helvet}\renewcommand{\familydefault}{\sfdefault}` (or set the figure's nodes to `\sffamily`).
- **Restrained, colour-blind-safe colour that *encodes something*.** Use the Wong palette (the one *Nature* recommends): `#000000 #E69F00 #56B4E9 #009E73 #F0E442 #0072B2 #D55E00 #CC79A7`. For ordinal data use a single-hue sequential map (`Blues`), never rainbow/`jet`. ≤ ~5 hues per figure; colour must mean something, not decorate.
- **Maximise data-ink.** Despine top + right; ticks short and outward; axis lines ~0.6 pt; no gridlines (or very faint); **direct-label lines** instead of a legend box where possible. Banned: 3-D, pie charts, drop shadows, gradients, raster screenshots.
- **Exact sizing.** *Nature* column width = **89 mm** single (≈ 3.5 in), **183 mm** double (≈ 7.2 in). Set matplotlib `figsize` to these in inches; in this single-column A4 template include at `width=\linewidth`.
- **The caption states a finding.** Bold "Figure N." + one declarative sentence giving the takeaway, then detail. Not "Taxonomy of methods." but "Open-source LLM research splits into four lineages that diverge after the 2024 MoE shift."
### Nature-style matplotlib preamble — use this everywhere instead of the old serif block
```python
import matplotlib as mpl
WONG = ["#000000","#E69F00","#56B4E9","#009E73","#F0E442","#0072B2","#D55E00","#CC79A7"]
mpl.rcParams.update({
"font.family":"sans-serif", "font.sans-serif":["Helvetica","Arial","DejaVu Sans"],
"font.size":7, "axes.labelsize":7, "axes.titlesize":7,
"xtick.labelsize":6.5, "ytick.labelsize":6.5, "legend.fontsize":6.5,
"axes.linewidth":0.6, "axes.spines.top":False, "axes.spines.right":False,
"xtick.direction":"out", "ytick.direction":"out",
"xtick.major.size":2.5, "ytick.major.size":2.5,
"xtick.major.width":0.6, "ytick.major.width":0.6,
"axes.grid":False, "lines.linewidth":1.2, "lines.markersize":3.5,
"savefig.dpi":400, "savefig.bbox":"tight", "pdf.fonttype":42, "ps.fonttype":42,
"axes.prop_cycle": mpl.cycler(color=WONG[1:]),
})
# figsize: single column = (89/25.4, h); double column / 2-panel = (183/25.4, h)
```
### The design process — this is where flexibility lives
Templates are rigid because they answer "what figure exists?" Design answers "what does *this* survey need to show?" For each figure, decide from scratch:
1. **What claim in this section must the reader *see* to believe it?** No claim → no figure (cut it; decoration fails the Nature bar).
2. **What is the shape of that evidence?** hierarchy → tree (`forest`); change over time → timeline / line; coverage or comparison → matrix / small-multiples; mechanism → schematic; distribution → strip/box. Let the data shape pick the form — don't force every survey into taxonomy+timeline+matrix.
3. **What is the most reductive form that still makes the point?** One well-composed panel beats a busy one; merge weak figures, split overloaded ones.
4. **Compose** with the Nature language above, then apply the mechanical floor below (vector, `forest`/`\resizebox`, zero overflow/overlap).
Steps 1–3 change with every topic — that is the flexible craft. The mechanical floor (next section) never changes.
## Fitting & overflow — the mechanical floor (read BEFORE drawing any figure)
Most "ugly survey PDF" problems are not bad taste, they are **figures that overrun the column or overlap themselves** because the source used hand-tuned absolute sizes (`sibling distance=42mm`, `figsize=(7,…)`) that happen not to fit. The fix is to never hand-tune for fit — let the figure *adapt* to the available width.
**Know your column width first.** This template is **single-column** `article` on A4 with 1-inch margins → text width ≈ **159 mm (≈ 6.2 in)**. (`\documentclass{article}` is single-column; `figure*` does **not** widen anything here — it only spans columns in a genuinely two-column class such as IEEEtran. Don't reach for `figure*` to "get more room"; you don't have a second column.)
**There are two different failure modes, and they need two different fixes. Confusing them is why the old taxonomy sample both ran off the page _and_ overlapped.**
### Failure A — figure wider than the column (runs off the right margin)
Fix: wrap the picture so its *rendered width* is clamped.
- **TikZ:** wrap in `\resizebox{\linewidth}{!}{ … }`.
- **Includes:** always `\includegraphics[width=\linewidth]{…}` (or `0.85–0.95\linewidth`), never a bare `\includegraphics{file}`. matplotlib `figsize` then only sets aspect ratio; keep its width ≤ 6.2 in so in-figure fonts aren't double-shrunk.
```latex
\begin{figure}[!t]
\centering
\resizebox{\linewidth}{!}{%
\begin{tikzpicture}[ ... ] ... \end{tikzpicture}%
}
\caption{...}\label{fig:...}
\end{figure}
```
### Failure B — nodes overlapping each other (the real "ugly" problem)
**`\resizebox` does NOT fix overlap.** It scales the *whole* picture uniformly, so two boxes that overlap at natural size still overlap after shrinking — you just get a smaller tangle. Overlap comes from hand-picked spacing (`sibling distance=42mm`) where adjacent sub-trees are wider than the gap between them. The fixes, in order of preference:
1. **Use a layout engine that auto-spaces — `\usepackage{forest}`.** Forest computes sibling positions so children never collide, for any branch/leaf count. This is the default for taxonomies now (see Family 1). It removes the whole class of "magic mm that happens to overlap".
2. **Pick orientation by size.** Few leaves (≲ 12) → top-down reads well. Many leaves → grow the tree **horizontally** (`grow'=east`) so leaves stack down the page (vertical space is plentiful, horizontal isn't).
3. **Fold.** If one figure still can't hold it legibly, split a branch into its own sub-figure.
Then apply Failure-A's `\resizebox` on top as a width backstop. Order matters: forest (or real spacing) removes overlap; resizebox only then trims width.
The quality gate (`05-quality-gate.md` G1 + S5) treats residual `Overfull \hbox` as a remediation loop, and reminds you that a figure shrunk to illegibility is *not* a pass — fold it instead.
## File layout
All figures land under `output/literature-survey/<slug>/survey_paper/figures/`. Use vector PDF for LaTeX (`.pdf`); keep a PNG sibling only for previewing. TikZ figures live inline inside the relevant `sections/*.tex` (no separate file needed). matplotlib / seaborn figures get a `make_fig_NN_<slug>.py` script alongside the PDF.
Naming: `fig_<NN>_<short-slug>.pdf`. Numbers correspond to citation order.
## Family 1 — Taxonomy / classification diagrams (TikZ)
The single most important survey figure. A taxonomy figure says: *here is how I cut the field*. Readers will refer back to it constantly.
### Setup
In `survey_paper/main.tex`:
```latex
\usepackage{tikz}
\usetikzlibrary{positioning, shapes.geometric, arrows.meta, fit, backgrounds, calc, trees}
\usepackage{forest} % auto-spaced trees — taxonomies use this, NOT hand-built child{} trees
```
### Tree-style taxonomy — use `forest`, not hand-tuned `child{}` distances
> **Do not** build the taxonomy from a `tikzpicture` with `level/.style={sibling distance=42mm}` and nested `child{}` (the old sample here did exactly that). With more than ~3 leaves per branch, adjacent sub-trees are wider than the fixed gap and **the leaves overlap** — and because `\resizebox` scales the overlap too, you can't shrink your way out of it. `forest` computes sibling spacing automatically, so children never collide regardless of count.
**Flat, sans-serif, journal-style top-down (default; good up to ~12 leaves).** Define two colours once in `main.tex` (`\definecolor{nblue}{HTML}{0072B2}` and `\definecolor{nfill}{HTML}{EAF2FB}`, `\definecolor{ngrey}{HTML}{4D4D4D}`); thin uniform grey strokes + one accent + sans labels is the Nature diagram look — not the heavy blue/orange boxes the old sample used. **Replace every label with your own taxonomy.**
```latex
\begin{figure}[!t]
\centering
\resizebox{\linewidth}{!}{%
\begin{forest}
for tree={font=\sffamily\small, draw=ngrey, line width=0.4pt, rounded corners=1pt,
inner sep=3pt, align=center, edge={draw=ngrey, line width=0.4pt},
l sep=7mm, s sep=3mm, parent anchor=south, child anchor=north}
[Open-source LLMs, draw=nblue, line width=0.7pt, text=nblue
[Architecture, fill=nfill, draw=nblue [Llama 3][Mistral][Qwen2]]
[Sparse / MoE, fill=nfill, draw=nblue [DeepSeek][Mixtral][OLMoE]]
[Alignment, fill=nfill, draw=nblue [DPO][ORPO][KTO]]
[Efficiency, fill=nfill, draw=nblue [GPTQ][AWQ][QLoRA]]
]
\end{forest}%
}
\caption{\textbf{Figure 1.} Open-source LLM research organises into four lineages. Each leaf cites its primary source; full coverage in Section~\ref{sec:methods}.}
\label{fig:taxonomy}
\end{figure}
```
(`\sffamily` gives Helvetica when `main.tex` loads `\usepackage[scaled]{helvet}` — which the template now does — while body text stays serif, the standard journal split.)
**Horizontal / folder (use when there are many leaves — leaves stack down the page where there is room):** add `grow'=east, parent anchor=east, child anchor=west, anchor=west` to the `for tree={…}` options and switch `align=center`→`align=left`. This keeps labels full-size instead of shrinking them to fit one row. (Verified: a 5-branch / 20-leaf tree renders with zero overlap and zero overfull in both orientations; the same content as a hand-built `child{}` tree overflowed the page by 270 pt and merged half its leaves.)
### Layered / hierarchy diagram (when tree doesn't fit)
When the field has a layered structure (e.g., infrastructure → models → applications), use horizontal layers with `\node[fit=...]` to draw boundary boxes.
### Taste
- Color: one family per branch; orange for the row that contains your contribution if you have one.
- Leaves: 8–15 reads best top-down. With `forest` there is no hard cap (it won't overlap), but past ~15 switch to the horizontal orientation so labels stay full-size rather than shrinking; past ~24 fold into sub-figures.
- Always cite each leaf in the prose; the leaf names alone are not the survey, the citations are.
## Family 2 — Timeline of major works (matplotlib)
A survey timeline shows how the field evolved. Place key papers on a horizontal time axis with publication-year ticks.
```python
"""Generate fig_02_timeline.pdf — chronology of major works."""
import os
import matplotlib.pyplot as plt
# Apply the Nature-style preamble from the top of this reference (sans-serif,
# Wong palette, despined, thin axes). Do NOT use font.family:"serif".
events = [
# (year, lane, label, color)
(2017, 0, "Transformer\n(Vaswani)", "#1f77b4"),
(2019, 0, "LogSparse", "#1f77b4"),
(2020, 0, "Reformer", "#1f77b4"),
(2021, 1, "Informer\nAutoformer", "#ff7f0e"),
(2022, 1, "FEDformer\nPyraformer", "#ff7f0e"),
(2022, 2, "RevIN", "#2ca02c"),
(2023, 1, "PatchTST\nDLinear", "#ff7f0e"),
(2023, 3, "TimesNet\nTSMixer", "#9467bd"),
(2024, 1, "iTransformer\nTimeMixer", "#ff7f0e"),
(2024, 4, "MOMENT, Moirai\nTimeGPT, Chronos", "#d62728"),
]
LANE_LABELS = {
0: "Foundations",
1: "Time-domain Trans.",
2: "Normalisation",
3: "MLP / 2D",
4: "Foundation models",
}
fig, ax = plt.subplots(figsize=(6.0, 3.4)) # width ≤ column (6.2in); include with width=\linewidth
years = [e[0] for e in events]
ax.set_xlim(min(years) - 0.5, max(years) + 0.5)
ax.set_ylim(-0.7, max(LANE_LABELS) + 0.7)
for year, lane, label, color in events:
ax.scatter([year], [lane], s=120, color=color, edgecolor="black", linewidth=0.5, zorder=3)
ax.annotate(label, (year, lane), xytext=(0, 12), textcoords="offset points",
ha="center", fontsize=7.5, color="black")
ax.set_yticks(list(LANE_LABELS.keys()))
ax.set_yticklabels([LANE_LABELS[k] for k in sorted(LANE_LABELS)])
ax.set_xlabel("Year")
ax.grid(True, axis="x", alpha=0.25)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
plt.tight_layout(pad=0.4)
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "fig_02_timeline.pdf")
plt.savefig(out)
plt.close(fig)
print(f"Wrote {out}")
```
### Taste
- Lanes carve the timeline into sub-areas (rows of the figure) — the same sub-areas as the taxonomy (Fig~\ref{fig:taxonomy}). Consistency helps readers connect the two.
- Annotate ~10–15 key works; more is clutter. Pick the works that defined the year, not every paper.
- Color matches taxonomy color so the reader can cross-reference.
## Family 3 — Coverage matrix / capability heatmap (seaborn)
A survey often makes claims like "method X covers capabilities A, B but not C". A binary or three-level matrix makes that scannable.
```python
import os
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
methods = ["DLinear", "Informer", "Autoformer", "FEDformer",
"PatchTST", "iTransformer", "TimeMixer",
"MOMENT", "Moirai", "Chronos"]
caps = ["Long horizon", "Multivariate", "Probabilistic",
"Zero-shot", "Efficient", "Interpretable"]
# 0 = no, 1 = partial, 2 = yes (illustrative — derive from your survey reading)
cov = np.array([
[2, 1, 0, 0, 2, 1], # DLinear
[2, 1, 1, 0, 1, 0], # Informer
[2, 2, 1, 0, 1, 1], # Autoformer
[2, 2, 1, 0, 1, 1], # FEDformer
[2, 2, 0, 0, 2, 1], # PatchTST
[2, 2, 0, 0, 2, 0], # iTransformer
[2, 2, 0, 0, 2, 0], # TimeMixer
[2, 2, 1, 2, 1, 0], # MOMENT
[2, 2, 2, 2, 1, 0], # Moirai
[2, 2, 2, 2, 1, 0], # Chronos
])
# Apply the Nature-style preamble from the top of this reference (sans-serif, despined).
fig, ax = plt.subplots(figsize=(5.6, 3.6))
sns.heatmap(cov, annot=False, cmap="Blues", vmin=0, vmax=2,
xticklabels=caps, yticklabels=methods,
linewidths=0.4, linecolor="white",
cbar_kws={"label": "Coverage", "ticks": [0, 1, 2], "shrink": 0.6},
ax=ax)
ax.set_xticklabels(ax.get_xticklabels(), rotation=30, ha="right")
ax.set_yticklabels(ax.get_yticklabels(), rotation=0)
plt.tight_layout(pad=0.4)
plt.savefig("fig_03_capability_matrix.pdf")
plt.close(fig)
```
### Taste
- 0/1/2 (no/partial/yes) is more readable than continuous numbers when the underlying judgement is qualitative.
- Annotate cells only if there are ≤ 60.
- Cmap: greens for "more is better" (coverage); avoid traffic-light reds in surveys.
## Family 4 — Architecture / mechanism diagrams (TikZ)
When a sub-area shares a common architectural pattern (e.g., "all decomposition Transformers do X then Y"), a single TikZ figure illustrating the canonical pipeline saves several pages of prose. See the `paper-writer` skill's `references/02-figures-publication-grade.md` § Family 1 for the full template.
For a survey, prefer **abstracted** architectural diagrams that show the pattern shared by a family of methods, not one specific method.
## Family 5 — Quantitative trends (matplotlib)
Examples that work in a survey:
- Number of papers per year (publication trend)
- Reported MSE on a single benchmark over time (the SOTA curve)
- Compute requirements over time (size/cost trend)
These earn their place when they reveal something the prose can't. A "papers per year" plot that just goes up linearly is decoration; if it reveals a plateau, an inflection, or a divergence between sub-areas, it's content.
## Family 6 — Optional advanced
- **Citation co-occurrence network**: dot/network plot showing which papers cite each other (use NetworkX → matplotlib). Powerful when the field has clear clusters.
- **Geographic / institutional map**: world map with author affiliations marked. Niche but illuminating for cross-cultural fields.
- **Paradigm comparison**: side-by-side architectural sketches (multi-panel TikZ).
## No default figures
This skill has no default figure (unlike experiment-suite). All figures are agent-generated.
## Quick checklist
- [ ] **Designed for THIS topic** — zero labels/leaves/data carried over from the worked examples (no `Informer`/`PatchTST`/time-series content in a non-time-series survey)
- [ ] Each figure earns its place by making a specific claim visible (design process step 1)
- [ ] Nature/Science look: sans-serif labels, Wong palette / single-hue sequential, despined axes, direct labels, multi-panel with **a**/**b** where it tells one story
- [ ] matplotlib uses the sans-serif Nature preamble (not `font.family:"serif"`); `figsize` at 89 mm / 183 mm
- [ ] Caption leads with a one-sentence finding, not a noun phrase
- [ ] Taxonomy built with `forest` (auto-spaced), NOT hand-tuned `sibling distance` + `child{}` — no overlapping leaves
- [ ] Every TikZ/forest figure wrapped in `\resizebox{\linewidth}{!}{…}` as a width backstop (after spacing is correct, not instead of it)
- [ ] Every `\includegraphics` has `width=…\linewidth`; matplotlib `figsize` width ≤ 6.2 in
- [ ] No `figure*` used to "gain width" (single-column template); many-leaf trees go horizontal / fold, not squashed
- [ ] At least 1 taxonomy diagram; cited from §Methods or §Background
- [ ] At least 1 timeline; cited from §Introduction
- [ ] At least 1 capability / coverage matrix; cited from §Discussion
- [ ] 6–10 figures total
- [ ] All figure files are vector PDF; fonts embedded (`pdf.fonttype=42`)
- [ ] Each figure referenced in prose with `\ref{fig:...}`
- [ ] Each caption stands alone (a reader who only sees the figure understands it)
- [ ] No 3-D bars, no pie charts, no rainbow palettes, no raster screenshots
@@ -0,0 +1,172 @@
# Survey Section-by-Section Playbook
## Why this exists
A survey paper is not a longer research paper. The sections look superficially similar but carry different load. A research paper has a contribution (Method) and evidence (Experiment / Results); a survey has organisation (Taxonomy / themed reviews) and judgment (Discussion / Open challenges). This reference gives the per-section playbook for surveys specifically.
## Universal rules
- Every section starts with `\section{Title}\label{sec:slug}`.
- Cross-references between sections use `Section~\ref{sec:slug}` (non-breaking space).
- Inline citations: `~\cite{key}` for textual flow. With `[numbers,sort&compress]`, this produces `[3, 7]`-style refs.
- Figures: see `04-layout-discipline.md`. Survey figures are organisational; cite them often.
- One topic per paragraph.
- Use first-person plural ("we") consistently.
## Abstract — `sections/abstract.tex`
**Length:** 200–300 words. **Citations:** 4–8.
**Structure (one paragraph):**
1. **Domain & importance** (1 sentence).
2. **Why a survey now** (1 sentence): why is this the moment, what was missed by prior surveys.
3. **Scope** (1–2 sentences): what's in, what's out.
4. **Approach to the survey** (1 sentence): your taxonomy / lens.
5. **Headline findings** (2–3 sentences): the most useful generalisations the reader can take away.
6. **What's next** (1 sentence): open challenges teaser.
**Anti-patterns:**
- Marketing prose ("This survey provides a comprehensive overview…").
- No quantitative anchor (number of papers covered, time span).
- Spillover into Related Work.
## Introduction — `sections/introduction.tex`
**Length:** 4–5 paragraphs (~900–1300 words). **Citations:** 12–20.
**Structure:**
**¶1 — Problem frame.** Why is this field important? Use 2–3 application motivations and a quantitative anchor (market size, scale, dataset count). Cite foundational references.
**¶2 — Trajectory of the field.** A compressed history: dominant approaches over time. Reference the taxonomy figure (Section~\ref{sec:taxonomy}) and timeline figure (Fig~\ref{fig:timeline}). 5–10 citations grouped chronologically.
**¶3 — Why now / why this survey.** What changed recently that motivates a new survey. Cite prior surveys explicitly and contrast scope: what they covered, what they missed, why a new lens is needed. 3–6 citations.
**¶4 — Survey structure (the lens).** Name your taxonomy axes, state your scope (in / out), and forecast the section structure. End with a contributions-style list:
```latex
\emph{First}, we ...
\emph{Second}, we ...
\emph{Third}, we ...
```
For a survey, "contributions" become "what this survey does" — namely, the taxonomy, the time-series of progress, and the synthesis of open challenges.
**¶5 — Reading order.** Brief paragraph telling readers how to traverse the paper.
**Anti-patterns:**
- "Many works have addressed this~\cite{a, b, c, d}" — prose without distinction.
- Not citing prior surveys.
- Promising sub-areas not delivered later.
## Background — `sections/background.tex`
**Length:** 3–4 `\paragraph{}` subsections (~600–1200 words). **Citations:** 8–15.
This section is the survey's pedagogical foundation. Define notation, recall the prerequisites, give the canonical formulation of the problem, and present the canonical baseline / first solution.
**Subsections to consider:**
- Problem definition with notation
- Canonical baseline formulation (e.g., recurrent / linear / classical)
- Evaluation conventions in the field
- Unifying mathematical framework if one exists
End the section by referencing the taxonomy figure: "In the rest of the survey, we organise the literature according to Figure~\ref{fig:taxonomy}."
**Anti-patterns:**
- Skipping background under the assumption the reader knows the field — surveys are read by people new to it.
- Notation that doesn't match later sections.
## Methods — `sections/methods.tex`
**Length:** 1200–2200 words. **Citations:** 35–60 here alone.
This is the survey's central section. Each branch of the taxonomy gets a `\paragraph{}` (or even a `\subsection{}` when it's large enough), in roughly the order shown in Figure~\ref{fig:taxonomy}.
**Per-branch structure:**
1. **Premise** (1 sentence): the architectural / theoretical commitment that defines this branch.
2. **Canonical works** (3–5 papers cited individually with prose distinguishing them).
3. **Refinements / extensions** (3–8 follow-up papers grouped 2–3 per claim).
4. **Limitations** (1–2 sentences acknowledging the open critique within this branch).
End with a comparison paragraph that ties the branch back to the taxonomy and the timeline.
**Subsections:** for a large branch (10+ key papers), use `\subsection{}` and split into smaller paragraphs.
**Tables:** in this section a "method × property" comparison table (see `04-layout-discipline.md`) is often valuable.
**Anti-patterns:**
- Chronological dump within a branch ("In 2019, X… In 2020, Y…").
- Branches that don't connect back to the taxonomy.
- Branches with no critique — every architectural commitment has trade-offs; surveys should name them.
## Discussion — `sections/discussion.tex`
**Length:** 3–5 `\paragraph{}` subsections (~800–1500 words). **Citations:** 10–18.
Discussion is the survey's *judgment*. It synthesises across the methods covered.
**Subsections to consider:**
- **Cross-cutting trends.** Patterns visible across branches (e.g., "all of patching, inversion, and decomposition are forms of inductive bias re-injection").
- **Empirical maturity.** What has been measured well, what hasn't.
- **Coverage matrix.** Reference Fig~\ref{fig:capability_matrix}; what does the matrix tell us?
- **Where the field is converging or diverging.**
- **Engineering vs. science gaps.**
**Anti-patterns:**
- Restating Methods without adding judgment.
- Avoiding controversy (e.g., refusing to acknowledge a debate that exists).
## Conclusion — `sections/conclusion.tex`
**Length:** 2–3 paragraphs (~400–700 words). **Citations:** 4–8.
**Structure:**
**¶1 — What the survey did.** In 4–5 sentences, summarise the taxonomy and the most important findings.
**¶2 — Open challenges.** 4–6 concrete unresolved questions, each named and accompanied by 1–3 citations of work that points toward them.
**¶3 — Outlook.** Where the field is likely heading. This is forecast, not fact — write it as such (using "may" / "is likely to" rather than "will").
**Anti-patterns:**
- Repeating the abstract.
- Vague open challenges ("future work will explore extensions").
- Predictions stated as facts.
## Related Work — `sections/related_work.tex`
**Length:** 1–2 paragraphs (~400–700 words). **Citations:** 5–12.
In a survey, "Related Work" specifically means **other surveys** on the same or adjacent topics. This is short and deliberate.
**Structure:**
- Cite each prior survey by name (`Wen et al.~\cite{wen2023survey}`), with prose stating its scope and how yours differs.
- 5–10 prior surveys.
- 1 paragraph at the end discussing tutorials, blog series, and book chapters that complement the surveys.
**Anti-patterns:**
- Confusing "Related Work" with the methodology survey (Methods).
- Including every paper instead of just other surveys.
## Cross-section discipline
A survey's promises are made in the Introduction:
- "We organise the field according to Figure~\ref{fig:taxonomy}" → Methods must follow that taxonomy exactly.
- "We argue X" → Discussion must argue X explicitly.
- "We identify N open challenges" → Conclusion must list N.
Notation introduced in Background must reappear in Methods. Figures cited in Introduction must be referenced again later. The timeline cited in Introduction should be referenced again in Discussion when discussing trends.
## Quick checklist
- [ ] Every section has `\section{}\label{sec:...}` and is referenced from at least one other section.
- [ ] Abstract: 4–8 cites; one paragraph; quantitative anchor (papers covered, time span).
- [ ] Introduction: 12–20 cites; 4–5 paragraphs; explicit "First / Second / Third" what-this-survey-does.
- [ ] Background: 8–15 cites; notation + canonical baseline + evaluation conventions.
- [ ] Methods: 35–60 cites; structured per taxonomy branch; per-branch premise / canon / extensions / limitations.
- [ ] Discussion: 10–18 cites; cross-cutting trends and judgment.
- [ ] Conclusion: 4–8 cites; summary / open challenges / outlook.
- [ ] Related Work: 5–12 cites; **other surveys**, not the methodology body.
- [ ] Notation consistent across sections.
- [ ] First-person plural ("we") throughout.
+160
View File
@@ -0,0 +1,160 @@
# Layout Discipline — Tables, Figures, Floats, Cross-references
## Why this exists
A first draft is usually layout-naive: tables are bare `\begin{tabular}` blocks, figures use `[h]`, and the author block has no disclosure footnote. These choices break in journal/conference templates and look amateurish even where they don't break.
## Tables
### Always wrap in a `table` float
A bare `\begin{tabular}` in body text gets wrong placement, no caption, no label, and may break across pages. Always wrap:
```latex
\begin{table}[!t]
\centering
\small
\setlength{\tabcolsep}{4pt}
\caption{Comparison of Transformer-based time-series forecasters across capability dimensions. \checkmark = supported; \cmark[half] = partial; blank = not supported.}
\label{tab:capability}
\begin{tabular}{l c c c c c c}
\toprule
Method & Long horizon & Multivariate & Probabilistic & Zero-shot & Efficient & Interp. \\
\midrule
DLinear~\cite{zeng2023dlinear} & \checkmark & -- & -- & -- & \checkmark & -- \\
Informer~\cite{zhou2021informer} & \checkmark & \checkmark & -- & -- & \checkmark & -- \\
Autoformer~\cite{wu2021autoformer} & \checkmark & \checkmark & -- & -- & \checkmark & -- \\
PatchTST~\cite{nie2023patchtst} & \checkmark & \checkmark & -- & -- & \checkmark & -- \\
iTransformer~\cite{liu2024itransformer} & \checkmark & \checkmark & -- & -- & \checkmark & -- \\
Moirai~\cite{woo2024moirai} & \checkmark & \checkmark & \checkmark & \checkmark & -- & -- \\
\bottomrule
\end{tabular}
\end{table}
```
### Float placement
- `[!t]` — top of page. Default for tables and figures.
- `[!ht]` — top, otherwise here.
- Avoid `[h]` and `[h!]` — they cause floats to land in the middle of paragraphs.
- For a wide method-comparison table that overruns the text width, **do not** reach for `table*` (no second column to span here). Instead shrink to fit: `\small`/`\footnotesize`, tighten `\tabcolsep`, drop vertical padding, or wrap the `tabular` in `\resizebox{\linewidth}{!}{…}`; use `tabularx` with an `X` column when one text column should absorb the slack.
### Style
- **Always use `booktabs`**: `\toprule`, `\midrule`, `\bottomrule`. Never `\hline`.
- **No vertical rules** (`|` in column spec).
- **Numbers right-aligned** when comparing magnitudes.
- **Bold the cell that wins per row** if applicable. For survey capability tables, prefer `\checkmark` / `--` / partial markers over numerical scores.
- **Caption above** the tabular (scientific convention for tables).
### Caption rule
Captions must let a reader who reads only the caption + table understand what's shown. "Comparison." is not a caption; aim for 1–3 sentences naming the axis of comparison and the legend.
## Figures
### Float wrapper
```latex
\begin{figure}[!t]
\centering
\includegraphics[width=0.95\linewidth]{figures/fig_02_timeline.pdf}
\caption{Chronology of representative works on Transformer-based time-series forecasting. Lanes correspond to the taxonomy branches in Fig~\ref{fig:taxonomy}.}
\label{fig:timeline}
\end{figure}
```
### Width
- This template is **single-column** `article` → there is no second column to span. `figure*` behaves exactly like `figure` here, so it buys no width. Don't use it to "make room".
- Includes: `width=0.85\linewidth` to `width=\linewidth` — never a bare `\includegraphics{file}`.
- TikZ figures (taxonomy, timeline, architecture): wrap in `\resizebox{\linewidth}{!}{…}` so they fit the column whatever their natural size (see `02-survey-figures.md` § *Fitting & overflow*). If shrinking makes a tree unreadable, fold it into sub-figures rather than spilling past the margin.
### Path
`\includegraphics{figures/<basename>}` — never absolute paths.
### Caption
Same standalone-readable rule as tables. Caption goes **below** the figure.
### Multi-panel
Use `\begin{subfigure}` (the `subcaption` package is already loaded). For surveys, sub-figures are common when comparing canonical architectures across a family.
## Cross-references
### Every label must be referenced
If you `\label{eq:x}`, refer to it later with `Eq.~\ref{eq:x}`. Same for `\label{tab:...}`, `\label{fig:...}`, `\label{sec:...}`.
```bash
grep -oE '\\label\{[^}]+\}' sections/*.tex | sort -u > /tmp/labels.txt
grep -oE '\\ref\{[^}]+\}' sections/*.tex | sort -u > /tmp/refs.txt
diff <(comm -23 /tmp/labels.txt /tmp/refs.txt) <(echo)
```
### Non-breaking spaces
Use `~` not regular space:
- `Section~\ref{sec:methods}`
- `Table~\ref{tab:capability}`
- `Figure~\ref{fig:taxonomy}` (or `Fig.~\ref{...}`)
- `\cite{key}` is preceded by `~`: "as shown in PatchTST~\cite{nie2023patchtst}"
## Author and disclosure footnote
**Author:** the default template uses `\author{AI4S Agent}`. Keep this unless the user has provided a specific author block.
**Disclosure:** every survey produced by this skill must carry a `\thanks` footnote on the author block recommending human review. Surveys do not present numerical experimental results, so the simulated clause from `paper-writer`'s template is **not** included.
```latex
\author{AI4S Agent\thanks{This survey was generated by the AI4S Agent. \textbf{Human review by a domain expert is strongly recommended} before any scientific publication or production use.}}
```
Do **not** put `\input{simulated}` inside `\title{}`.
## Common compile errors
### `Citation X undefined`
- bib_key in `\cite{X}` does not appear in `bibliography.bib`. Check spelling.
- Forgot to run `bibtex main` between `pdflatex` passes. Compile sequence: `pdflatex` → `bibtex` → `pdflatex` → `pdflatex`.
### `Missing $ inserted`
- Math symbol used outside math mode. Wrap with `$...$`.
- Underscore in non-math text: escape with `\_`.
### `Overfull \hbox`
- A line is wider than the column. Caused by long unbreakable strings (URLs, long bib-key clusters, equations).
- Fix by breaking the line, using `\sloppy`, or shortening.
### Float too large for page
- Reduce `width=`, or wrap the content in `\resizebox{\linewidth}{!}{…}` (TikZ/tabular). `figure*`/`table*` do not help in this single-column template.
## Verification commands
After any compile:
```bash
cd output/literature-survey/<slug>/survey_paper
grep -E "Citation .* undefined" main.log # must be empty
grep -E "Reference .* undefined" main.log # must be empty
grep -E "Overfull|Underfull" main.log | head # should be near-empty
ls main.pdf # must exist
pdfinfo main.pdf | grep Pages # must be ≥ target
```
## Quick checklist
- [ ] Every table wrapped in `\begin{table}[!t]` with caption + label, using `booktabs`; wide tables fit via `\small`/`\resizebox`/`tabularx`, not `table*`
- [ ] Every figure wrapped in `\begin{figure}[!t]` with caption + label; TikZ in `\resizebox{\linewidth}{!}{…}`, includes with `width=…\linewidth`
- [ ] Captions are standalone-readable (1–3 sentences)
- [ ] Cross-refs use non-breaking space (`~`)
- [ ] No vertical rules in tables; no `\hline` inside `\toprule`/`\midrule`/`\bottomrule`
- [ ] Author = `AI4S Agent`; `\thanks` footnote present with human-review clause
- [ ] No simulated clause in the `\thanks` (surveys don't claim numerical results)
- [ ] Final compile log: 0 undefined citations, 0 undefined references, 0 overfull boxes (remediate, don't tolerate)
+303
View File
@@ -0,0 +1,303 @@
# Survey Quality Gate — Self-Check Before Delivery
## Why this exists
Even a thorough first pass produces a survey with one or two issues — citations that don't resolve, a figure that's too small, a section caption that's a fragment. This checklist runs **after** drafting and recompiling, **before** telling the user "it's done". If any item fails, return to the relevant reference.
The gate is bright-line. Do not soften the targets to ship.
## Hard gates (must pass)
### G1 · PDF compiles cleanly
```bash
cd output/literature-survey/<slug>/survey_paper
pdflatex -interaction=nonstopmode main.tex >/dev/null 2>&1
bibtex main >/dev/null 2>&1
pdflatex -interaction=nonstopmode main.tex >/dev/null 2>&1
pdflatex -interaction=nonstopmode main.tex >/dev/null 2>&1
test -s main.pdf || echo "FAIL: main.pdf missing or empty"
echo "undefined cites: $(grep -c 'Citation .* undefined' main.log) (must be 0)"
echo "undefined refs: $(grep -c 'Reference .* undefined' main.log) (must be 0)"
# Overfull boxes = content spilling past the margin (the "elements run off the
# page / overlap" complaint). List the worst offenders with how far they overrun:
grep 'Overfull \\hbox' main.log | grep -oE '\([0-9.]+pt too wide\)' | sort -t'(' -k2 -rn | head
echo "overfull boxes: $(grep -c 'Overfull \\hbox' main.log) (target 0)"
```
**Overfull is a remediation trigger, not a tolerated warning** (unattended runs have no human to eyeball the PDF). Any overfull box > ~2pt means something visibly crosses the margin — fix it, don't ship it:
- **Figure/table overrun** → it isn't wrapped per `02`/`04`. Wrap TikZ in `\resizebox{\linewidth}{!}{…}`; add `width=\linewidth` to the include; shrink/`tabularx` the table. This alone clears almost all overfull boxes.
- **A long unbreakable token** (URL, code, long math) → `\sloppy`, `\url{}`, or manual break.
- Recompile and re-grep until the count is 0 (a stray ≤ 1–2pt box from microtype is acceptable; anything larger is not).
### G2 · Bibliography size
```bash
grep -c "^@" bibliography.bib # must be ≥ 60 (100+ recommended)
```
No fabricated entries:
```bash
# Every entry should have a url= field that the agent fetched in this session
grep -c "url = {" bibliography.bib # should be close to total entry count
```
If many entries lack `url=`, you may have leaked memory-sourced entries; audit them.
### G2.5 · No orphan bib entries
A bib that contains entries never `\cite{}`-d in the prose is **padding**.
The common failure mode is reaching G2's count by appending famous papers
from adjacent fields (LLM, vision, foundational deep learning, …) that
the survey never uses. This gate detects orphans; **detection is not
termination — it triggers remediation**.
```bash
# every key listed in bibliography.bib must appear in at least one \cite,
# \citep, \citet, etc. in main.tex or sections/*.tex
bib_keys=$(grep -oE '^@[a-z]+\{[^,]+,' bibliography.bib \
| sed -E 's/^@[a-z]+\{//; s/,$//' | sort -u)
cite_keys=$(grep -hoE '\\cite[a-z]*\{[^}]+\}' main.tex sections/*.tex 2>/dev/null \
| grep -oE '\{[^}]+\}' | tr ',' '\n' | tr -d '{} \n' \
| sort -u | sed '/^$/d')
orphans=$(comm -23 <(echo "$bib_keys") <(echo "$cite_keys"))
orphan_count=$(echo "$orphans" | grep -c .)
echo "orphan bib entries: $orphan_count (must be 0)"
test "$orphan_count" -eq 0 || {
echo "ACTION REQUIRED · $orphan_count orphans (first 10):"
echo "$orphans" | head -10
}
```
**This is a remediation trigger, not a task-failure signal.** If
`orphan_count > 0`, DO NOT exit the step or report failure. Loop on
remediation until orphans reach 0, in this priority order:
1. **Cite them in prose** (preferred). Most orphans are real on-topic
papers you researched but skipped writing about. Go back to
`03-survey-section-playbook.md` and add each to the appropriate
section with a one-to-three-sentence treatment. A survey *is* the
argument that every cited paper deserves citation. Re-run the gate.
2. **Prune + lower scope.** If after honest effort you cannot extend prose
to cover the orphans, lower the target toward the 60 floor (100+ recommended)
and prune the bib to entries you actually cite. Update the abstract
to reflect the narrower scope. Re-run the gate.
3. **Prune + honest shortfall report.** If even the focused target
cannot be honestly reached, prune to the cited entries and add a
note to the introduction / abstract: "Scope limited to N entries
due to limited on-topic literature; expanded coverage left to
future work." Then re-run the gate. Never quietly pad — but a
smaller, honest bib is acceptable output.
Only after `orphan_count == 0` may you proceed past this gate.
### G2.6 · Temporal coverage matches the stated intent
If the topic named a year or recency window (the §0 *recency-led* posture in `01-bibliography-expansion.md`), the bib must actually contain real entries from it. This is the gate that catches "asked for 2026, delivered all 2024".
```bash
# Histogram the bib by year — eyeball it against the recorded posture.
grep -oE 'year[[:space:]]*=[[:space:]]*[{"]?[[:space:]]*(19|20)[0-9]{2}' bibliography.bib \
| grep -oE '(19|20)[0-9]{2}' | sort | uniq -c
```
There is **no universal threshold** — judge against the posture in `.bib_progress.txt`:
- **Recency-led** (topic named year Y / "latest"): the bulk of entries fall in the window, and there is a meaningful count *from Y itself*. Zero entries from the named year is an automatic fail; a handful is a warning — search harder before shipping.
- **Timeline-spanning / balanced**: the bib reaches the last ~6–12 months, not stopping 2 years short.
**Detection is a remediation trigger, not a stop.** If coverage doesn't match intent, loop:
1. **Search harder with date filters.** Re-run the §3.5 date-sorted arXiv queries with the explicit year; the newest papers are almost never in the model's prior knowledge, so relevance-ranked search alone keeps missing them. Add the real entries, recompile, re-check.
2. **Honest shortfall note** — only if, after genuine date-filtered searching, the literature in that window is truly thin: add one sentence to the introduction/abstract stating the actual coverage. Never silently substitute old papers for the requested recent ones.
### G3 · Page count
```bash
pdfinfo main.pdf | grep Pages # must be ≥ 6 (8+ recommended)
```
A survey under 5 pages is a digest, not a survey. Re-scope or expand.
### G4 · Cite count across sections
```bash
total=0
for f in sections/*.tex; do
c=$(grep -o "\\\\cite{" "$f" | wc -l)
total=$((total + c))
done
echo "TOTAL \\cite{} markers: $total" # must be ≥ 60
```
Per-section minimums:
| Section | Min `\cite{` count |
|---|---|
| abstract | 3 |
| introduction | 10 |
| background | 6 |
| methods | 25 |
| discussion | 6 |
| conclusion | 3 |
| related_work | 5 |
Methods carries most of the load — that is correct for a survey.
### G5 · Required figures present
```bash
grep -rh "begin{figure" sections/ | wc -l # must be ≥ 6
```
Specifically, the survey must have:
- ≥ 1 taxonomy / classification diagram (TikZ-style figure tag in Background or Methods)
- ≥ 1 chronological timeline (matplotlib-style figure tag, typically in Introduction)
- ≥ 1 coverage / capability matrix (heatmap-style figure tag, typically in Discussion)
```bash
grep -l "fig:taxonomy" sections/*.tex # must list the section that owns the taxonomy fig
grep -l "fig:timeline" sections/*.tex
grep -l "fig:capability\|fig:coverage" sections/*.tex
```
(These three are the *common* survey figures, not a mandatory trio — per `02`'s design process, let the topic decide. The bar is "every figure makes a claim visible", not "fill these slots".)
### G5.5 · No template leakage; Nature/Science look
The figures must be designed for this survey, not copied from the playbook's worked examples (a real run once shipped time-series leaves — `Informer`, `PatchTST` — inside an LLM survey).
```bash
# Sample/example tokens that must NOT appear unless the topic genuinely is time-series:
grep -rIE "Informer|Autoformer|FEDformer|PatchTST|iTransformer|Moirai|TimeGPT|Time-Series Forecasting" \
sections/ figures/ *.tex 2>/dev/null | grep -v "%" # expect empty for non-TS topics
# Figures should be sans-serif (Nature), not the default serif:
grep -rn 'font.family.*serif' figures/*.py 2>/dev/null # expect empty (use the sans Nature preamble)
# Taxonomies must be forest-based (auto-spaced), not hand-tuned overlapping trees:
grep -rn 'sibling distance' sections/*.tex 2>/dev/null # expect empty
```
If any fires: redraw the offending figure for *this* topic with the Nature language in `02` (sans-serif, Wong palette, despined, panel labels, finding-first caption). This is a remediation trigger — fix and re-run, don't ship a leaked or generic-looking figure.
### G6 · Comparison table present
```bash
grep -rh "begin{table" sections/ | wc -l # must be ≥ 1
```
A survey should have at least one method-comparison table (often spanning the column with `\begin{table*}`).
### G7 · Disclosure footnote correct
The `\author{}` block in `main.tex` carries a `\thanks` footnote with the always-on human-review clause:
```bash
grep -E "Human review|human review" main.tex # must match
```
Surveys do **not** include the simulated clause:
```bash
grep -i "simulated" main.tex sections/abstract.tex # should be empty
```
If your survey somehow ended up with the simulated clause, remove it — surveys don't carry numerical experiments to simulate.
### G8 · Cross-reference integrity
```bash
grep -ohE '\\label\{[^}]+\}' sections/*.tex | sed 's/.*\\label{//;s/}.*//' | sort -u > /tmp/labels
grep -ohE '\\ref\{[^}]+\}' sections/*.tex | sed 's/.*\\ref{//;s/}.*//' | sort -u > /tmp/refs
diff <(comm -23 /tmp/labels /tmp/refs) <(echo) # labels with no ref → bad
diff <(comm -13 /tmp/labels /tmp/refs) <(echo) # refs with no label → bad
```
## Soft gates (should pass)
### S1 · Notation consistency
Skim all sections for the same concept under different symbols. Pick one and globally replace.
### S2 · Caption quality
Read each caption alone (cover the figure/table). If it doesn't convey what's shown, lengthen.
### S3 · Anti-pattern sweep
```bash
# Marketing prose
grep -E "comprehensive overview|extensive review|cutting-edge|state-of-the-art" sections/*.tex | head
# These are not always wrong, but if they're frequent the prose is fluffy.
grep -E "the authors|This paper presents|This survey provides" sections/*.tex # should be empty / minimal
# Citation dumps (≥ 6 keys in one \cite{})
grep -oE '\\cite\{[^}]+\}' sections/*.tex | awk -F, '{print NF}' | sort -nr | head -3
# top number should be ≤ 5
```
### S4 · Prior surveys actually cited
```bash
# Open Related Work; check it cites at least 5 prior surveys by name
wc -l sections/related_work.tex
```
A survey that does not engage with prior surveys is rude (and incomplete).
### S5 · Figures look right
Unattended runs can't rely on a human opening the PDF, so this is now two layers:
**Machine check (always):** G1's overfull list above must be empty (or ≤ ~2pt). A figure that overruns the margin shows up there; a figure correctly wrapped in `\resizebox`/`width=\linewidth` cannot. If you have `pdftoppm`/ImageMagick, rasterize the figure pages (`pdftoppm -png -f <p> -l <p> main.pdf /tmp/chk`) and confirm no glyphs touch the page edge.
**Taste check (when a reviewer is available):** open `main.pdf` and verify:
- Taxonomy figure: leaves are readable (not shrunk to illegibility by `\resizebox` — if so, fold the tree); fits cleanly within the column.
- Timeline: lane structure visible; labels not overlapping.
- Coverage matrix: cell colors readable; legend explained.
- Architecture figures (if any): consistent style with the taxonomy.
## Final report format
When all gates pass:
```
Survey ready: output/literature-survey/<slug>/survey_paper/main.pdf
Stats:
Pages: 9
Bibliography: 112 entries (all url-backed)
\cite{} total: 78 across 7 sections
Figures: 8 (1 taxonomy, 1 timeline, 1 coverage matrix, 3 architecture, 2 trend)
Tables: 2 (capability comparison, paradigm summary)
Compile: 0 undefined citations, 0 undefined refs, 0 overfull boxes
Coverage: recency-led; 41/58 entries in 2026 window (posture honoured)
Quality gate: PASSED (G1–G8 hard incl. G2.6 temporal coverage, S1–S5 soft).
```
If you cannot pass G1–G4 without compromising honesty, **say so explicitly**:
> "Bibliography stalled at 52 entries — could not find more high-quality citations on this niche topic via WebFetch. Page count 5. The survey is delivery-quality at this scope; raising to 100 cites would require padding with low-relevance entries that hurt readability."
That's a legitimate stop. Fabricating entries to clear the gate is not.
## Quick checklist
- [ ] G1 compile clean; 0 overfull boxes (remediate, don't tolerate)
- [ ] G2 bibliography ≥ 60 (100+ recommended); every entry has `url=`
- [ ] G2.6 temporal coverage matches the §0 posture (recency-led topic → real entries from the named year)
- [ ] G3 PDF ≥ 6 pages
- [ ] G4 `\cite{}` total ≥ 60; per-section minimums hit
- [ ] G5 ≥ 6 figures; taxonomy + timeline + coverage matrix all present
- [ ] G6 ≥ 1 comparison table
- [ ] G7 `\thanks` carries human-review clause; no simulated clause
- [ ] G8 every label is referenced
- [ ] S1–S5 soft gates reviewed
- [ ] Visual sanity check on the rendered PDF
- [ ] Honest report — don't pad to clear gates
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
set -e
OUTPUT_DIR="output/survey_paper"
mkdir -p "$OUTPUT_DIR"
# Copy template files to output
if [ ! -f "$OUTPUT_DIR/main.tex" ]; then
cp templates/survey/main.tex "$OUTPUT_DIR/"
fi
# Copy sections and bibliography
cp -r templates/survey/sections "$OUTPUT_DIR/" 2>/dev/null || true
cp templates/survey/figures "$OUTPUT_DIR/" 2>/dev/null || true
cd "$OUTPUT_DIR"
echo "First pdflatex run..."
pdflatex -interaction=nonstopmode main.tex || true
echo "Running bibtex..."
if [ -f bibliography.bib ]; then
bibtex main || true
fi
echo "Second pdflatex run..."
pdflatex -interaction=nonstopmode main.tex || true
echo "Final pdflatex run..."
pdflatex -interaction=nonstopmode main.tex || true
echo "Compilation complete. PDF: $OUTPUT_DIR/main.pdf"
Whitespace-only changes.
+61
View File
@@ -0,0 +1,61 @@
% =================================================================
% SURVEY PAPER TEMPLATE
% =================================================================
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{amsmath,amssymb,amsfonts}
% Helvetica for \sffamily so figure labels match the Nature/Science sans-serif
% convention, while body text stays serif (familydefault unchanged).
\usepackage[scaled]{helvet}
% Nature-ish figure palette (used by TikZ/forest diagrams). Wong palette in scripts.
\usepackage{xcolor}
\definecolor{nblue}{HTML}{0072B2}
\definecolor{ngrey}{HTML}{4D4D4D}
\definecolor{nfill}{HTML}{EAF2FB}
\usepackage[a4paper, margin=1in]{geometry}
\usepackage[numbers,sort&compress]{natbib}
\usepackage{hyperref}
\usepackage{booktabs}
\usepackage{microtype}
\usepackage{algorithm}
\usepackage{algpseudocode}
\usepackage{enumitem}
\usepackage{array}
\usepackage{tabularx}
\usepackage{multirow}
\usepackage{subcaption}
% Taxonomy/diagram figures: TikZ for drawing, forest for auto-spaced trees
% (taxonomies MUST use forest, not hand-tuned sibling distances — see
% references/02-survey-figures.md). graphicx
% (above) provides \resizebox for clamping any figure to \linewidth.
\usepackage{tikz}
\usetikzlibrary{positioning, shapes.geometric, arrows.meta, fit, backgrounds, calc, trees}
\usepackage{forest}
% Custom commands
\newcommand{\todo}[1]{\textcolor{red}{[TODO: #1]}}
\title{\textbf{{{TITLE}}}}
% Author defaults to "AI4S Agent". The enrichment step
% (see SKILL.md Step 3) is responsible for
% adding a \thanks footnote that recommends human review. Surveys do NOT
% include a simulated clause (no numerical experiments).
\author{AI4S Agent}
\date{\today}
\begin{document}
\maketitle
\input{sections/abstract}
\input{sections/introduction}
\input{sections/related_work}
\input{sections/background}
\input{sections/methods}
\input{sections/discussion}
\input{sections/conclusion}
\bibliographystyle{plainnat}
\bibliography{bibliography}
\end{document}
Whitespace-only changes.