Edits that cost nothing
Subhankar Denria
CTO & product engineer
What this part does
Let an admin change an amount after the kit is written and have every page, email and button follow at once — with no model call — while every figure and every claim is still checked before it goes out.
- The idea
- The model writes a placeholder; code fills it in whenever the text is shown
- Costs to run
- Nothing. An edit never reaches the model
- What you get
- Copy that never goes stale, and a person behind every claim
A real moment: £25 becomes £30
The kit is written and it reads well. Then the admin does the most natural thing in the world, and adjusts a number.
The moment
The kit is written and reads well. Looking over the giving levels, the admin decides £25 should be £30, and changes it.
A typical first build
- The amount is written into the story, the email and the buttons as text
- Each one needs a fresh model call, or editing by hand
- One place is missed, and two different figures go out
This build
- The story, the email and the buttons all show £30 at once
- No model call is made, so the edit costs nothing
- The posts and plan mention only the target, so they stay right too
How: the model writes a placeholder where the amounts belong, and code fills it in every time the text is shown.
1. Late binding: placeholders instead of amounts
This is the idea in the build we like most.
The prompt asks the model not to write any giving amount in running text. Where the amounts belong in the email, it writes a placeholder on its own line: [giving levels]. Where the link belongs, it writes [link].
The placeholder is filled in every time the email is shown:
function emailBody(kit):
list = for each level in kit.levels:
"• {currency}{level.amount} {level.impact}"
return kit.email.body with "[giving levels]" replaced by listWhat the model wrote, once
Your gift makes this possible:
[giving levels]
Page story
- • £10 could help with materials for a week
- • £25 could help fund a session
- • £50 could help keep the doors open for a day
Supporter email
- • £10 could help with materials for a week
- • £25 could help fund a session
- • £50 could help keep the doors open for a day
Buttons
So when an admin changes £25 to £30, the story's list, the supporter email and the buttons on the public page all follow at once. No model call. No cost. No second version to keep in step.
Social posts and plan messages mention only the target, so they stay current as well.
The general lesson: anything that might change later shouldn't be baked into generated text. Keep it as data, and bind it at the last moment.
2. Trust, then verify
A rule in a prompt is a request. So after the response arrives, code reads every piece of copy, finds each money figure, and flags any that isn't the target.
Help us reach £4,000 before the end of the month.
£4,000 · The target
Every gift brings the £4,000 goal closer.
£4,000 · The target
Last winter we raised £12k for this work.
£12k · Not the target — shown to the admin to check
Flagged figures appear on the review page as gentle warnings. They never block the admin, who may well know something the app doesn't.
A detail worth knowing if you build this: match in Unicode mode. A currency sign such as £ is more than one byte, and a byte-wise pattern will split it in half.
3. The admin's own words are always kept
When the draft is created, a fingerprint of its starter description is stored alongside it. The kit places its story on the draft only if two things are true: it's still a draft, and the description still matches that fingerprint.
The check
- Still a draft
- Fingerprint matches the starter text
The story is placed on the draft
Nobody has written anything there yet, so nothing is lost.
One edit by the admin, and their words stay exactly as they wrote them, for good. The generated story is still there on the review page to copy from. It just never replaces something a person chose to write.
4. Claims need a person
A line such as "£25 could help fund a session" is the most important thing the model writes, because it's a promise an organisation makes to its supporters.
Three things protect it:
- The prompt requires modest wording. "Could", not "will". No invented statistics, names or quotes.
- The admin confirms the impact lines before publishing.
- A rewrite clears the confirmation, because nobody has read the new lines yet.
Impact lines · version 1
3 rewrites left£25 could help fund a session.
“Could”, not “will”. No invented statistics, names or quotes.
Waiting for a person to read them
Publishing stays possible, with a reminder. The final say is theirs.
Publishing with unconfirmed lines shows a reminder and stays possible. The organisation knows its own work, and the final say is theirs.
One more guard sits behind all of this. Research findings come from public web pages, so the system prompt marks them as untrusted content: information to draw on, never instructions to follow.
5. Twenty-five seconds, handled properly
The kit runs on the generator's own queue connection, apart from everyday emails and notifications. Its status is a single column on the idea:
queued●
waiting for a worker
generating
one call, about 25 seconds
ready
the review page fills in
A kit that can’t finish is closed off cleanly, and the page offers a fresh attempt. Nothing is ever left spinning.
- The job acts only on a kit that is still
queued, so a duplicate or a late job simply does nothing. - One attempt, with a five-minute limit. The kit is paid for once.
- If a worker stops mid-job, the kit is closed off and the page offers a fresh attempt.
- A kit queued for over a minute tells the admin it's waiting to start.
The browser polls a small status endpoint. For a 25-second job, that's all the real-time infrastructure it needs. The Three-Minute Button covers this pattern in depth.
6. Built and tested without a key
With no API key, or with a flag set, the generator returns a sample kit shaped from the draft's own facts and clearly marked as a sample. Every screen, every demo and every test runs with no network and no spend.
Close to eighty feature tests cover the module, including the billing path and every check described in this series.
Kept focused on purpose
Generated images, desktop and mobile previews, posting straight to social networks, and saving edits made to the kit's text are all natural next steps. Each will be added when customers ask for it. An organisation can launch today without any of them, and that was the goal.
What carries over
Strip out the specifics and five ideas apply to any feature that puts model output in front of the public.
- 1Give the model the facts and take back only words. Then check the words.
- 2Compute anything computable. Dates, sums and layout don't need a model.
- 3Use placeholders for values that can change, and fill them in at display time. Edits then cost nothing.
- 4Record the cost of every call next to the thing it produced.
- 5Put caps in the product, and the cost of serving a customer becomes arithmetic.
The model call is a small part of this feature. The craft is in the code around it — the part that makes five pence of writing something an organisation is proud to put its name to.
Booking new builds now
