Preflight Check
Run a deterministic desk-reject lint over a LaTeX submission before the
authors hit "submit". Venues explicitly desk-reject — without review — for
page-limit violations, template tampering, anonymization leaks, and missing
mandatory sections. Every one of those is machine-checkable from the source.
This skill catches them while there is still time to fix them.
When to use
- "Is my paper ready to submit to NeurIPS / SIGSPATIAL / CHI / ...?"
- "Check my paper for desk-reject risks" / "run a preflight"
- "Did I anonymize this properly?" / "double-blind check"
- "Am I over the page limit?" / "is my template compliant?"
- Right after
tailor-to-venue, and always before any actual submission.
Inputs
- The main
.tex file of the submission (the one with \documentclass).
\input/\include files are followed automatically.
- A venue profile:
venues/conferences/<venue>-<year>.yml (schema in
venues/schema.yml). If the venue has no profile yet, create one first
with parse-cfp (or copy the nearest family file and fill it in).
- Optional but strongly recommended: a compiled
.log or .pdf next to the
.tex (same basename) so the page-count risk check can run.
Process
Resolve the venue profile. Find the matching file under
venues/conferences/. Confirm the year matches the target deadline cycle.
Ask the user which track they are submitting to — page limits differ per
track (e.g. SIGSPATIAL Research = 10 pages excl. references, Demo = 4
incl.). Sanity-check the merged profile with:
python3 scripts/venue_profile.py venues/conferences/<venue>.yml --track <name>
Re-verify critical facts against the live CFP — mandatory. Profiles
are a starting point, never ground truth; a stale page limit causes the
exact desk reject this skill exists to prevent. Fetch the profile's
cfp_url and confirm: page limit + what it excludes, blind level,
template invocation, required sections, and the deadline. If anything
differs, update the profile YAML first and say so in the report.
Run the full preflight:
python3 scripts/run_preflight.py paper.tex \
--venue venues/conferences/<venue>-<year>.yml --track "<track>"
Or run checkers individually when the user asks about one dimension:
| Script |
Checks |
Run |
scripts/check_template.py |
documentclass + options vs profile, year-versioned .sty (NeurIPS/ICML/ICLR), geometry/savetrees/fullpage, \setlength on layout dims, \linespread<1, negative \vspace patterns, column count, page-limit risk from .log/.pdf |
python3 scripts/check_template.py paper.tex --venue <yml> --track <t> |
scripts/check_anonymization.py |
\author/\affiliation/\email/\orcid/\thanks content, acknowledgments sections, funding/grant lines, identifying links (GitHub, personal pages) vs anonymized mirrors, first-person self-citations, hyperref pdfauthor |
python3 scripts/check_anonymization.py paper.tex --venue <yml> |
scripts/check_sections.py |
every format.required_sections token: NeurIPS checklist, ICML impact statement, AI-use acknowledgement (ICDE), COI declaration, CCS concepts + \keywords, plus title/abstract/bibliography presence |
python3 scripts/check_sections.py paper.tex --venue <yml> |
scripts/check_abstract.py |
abstract word count vs venue bounds (or the 150–250 norm), single-paragraph rule, citations/URLs in abstract, keywords format (ACM/IEEE Index Terms/LNCS 3–6) |
python3 scripts/check_abstract.py paper.tex --venue <yml> |
Useful flags on every script: --json (machine-readable), --strict
(warnings also fail), --track <substring>, --venues-dir <dir> (when the
profile lives outside this repo), --no-inputs. Anonymization adds
--force to scan even at single-blind venues.
Interpret severities for the user.
ERROR — documented desk-reject grounds at this venue. Must fix.
WARN — judgment call (e.g. one negative \vspace is normal; eight is
space compression). Walk through each with the user.
INFO — confirmations and pointers to manual checks. Do not pad the
report with these; summarize.
Exit codes: 0 = no errors, 1 = errors found (or warnings with --strict),
2 = bad arguments/missing files.
Do the manual checks the linter cannot do. Source-level linting
cannot see compiled-PDF metadata, where the references actually start,
supplementary files, or submission-form fields (COI declarations at ICDE
live in CMT, not the PDF). Work through
references/manual-checks.md with the user.
Fix and re-run until clean. Quote each finding's file:line, propose
the minimal edit, apply it if asked, and re-run the affected checker.
For the reasoning behind each check (which venue desk-rejects for what,
with sources), see
references/desk-reject-triggers.md.
Output
A findings report (text or --json) per checker or combined via
run_preflight.py: severity, check id, file:line, message, summary counts,
and a verdict (FAIL if any ERROR, PASS with warnings if only WARNs, else
PASS). Present it to the user as a fix-list ordered by severity, then offer
to apply fixes one at a time.
Worked example
A NeurIPS submission that still carries author identity and last year's style
file. Running the combined checker:
python3 scripts/run_preflight.py paper.tex \
--venue venues/conferences/neurips-2026.yml
=============================================================================
PREFLIGHT REPORT paper.tex
venue: neurips-2026 track: main
=============================================================================
-- template --------------------------------------------------------------
[ERROR] template/style-file-year paper.tex:1 — uses neurips_2025.sty; NeurIPS 2026 requires neurips_2026.sty
[WARN ] template/negative-vspace paper.tex:312 — negative \vspace before figure; isolated, likely fine
-- anonymization ---------------------------------------------------------
[ERROR] anonymization/pdf-metadata paper.tex:14 — \hypersetup{pdfauthor=...} leaks the author into PDF metadata
[WARN ] anonymization/author-block paper.tex:22 — \author populated; the .sty hides it at submission, but scrub the source
[WARN ] anonymization/self-citation paper.tex:88 — "our previous work [12]" — rewrite in third person
-- sections --------------------------------------------------------------
[ERROR] sections/missing:neurips-checklist paper.tex — no NeurIPS checklist found; a missing checklist is a desk reject
-- abstract --------------------------------------------------------------
clean.
=============================================================================
VERDICT: FAIL — fix ERRORs before submitting (3 error(s), 3 warning(s), 0 info)
Profiles can go stale: re-verify limits/policies at https://neurips.cc/Conferences/2026/CallForPapers
=============================================================================
How to present this: lead with the three ERRORs as a numbered fix-list
(neurips_2026.sty, drop the pdfauthor leak, add the checklist), each with
its file:line and the one-line edit; then walk the WARNs as judgment calls.
Re-verify the page limit and checklist requirement at the cfp_url before the
user relies on the verdict, then re-run the affected checker after each fix.
Adapt to your discipline
Profiles can represent conferences, journals, and workshops in any field. Add
venue YAMLs with your community's rules — the checkers only read the profile,
so new disciplines need data, not code.
Guardrails
- A clean preflight is necessary, not sufficient — never tell the user the
paper "will not be desk-rejected"; say "no machine-checkable desk-reject
triggers found".
- Always re-verify page limits/deadlines/policies against the live
cfp_url
before the user relies on them (step 2 is not optional).
- Never submit to any system on the user's behalf; stop at the report.
- Never paste large portions of the user's paper into the report — quote at
most the flagged line.
- Citation problems are out of scope here: route them through
verify-citations.
Memory
This skill uses the shared .paper-memory/ convention in the user's paper
directory, following paper-memory-convention.md.
- At start: read
.paper-memory/lessons.md (and profile.yml for venue
tier / constraints). Skip re-flagging issues already recorded and acted on;
lead with any recurring desk-reject habits this author has (e.g. "you tend
to compress layout near the page limit").
- At end: append each finding worth remembering as one dated entry in the
shared format
- [YYYY-MM-DD] (preflight-check | <scope>) issue -> recommendation (use reflect-and-improve's reflect_log.py append, which
dedupes and dates). Tag a repeat-across-papers habit recurring, a one-off
this-paper.
- Create
.paper-memory/ on demand if absent and offer to add it to the
project .gitignore. It is local-only; never upload it or copy it into this
repo.
1---2name: preflight-check3description: Deterministic desk-reject preflight linter for LaTeX paper submissions. Use it when a researcher asks "is my paper ready to submit", or mentions preflight, desk reject, submission check, page limit, anonymization, double-blind, missing checklist, or format/template compliance for a conference (NeurIPS, ICML, CHI, SIGSPATIAL, SIGMOD, ICDE, CVPR, LNCS...). Lints the .tex source against a machine-readable venue profile for documentclass and style-file options, margin/template tampering (geometry, savetrees, spacing hacks), anonymization leaks (author block, acknowledgments, repo links, first-person self-citations, \thanks, pdfauthor), required sections (NeurIPS checklist, ICML impact statement, AI-use acknowledgement, COI, CCS concepts/keywords), abstract length, keywords format, and page-limit risk. Every finding is reported with file:line. Runs bundled stdlib-only Python scripts; advisory only, never submits anything.4---56# Preflight Check78Run a deterministic desk-reject lint over a LaTeX submission before the9authors hit "submit". Venues explicitly desk-reject — without review — for10page-limit violations, template tampering, anonymization leaks, and missing11mandatory sections. Every one of those is machine-checkable from the source.12This skill catches them while there is still time to fix them.1314## When to use1516- "Is my paper ready to submit to NeurIPS / SIGSPATIAL / CHI / ...?"17- "Check my paper for desk-reject risks" / "run a preflight"18- "Did I anonymize this properly?" / "double-blind check"19- "Am I over the page limit?" / "is my template compliant?"20- Right after `tailor-to-venue`, and always before any actual submission.2122## Inputs23241. The main `.tex` file of the submission (the one with `\documentclass`).25 `\input`/`\include` files are followed automatically.262. A venue profile: `venues/conferences/<venue>-<year>.yml` (schema in27 `venues/schema.yml`). If the venue has no profile yet, create one first28 with `parse-cfp` (or copy the nearest family file and fill it in).293. Optional but strongly recommended: a compiled `.log` or `.pdf` next to the30 `.tex` (same basename) so the page-count risk check can run.3132## Process33341. **Resolve the venue profile.** Find the matching file under35 `venues/conferences/`. Confirm the year matches the target deadline cycle.36 Ask the user which track they are submitting to — page limits differ per37 track (e.g. SIGSPATIAL Research = 10 pages excl. references, Demo = 438 incl.). Sanity-check the merged profile with:39 `python3 scripts/venue_profile.py venues/conferences/<venue>.yml --track <name>`40412. **Re-verify critical facts against the live CFP — mandatory.** Profiles42 are a starting point, never ground truth; a stale page limit causes the43 exact desk reject this skill exists to prevent. Fetch the profile's44 `cfp_url` and confirm: page limit + what it excludes, blind level,45 template invocation, required sections, and the deadline. If anything46 differs, update the profile YAML first and say so in the report.47483. **Run the full preflight:**4950 ```51 python3 scripts/run_preflight.py paper.tex \52 --venue venues/conferences/<venue>-<year>.yml --track "<track>"53 ```5455 Or run checkers individually when the user asks about one dimension:5657 | Script | Checks | Run |58 |---|---|---|59 | `scripts/check_template.py` | documentclass + options vs profile, year-versioned .sty (NeurIPS/ICML/ICLR), geometry/savetrees/fullpage, `\setlength` on layout dims, `\linespread`<1, negative `\vspace` patterns, column count, page-limit risk from `.log`/`.pdf` | `python3 scripts/check_template.py paper.tex --venue <yml> --track <t>` |60 | `scripts/check_anonymization.py` | `\author`/`\affiliation`/`\email`/`\orcid`/`\thanks` content, acknowledgments sections, funding/grant lines, identifying links (GitHub, personal pages) vs anonymized mirrors, first-person self-citations, hyperref `pdfauthor` | `python3 scripts/check_anonymization.py paper.tex --venue <yml>` |61 | `scripts/check_sections.py` | every `format.required_sections` token: NeurIPS checklist, ICML impact statement, AI-use acknowledgement (ICDE), COI declaration, CCS concepts + `\keywords`, plus title/abstract/bibliography presence | `python3 scripts/check_sections.py paper.tex --venue <yml>` |62 | `scripts/check_abstract.py` | abstract word count vs venue bounds (or the 150–250 norm), single-paragraph rule, citations/URLs in abstract, keywords format (ACM/IEEE Index Terms/LNCS 3–6) | `python3 scripts/check_abstract.py paper.tex --venue <yml>` |6364 Useful flags on every script: `--json` (machine-readable), `--strict`65 (warnings also fail), `--track <substring>`, `--venues-dir <dir>` (when the66 profile lives outside this repo), `--no-inputs`. Anonymization adds67 `--force` to scan even at single-blind venues.68694. **Interpret severities for the user.**70 - `ERROR` — documented desk-reject grounds at this venue. Must fix.71 - `WARN` — judgment call (e.g. one negative `\vspace` is normal; eight is72 space compression). Walk through each with the user.73 - `INFO` — confirmations and pointers to manual checks. Do not pad the74 report with these; summarize.75 Exit codes: 0 = no errors, 1 = errors found (or warnings with `--strict`),76 2 = bad arguments/missing files.77785. **Do the manual checks the linter cannot do.** Source-level linting79 cannot see compiled-PDF metadata, where the references actually start,80 supplementary files, or submission-form fields (COI declarations at ICDE81 live in CMT, not the PDF). Work through82 [references/manual-checks.md](references/manual-checks.md) with the user.83846. **Fix and re-run until clean.** Quote each finding's `file:line`, propose85 the minimal edit, apply it if asked, and re-run the affected checker.86 For the reasoning behind each check (which venue desk-rejects for what,87 with sources), see88 [references/desk-reject-triggers.md](references/desk-reject-triggers.md).8990## Output9192A findings report (text or `--json`) per checker or combined via93`run_preflight.py`: severity, check id, `file:line`, message, summary counts,94and a verdict (`FAIL` if any ERROR, `PASS with warnings` if only WARNs, else95`PASS`). Present it to the user as a fix-list ordered by severity, then offer96to apply fixes one at a time.9798## Worked example99100A NeurIPS submission that still carries author identity and last year's style101file. Running the combined checker:102103```104python3 scripts/run_preflight.py paper.tex \105 --venue venues/conferences/neurips-2026.yml106```107108```109=============================================================================110PREFLIGHT REPORT paper.tex111venue: neurips-2026 track: main112=============================================================================113114-- template --------------------------------------------------------------115 [ERROR] template/style-file-year paper.tex:1 — uses neurips_2025.sty; NeurIPS 2026 requires neurips_2026.sty116 [WARN ] template/negative-vspace paper.tex:312 — negative \vspace before figure; isolated, likely fine117118-- anonymization ---------------------------------------------------------119 [ERROR] anonymization/pdf-metadata paper.tex:14 — \hypersetup{pdfauthor=...} leaks the author into PDF metadata120 [WARN ] anonymization/author-block paper.tex:22 — \author populated; the .sty hides it at submission, but scrub the source121 [WARN ] anonymization/self-citation paper.tex:88 — "our previous work [12]" — rewrite in third person122123-- sections --------------------------------------------------------------124 [ERROR] sections/missing:neurips-checklist paper.tex — no NeurIPS checklist found; a missing checklist is a desk reject125126-- abstract --------------------------------------------------------------127 clean.128129=============================================================================130VERDICT: FAIL — fix ERRORs before submitting (3 error(s), 3 warning(s), 0 info)131Profiles can go stale: re-verify limits/policies at https://neurips.cc/Conferences/2026/CallForPapers132=============================================================================133```134135How to present this: lead with the three ERRORs as a numbered fix-list136(`neurips_2026.sty`, drop the `pdfauthor` leak, add the checklist), each with137its `file:line` and the one-line edit; then walk the WARNs as judgment calls.138Re-verify the page limit and checklist requirement at the `cfp_url` before the139user relies on the verdict, then re-run the affected checker after each fix.140141## Adapt to your discipline142143Profiles can represent conferences, journals, and workshops in any field. Add144venue YAMLs with your community's rules — the checkers only read the profile,145so new disciplines need data, not code.146147## Guardrails148149- A clean preflight is necessary, not sufficient — never tell the user the150 paper "will not be desk-rejected"; say "no machine-checkable desk-reject151 triggers found".152- Always re-verify page limits/deadlines/policies against the live `cfp_url`153 before the user relies on them (step 2 is not optional).154- Never submit to any system on the user's behalf; stop at the report.155- Never paste large portions of the user's paper into the report — quote at156 most the flagged line.157- Citation problems are out of scope here: route them through158 `verify-citations`.159160## Memory161162This skill uses the shared `.paper-memory/` convention in the user's paper163directory, following [`paper-memory-convention.md`](../paper-profile/references/paper-memory-convention.md).164165- **At start:** read `.paper-memory/lessons.md` (and `profile.yml` for venue166 tier / constraints). Skip re-flagging issues already recorded and acted on;167 lead with any `recurring` desk-reject habits this author has (e.g. "you tend168 to compress layout near the page limit").169- **At end:** append each finding worth remembering as one dated entry in the170 shared format `- [YYYY-MM-DD] (preflight-check | <scope>) issue ->171 recommendation` (use `reflect-and-improve`'s `reflect_log.py append`, which172 dedupes and dates). Tag a repeat-across-papers habit `recurring`, a one-off173 `this-paper`.174- Create `.paper-memory/` on demand if absent and offer to add it to the175 project `.gitignore`. It is local-only; never upload it or copy it into this176 repo.