AI operator: AfterAir 0.1.0 beta
How to run a small show-notes service with AfterAir plus an AI assistant, and exactly which parts are automated.
What is automated, and what is not
| Step | Who/what does it | Notes |
|---|---|---|
| Turn bullets, quotes and times into four draft files | AfterAir (no AI inside; deterministic code, tested) | node --test source/test.mjs |
| Check quotes against a transcript, word for word | AfterAir (paste the transcript in the optional field) | Flags quotes it cannot find; does not judge meaning |
| Turn a transcript into bullets, quotes, timestamps | Your own LLM + the prompt below, then you verify | This is the real work. Not part of the tool. No model quality is guaranteed or tested here |
| Check timestamps against the audio | A person | Seek to each time and listen for the topic change |
| Client consent, delivery, invoicing, replies | A person |
Swipe the table sideways to see every column →
"Automation" here means: an AI assistant drafts the extraction, AfterAir formats and checks it, a person verifies and delivers. There is no scheduled job and no integration (no Buzzsprout/Transistor API, no posting, no email sending).
Fields AfterAir takes
| Field | Required | Notes | |
|---|---|---|---|
| showName, hostName, episodeTitle | yes | ||
| publishDate | yes | YYYY-MM-DD; the form pre-fills today's local date. An impossible date such as 2026-02-30 is copied as typed and warned about | |
| durationMin | yes | positive number | |
| guestName | no | "Dr. Jose Nunez" and "Quinn, Riley" both work; triggers the thank-you draft | |
| episodeNumber, tone, episodeUrl | no | tone: professional or casual; episodeUrl replaces [link] in the posts | |
| topics | yes | one idea per line; list markers (-, •, 1.) are removed; long paragraphs are kept in show notes but shortened in social posts | |
| keyQuotes | no | verbatim only; write Name: "quote" to attribute, otherwise the quote is posted unattributed | |
| timestamps | no | 04:12 Label, 1:02:30 Label, [04:12] Label, (04:12) Label, 4m12s Label, 1h02m Label, and a trailing time (Label 04:12, Label [04:12]); Markdown bold or backticks around the time are removed. Clock times (12:30 PM) are not read. Unreadable lines are listed in a warning, never guessed. No timestamps = [TIME NEEDED] placeholders (the first 12 topics, with a warning if there are more) | |
| resources | no | `Title | URL` |
| transcript | no | only used to check quotes; never added to the files |
Swipe the table sideways to see every column →
Privacy floor
The form and the function reject SSN-shaped text (###-##-####, ### ## ####, nine plain digits that follow SSN rules, and the same groups separated by dots, slashes, en or em dashes, several spaces or line breaks; numbers inside URLs are ignored) and payment-card-shaped numbers (13–19 digits, grouped with any of those separators, that match a major-brand prefix or pass the Luhn checksum) in any field, and name the field. It is a safety net: numbers spelled out in words, or split by other text, are not caught. A valid ISBN-13 book number is allowed. A long ID can occasionally look like a card number, and a nine-digit order number can look like an SSN; the message says how to rewrite it.
Calling buildAfterAir with JSON additionally rejects any field whose name contains one of these words, ignoring case, camelCase and punctuation (so subscriberList, credit_card_number and PaymentLink are all rejected): ssn (as a whole word), socialSecurity, subscriber, emailList, mailingList, creditCard, cardNumber, cvv, bankAccount, accountNumber, routingNumber, payment, diagnos…, medication, medical, prescription, patient, password, apiKey, secretKey, credential, accessToken, privateKey, and any name whose last word is token, secret or bearer (or their plurals) (so token, sessionToken, csrfToken and clientSecret are rejected, but tokenCount and className are not). The web/OPEN-ME form has no such fields, and it does not detect free-text medical details, email lists or API keys. Never paste those.
"Nothing is uploaded" — and the one exception
AfterAir itself runs in your browser and uploads nothing. If you use an LLM with the prompts below, you are pasting the client's transcript into a third party's service. Tell the client, get their OK in writing, check that provider's data-use terms, and do not use it for confidential or sensitive episodes.
Weekly workflow
- Client sends the episode (audio link) and, ideally, a transcript (their host often creates one; many hosts include transcripts on paid plans).
- Run Prompt 1 on the transcript (with the client's consent). Paste the result into the AfterAir form fields.
- Paste the transcript into the optional Transcript field so quotes are checked. Resolve every warning.
- Verify against audio: open the audio, jump to each timestamp, confirm the label matches. Fix or delete any that do not. A wrong chapter published under your name is worse than no chapter.
- Build, read all four files once, download, send. The thank-you is a draft the host sends from their own mailbox.
Prompt 1 — transcript → bullets, quotes, timestamps, guest and links (the real work)
Use a transcript that has real time codes. The chapter step below only copies times that appear in the transcript. If yours has none, the model writes TIME UNKNOWN and you must find every chapter time by seeking through the audio, which turns the job into the slower audio-only case in ECONOMICS.md (about 160 minutes, a $133.33 break-even instead of $83.33). Ask the client for a transcript with time codes before you quote a price.
Auto-generated transcripts often misspell guest, brand and product names. Before you paste the output, fix names against the guest's own website or the host's notes.
You are helping a podcast show-notes writer. Use ONLY the transcript below. Do not add facts, names, links, numbers, or quotes that are not in it.
Return exactly five sections with these headings and nothing else.
TOPICS
- 5 to 8 bullets, one idea each, 120 characters or fewer, plain words taken from the speakers where possible. No marketing language.
QUOTES
- 2 to 4 lines in the form: Speaker Name: "exact words copied from the transcript, unchanged"
- If you cannot copy a quote exactly, leave it out.
CHAPTERS
- One line per topic change in the form: MM:SS Short label (use H:MM:SS after one hour).
- Use ONLY times that appear in the transcript's own time codes. If the transcript has no time codes, write the single line: TIME UNKNOWN
- Never estimate, round, or invent a time.
GUEST
- Name: the guest's name exactly as the transcript spells it, or NOT STATED
- Bio: one sentence, only if the host or guest says it in the transcript; otherwise BIO NOT STATED
- Links: websites, handles or books ONLY if they are spoken or written in the transcript, one per line; otherwise LINKS NOT STATED
RESOURCES
- One line per book, tool, site or document the speakers mention, in the form: Title | URL
- Write the URL only if it appears in the transcript. Otherwise end the line with "| " and nothing after it. If nothing is mentioned, write NONE.
TRANSCRIPT:
<<<paste transcript here>>>
Paste TOPICS into Topics, QUOTES into Key quotes, CHAPTERS into Chapter timestamps, the guest's name into Guest name and RESOURCES into Resources. AfterAir has no bio field: use the GUEST bio and links in your own handover message or episode page. If you see a TIME UNKNOWN line, AfterAir will list it as unreadable and mark chapters [TIME NEEDED]; add the times yourself from the audio.
Long episodes: chunk the transcript
A transcript of a long episode may not fit in the assistant's context, and long inputs make the assistant skip or invent more. As a rule of thumb, split anything over about 6,000 words (roughly 40 minutes of speech) at a speaker turn into parts of about that size and run Prompt 1 on each part with the line PART 2 OF 3 above the transcript. Then combine the lists yourself:
- TOPICS: join the parts, delete duplicates, keep the order of the episode, and cut to the 5 to 8 that matter.
- QUOTES: keep the best 2 to 4. Every quote must still pass the Transcript check against the whole transcript.
- CHAPTERS: join the parts. Times come from the transcript's own time codes, so they are already on the episode clock; sort them with AfterAir (it does) and delete a chapter that repeats a neighbour.
- GUEST and RESOURCES: take them from the part where the guest is introduced and from every part that mentions a resource.
Do not ask the assistant to "merge" by re-reading the whole transcript; merge the short lists yourself.
Worked example (fictional, hand-written to show the format; not a captured model run)
Input excerpt (fictional show "Shelf Talk"):
[00:00] CASEY MORGAN: Welcome back to Shelf Talk. Today: why small brands should write their own product stories. My guest is Riley Quinn.
[04:12] RILEY QUINN: Shoppers skim. The first two sentences of a product story decide the click.
[04:40] RILEY QUINN: If the facts are wrong, beautiful copy still loses the sale.
[14:40] CASEY MORGAN: Let's walk through a three-beat structure: problem, proof, plain next step.
[27:05] RILEY QUINN: There is a free worksheet at example.com/story-worksheet.
Output in the requested format:
TOPICS
- Shoppers skim, so the first two sentences of a product story decide the click
- If the facts are wrong, beautiful copy still loses the sale
- A three-beat structure: problem, proof, plain next step
QUOTES
- Riley Quinn: "If the facts are wrong, beautiful copy still loses the sale."
CHAPTERS
00:00 Welcome and topic
04:12 Shoppers skim
14:40 Three-beat structure
27:05 Free worksheet
GUEST
- Name: Riley Quinn
- Bio: BIO NOT STATED
- Links: LINKS NOT STATED
RESOURCES
- Story worksheet | example.com/story-worksheet
Every line of that output comes from the excerpt. It builds with no ignored lines (this format contract is covered by a test in source/test.mjs, which also checks that the quote and every chapter time appear in the excerpt); the quality of any model's output is not tested and you must verify it.
Prompt 2 — shorten a social post for one platform
Shorten this social post for [X / LinkedIn / Instagram] to [280 / 700 / 400] characters or fewer. Keep the meaning, the episode title, and the [link] placeholder. Do not add hashtags, claims, numbers, or quotes. Return only the post.
POST:
<<<paste one post from social-posts.txt>>>
Prompt 3 — make the guest thank-you sound like the host
This sends a sample of the host's own writing, plus the guest's name and the email draft, to the assistant's provider. Get the host's OK first, the same as for the transcript.
Rewrite this thank-you email so it sounds like the host (sample of their writing below). Keep every fact unchanged. Do not add promises, dates, or links. Return plain text.
HOST WRITING SAMPLE:
<<<paste 3-4 sentences the host wrote>>>
EMAIL:
<<<paste guest-thank-you.txt>>>
Failure modes
- No transcript → you must listen and write the bullets yourself (case B2 in
ECONOMICS.md; budget about two hours for a 40-minute episode). - The LLM returns a paraphrased quote → the Transcript check flags it; replace it with the exact words or drop it.
- The LLM guesses times → delete them; AfterAir cannot tell a guessed time from a real one.
- Empty topics → the tool refuses (required).