| name | essay-iter |
| description | Iterate academic writing through a four-reviewer loop: rubric alignment, in-distribution fit, citation accuracy, AI-text detection. For coursework essays, dissertations, journal submissions, or conference papers. |
Essay Iteration Loop
A workflow for drafting and refining any piece of academic writing under four pressures simultaneously, applied by a team of sub-agent reviewers.
When to use
User has academic writing to plan, draft, or refine. Triggers:
. coursework essays (with markscheme + reference essays)
. dissertation or thesis chapters
. journal article submissions (with target-journal style guide + recent papers)
. conference papers (with venue rubric or accepted-paper exemplars)
. anything where there's a target rubric or set of in-distribution writing to fit
The two phases
Phase 1: approach session (with user)
Before any drafting, the agent has a conversation with the user to lock down:
- Task: what's being written, for what audience, by what deadline, at what length.
- Plan + thesis: high-level structure, sections + word allocations, the core argument or claim, the analytical lens or method.
- References (in-distribution corpus): what reference / exemplar texts will the in-distribution reviewer use? Possibilities:
. course Moodle / VLE: pull student exemplars + lecturer-published model answers if any (e.g. for a UK undergraduate course on Moodle, use whatever scraping pattern the user has set up for that course)
. target journal: pull 3 to 5 recent accepted papers
. conference proceedings: pull last year's best-paper-track winners
. user-supplied PDFs or URLs
. quasi-exemplar fallback: if no student exemplar exists but the lecturer has published their own writing on the topic (a paper, a class handout, a notes doc), use that as the in-distribution reference. The voice differs (lecturer not student) but the framing, theoretical commitments, citation tier, and rhetorical moves are signals the marker IS calibrated to.
. If no real references AND no quasi-exemplar exist, drop the in-distribution reviewer entirely. Do not pivot to synthetic essays. Synthetic references are a fake signal: a sub-agent's "in-distribution" judgement against essays generated by another sub-agent is not informative about whether the draft would pass a real human marker. The loop runs on 3 reviewers (rubric, citation, ai-detection) instead of 4.
- Background reading corpus: what the writer should actually engage with (not just cite). Distinct from the in-distribution corpus.
. course context: lecture slides, seminar materials, the reading list (required + recommended), the lecturer's published work, in-class handouts
. journal/conference context: 5 to 10 most-cited recent papers in the topic, plus any work the user already cites
. user-supplied: notes, books, papers the user wants integrated
. the agent reads enough of this corpus before drafting that the essay can engage with it specifically. Lecture-slide jargon, the lecturer's positions on contested issues, the seminar examples should leave fingerprints in the draft. Engagement looks like: citing readings the lecturer flagged as canonical, picking up the framing they used in week N, taking a position on a debate they raised in lecture.
. the corpus is also passed to the rubric reviewer (so they know what theories the rubric expects to see) and the citation reviewer (so they know what canonical sources are missing if absent).
- Rubric: what's being optimised against?
. course markscheme if available
. journal review criteria if a journal submission
. user-defined rubric if neither applies (the agent can scaffold one based on the writing type and field)
- Citation conventions: which style (Harvard, Chicago, APA, MLA, Vancouver, IEEE, journal-specific)? What references must be primary vs secondary?
- AI-detection target threshold: default 15% AI-likelihood. Adjust based on the marker's stated AI policy: if the lecturer is permissive ("anarchy", openly uses LLMs themselves) this becomes secondary; if the institution or marker penalises AI use, push to 5%.
When references and rubric aren't obvious, the agent proposes options and the user picks. When they are obvious (e.g. coursework with everything on Moodle), the agent surfaces the plan and waits for OK before drafting.
Phase 2: the loop
draft v0 = initial draft (or starting point if user provides one)
reviewers = [rubric, citation, ai-detection]
if real reference corpus available:
reviewers += [in-distribution]
for round = 1, 2, 3, ...:
spawn all reviewers in parallel:
A. rubric reviewer -> per-criterion grade + edit notes
B. in-distribution -> picks "odd one out" + reasoning + tells to fix
(only when corpus is real, not synthetic)
C. citation reviewer -> per-citation accuracy, hallucination check, style consistency
D. ai-detection -> ai-likelihood per sentence + overall
aggregate feedback
write draft v(round) addressing the weakest axis first, then the others
if all active reviewers pass thresholds:
present final draft to user, exit
if 5 rounds elapsed without convergence:
surface current state to user, exit
Reviewer thresholds
. Rubric: every criterion at user's target tier (default Distinction or 70%+ band).
. In-distribution: reviewer's guess_confidence for the user's draft below 0.5, OR guess wrong.
. Citation: zero hallucinations (no cited work that doesn't exist or doesn't say what's claimed), citation style 100% consistent.
. AI-detection: AI-likelihood overall below the threshold locked in Phase 1.
File layout
~/agent/skills/essay-iter/
SKILL.md (this file)
gptzero.py (reverse-engineered AI detector)
rubric_prompt.md (sub-agent A prompt template)
adversarial_prompt.md (sub-agent B prompt template)
citation_prompt.md (sub-agent C prompt template)
~/.tasks/metadata/<task_id>_essay/
approach.md (locked plan from Phase 1)
references/<n>.{md,pdf} (in-distribution corpus)
rubric.md (operative rubric)
draft.md (current working draft)
iterations/round_<N>/
draft.md (snapshot)
rubric_review.json
adversarial_review.json
citation_review.json
ai_detection.json
summary.md (what the agent changed and why)
scores.json (running tally, latest round at top)
Running the skill
The two phases above are the whole workflow:
- Run the approach session
- Write the initial draft to
<task_id>_essay/draft.md (or copy the user's existing draft in as v0)
- Run the loop, saving each round's reviews and a
summary.md under iterations/round_<N>/
- Present the final draft with a round-by-round score table per axis and any residual gaps flagged honestly
The user submits or asks for another round.
Reviewer prompt templates
The AI detector is a Python module, not a sub-agent: python ~/agent/skills/essay-iter/gptzero.py <file.md> returns the JSON.
Notes for the agent running this skill
. Anonymise rigorously before the in-distribution review. Strip:
. name, candidate number, course handbook tics that mark a doc as the user's
. first person "I" if only one essay uses it
. all citation dates in both in-text citations and reference list. Replace (Smith, 2024) with (Smith, YEAR) and the reference list Smith, J. (2024) Title. with Smith, J. (YEAR) Title.. Apply consistently across user's draft AND every reference essay. This prevents the critic from cheating by picking the essay with the newest sources as the odd one out (which is a non-signal, not an actual quality differentiator).
. any URL or DOI that gives away publication year or accessed date
. file metadata if essays are PDFs (export as plain text first)
. The citation reviewer can take a while (web lookups). Run it last in parallel, or accept that a round takes longer.
. Save state every round. The loop should be resumable after a crash.
. Do not modify the user's voice into something generic. Adversarial-fooling and AI-detection minimisation often pull toward "more human, more idiosyncratic". Lean into that.
. Do not pad the draft to satisfy a metric. A 2:1 with integrity beats a Distinction with hallucinated citations.