# Preflight

> Challenges a draft before it goes out and hands back a revised version plus the facts only you can supply -- the six substance checks, then a set of reviewer personas whose wording problems it fixes. Never sends anything.

- Skill: `by-carlos/preflight` (Agent Skill)
- Install (CLI): `npx skillmds@latest add by-carlos/preflight`
- Raw SKILL.md: https://api.skillmd.com/api/skills/by-carlos/preflight/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: by-carlos (https://skillmd.com/u/by-carlos)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/by-carlos/preflight

---


# Preflight

A bounded review loop. Run the substance checks, put the draft in front of
reviewers who each read it for a different failure mode, apply what can be
fixed, re-check once, and hand back a revised draft plus the questions only the
user can answer.

A real preflight is a walkaround where the pilot fixes what they find and looks
again. Iteration is already in the name.

**The rule that makes the loop safe, and the one this skill cannot break:**

> **The loop may change wording. It may never change content.**

Anything a reviewer raises that cannot be fixed from material already in the
draft becomes a question back to the user. It never becomes an invented
sentence. This skill has no send action.

## The model this context runs on

Check this first, before Step 0.

The safety hinge is Step 6, where every proposed fix is tested against the
draft: one that needs an absent fact is reclassified instead of applied, and
one that needs nothing outside the draft is applied instead of sent back as a
question. That judgment is the whole difference between a loop that revises and
a loop that invents, and it is materially better on Opus.

**If you can tell you are not running on Opus, say this in one line, then
carry on:**

```
Running on <model>. This loop's adjudication step is materially better on Opus
-- `/model opus` and re-run if this message matters.
```

**This never blocks**, per `config-resolution.md`'s standing rule -- one notice
line, then continue with reduced behaviour. A weaker model still runs the whole
loop. It is just likelier to let an invented fact through Step 6, which is the
one error the user cannot see by reading the output.

**Say nothing when you are on Opus, and say nothing when you cannot tell.** A
hedged nag on every run is worse than no notice at all.

**This is about `preflight`'s own context, not the reviewers.** Each reviewer
is dispatched on the model tier its archetype carries, per
`docs/reviewer-personas.md` § What each reviewer runs on, whatever this context
is running on. A weak busy reader is the intended behaviour; a weak adjudicator
is not.

## Step 0: read the shared docs

Read these before doing anything. Do not work from memory of them.

- `${CLAUDE_PLUGIN_ROOT}/docs/substance-checks.md` § When the checks apply, §
  The six checks and § How a fail is reported -- when cycle 0 runs (Step 2),
  what the six checks are (Step 3), and how a failure is reported (Step 3).
- `${CLAUDE_PLUGIN_ROOT}/docs/reviewer-personas.md` § How a brief is
  assembled, § What every reviewer is told, § The critique contract, § What
  each reviewer runs on, § The roster and § The two checks that never
  dispatch -- the reviewer roster this skill selects from and never invents
  a member of (Step 4), the isolation rule and the two bars every dispatched
  finding is held to (Step 5), and the model tier each reviewer runs on
  (Step 5). Not § Archetypes are reading behaviours, not people -- that
  section explains the design; nothing in this skill's own steps depends on
  it.
- `${CLAUDE_PLUGIN_ROOT}/docs/rewrite-rules.md` -- read in full: Step 7
  applies it "in full", by its own words, and every one of its rules bounds
  the wording fixes this skill makes.
- `${CLAUDE_PLUGIN_ROOT}/docs/voice.md` -- read in full: Step 7 layers the
  user's `writing_style` prose under it, and that layering rule (§ Fixed
  cannot be overridden, § Defaults can) depends on the whole Fixed/Defaults
  split, not one rule in isolation.
- `${CLAUDE_PLUGIN_ROOT}/docs/config-resolution.md` § Resolution order, §
  Resolving `writing_style` and `personas` and § Failure behavior -- how the
  ledger location for check 6 resolves (Step 3), how the `writing_style` and
  `personas` pointers resolve (Step 4, Step 7), and the failure-behavior
  table this skill's own failure cases and "never blocks" notices follow
  throughout.
- `${CLAUDE_PLUGIN_ROOT}/docs/config-schema.md` § Field notes -- where
  `profile.tone` is defined.
- `${CLAUDE_PLUGIN_ROOT}/docs/response-format.md` -- how the reply to the user
  is shaped. Read in full and not narrowed to a section: Step 10 says its
  report shape "implements `response-format.md`" as a whole, and the
  contract's own scope says a skill "implements it; it never redefines it" --
  every rule in the file governs this skill's replies, not only
  § Entries are named topic-first, ID in parentheses, the one heading Step 3
  cites by name.

One more, read only when the run actually needs it:
`${CLAUDE_PLUGIN_ROOT}/docs/preflight-reference.md`, which holds this skill's
own branch-only sections -- a re-run, an unresolvable recipient conflict, a
person described inline, a run without dispatch, the failure cases, and what
this skill does not do. Every rule there binds exactly as if it sat here, and
each step below names its section at the moment that branch opens.

## Step 1: take the input as given

- **A pasted draft.** The normal case, and the only shape the loop runs on.
  Everything below applies.
- **No draft, just a description** of what the user wants to raise ("should I
  even bring up that the migration slipped again?"). There is no text for a
  reviewer to read, so run cycle 0 against the description, report the verdict,
  and stop. Say what is missing and hand off: "Run `/daikenja:compose` when you
  want this drafted." Do not draft it here, not even a rough version.
- **Neither.** Ask for one. Do not guess what the user wants to raise.

Do not invent or fill in anything absent from what was given. A gap is a
finding, never something to guess at.

**A revision of a draft this skill already reported on in this conversation
does not start cold**: read `preflight-reference.md` § Re-running on the same
draft now, and § Reporting a re-run at Step 10. A draft with no earlier report
in front of you is not a re-run, whatever it contains.

## Step 2: determine the goal

The six substance checks apply only when the goal is a `request` -- asking
someone to do, decide, or answer something. If the goal is obvious from the
input, use it. Otherwise ask one short question: "Is this asking someone to do
or decide something, or just informing them?"

- **A request.** Run cycle 0, then the loop.
- **Not a request** (announcement, FYI, status update). **Skip cycle 0 and go
  straight to the loop.** The substance checks do not apply, and say so in one
  line -- but an announcement can still be too long, land badly, or read as
  blame, and those are exactly what the reviewers catch.

## Step 3: cycle 0 -- the substance checks

Run all six checks from `docs/substance-checks.md` against the draft. Report
every check, pass or fail, per Step 10's depth rule.

For check 6, **already answered**, only check material this skill can actually
see:

- A pasted thread or conversation, if one was given alongside the draft.
- The project's ledger, if a project is configured and a ledger is found
  (`~/.claude/daikenja/daikenja.yaml`, resolved per `docs/config-resolution.md` §
  Resolution order; `.daikenja/ledger.md` if unconfigured). Read it the way
  `docs/reading.md` § Step A-C describes, for lookup only -- this skill never
  writes to it.

If neither is available, say so plainly rather than implying a broader check
happened: "Already answered: not checked -- no thread or ledger was available
to check against." That is not a pass and not a fail; it is an honest gap,
reported alongside the other five.

**A failing check does not stop the loop, but not every failure is a content
gap.** Where it lands depends on what closing it actually needs -- checks 4
and 6 fail in ways the other four cannot.

- **Checks 1, 2, 3 and 5** fail only when the message needs a fact the sender
  has not stated -- background, a prior attempt, the options on the table, or
  the right person to ask. Nothing expressible from the draft alone supplies
  any of those, so a failure here is always a content gap: it joins the
  questions list in Step 10 and the loop carries on. Never invent the missing
  piece to turn a fail into a pass.
- **Check 4, one specific question**, fails two different ways and they are
  not the same kind of gap. A message with no ask at all ("any thoughts?")
  needs the sender to say what they actually want -- a content gap, routed
  like the four above. A message carrying several asks at once needs no new
  fact: splitting or labelling what is already there so each reader can tell
  which part is theirs is expressible from the draft alone, so fix it
  directly in Step 7 like any other wording fix and report it there, never in
  the questions list.
- **Check 6, already answered**, fails by finding an answer, not by missing
  one -- the opposite of every check above. Report the pre-existing answer,
  named topic-first with its decision ID in parentheses when it comes from
  the ledger (`docs/response-format.md` § Entries are named topic-first), and
  ask only whether the draft should defer to it. That is a question about
  which way to resolve a known answer, not a fact gap, and it is reported
  as such rather than folded into the questions list as an unstated fact.

## Step 4: select the reviewers

Two counts, kept separate. **Archetypes cap at 4. Persona slots cap at 2.**
Naming a person must never cost a lens.

### The archetypes

1. **The busy reader is pinned.** It runs on every draft, always, without
   inference. Length and a buried ask are failure modes on essentially every
   message regardless of audience.
2. **Infer three more** from the draft itself -- what it asks, who it lands on,
   and what it touches:

   | Signal in the draft | Reviewer |
   |---|---|
   | Money, HR, legal, security, an incident, or blame attached to a person | the risk reader |
   | A decision going to a director or above | the executive |
   | Numbers, causal claims, technical assertions | the fact-checker |
   | A request that lands on one identifiable person | the person being asked to do the work |
   | Frustration in the source, or a history the reader may take personally | the tone-sensitive reader |
   | Cheer, "as discussed", or anything the sender means more warmly than it reads | the subtext reader |
   | A ticket system, an assistant or an agent will read it; or the ask is compound | the machine reader |
   | The message is arguing a position someone has not accepted yet | the dissenter |

   The dissenter is **inference-only and never pinned**. It runs when the
   message is trying to persuade, and not otherwise.

3. **Skip an archetype a named persona already carries in full.** A generic
   executive alongside a named person who *is* the executive returns the same
   findings twice. The freed slot goes to the next uncovered lens, so the count
   stays at 4.

### The named personas

**Only people the draft actually addresses become reviewers.** `personas.md` is
an index, not a roster to sweep. This is what stops a large org from exploding
the reviewer count.

`personas.md` below means whatever `profile.personas` resolves to -- a local
file or a Google Drive file, per `config-resolution.md` § Resolving
`writing_style` and `personas`. Nothing in this skill changes with the form of
the pointer except what happens when it fails.

For each addressee, assemble a brief per `docs/reviewer-personas.md` § How a
brief is assembled -- the archetype they embody, plus their `personas.md` entry
if one matches, plus whatever the user said inline this run. Inline wins over
the file; the file wins over the archetype.

- **Named, with nothing known about them.** Not in `personas.md`, nothing said
  inline -- including because the `personas` pointer itself never resolved, in
  which case every named reviewer lands here. Archetypes only. Not an error,
  but name the capture path: one line in the report that no `personas.md`
  entry exists for them and `/daikenja:remember-persona` is how to add one.
  This line is the report substitution `config-resolution.md` § Failure
  behavior allows in place of a standalone notice for a local pointer failure.
- **A local `personas` pointer does not resolve, and no reviewer is named
  explicitly.** Silent -- there is nothing to disclose when nothing was going
  to use the file.
- **A `drive:` pointer does not resolve, or reads back empty.** Stop and name
  the file, per `config-resolution.md` § Failure behavior. This one is not silent:
  reviewing without the personas the user configured would look like reviewing
  with them.
- **More addressees than slots.** Direct addressees beat cc'd. Name who was
  dropped in the report.

A `personas.md` entry is scoped to that person and **never modifies a shipped
archetype for anyone else**. Changing an archetype globally is a pull request to
`docs/reviewer-personas.md`.

## Step 5: cycle 1 -- dispatch

Dispatch **one subagent per selected reviewer, all in a single parallel block**.
Each subagent gets the draft and its own brief, and nothing else -- not the
other reviewers, not their findings, and **not the cycle-0 verdict**, which
would anchor it onto ground already covered.

Isolation is the point. A reviewer that can see another reviewer's critique
defers to it, and the second opinion stops being one.

**Dispatch each reviewer on the model tier its archetype carries**, from
`docs/reviewer-personas.md` § What each reviewer runs on. Pass the tier as the
subagent's model at dispatch, as the family alias that table gives -- `haiku`,
`sonnet` or `opus`, never a versioned model ID. A named addressee takes the
tier of the archetype it embodies.

**Do not raise or lower a tier to match the session.** The tiers are what each
persona simulates, not a budget. The busy reader is *meant* to be weaker than
the session -- a strong model asked to skim reads properly and then reports what
a skimmer would have missed, which is a different signal -- and the risk reader
is meant to be strong whatever the session is set to.

If the dispatch available to you takes no model, dispatch anyway and say
nothing. The tier is a preference, not a dependency, per `config-resolution.md`'s
standing rule: continue with reduced behaviour rather than stopping.

At the same time, in this context, run the two checks that never dispatch --
the AI-tell check and non-native English readability, both defined in
`docs/reviewer-personas.md`.

**Discard any finding that misses either bar in `docs/reviewer-personas.md`
§ The critique contract.** A finding that cannot quote the span it is reacting
to is too vague to act on, and a finding whose stated cost is only that a reader
might land somewhere else has not said what the draft loses by keeping the
phrase. Discard both outright. Do not go looking for what a finding might have
meant, and do not carry a weak one forward as a nitpick -- a finding that was
not worth applying is not worth mentioning either.

**Discarding is not overruling the reviewer.** Both bars are part of the brief
every reviewer was given, so a finding that misses one was never within the
contract to begin with. This is not the same as disagreeing with a finding that
clears both, which Step 6 and `preflight-reference.md` § Conflicts handle.

## Step 6: adjudicate -- the safety hinge

**Decide the wording-or-content call yourself. Do not trust the subagent's
label.** A reviewer can label either way round: it can call a content gap a
wording fix and smuggle an invented fact in through its suggested `Fix`, and it
can call a wording fix a content gap and send the user a question they did not
need. This is the one place both get caught.

Every proposed fix gets one test:

> **Is this expressible using only material already in the draft?**

- **Yes.** It is a wording fix. Apply it in Step 7.
- **No -- it introduces a fact, number, date, owner, constraint or commitment
  the draft does not contain.** Reclassify it as content. It goes to the
  questions list with the fact named, and the suggested `Fix` is discarded
  rather than softened into place.

**The test asks what the fix needs, not what the finding noticed.** A reviewer
often notices a problem by reasoning about something outside the draft. That
does not make the repair a content gap. Test the repair.

Prior turns in this conversation are not a source of content, per
`docs/rewrite-rules.md` § Prior conversation context. Knowing the answer does not
license writing it in. If it belongs in the message, it is a question.

### The hinge fails in two directions

Both directions are wrong, and neither is a safe default to drift toward.

**Inventing.** A fix that needs a fact the draft does not have is applied
anyway, and the message goes out carrying something the user never said. This
is the hinge's primary job and nothing below relaxes it: a fix that introduces
a fact, number, date, owner or commitment is content, every time, whatever
label the reviewer put on it.

**Over-referring.** A fix that needs nothing outside the draft is sent back as
a question. The user is asked for a fact the message did not need, and because
the verdict line counts outstanding facts, a draft that was ready to send is
reported as blocked. One unnecessary question also teaches the user that the
questions are optional, which is how a real one gets skipped.

**Deleting words is a wording fix.** A fix that only removes or rearranges what
is already on the page needs no fact from outside the draft, so it stays a
wording fix even when the reason to remove it turns on something only the
sender knows. Cut the words and say so.

Worked example. A reviewer flags "as discussed" in a draft whose reader may
remember no such discussion, and the same for "as you know". The repair is to
delete four words. The revised message says everything it said before without
them, and nothing outside the draft was needed to write it -- so it is a
wording fix, applied in Step 7, and it produces no question. Asking the user
"is 'as discussed' accurate?" turns a deletion into a blocker.

**When a phrase is a content gap.** Only when the message needs the absent fact
in order to stand -- cut the phrase, and the draft loses something it depends
on. "As we agreed on the call, I am proceeding on Tuesday" grounds the whole
ask in an agreement, and deleting the clause leaves the ask with no basis, so
what the agreement actually was is a question. "As discussed, here is the
staging failure" grounds nothing, and deleting it costs the message nothing.

**Two reviewers can want incompatible things.** Where no single fix serves
both, read `preflight-reference.md` § Conflicts for the order they resolve in
and which case is reported rather than resolved -- Step 7 and Step 10 both
refer to its case 3. Fixes that sit together need none of it.

## Step 7: rewrite -- never dispatched

Apply the accepted wording fixes here, in this context. **The rewrite step is
never delegated.** Rewriting is where invention happens, so it stays in the one
place that has read `docs/rewrite-rules.md`, `docs/voice.md` and the user's own
writing style.

- Apply `docs/rewrite-rules.md` in full. The ask, the stance, the confidence
  level, the owners, the timing and how blocking it is all survive untouched.
- Apply `docs/voice.md`, layered under the user's `writing_style` prose if the
  pointer resolves -- that prose reaches the file's `## Defaults` tier only, and
  a line contradicting a `## Fixed` rule is not applied
  (`profile.writing_style`, per `config-resolution.md`
  § Resolving `writing_style` and `personas` -- a local file or a Google Drive
  file). A local pointer that does not resolve gets one notice, then the default
  voice alone; a `drive:` pointer that fails stops the run, per that document's
  § Failure behavior.
- A rule that cannot be honoured is named in the report, never broken silently.

**Keep a record of what this step changed, finding by finding.** Against each
cycle-1 finding write either the edit made in answer to it, or nothing. A
content finding gets nothing by definition -- its repair needed a fact the draft
does not have. So does a finding left unfixed because no fix served both
recipients, per `preflight-reference.md` § Conflicts case 3. Step 8 reads this
record, and without it cycle 2 cannot tell a fix that landed from a sentence
nobody touched.

## Step 8: cycle 2 -- re-check once

**Re-dispatch only the reviewers that raised something in cycle 1**, each on the
same model tier it ran on then, against the revised draft. They read the
revision and say whether each problem is still there.

- New wording findings are adjudicated and applied the same way.
- New content findings join the questions list.
- **Zero wording findings in cycle 1 skips cycle 2 entirely.** There is nothing
  to re-read.

### A finding is resolved only where Step 7 changed something

A cycle-2 reviewer **reads cold**. Step 5's isolation rule means it has not seen
its own cycle-1 finding, so what comes back is a second read of the revision and
not a memory of what it said the first time. It can therefore decide it no
longer minds a sentence nobody touched. On 20 August 2026 two reviewers did
exactly that: both closed a cycle-1 finding by citing a clause that was in the
original draft and had never been edited, and the finding left the report with
nothing in the message having changed.

So the resolution is not the reviewer's to give on its own:

> **A cycle-1 finding is recorded as resolved only where Step 7's record shows
> an edit made in answer to it. A finding with nothing recorded against it
> stands, whatever cycle 2 says about it.**

- **Step 7 edited for it and cycle 2 finds it gone.** Resolved. Drop it.
- **Step 7 edited for it and cycle 2 still raises it.** It stands. The edit did
  not land, which is the thing cycle 2 exists to catch.
- **Step 7 made no edit for it.** It stands as a **restate**, and cycle 2's
  reading changes nothing. Report it where it already sat -- a content finding
  in the `Needs you` list, an unresolvable recipient conflict in the conflict
  line.

**The test is the edit, not the wording of the anchor.** A length finding
answered by cutting a different paragraph was acted on, and cycle 2 may close
it. Where the record is empty nothing was acted on, and no reading of the
revision changes that.

This adds no cycle and no reviewer. It is a check on what the loop already
holds, applied before a finding is allowed to leave the report.

**If cycle 2 runs at all, it runs as a dispatch. Cost is not a reason to skip
it.** Judging in this context that a fix "plainly resolves" a reviewer's finding
is the exact unchecked self-assessment cycle 2 exists to prevent -- the reviewer
raised it, the reviewer has not seen the revision, and the reviewer is the one
who says whether it landed. Spawning fewer agents is not a saving if what you
bought was the confirmation.

**The loop stops here. Two cycles, no exceptions.** After the first rewrite what
remains is almost always content, which no further cycle can fix. Collect it and
report it once rather than bouncing back at the user three separate times.

## Step 9: learned personas

**Only when the user described someone inline this run who has no entry in
`personas.md`.** Read `preflight-reference.md` § Step 9: learned personas and
follow it -- it owns the routing, the synthetic-material exception and the line
it hands to Step 10. Where nobody was described inline, this step does nothing
and Step 10 carries no `Learned:` or `Not learned:` line.

## Step 10: report

The shape below implements `response-format.md`; where the two ever disagree,
the contract wins. Verdict first, deliverable second, evidence third:

```
Verdict: needs 2 facts from you before it goes

<the revised message>

Needs you
1. [the fact-checker] The message says the migration "will take a while" --
   they need the actual window to plan around it. You have not stated one.
2. [substance check: attempts stated] The message asks priya to look at the
   failure but does not say what you already tried.

Reviewers: busy reader (always on), the executive (the ask lands with a
director), S (named in the draft)

Reviewed: dispatched, each reviewer reading cold.
Applied: 4 wording fixes across 2 cycles.
Already answered: the events-table schema freeze (D-003) says hold off until
the rollout completes. Defer to it?
Conflict: R needs the rollback detail kept and M needs this under ten lines.
No fix serves both -- this may want to be two messages.
Learned: added S to ~/.claude/daikenja/personas.md.
```

The verdict line is `ready to send` or `needs <n> facts from you before it
goes`. Nothing else.

**`Already answered:` reports a check-6 hit, not a content gap.** Name the
pre-existing answer topic-first with its ID in parentheses when it comes from
the ledger, state what it settled, and ask only whether the draft should
defer to it. It never joins the `Needs you` list and never counts toward the
verdict's fact count -- the sender is not missing a fact, they are being
asked which way to resolve one they already have. One line per hit, reported
alongside `Conflict:` for the same reason that line is: it is something only
the user can settle, but it is not an unstated fact.

**`Learned:` has a counterpart that says nothing was written.** Where Step 9
routed someone and `remember-persona` offered the entry instead of writing it,
the line reads `Not learned: S came in with the material you pasted, so I have
not added them to ~/.claude/daikenja/personas.md. Say the word and I will.` It
is one line in the same place, it carries the question, and the verdict above it
is unaffected -- the review is finished either way.

**`Applied:` counts edits, not findings closed.** It is the number of wording
fixes Step 7 actually made across both cycles. A cycle-1 finding that stands
under Step 8 was never an edit, so it is not counted there and it does not
leave the report -- it stays in the `Needs you` list or the conflict line it
already belonged to.

**A re-run's report carries one more line.** Where Step 1 established this run
is a re-run, read `preflight-reference.md` § Reporting a re-run for that line
and for what a second consecutive run has to state. A first run adds nothing
here.

### The `Reviewed:` line is mandatory

**Every report carries it, on every run, whichever way the reviewers ran.** It
is not a warning that appears when something is wrong -- it is a statement of
how this particular run was produced, and it is written last, from what
actually happened, never from what was supposed to happen.

| How the reviewers ran | The exact line |
|---|---|
| Dispatched | `Reviewed: dispatched, each reviewer reading cold.` |
| In this context | `Reviewed: in sequence in this context -- no dispatch available, so the reviewers are not independent and each one had read the ones before it. Treat this as weaker than a dispatched run.` |

Stating it unconditionally is the point. A notice that only appears when
dispatch is missing asks this skill to notice an absence, and an absence is the
one thing it reliably fails to notice -- so the run that most needs the warning
is the run least likely to print it.

**When the reviewers ran in this context, cycle 2 confirmed nothing.** Say
`re-read once in the same context`, never `confirmed`. A reviewer that never
read the revision independently cannot confirm a fix landed, and a report that
says it did has invented the one thing the second cycle exists to buy.

**A dispatched cycle 2 is a second read of the revision, not a memory of the
first read.** The re-dispatched reviewer reads cold, per Step 5, and has not
seen its own cycle-1 finding. What it can settle is whether an edit landed. A
finding Step 7 never edited for is not its to close, per Step 8, and it stays
in the report whichever way the reviewers ran.

**Depth keys off `profile.tone`**, per `docs/config-schema.md` § Field notes:

| `tone` | What the report shows |
|---|---|
| `direct` | The six checks collapse to one line when they all pass. Only failures are itemised. |
| `standard` | Every check on its own line. Findings summarised without their anchors. |
| `guided` | All six checks, every finding with its anchor, and the reasoning behind each fix. |

**A clean draft produces a short report, not a padded one.** If every reviewer
returns nothing -- because nothing was raised, or because nothing raised cleared
the two bars -- say so plainly and hand back the draft unchanged.

That report is the verdict, the original draft and the evidence lines, and
nothing else:

```
Verdict: ready to send

<the draft, exactly as the user gave it>

Nothing to fix. No reviewer found anything that would change how this lands.

Reviewers: busy reader (always on), the machine reader (the ask is a dated
question someone may action from a summary)

Reviewed: dispatched, each reviewer reading cold.
Applied: no fixes -- cycle 2 skipped.
```

**No rewrite is offered on this path, not even as an option.** There is no
`Needs you` list, no nitpick, and no alternative version alongside the original.
A user who asked whether a draft was ready and gets back a criticism and a
replacement reads the original as having fallen short, whatever the covering
sentence says -- so the clean answer has to look clean. Offering a second version
"in case you prefer it" is the padded report wearing a hedge.

This is the one case the loop exists to handle well: a draft that really is fine
and should go out now.


## When dispatch is unavailable

**Only when subagent dispatch did not run.** Read `preflight-reference.md`
§ When dispatch is unavailable and follow it -- how the reviewers run instead,
what that costs, and that no model tier applies. It is still reported through
the mandatory `Reviewed:` line above and not by a notice raised there.

## Failure cases

`preflight-reference.md` § Failure cases. Read it the moment a run meets a
situation the steps above do not settle -- a missing draft, a finding that
fails a bar, a config pointer that does not resolve, a check that fails -- and
before improvising a way through one.

## What this skill does not do

`preflight-reference.md` § What this skill does not do. Read it when a run is
about to do something no step above told it to.

