Files
AOS/skills/literature-survey/references/00-incremental-execution.md
T
Z User e45b68bb8b 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
2026-10-27 22:50:50 +00:00

154 lines
7.5 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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"