aperivue/revise
Parse peer reviewer comments and generate a structured Response to Reviewers document with tracked manuscript changes. Classifies comments as MAJOR/MINOR/REBUTTAL, coordinates new analyses with /analyze-stats and /make-figures, and produces cover letter for editor.
npx skills add https://github.com/Aperivue/medsci-skills --skill revise
Parse reviewer decision letters, classify each comment by type, generate a formal Response to Reviewers document, track required manuscript changes, and coordinate with /analyze-stats or /make-figures when new analyses or visuals are needed.
When the user provides reviewer comments (pasted text, PDF, or file path), or requests revision of a manuscript, this skill activates. Before proceeding, confirm:
paper/main.tex or paper/main.qmd)${CLAUDE_SKILL_DIR}/references/r2r_voice.md -- before/after examples, three response skeletons (accept / partial-accept / polite-rebuttal), and a meta-phrase-to-natural conversion table. Read it before drafting the Response to Reviewers document.Read the full decision letter. Extract every discrete comment from every reviewer and the editor.
E-1, E-2, ... <- Editor comments
R1-1, R1-2, ... <- Reviewer 1 comments
R2-1, R2-2, ... <- Reviewer 2 comments
R3-1, R3-2, ... <- Reviewer 3 (if present)
If a reviewer groups multiple requests in one paragraph, split them into sub-items: R1-3a, R1-3b, R1-3c
| Type | Symbol | Definition |
|------|--------|------------|
| MAJOR | [MAJ] | Requires new experiment, re-analysis, new figure/table, or substantial structural rewrite |
| MINOR | [MIN] | Requires text revision, clarification, formatting change, or additional citation |
| REBUTTAL | [REB] | Reviewer is factually incorrect, misunderstood the study, or requests something scientifically unjustified |
Output a classified comment list before generating responses:
E-1 [MIN] Request to shorten abstract
R1-1 [MAJ] Requires subgroup analysis by scanner type
R1-2 [MIN] Clarify exclusion criteria rationale
R1-3 [REB] Claims our sample size is underpowered (we disagree)
R2-1 [MAJ] Requires additional figure showing calibration curve
R2-2 [MIN] Add reference to [Author Year]
Gate: Present the classified comment list to the user. Confirm classifications
(especially REBUTTAL vs MAJOR) before generating responses. A misclassified REBUTTAL
generates a response that argues with a valid reviewer point.
Before writing responses, identify which comments require external action:
Comments requiring /analyze-stats: Flag any MAJOR comment that requires new statistical analysis, re-run of existing analysis, additional metric (calibration, NRI, ICC), or sample size recalculation. When the source is a /self-review finding, any issue carrying requires_reanalysis: true (power/MDE re-simulation under the full model, first-visit / one-record-per-subject dedup, an extended- or reduced-adjustment over-adjustment sensitivity, optimism correction of calibration) is automatically a /analyze-stats routing item — it cannot be answered by a prose edit, so it must produce a committed script + CSV whose numbers are then fed back here.
Comments requiring /make-figures: Flag any MAJOR comment that requires a new figure or revised figure (calibration plot, subgroup forest plot, Bland-Altman, new panel).
Output: "The following comments require statistical analysis before responses can be finalized: R1-1, R2-3. Run /analyze-stats with these tasks, then return to /revise."
If /analyze-stats or /make-figures is not installed in this environment, do not invent numbers or figures. Emit the same routing list as an explicit checklist for the author to run manually (the named analysis or figure per comment) and hold those responses as BLOCKED — pending analysis/figure until the committed script + CSV (or figure file) returns. The reviewer-response numbers must always trace to a produced artifact, never to a model estimate.
Revision-time is the highest-risk moment for numerical hallucinations. A new analysis script
written to satisfy a reviewer — typically a comparative arm, a subgroup, or a sensitivity
check — frequently hand-enters values copied by eye from the original paper's tables, bypassing
the locked extraction CSV. The resulting numbers then flow into the response letter, the
revised manuscript, and regenerated figures, and they can be internally consistent everywhere
while still being wrong at the source.
Precedent failure pattern — treat as a lived failure, not hypothetical:
> An R1 revision introduced a new comparative-arm analysis script to answer a reviewer
> request. The Fisher exact matrix was hand-typed from the primary source Table, with an
> adjacent severity-grade column misread as the event count. The script, the revised
> manuscript, and an accompanying Table all converged on the same direction-reversed
> numbers relative to what the primary source actually reported.
Non-negotiable actions when Step 2 flags any /analyze-stats re-run:
[VERIFY-CSV] as it is written into the revisedmanuscript, response letter, or new table. The tag is a tripwire — it only comes off at
Step 7 (Final Verification) after explicit CSV + primary-source back-check.
matrix(),c(...), or data.frame(...) numerical inputs are PROHIBITED when a CSV row exists. If
hand entry is truly unavoidable (e.g., comparative-arm subset not present in the CSV), the
line MUST carry a comment citing the CSV coordinate AND the primary-source Table/Figure:
# source: data_extraction_final.csv row <N> (<first-author> <year>, <arm> only),
# verified against <primary source> Table <X>, page <P>
fisher.test(matrix(c(0, 45, 1, 55), nrow = 2, byrow = FALSE))
extraction_consensus_log.md as separaterows** before the analysis script references them. Do not let a new script invent values
that never passed through the dual-extraction consensus layer.
and copy into the final change log:
| New claim (response + manuscript location) | Source script:line | CSV row/col | Primary source (Table/Fig, page) | Match? |
|---|---|---|---|---|
numbers have not yet cleared this check. Prose written around un-audited numbers is very
hard to unwind cleanly after a mismatch is found.
Why this matters for reviewer politics: a numerical reversal caught by the reviewer in R2
is far more damaging than the same error caught internally in R1 — it implies extraction
integrity problems to the editor and licenses deeper scrutiny of the rest of the data. Treat
Step 2.5 as a reputation-preservation gate, not just a QC step.
Output location: revision/R[N]/response_to_reviewers_R[N].md
Response to Reviewers
Manuscript ID: [JOURNAL-XXXXX]
Manuscript Title: [Full title]
Authors: [Last name of first author] et al.
Revision Round: [R1 / R2 / R3]
Date: [YYYY-MM-DD]
We thank the Editor and reviewers for their careful reading of our manuscript
and their constructive comments. We have revised the manuscript accordingly
and provide a point-by-point response below. All changes are shown in the
revised manuscript with tracked changes (or highlighted in yellow).
---
**Comment R[X]-[Y]** [MAJ/MIN/REB]
*Reviewer's comment:*
> [Exact text of the comment, quoted verbatim]
**Response:**
[Response text -- format by type below]
**Manuscript change:**
- Section: [Methods / Results / Discussion / etc.]
- Page [X], Line [Y] (in the revised manuscript)
- [Quote the new or changed sentence if short]
Keep concise (3-8 sentences). Acknowledge, explain the change.
We thank the reviewer for this observation. We have [describe change] in
the [section] section. The revised text now reads: "[new sentence]."
Structured response with four parts: acknowledgment -> new analysis -> key result -> location of changes.
We thank the reviewer for this important suggestion. [State the concern.]
To address this, we [describe new analysis/experiment/rewrite].
[Key result: metric = value (95% CI, lower-upper; P = exact value)]
(All new results MUST include 95% CI and exact p-value.)
This finding [supports / strengthens / does not change] our original
conclusion because [brief interpretation].
Note: New text added to the Results section must contain only factual
findings. Interpretation belongs in the response letter text or Discussion.
We have added:
- New [Table X / Figure X / Supplementary Table X] showing [content]
- Methods revised: Page X, Lines Y-Z
- Results revised: Page X, Lines Y-Z
Polite but firm. Do not capitulate without scientific justification.
We thank the reviewer for raising this point. We respectfully suggest
that [restate reviewer's claim], while we [state your position].
[Explanation with supporting evidence. Cite literature if available:
"This is consistent with [Author et al., Year; PMID XXXXXX], who
demonstrated that..."]
[If applicable: "We have added the following clarifying sentence to
[section] (Page X, Line Y): '[new sentence].'"]
We believe this issue does not warrant [the specific change requested]
because [reason]. We hope the reviewer finds this explanation satisfactory.
Voice caution: The acknowledgment lines in these templates are schematic placeholders, not literal text to paste under every comment. Repeating the same opener ("We thank the reviewer for this important suggestion.") across a dozen responses is itself an AI-tell that careful reviewers notice. Vary the openers and apply the Response-Letter Voice & AI-Tell Avoidance section below before finalizing any response.
Before writing individual responses, classify every comment into one of five categories.
This classification determines the response template and effort level. Process Category 1
(Simple) comments first — they are the most numerous and clearing them early reduces the
perceived workload.
Reviewer asks for additional description, clarification, or minor data.
Response: Add the requested text and point to the location. Keep the response short.
Example: "Please specify the study period" → add dates, reply "Done. See page X, line Y."
Reviewer misinterpreted the study design, population, or analysis.
Response: Never say "you are wrong." Instead: "We apologize for the lack of clarity"
→ re-explain the intended meaning → revise the manuscript text to prevent future confusion.
Reviewer raises a contextual concern (different healthcare system, different clinical practice).
Response: Acknowledge the valid perspective → explain your study context → add a brief
note in Discussion if appropriate. The full explanation can stay in the response letter
without bloating the manuscript.
Reviewer requests new analysis (subgroup, sensitivity, additional metric).
Response: Perform the analysis → add results to Supplementary (or main text if important)
→ describe what was done and what was found. Treat this as a constructive contribution,
not an attack. Never ignore these requests — reviewer engagement is a positive signal.
Reviewer questions or requests changes to statistical methods.
Response: Provide a reasoned justification for the method with references. If the reviewer's
suggestion is valid, run both analyses and show the results are consistent. If a statistician was
in fact consulted, say so; do not write that sentence because it *sounds* credible — a claim about
who reviewed the work is a claim about the world, and this letter goes to an editor.
| Category | Typical Classification |
|----------|----------------------|
| 1. Simple Question | MIN |
| 2. Misunderstanding | MIN or REB |
| 3. Further Discussion | MIN (if text change) or REB (if disagree) |
| 4. Additional Results | MAJ |
| 5. Statistical Challenge | MAJ |
Use the 5-category triage to inform the MAJ/MIN/REB classification in Step 1, not replace it.
Reviewer quality varies widely. When facing comments that suggest the reviewer did not
carefully read the manuscript:
disrespect to the editor.
reply: "We have added clarification in [section] to address this concern." This shows
effort without conceding a scientific point.
Frame as "We believe there may be a misunderstanding" rather than "The reviewer is wrong."
reviewer. A measured, thorough response demonstrates manuscript quality even when
the review does not.
A response-to-reviewers letter is a reviewer-facing scientific argument, not an internal
change-log. The dominant AI-tell in machine-drafted letters is the **editing-mechanism
register**: prose that narrates *how the text was edited* ("the revised Methods adds one
sentence at line 88", "a grep-and-soften pass replaced six phrases", "no further manuscript
change") instead of stating, in plain language, what changed and why.
Three principles when drafting (the AI-tell patterns themselves are defined once in humanize
references/ai_patterns.md, patterns 22-24 — this section is the authoring guidance):
why, and quote the new sentence. Never narrate the diff: no version prefixes ("v2 adds..."),
no "softened N phrases", no grep/verification language, no internal FIX codes, no bare "No
further manuscript change" stubs. Describing a *new analysis you ran* ("we performed a
sensitivity analysis and found X") is the science, not a tell — that is welcome.
§ symbols, no internal draft line numbers. A revised-manuscript page/line("page 7, lines 177-178", stated once as referring to the revised manuscript) is fine;
only internal draft line numbers that will not match the reviewer's view are banned.
Response: / Changes made: block, anOriginal → Revised pair, or a left-comment/right-response table are all standard human
conventions. Pick any; strip only the mechanism narration.
Let the point-by-point prove the work; strip the pre-emptive defence. This matters most on R2+ rounds, where over-explaining reads as anxiety rather than rigor.
See ${CLAUDE_SKILL_DIR}/references/r2r_voice.md for the before/after gallery, response
skeletons, and the meta-phrase conversion table.
Before circulating or uploading the response letter and cover letter, run /humanize on
both documents. The R2R AI-tell patterns (22-24) are defined in humanize
references/ai_patterns.md; together with 13 (em dash), 16 (filler), and 19 (§) they form
the response-letter scan. Hold the letter to the same classical-style bar as the manuscript:
zero § symbols and no (Methods §X) self-references, em-dash use kept low, and the heading
style the target journal actually publishes. The enforced item list lives in /write-paper
references/section_guides/step7_1_classical_qc.md — these are the marks a senior reviewer
reads as machine-drafted, and they are as visible in a letter as in a manuscript.
The single source of truth is the revised manuscript, not the response prose. A letter
that says *"we added the sentence '…'"* or *"we now cite Tariq et al. [15]"* must be
verifiable in the body — a claimed edit that was never actually inserted is a reputation-fatal
class that both a reviewer round and the authors have missed. Run the gate before sending:
python3 ${CLAUDE_SKILL_DIR}/scripts/check_response_claims.py \
--response revision/response_to_reviewers.md \
--manuscript manuscript/manuscript.md --strict
It flags RESPONSE_QUOTE_UNVERIFIED (a quoted added sentence absent from the body) and
RESPONSE_CITATION_UNVERIFIED (an added citation whose token is nowhere in the body). It is
conservative — vague, paraphrased claims are not flagged — so a firing verdict is a real
discrepancy: either insert the promised edit or correct the response wording. This directly
enforces the *"quote the new manuscript text verbatim"* discipline above, and is the same
check a reviewer runs against your revision (see /peer-review).
A third verdict, RESPONSE_QUOTE_UNRESOLVED (minor, never drift), exists because the
manuscript is often read through an extractor. When the quoted words are all present **in
order** but separated by foreign tokens — a reference column bled into the sentence by a
two-column PDF, line numbers from a supplement proof, a footnote marker, a hyphen split across
a line — the text is there and only the extraction is dirty. A contiguous substring test
cannot tell that from a missing edit and reports the correct quote as absent; that once came
one step from having two accurate verbatim quotes deleted. So those cases are reported for a
human to eyeball and do not fail --strict; only a genuinely absent quote does.
If a reviewer called the manuscript too long or too dense, prove the body got shorter. Answering
a density comment point-by-point is a trap: each point is answered by adding a sentence, so the
revision that responds to "shorten this" comes back *longer*. One real revision did exactly that —
four reviewers said too dense, the point-by-point answer added 613 words, and it took three rounds
to land at 733 words below where it started. This gate is arithmetic: if the decision letter
contains a density/length complaint and the revised body did not shrink, it fires.
python3 ${CLAUDE_SKILL_DIR}/scripts/check_density_complaint.py \
--comments revision/decision_letter.md \
--previous manuscript/manuscript_R0.md \
--revised manuscript/manuscript.md --strict
DENSITY_COMPLAINT_UNADDRESSED fires only when a complaint was raised AND the body word count
(Introduction through Discussion, citation markers excluded) did not fall. With no density complaint
it stays silent — it is not a "shorter is always better" nag. When it fires, cut or move detail to
the supplement; do not defend the length by adding a paragraph that explains it.
Output location: revision/R[N]/cover_letter_R[N].md
[Date]
Dear Dr. [Editor Name / "Editor-in-Chief"],
Thank you for the opportunity to revise our manuscript, "[Full title]"
(Manuscript ID: XXXX), submitted to [Journal Name]. We have carefully
reviewed the comments from the Editor and reviewers and have revised
the manuscript accordingly.
In brief, the principal changes in this revision are: [1) ..., 2) ...,
3) ...]. A point-by-point response to each comment is provided in the
accompanying Response to Reviewers document. Revised sections are
highlighted in yellow in the manuscript.
We believe the revised manuscript addresses all concerns raised in the
review and is now suitable for publication in [Journal Name].
Sincerely,
[First Author Name], MD/PhD
[Institution]
[Email]
On behalf of all authors
The template above is the R1 convention: a standalone editor cover letter (200-400 words).
On an R2+ round (second revision onward), do not write a separate cover letter. Whatever you would say to the editor — the greeting and the brief change summary — belongs in the head of the response-to-reviewers letter, not in a second document. A standalone cover letter that merely restates the response letter's summary reads as redundant and, on later rounds, as boilerplate. If an earlier round already produced a cover_letter_R1.md, move it to _superseded/, exclude it from the R2+ package, and reuse the response-letter head verbatim in any portal "cover letter" field. (Exception: a journal that explicitly requires a separate cover letter at every round — then keep the head summary and the cover letter from duplicating each other.)
Response-letter head (R2+) — placed at the top of response_to_reviewers_R[N].md, before the point-by-point:
Dear Dr. [Editor Name / "Editor-in-Chief"],
Thank you for the opportunity to revise our manuscript once more. In brief, this
revision [1-2 sentence summary of the principal changes — e.g., "adds the requested
subgroup analysis and tempers the three comparisons the reviewers flagged as
over-stated"].
[If applicable: one sentence on a companion paper, a re-analysis, or a verification
the editor requested.]
All quotations below are from the revised manuscript. A point-by-point response to each
comment follows.
Sincerely,
[First Author Name], on behalf of all authors
Keep the head to a short greeting, a one-paragraph "in brief," an optional companion/verification note, the single line stating quotations are from the revised manuscript, and the signature. Everything else is point-by-point.
Output location: revision/R[N]/change_log_R[N].md
| Comment | Type | Change Made | Section | Page | Lines |
|---------|------|-------------|---------|------|-------|
| R1-1 | MAJ | Added subgroup analysis by scanner type | Results 4.3, Table 3 | 12 | 234-251 |
| R1-2 | MIN | Clarified exclusion criteria for motion artifact | Methods 2.2 | 6 | 112-115 |
After all responses are drafted, check:
§ symbols and no editing-mechanism narration ("v2 adds one sentence", "grep verification", "No further manuscript change")/humanize (patterns 22-24 triage hits reviewed; confirmed instances = 0; § = 0 hard)The journal wants the revised paper with tracked changes against the version the reviewers saw (R0 — not the previous round). Produce it with Word's Compare, which /sync-submission drives from the command line, and verify it with a round trip rather than a spot-check: accepting every revision must reproduce the revised manuscript exactly, and rejecting every revision must reproduce the original. Confirming that "sentence X appears as an insertion" passes even when Compare has dropped a paragraph or attributed half the changes to another author.
python3 <medsci-skills>/skills/sync-submission/scripts/check_marked_manuscript.py \
--marked revision/R1/manuscript_marked.docx \
--original submission/R0/manuscript.docx \
--revised revision/R1/manuscript_clean.docx \
--author "Submitting Author" --strict
See /sync-submission Phase 10 for the build step and for why the check must be move-aware (w:moveFrom / w:moveTo are not w:ins / w:del).
| Round | Folder | Files |
|-------|--------|-------|
| R1 | revision/R1/ | response_to_reviewers_R1.md, cover_letter_R1.md, change_log_R1.md |
| R2 | revision/R2/ | response_to_reviewers_R2.md, cover_letter_R2.md, change_log_R2.md |
Revised manuscript: paper/main_revised_R[N].tex (or .qmd)
For R2+, acknowledge whether R1 concerns were fully resolved. If a reviewer raises a new concern at R2, note: "This comment was not raised in the first review round; we address it as follows."
/search-lit with confirmed DOI or PMID. Mark unverified references as [UNVERIFIED - NEEDS MANUAL CHECK].[VERIFY] and ask the user.| Gate | Severity | Trigger | Action on fail |
|---|---|---|---|
| Comment classification (MAJOR / MINOR / REBUTTAL) | ENFORCED | comment unclassified or classification disputed | ask user; do not silently default |
| Step 2.5 [VERIFY-CSV] tagging on revision-introduced numbers | ENFORCED | new numerical claim added without [VERIFY-CSV] tag | tag automatically; HALT until CSV cross-check completes |
| Reference re-render after revisions touching citations | ENFORCED | any new [@bibkey] added in R1+ | route to /manage-refs Phase 7.6 re-render before R1 submission |
| /verify-refs --strict post-revision | ENFORCED | FABRICATED / HIGH_MISMATCH_FIRST_AUTHOR > 0 | HALT R1 submission |
| New analysis coordination | ENFORCED | reviewer asks for new analysis | route to /analyze-stats (and /make-figures if figure changes); never hand-write new numbers |
| Body word count vs journal cap (revision-inflation trap) | ENFORCED after every revise pass | resolving majors pushes the body over the target journal's word limit | run /sync-submission scripts/check_wordcount_cap.py (--journal-profile or --limit; prefer the rendered DOCX count); WORDCOUNT_OVER_CAP blocks submission — relocate methods/sensitivity detail to the Supplement, do not silently exceed |
| Cover letter to editor | ENFORCED at R1 submission | R1 missing editor cover letter | block submission |
| R2+ cover-letter handling | ENFORCED at R2+ submission | standalone cover letter present on an R2+ round (not folded into the response-letter head) | move it to _superseded/; fold the summary into the head |
| Response-letter voice / AI-tell | ENFORCED before submission | editing-mechanism narration, internal draft line refs, §, tooling leak, or repeated openers in response/cover letter | run /humanize (patterns 22-24 as triage; § = 0 hard); resolve confirmed tells before submission |
Take aperivue/revise from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.