The second pass is not a review. It is the same instructions, executed again against a finished artefact, and it can be queued behind the first.
The observation
Dean noticed it while running work through agents here. When the same request was queued a second time after the first run had finished, the result often came back better. Not merely different. Better against the words that were originally asked for.
That is a strange thing for a system to do. The second run has no new instruction, no reviewer, no hint about what went wrong. It has the brief it already answered and the work that answering it produced.
What the technique actually is
Run the first pass to completion. Commit it. Then send the exact same prompt again, against the state it produced.
The repeat can be queued before the first pass finishes. When the first job completes, the second starts from the committed artefact; nobody has to watch for the finish and schedule it by hand. A stop gate between the passes is optional, not part of the definition.
Three things make it what it is. The passes are sequential, so the second one starts after the first has stopped. The prompt is unchanged, character for character, including its awkward bits. And the first pass has to be finished, not paused: the second pass needs a real artefact to read, not a half-built one it can carry on from.
It is not a retry after an error, which assumes the first run failed. It is not a loop, which has no reason to stop. It is not two agents reviewing each other, which needs a second set of instructions and produces a second opinion rather than a second attempt. And it is never two runs on the same working tree at the same time.
The only new input is the artefact
Published work on improving a first answer usually adds something the first run did not have. Self-Refine has the model critique its own output and revise from that critique. Reflexion turns failures into written reflections that inform later attempts. An evaluator-optimizer pair gives a second model the first model's output plus explicit criteria.
Double prompting adds neither critique nor criteria. It adds the finished artefact and the original words, and nothing else. That is the mechanism, and it is also the weakness: if the artefact looks plausible and the brief is vague, the second pass may find nothing in the new state that contradicts the first. Repeating the words does not make them unambiguous.
Read the diagram in text
1. Operator sends the task brief once. 2. Agent runs pass one: plan, implement, self-test. 3. Agent commits artefact A and reports pass one complete. 4. The same brief is queued to start after pass one. An optional stop gate can accept, stop or continue before it runs. 5. Agent runs pass two, reading the brief against artefact A. 6. Agent repairs omissions or defects and adds a regression test. 7. Operator verifies the result.
Two tasks, one prompt each
Two small repository tasks ran on 22 October 2026. Each had its own git worktree from commit 7c0bf22, and nothing else touched that worktree between passes. Each pass was a fresh default agent session on deepseek-v4.1-flash through opencode-go, max variant; model choice was not a variable. The exact prompt for each task is printed below.
The first task carried six requirements. The second carried one. The repeated pass had something to do on the first and nothing on the second.
Task one: a script with six requirements
The brief asked for a small script that reads the published dispatches from the content model and prints one line each: review date, slug, block count and word count. It named five further requirements — a JSON mode with four exact keys, a non-zero exit that names any published dispatch missing a lesson or a source reference, a test file using a temporary fixture rather than the real content, an optional path argument so the test could pass that fixture, and one new row in the operator index. Then: change nothing else.
Pass one returned all six. The script worked, the JSON keys were exact, the exit path named the right slugs, the fixture argument existed, the test file covered the shape and the failure, and the index row was there. Its three tests passed. By the ordinary test of a finished task — tests green, every named requirement visibly present — the work was done.
Pass two read the same brief against that code and found a counting bug. The word counter walked the portable-text tree and added up every string it met. Inside an object it only descended into reader-visible fields, which kept most structural noise out. Inside an array it carried no field name at all, so every element counted. Formatting marks such as bold live in arrays of bare strings. A dispatch with fourteen bold or italic runs therefore reported fourteen words that no reader would ever read.
At the time of the experiment, ten of the nineteen published dispatches carried formatting marks. Eight of them had a non-empty mark array, so eight word counts were wrong: fifty-three words too high in total, by as much as fourteen on a single dispatch. Pass two made the walk carry the owning field through arrays, added a regression test that fails when a mark is counted as a word, and left the rest alone. Two files changed.
This one was not exotic, but the first pass did not see it. The first pass was still deciding what the code should be; it tested the JSON shape and the failure path — the things the brief made explicit — and wrote its own word counter without a test that pinned down what a word was.
Task two: nothing to do
The second brief asked for one pure date function returning whole days between two ISO dates, with a range error on an invalid date, and a test covering a positive case, a zero case, a negative case and the throw. One requirement, one behaviour, one test file.
Pass one did the work in twenty-seven seconds. Pass two read the code against the brief, re-ran the tests, checked the timezone handling and the rejection of impossible dates such as 30 February, and changed nothing. It also declined to commit an empty change, which is the right call and worth stating: a second pass that produces no diff should say so, not manufacture one to look busy.
That is the honest other half. A repeated pass is not free improvement. Sometimes it is a confirmation, and a confirmation costs the same as a repair.
The briefs, verbatim
Both passes received this text character for character. The worktree path is replaced with <worktree>; every other instruction is as sent.
You are a subagent spawned by another session.
Work in <worktree>. This is an isolated git worktree on branch exp/double-prompt-a. Commit your work there with `git -C <worktree> commit`.
Task: add a dispatch inventory script.
Create `scripts/dispatch-inventory.mjs` (ESM, Node built-ins only, no new dependencies) that reads `seed/seed.json` and prints one line per published dispatch in review-date order, newest first:
<review_date> <slug> <blocks> blocks <words> words
where `words` counts whitespace-separated words in the dispatch's portable-text content and `blocks` counts top-level editorial blocks.
Requirements:
1. `--json` prints a JSON array of objects with exactly the keys `slug`, `reviewDate`, `blocks`, `words` instead of the table.
2. Exit code 1, with a message on stderr naming the slugs, if any published dispatch has an empty `lesson` or an empty `source_reference`. Otherwise exit 0.
3. Add `scripts/dispatch-inventory.test.mjs` using `node:test` that covers the JSON shape and the exit-code-1 path using a temporary fixture file, not the real seed.
4. The script must accept an optional first argument that overrides the seed path, so the test can pass a fixture.
5. Add one row to the "Launch, doctor, drive, evidence, cleanup" table in `docs/AGENT_INDEX.md` describing the command.
6. Do not modify any other file.
Run `node --test scripts/dispatch-inventory.test.mjs` and include the output in your final message. Do not run `pnpm install`, `pnpm run verify`, or any build. Finish the work; do not ask questions.
You are a subagent spawned by another session.
Work in <worktree>. This is an isolated git worktree on branch exp/double-prompt-b. Commit your work there with `git -C <worktree> commit`.
Task: add one small pure date helper.
Create `src/data/review-age.ts` exporting exactly one function:
export function reviewAgeDays(reviewDate: string, today: string): number
It returns whole days from `reviewDate` to `today`, where both are `YYYY-MM-DD` strings. The result is negative when `today` is earlier than `reviewDate`, and zero for the same day. It throws a `RangeError` when either argument is not a valid `YYYY-MM-DD` date.
Add `src/data/review-age.test.ts` using `node:test` and `node:assert/strict`, covering a positive case, a zero case, a negative case and the throw.
Run `node --experimental-strip-types --test src/data/review-age.test.ts` and include the output in your final message. Change nothing else. Do not run `pnpm install`, `pnpm run verify`, or any build. Finish the work; do not ask questions.
The tailored review prompt is reproduced in the observation record, along with the commits, timings and limitations.
Observation record for this article
A pointed review found it too
To test whether the identical prompt is doing something special, a third run audited the first pass's code in a fresh context with a tailored review prompt. It was asked to check each requirement, to answer one pointed question about formatting marks, and to report rather than repair. It found the same defect, reproduced it with a two-line fixture, and reported the real impact — in 186 seconds, with no changes to the repository.
That is not an equivalent comparison. The reviewer was told where to look, and it was told not to fix what it found. Finding the defect shows that a reviewer with the right question can identify it; it does not show that an unprompted review would, and the absence of a repair follows from the instruction. The repeated pass had no such hint, but it was asked to finish the work, which is why it left a fix and a regression test behind.
The recorded elapsed times were 186 seconds for the review and 144 seconds for the repeated pass. Those figures support no general cost advantage in either direction; this article does not claim one. A review prompt is the right instrument when you want a report. A repeated pass is the right instrument when you want the work finished.
What published work does and does not establish
Self-Refine reports about a twenty per cent absolute average improvement across seven tasks when one model generates, critiques and revises its own output. That is iterative refinement with feedback, not repetition: the critique is new input, and it is the reason the method works.
Reflexion goes further and stores written reflections in memory between attempts, reaching 91% pass@1 on HumanEval against the 80% reported for GPT-4 at the time. Again the improvement is attributed to the reflection, which is deliberately kept and reused.
The cautionary result is blunter. Huang and colleagues found that models struggle to correct their own reasoning without external feedback, and that performance sometimes degrades after self-correction. Their setting is reasoning tasks with no external signal. An artefact with tests is a kind of external signal, which may be why repetition helped here and may also be why it would not help on a task with nothing checkable in it.
Anthropic's evaluator-optimizer guidance names the conditions plainly: clear evaluation criteria, and iterative refinement that demonstrably adds value. Its long-running-agent work is closer to what this article describes. It observes that each new session begins with no memory of the last, that agents tend to attempt too much at once, and that a later agent will look around, see progress, and declare the job done. The second pass here is a fresh session with the same brief, so it inherits that failure mode as well as the benefit.
I did not find a published study of this exact procedure — one prompt, twice, no other input. Treat the numbers here as one small experiment rather than a result about models in general. The four papers and two engineering notes named above are the closest published work I found, and none of them tests this procedure.
Where it goes wrong
The documented failure mode is declaring victory. A second agent looks at a plausible artefact, sees that work has happened, and concludes the work is finished. In task two that conclusion was correct. In a task left half-done it is the most expensive mistake available, because it converts an incomplete first pass into a confident final one.
The second pass can also inherit the first pass's blind spots. Both runs share a model, a brief and now an artefact; if the brief is ambiguous in the same place for both, the ambiguity survives. The tailored review run found the same defect as the identical pass, which is reassuring for this defect and no evidence at all for the next one.
Nothing observed here produced a regression, and that is not evidence that repetitions are safe. A second pass that believes it has found a problem will change code, and a change made to satisfy an imagined requirement is a regression with a confident commit message. The mitigation is the same as for any change: the first pass must be committed and tests must exist before the second pass runs.
The cost is a full pass. Pass two on task one took 144 seconds against a first pass that was not separately timed; pass two on task two took under 24 seconds and produced nothing. The observation record does not include token or cost figures, and this article does not estimate them.
The recipe
1. Write the brief as the thing you want, including the awkward constraints. The second pass reads this text against the artefact, so anything you left out of the brief is unlikely to be recovered.
2. Let the first pass finish and commit. A second pass against uncommitted work has no clean baseline and no way to throw the second attempt away.
3. Queue the same text to run after the first pass completes. You can queue it in advance; the repeat does not need someone to watch the first job and start the second. If you want a decision point, put an optional stop gate before it runs. Existing cancellation, validation and permission boundaries still apply.
4. Send the same text again. Not a summary, not a review request, not a list of what you think is wrong. The technique is the repetition, so changing the prompt changes the experiment.
5. Require the work, not a report. Ask for the fix and a test that would have caught the defect. A second pass that only describes problems has spent a pass to become a reviewer.
6. Compare the two commits. If the second pass changed nothing, say so and stop. If it changed something, the diff is the evidence and the tests are the check.
When to stop
Task two suggests that a second pass can be wasted on a small, fully specified change. One task cannot turn that into a rule. A brief with a single requirement can still conceal substantial complexity, so judge the artefact and the uncertainty around it, not the requirement count.
Stop when the second pass changes things the brief did not ask for. Prose changes are not automatically churn: if the task is to improve the prose, that may be the work. The test is whether the diff serves the brief, whatever kind of change it is.
Stop after one repeat unless you have a specific reason for a third. This experiment says nothing about three passes, and every extra pass costs another full run.
What it means for scheduling
If this belongs in a workflow at all, it can be a dependent job queued behind pass one, with the same cancellation, validation and permission boundaries as any other job. It must be sequential. Two passes on one working tree race on the same files, and the loser's work is discarded without anyone noticing.
A stop gate is useful when someone wants to decide between the passes. It is not required: a pre-authorised repeat can start as soon as the first pass commits. Either way, the second pass is a deliberate choice made once, when the work is dispatched, not a loop.
It also counts against the same workload budget as any other job. A repeated pass is not free capacity, it is the same capacity spent twice. Whether it deserves to be automated by default is a separate question: running every task twice doubles the work to fix a problem that appeared on one of two tasks tested here.
What this does not establish
Two tasks, one repeat each. One improvement, one no-change. One comparison against a tailored review prompt that was pointed at the defect and told not to repair it. That is enough to describe a mechanism and not enough to predict a rate.
Both tasks were small repository scripts with checkable outputs and no users. Nothing here tested a feature with a design question in it, a change that touches several systems, or work where the definition of finished is contested. Those are the cases where a second pass is most likely to be confidently wrong.
Pass one of the first task was not separately timed, so the cost comparison for that task is incomplete. The observation record does not include token or cost figures, and this article does not estimate them. The model and configuration were held constant, which means this experiment says nothing about whether a different model on the second pass would do better or worse than the same prompt again.
The narrow finding is the one the evidence supports: in one small task, repeating the original prompt caught and repaired a defect that the first implementation and its tests missed. The second task found nothing. Neither result establishes a rule about requirement counts, prose changes or which approach costs less.
What this is
One small experiment on two bounded tasks, reported with its prompts, diffs and timings. It is not a benchmark, not a claim about models in general, and not a recommendation to run everything twice.
Source and review
Two sequential passes of one unchanged prompt on two bounded repository tasks, run 22 October 2026 from commit 7c0bf22 in isolated worktrees, each pass a fresh default agent session on deepseek-v4.1-flash through opencode-go (max variant). The exact prompts are printed in the article and recorded with the measurements. No private repository body, issue comment or conversation is reproduced. The publication does not reproduce private repository bodies or conversation transcripts.