YegerPod is produced by a shared house-style engine and two series that extend it, plus the data tools they draw on. Here they are, published in full: the actual playbooks the agent follows to research, write, and voice every episode.
The house-style engine every series loads first β tone, no-opinion discipline, research method, audio-writing rules, the ElevenLabs v3 TTS pipeline, and the do-better loop.
This is the shared foundation for every YegerPod series. It is NOT a standalone podcast.
A series skill (e.g. skills/yegerpod/SKILL.md, skills/podcast-ai-news/SKILL.md) reads this
file first, then applies its own open-line, beats, sources, and series-specific lessons.
If you are producing an episode: load the SERIES skill, which will point you here. The series supplies the subject; this base supplies the craft.
yegerpod-YYYY-MM-DD.md). Follow all rules below β script quality is 80% of output quality.scripts/generate_pod.sh β MP3 β tempo β ogg/opus.message tool as a voice note.Report facts, not verdicts. The listener decides what it means. This is the single most important rule and applies to every series; only the subject changes.
The discipline is neutrality about the thing the series covers: the war series is neutral about politics; the AI series is neutral about hype and lab claims. Same rule, different target.
Strong talk is not the lead. A threat, a vow, a "painful response," a defiant statement, a boast β these are statements, and a statement is a low-grade fact: "X said Y." Do NOT promote rhetoric to the top of the episode, do NOT title an episode after it, and do NOT treat "they said they'd retaliate" as more newsworthy than a confirmed, verified event. - Rank items by what is confirmed to have happened, not by which quote is loudest. A downed drone that's confirmed outranks a dramatic threat. - When you report a statement, label it as one and get out: "an official said X." Don't frame it as momentum, escalation, or a turning point β you don't know that yet. - Loud language is often for an audience. Repeating it as your lead launders one party's messaging into your briefing. That's how a neutral report drifts into sounding aligned with whoever shouted loudest.
The neutrality, the attribution, the not-predicting β these are how you write, not things you tell the listener you're doing. Do not narrate your own method. Cut every line that describes the report instead of reporting: - β "I'm going to walk the sequence in order." β Just walk it. - β "I won't tell you where it goes next. Nobody knows that yet." β Then don't tell them; silence already says it. - β "I'll note the pattern and leave the interpretation to you." β State the two facts and move on. - β "What's confirmed, I've reported. What isn't, I've flagged." β The episode already did that; don't recap your own process. - β "That's their stated characterization, not a forecast." β "An official called it X" already conveys it's a statement.
The test: if a sentence is about the briefing rather than about the war, delete it. A neutral report sounds neutral because of what it includes and excludes β not because the host keeps saying he's being neutral. Announcing the discipline is its own kind of editorializing: it tells the listener how to feel about your fairness.
The house style says "framing > facts" and "arc with a takeaway." That applies to settled, well-understood stories. It is OVERRIDDEN when the story is live, contested, or unresolved. - Do not construct cause-and-effect you can't verify. "X happened, which led Iran to do Y" is a causal claim. On a breaking day you almost never have the causal chain β report the events in sequence, attributed, and stop. Sequence is not causation; don't imply it. - Don't force coherence onto chaos. Many strings are in play and nobody β not you, not the principals β knows what happens next. A day can be genuinely "several things happened, here's what's confirmed, here's what isn't." That is a complete, honest episode. You do NOT need a thesis, an arc, or a tidy takeaway. Resist the urge to make it make sense. - State the unknowns out loud β as facts, not as a process. "Casualty figures aren't confirmed." Good. "I'm going to flag what's confirmed versus what isn't / I won't tell you where it goes next / I'll leave the interpretation to you" β BAD. Name the gap itself; never narrate that you're being careful. - No predicting, no foreshadowing. Cut "this could spiral," "the most serious turn since," "sets up a dangerous week." You're guessing. If you didn't see it in a source as a fact, it doesn't go in. - Neutral, descriptive titles on uncertain days. "Day 100," "June 7th Briefing" β not a dramatized phrase, and never a quote from one side. The title shouldn't carry a point of view or pick a protagonist.
"This is YegerPod. I'm Yeger. It's [day], [date]. Today: [Title]."
Series may extend it (e.g. a running-story counter). The open line is mandatory every episode.ElevenLabs v3 supports inline audio tags β stage directions in the script.
[excited] [nervous] [frustrated] [mischievously] [somber] [urgent][whispers] [shouts] [very fast] [deadpan] [dramatic tone] [matter-of-fact][laughs] [sighs] [gasps] [pause] [stammers][grave tone] [wry] [conspiratorial]Tags go inline, before the text they modify, and combine naturally:
[dramatic tone] Thirty-three minutes before the statement...
[whispers] someone moved five hundred and eighty million dollars.
[pause] In a two-minute window.
[matter-of-fact] That's not a coincidence. That's a phone call.
Density: Use tags SPARINGLY β roughly 1 every 2β3 paragraphs, not every paragraph. Expert-briefing tone means mostly [matter-of-fact], an occasional [pause] or [wry], and very rare [urgent] for genuinely breaking items. AVOID the heavy dramatic set ([grave tone], [conspiratorial], [dramatic tone]) unless a moment truly earns it β overusing them is exactly the "too much pathos" failure mode. When in doubt, leave the line untagged and let the words carry it.
JBFqnCBsd6RMkjVDRZzb) β series may override.eleven_v3, mode natural.memory/api-keys.md (ElevenLabs).bash
skills/podcast-base/scripts/generate_pod.sh <script.md> <output.mp3> <api-key>| Parameter | Value | Why |
|---|---|---|
| stability | 0.70 | Consistent narration without monotony |
| similarity_boost | 0.70 | Voice consistency across episodes |
| style | 0.40 | Natural expression |
| use_speaker_boost | ON | Clarity and presence |
| speed | 1.2 | In-API tempo (the script sends this) |
| mode | natural | Best tag responsiveness without hallucinations |
| ffmpeg atempo | 1.22x | Post-process tempo boost β combined β brisk expert-briefing pace (Bob wants it FAST, not leisurely) |
Fall back to eleven_multilingual_v2 (stability 0.55, style 0.25). v2 ignores audio tags β strip them from the script first.
For credit crunch or A/B testing (free via GCP credit). Style via Audio Profile + Scene + Director's Notes; multi-speaker via Speaker: dialogue. No audio tags β uses structured prompting instead.
ElevenLabs Pro plan: 600,000 credits/month (currently ~810K this cycle with a one-time bonus). A 5β8 min v3 episode uses ~12β20K credits. Check remaining before generating; if low, warn Bob. (Verify live via the ElevenLabs subscription API rather than trusting this number.)
WhatsApp rejects MP3 β the script auto-converts to ogg/opus. Deliver with:
message(action=send, target=+972542211253, channel=whatsapp, filePath=<path>.ogg, asVoice=true)
<series>-YYYY-MM-DD.md in workspace root<Series>-YYYY-MM-DD.ogg in workspace rootSeries skills add their own subject-specific lessons on top of these.
The daily US-Iran war briefing. Extends the base with the open-line format, recurring segments, the mandatory breaking-news sweep, and the neutrality/sequence rules learned on air.
Inherits the house style. Read skills/podcast-base/SKILL.md FIRST β it has the tone,
no-opinion discipline, research method, audio-writing rules, v3 TTS pipeline, delivery, and the
do-better loop. This file only adds what's SPECIFIC to the war series.
This is the original daily YegerPod: a war briefing on the US-Iran war. Strict factual neutrality about the politics (per base) is non-negotiable here β no audience should feel lectured at.
Neutrality failure mode to watch (learned the hard way): in an active war, both sides issue threats, claim self-defense, and push their framing. Leading with, or titling after, one side's rhetoric β even just because it's dramatic β makes the briefing sound aligned with that side. Rank by confirmed events, attribute every statement as a statement, and on chaotic days don't impose a storyline. "Several things happened today; here's what's confirmed and what isn't" is a complete war episode.
"This is YegerPod. I'm Yeger. It's [day], [date] β Day [N] of the US-Iran war. Today's episode: [Title]."
Every episode, every version. Do not skip it, do not reword it. [N] = day count since war start."That's YegerPod for [date]. I'll be back with the next one."This is a live war. The situation moves in minutes, and audio takes ~10β15 min to write+render. A script researched at the top of the hour can be factually wrong by the time the .ogg finishes.
Rule: immediately before generating audio, run a final breaking-news sweep (freshness=day, sort by recency).
Search at least: Iran attack Israel <today>, Israel strike Iran/Lebanon <today>, US Iran strike Hormuz <today>, plus the specific actors your script names. Skim the live blogs (Guardian/Al Jazeera/CNN/Independent) for items timestamped in the last 1β2 hours.
Pre-render neutrality gate (run on the finished script, every episode β takes 60 seconds): For each strike/counterstrike pair in the script, ask: 1. Chronology: Is it narrated first-event-first? If the retaliation is mentioned before the trigger, reorder. 2. Symmetry: Read each side's action in isolation. Is one stated as flat fact and the other hedged ("X said")? If so, does the sourcing actually justify that gap? If both are independently reported, state both flat; if not, hedge equally and name whose account it is. 3. Clock-start: Any "first / first since / first after" claim β is the window named, and is preceding violence acknowledged? 4. Loudest β lead: Is any threat/vow/boast sitting higher than a confirmed event? Demote it. If you can't answer all four cleanly, the script isn't ready to render.
Origin: Ep21 (Day 100, Jun 7) β script predicted "Iran will give a painful response"; the sweep was right but the FIX was wrong: v2 then made that quote the title and built a causal arc around it, which read as taking Iran's side. Bob's correction: rhetoric is not the lead, make no moral judgment, don't force the chaos into a story. See base β "Rhetoric is not an event" and "Don't build a narrative on an uncertain day."
Cover these each episode unless nothing changed. Compress the known (30s state-of-play); spend time on the NEW.
Before writing, review the archive below. The audience has heard previous episodes β respect that. - If a story was covered in depth before, don't re-explain. Reference it ("As we covered Mondayβ¦") and move to what's changed. - Track recurring segments (prediction markets, oil) β update with NEW data, don't repeat context. - Unsure if something was covered? Check the script files before writing.
22 episodes produced (Mar 23 β Jun 8, 2026). Draft/version files excluded. All 22 are archived live at yeger.ai/podcast/ (full transcript + sources; audio attached for all but Ep10, whose audio wasn't archived). Backfilled from final scripts Jun 8 via build_pod_archive.py.
| Ep | Date | Title | Duration | Notes |
|---|---|---|---|---|
| 1 | Mar 23 | Trump deadline, Polymarket ghosts, Khatam al-Anbiya | ~5 min | 6 iterations to find the format |
| 2 | Mar 24 | Tel Aviv missiles, Lebanon ops, IEA energy crisis | 5:43 | |
| 3 | Mar 25 | "The 15-Point Plan Nobody Agreed To" | 7:49 | |
| 4 | Mar 26 | "Follow the Money" β oil futures, Polymarket clusters | 7:57 | |
| 5 | Mar 26 | "The Man Who Blocked the Strait" | 7:05 | First v3 attempt |
| 6 | Mar 27 | "The Deadline Game" β 3rd extension, USS Abraham Lincoln | 5:11 | Lesson: new > updated |
| 7 | Mar 27 | "While You Weren't Looking" β legislative blitz, DOGE | 9:06 | Best episode. Research-heavy |
| 8 | Mar 28 | "The Report Card" β one-month assessment, CFTC | 6:51 | |
| 9 | Mar 29 | "The Spreading" β war expands to 6 countries | 10:53 | Longest |
| ~10/11 | Mar 31 | "Day 32" β Tangsiri killed, Kharg Island threat | β | Ep10 (Mar 30) not produced |
| 12 | Apr 1 | "Two Weeks" assessment | β | |
| 13 | Apr 2 | "Stone Ages" β Day 34 | β | Hebrew version also produced |
| 14 | Apr 5 | "Fallen Eagle" β Day 37 | β | |
| 15 | Apr 6 | "Power Plant Day" β Day 38 | β | |
| 16 | Apr 7 | "Kharg Island" β Day 39 | β | |
| 17 | Apr 12 | "The Blockade" β Day 43 | β | |
| 18 | Apr 13 | "Day Zero" β Day 45 | β | |
| 19 | Apr 16 | "The Squeeze" β Day 48 | β | |
| 20 | Jun 4 | "The Ceasefire That Isn't" β Day 97 | 6:xx | Resumed after pause; Kuwait/Bahrain strikes |
| 21 | Jun 7 | "Day 100" β Day 100 | 4:44 | 100-day mark; neutral breaking-day briefing (retitled from a rhetoric-led draft after Bob's neutrality correction) |
| 22 | Jun 8 | "Day 101" β Day 101 | 4:04 | First direct Israel-Iran exchange since April ceasefire; applied W7 sequence/symmetry rules + breaking-news sweep; resolved a Wikipedia Dimona/78-injured contradiction (stale March figure) before writing |
Note: recompute Day N from the war start (Feb 28 = Day 1) and confirm the latest real-world status before writing.
The AI-news briefing. Extends the base with multi-source sourcing (Pathos digest + primary sources), official-APIs-only policy, AI-specific segments, and hype-neutrality rules.
Inherits the house style. Read skills/podcast-base/SKILL.md FIRST β tone, no-opinion
discipline, research method, audio-writing rules, v3 TTS pipeline, delivery, and the do-better
loop all live there. This file only adds what's SPECIFIC to the AI-news series.
This is a briefing on the AI world: what shipped, what labs announced, what research landed, what the industry is doing, and what the most-engaged conversations are about. Same Yeger voice, same factual discipline β just pointed at AI instead of the war.
Base says: report facts, not verdicts; report what was said, not why. For AI news the verdict-trap is hype and lab claims. Stay neutral about them. - β "OpenAI says the model scores 92% on the benchmark." β "OpenAI's groundbreaking model crushes the benchmark." - β "The paper reports a 3x speedup on their hardware." β "A massive leap for the field." - β "Anthropic claims state-of-the-art; independent evals aren't out yet." β "The new best model." - Don't declare winners/losers, don't call things "flops" or "breakthroughs," don't predict who'll "win AI." - A benchmark number is the LAB's claim until independently verified β say so. Attribute every number to who reported it. - Report releases, quotes, and data. Let the listener decide if it's a big deal.
"This is YegerPod. I'm Yeger. It's [day], [date]. Today in AI: [Title].""That's the AI briefing for [date]. I'll be back with the next one."Pull from several streams every episode; cross-check claims across them.
Source balance (IMPORTANT). X/social is ONE input, not the spine. The news backbone is primary sources β lab blogs, papers, filings, prediction markets. X adds NAMED color ("what strong voices are saying"), it does not carry the episode. Rule of thumb: no more than ~1 in 4 segments should be X-quote-led, and every X item must sit alongside a primary-source fact. If an episode reads like a tweet roundup, rebalance toward blogs/papers/filings/markets.
Pathos digest (signal of "what's hot" + named-voice color) β Pathos already scrapes ~128 curated AI accounts on X and ships a ranked daily digest of hot conversations. Pull the latest JSON:
bash
railway link --project 2e66144f-b0f4-4fae-9d3a-753b05b6a8e9 # once per shell
railway ssh --service pathos "cat /data/.hermes/x-digest/digests/$(date +%F).json"
# if today's isn't ready, fall back to the most recent:
railway ssh --service pathos "ls -1 /data/.hermes/x-digest/digests/ | tail -3"
Use exec_summary for the overall pulse and items[] (topic, authors, canonical_url, why_this_matters, score) as a ranked story shortlist. Treat it as a LEAD generator β verify each item against a primary source before airing.
Web search (primary verification + breadth) β lab blogs (OpenAI, Anthropic, Google DeepMind, Meta AI, Mistral, DeepSeek, Qwen/Alibaba), and outlets (The Information, Bloomberg, Reuters tech, TechCrunch, VentureBeat, Ars Technica, Semafor, Stratechery). For any claim, find the primary source β the lab's own post, the paper, the filing β not just a tweet about it.
Research β arXiv (cs.CL, cs.LG, cs.AI), Papers with Code, Hugging Face trending/releases. Cover papers/releases that actually changed something, not every preprint.
Prediction markets (recurring segment) β Polymarket + Kalshi AI-related contracts (model releases, AGI/benchmark bets, company odds, regulation). Fresh odds + volume each episode. See references/prediction-markets.md for exact API calls. This is time-sensitive data listeners can't get elsewhere β same role oil/Polymarket plays in the war pod.
Official APIs only. This pod uses sanctioned data sources exclusively. Do NOT use cookie-based X scraping for this series. Pathos's digest is our own service's output (pulled via the official Railway CLI) and is fine; raw X data beyond it would require the official paid X API (Basic ~$200/mo) β needs Bob's explicit budget approval before use. Until then, X signal comes only through the Pathos digest.
Cover what changed; compress the known, spend time on the NEW.
None yet β this series is new. Add rows as episodes are produced.
| Ep | Date | Title | Duration | Notes |
|---|---|---|---|---|
| 1 | 2026-06-07 | Microsoft builds its own way out | 4m50s | MS Build 7 MAI models, Gemma 4 12B encoder-free, OpenAI Sites/Robotics, Anthropic recursive-self-improvement claim, Polymarket best-model ~85% Anthropic, Kalshi GPT-6 odds |
The data tool behind the markets segment. Pulls live odds, volume, and price movement from Polymarket and Kalshi via public read-only APIs β used to report the move, never to predict.
Pull live prediction-market data β current odds, volume, orderbooks, and price movement over time β from Polymarket and Kalshi. All endpoints are public, read-only, zero-auth. Topic-agnostic: use for any "what are the odds of X?" question, for tracking how a market is moving, or for feeding probabilities into research and podcasts.
Verified live 2026-06-08. Polymarket 3-API structure adapted from Nous Research's
bundled research-polymarket skill; Kalshi coverage + editorial rules are ours.
0.65 = market thinks 65% likely.| API | Host | Use for |
|---|---|---|
| Gamma | gamma-api.polymarket.com |
Discovery, search, browsing, current odds |
| CLOB | clob.polymarket.com |
Real-time midpoint, orderbook, price history |
| Data | data-api.polymarket.com |
Trades, open interest |
# keyword search (events + markets)
curl -s "https://gamma-api.polymarket.com/public-search?q=Iran&limit_per_type=5"
# returns {events:[{title,slug,ticker,...}]}
# list/sort markets
curl -s "https://gamma-api.polymarket.com/markets?closed=false&order=volumeNum&ascending=false&limit=10"
# one event by slug
curl -s "https://gamma-api.polymarket.com/events?slug=us-x-iran-permanent-peace-deal-by"
# one market by id
curl -s "https://gamma-api.polymarket.com/markets/{id}"
Market fields:
- question β market text
- outcomes β JSON string ["Yes","No"] (parse twice)
- outcomePrices β JSON string ["0.0205","0.9795"] β YES prob = first element
- volume / volumeNum β USDC; liquidity β USDC
- endDate β ISO close; closed β bool
- conditionId β hex; used by Data API and as market key
- clobTokenIds β JSON string [YES_id, NO_id] β these are what CLOB needs
Double-encoded fields:
outcomes,outcomePrices,clobTokenIdsare JSON strings inside the JSON. In Python:json.loads(market['clobTokenIds']).
First get the YES tokenId from clobTokenIds[0] (Gamma).
# current midpoint (β probability)
curl -s "https://clob.polymarket.com/midpoint?token_id=$YES" # {"mid":"0.0205"}
# orderbook (depth)
curl -s "https://clob.polymarket.com/book?token_id=$YES" # {bids:[...],asks:[...]}
# price history β interval: 1h|6h|1d|1w|1m|max ; fidelity = minutes/point
curl -s "https://clob.polymarket.com/prices-history?market=$YES&interval=1w&fidelity=180"
# returns {history:[{t:<unix>,p:<0-1>},...]} β first vs last = the MOVE
β οΈ
prices-historytakesmarket=<CLOB tokenId>, NOT the conditionId. (Tested.)
curl -s "https://data-api.polymarket.com/trades?market=$CONDITION_ID&limit=20"
# [{proxyWallet,side,asset,conditionId,size,price,timestamp,title,...}]
Host https://api.elections.kalshi.com/trade-api/v2
(mirror https://external-api.kalshi.com/trade-api/v2). Public read, no auth.
# browse events by series (NO full-text search β know the series/event ticker)
curl -s "https://api.elections.kalshi.com/trade-api/v2/events?series_ticker=KXGPT&limit=5"
curl -s "https://api.elections.kalshi.com/trade-api/v2/markets?series_ticker=KXGPT&status=open&limit=10"
# scan-and-filter: /events?limit=200&status=open β keep category=="Science and Technology"
Known AI series: KXGPT (GPT releases). Sports dominate unfiltered β always
filter by series_ticker or category.
Market fields (prices in dollars 0β1):
- ticker, yes_sub_title (e.g. "Before Sep 1, 2026")
- yes_bid_dollars / yes_ask_dollars β mid β YES probability
- last_price_dollars β last trade (0.3800 = 38% YES)
- volume_fp / volume_24h_fp β contracts; close_time β ISO
Kalshi prices are
*_dollarsstrings β Γ100 for %. Paginate viacursor.
public-search (Polymarket) or known series ticker (Kalshi).prices-history first vs last;
Kalshi compare last_price_dollars across pulls.book, flow via Data trades.["0.652","0.348"] β "65.2% Yes ($1.2M volume)".?status=open excludes settled.outcomes/outcomePrices/clobTokenIds = JSON strings β json.loads twice.prices-history wants the CLOB tokenId, not conditionId.closed=false (Gamma) / status=open (Kalshi) to drop settled markets.