T
Sign in

PROMPTING.md — how to phrase a correction so it lands first time

PROMPTING.md — how to phrase a correction so it lands first time

The queue runner is only as good as the row it is given. A correction that names a screen, a visible outcome, and a way to check it gets implemented and verified without a round-trip. A vague one gets guessed at — and guessing is the number-one source of the bugs and missed changes you are seeing.

This is the contract the lane triage step, the acceptance checks and the verifier all rely on. Write rows to it and the loop runs itself.

The 5 slots (fill all five)

Slot Question Bad Good
WHERE which screen/route/form? "the list page" Quote list / src/routes/quote
DO what exactly changes? "fix the buttons" remove Expire + Follow-up; keep Duplicate + Create SO
SHOW ME what will I see when it is done? "it works" clicking Add Quote opens a modal; table stays visible
MUST NOT what must stay untouched? (omitted) table + search stay; no cost lines in the customer share
EXAMPLE a concrete case / data (omitted) party "Shree", 32s CW, qty 1250 mtrs

If you cannot fill SHOW ME, the item is not a correction yet — it is a discussion. Say "discuss" and the runner holds it (blocked-owner) instead of guessing.

One correction = one screen

Your CORRECTIONS.md already breaks a message into one row per form. Keep that: a row that spans leads + quote + orders cannot be batched and cannot be verified in one shot. Split it. Wide rows are the exception.

Say when the AI must NOT act

Ambiguity is expensive. Mark it explicitly so the runner holds the row:

  • VERIFY-FIRST: confirm X feeds no calculation before removing; if it does, report back — do not delete. (this is exactly C35/C36 — good rows.)
  • NEEDS CLARIFICATION — owner to restate. (C56 — a good hold, a bad correction.)
  • awaiting owner decision / do not guess (C55 — correctly held.)

The runner auto-detects these phrases (blocked-owner). Use them and it will never invent an answer — instead it asks you: the question lands in docs/QUESTIONS.md and shows on the /queue board (banner + the row's "Needs your action" cell). Answer by telling any session — it records the answer and releases the row.

The "done looks like" line

End every correction with the acceptance check in plain words. The triage lane turns it into 2–6 checks; giving it yourself makes them correct on the first pass:

Done looks like: on /quote the row has Duplicate + Create SO + Re-quote only; clicking Duplicate opens /quote/new?reuse=<id> with rates prefilled; bun test tests/c32-requote.test.ts passes.

Rewrites from your own shelf

Row As told Why it stalls Rewrite
C56 "breakdown the gate prices into multiples of gate passes… check all the gate passes separately" no screen, no outcome, open to interpretation Gatepass list: group rows by gatepass kind, subtotal qty per kind, add per-kind filter; done = filter shows only that kind + subtotal matches sum of rows.
C32 "Re-quote button is NOT working — fix it; it must be present and allow ONLY a rate change" good, but no repro add done = clicking Re-quote on a quote row opens that quote with only rate + validity editable; other fields disabled; test tests/c32-requote.test.ts passes.
C45 "Wherever the system suggests data entry from past entries, use Chip Suggestions UI." "wherever" is open scope list the exact screens: rate + qty suggestions on quote, bookings, orders use the chip component (docs/UIPATTERN §chip); done = each shows chips from the last 5 entries.
C24 "Same separation for EVERY form in the app." unbounded Apply the list/entry separation to leads, quote, orders, bookings, gatepass, tippans, masters — done = each Add opens a popup; list shows table only.

Copy-paste template

WHERE:  <screen / route>
DO:     <the exact change>
SHOW ME:<what is visibly different when done>
MUST NOT: <what stays untouched>
EXAMPLE: <a concrete case>
DONE LOOKS LIKE: <observable acceptance; test file name if known>
HOLD IF: <phrases that mean stop and ask>

What the system does with it

  1. lane triage turns WHERE/DO into target: globs + observable checks in docs/QUEUE.md.
  2. lane implements it test-first on those files only.
  3. verifier reproduces the checks on the running app — never trusting the implementer. Fail → the row auto-reopens at P0.
  4. runner deploys one verified batch at a time and appends the ledger.

Your only jobs: queue rows in this shape, and answer the blocked-owner questions. Everything else is the loop.