Turn an AI-flavored or overwrought draft into prose that reads like a
careful researcher wrote it — without moving a single number, claim, or
citation. Reviewers now pattern-match the LLM register (delve/leverage
vocabulary, Moreover-stacked paragraphs, em-dash chains, uniform hedging),
and a leftover "Certainly! Here is..." or "[insert citation]" is a
desk-reject-grade embarrassment. This skill finds all of it
deterministically, then guides a disciplined human-in-the-loop rewrite:
expression changes, content does not.
-
Freeze the technical content first. Build the no-touch inventory
before editing anything: every number and unit, every \cite key, every
stated result, dataset name, and system name. Snapshot it:
grep -oE '[0-9][0-9.,]*\s*(%|\\%|ms|s|GB|MB|x|×)?' draft.tex | sort | uniq -c > /tmp/numbers-before.txt
The same command must produce identical output after the edit pass
(step 9). If polishing would require changing a claim, stop and tell
the user — that is a content decision, not a style edit.
-
Resolve the venue register and the LLM policy. If a venue profile is
given, read its family (register norms per
references/venue-register.md) and
review.llm_policy. Re-verify the LLM policy against the live
cfp_url before relying on it — these policies churn every cycle.
Tell the user plainly: polishing AI-assisted text does not remove a
disclosure obligation. If the venue requires an AI-use statement, help
write an honest one; never frame this skill as a way to avoid it.
-
Run the linters (Python 3, stdlib only, no network):
python3 scripts/prose_lint.py main.tex
python3 scripts/terminology_check.py main.tex --allow GPS,SDK
Both accept .tex, plain text, or - for stdin; --json for
machine-readable output; --strict to exit 1 while findings remain.
Exit codes: 0 ok, 1 strict-failure, 2 bad input. --allow skips the
undefined-acronym check for acronyms your community treats as
universally known; --glossary FILE enforces a terminology table.
Findings are candidates with line numbers, never auto-replacements —
domain terms can look like tells ("leverage scores", "robust
statistics").
-
Kill RISK findings immediately. Chatbot artifacts ("As an AI
model...", "Certainly! Here is...", "[insert X]") are deleted or filled
in, full stop. Several venues treat undisclosed LLM output as a
desk-reject trigger; an unfilled placeholder is also a missing citation
— route real citation needs through verify-citations, never invent
one.
-
Edit pass A — lexical and structural tells. Work section by section
with references/llm-tells.md open. For each
WARN: keep it if it is a domain term or genuinely the best word
(occasional use is fine — density is the tell, not existence);
otherwise apply the rewrite pattern. Break Moreover/Furthermore
paragraph chains by deleting the connective — if the logic no longer
flows, the paragraph order was wrong, which is worth knowing. Recast
surplus em-dashes as separate sentences or commas. Propose edits as
diffs (old → new, with line numbers) and apply only with the user's
approval.
-
Edit pass B — hedging and claims. Calibrate per
references/hedging-and-claims.md:
contributions, definitions, and completed actions lose their hedges
("we propose", not "we attempt to propose"); interpretations,
generalizations, and limitations keep exactly one honest hedge; double
hedges collapse to one; boosters (clearly, undoubtedly) are cut — the
evidence carries the claim or nothing does. Rewrite passive
contribution statements as active, specific claims that say what is
new. Never strengthen a claim beyond what the paper's own evidence
supports, and never weaken a result the user measured.
-
Edit pass C — terminology. Turn every compound-variant,
spelling-mix, and acronym finding into a one-line decision: present
the variants with counts, let the user pick the canonical form (default:
the majority form; spelling per the venue register), then apply it
everywhere. Record decisions in a glossary file and re-run:
python3 scripts/terminology_check.py main.tex --glossary glossary.txt
Fix acronym discipline: define once at first use, expand consistently,
drop definitions never used again.
-
Edit pass D — venue register. Apply the family norms from
references/venue-register.md: person
and voice conventions, tense discipline, spelling convention,
contraction policy, and the register differences between ML, systems,
HCI, and LNCS venues. When no profile is given, default to consistent
American spelling and the conventions already dominant in the draft.
-
Verify nothing technical moved. Re-run both linters (clean, or each
remaining finding consciously accepted by the user); re-run the step-1
number snapshot and diff it — any difference is a bug in the edit pass
and must be reverted; confirm the \cite count and keys are unchanged.
Present a short before/after table for every sentence whose claim
strength changed in pass B so the user signs off on each one.
-
Optional gate for CI or pre-submission: prose_lint.py main.tex --strict exits 1 while any RISK/WARN remains — useful as a final
check alongside preflight-check.