diff --git a/PROGRESS.md b/PROGRESS.md
index 73f3da6..6fc97bf 100644
--- a/PROGRESS.md
+++ b/PROGRESS.md
@@ -56,6 +56,24 @@ and until now nothing set them.
---
+## 2026-09-10 — Titles: RSS `
` is the only source
+
+Confirmed against the live feed rather than assumed: 131 feed items, 131 stored, **0 mismatches** —
+entry titles are byte-for-byte what the RSS `` publishes, separators included. `feed.rs` never
+consults `itunes:title`, and season/episode live in their own columns, rendered as chips rather than
+folded into the title.
+
+Pinned with a test: a fixture whose `itunes:title` differs from its `` must still yield the
+RSS title, and an item with `itunes:season` but no `itunes:episode` keeps a null episode instead of
+inventing one.
+
+That null-episode case is real in the wild — this feed's `Music from a Darkened Room | Session Zero`
+carries S8 with no episode number, while Parts 1-5 get E1-E5, and it drops the "Part N" convention
+its siblings use. The arc is 11 items: Session Zero plus five parts, each part being a main episode
+and its shorter `Junk in the Trunk` companion.
+
+---
+
## 2026-09-10 — Phase 3: full-featured UI
Rewrite of `web/index.html` (~714 lines) plus the backend it needed.
diff --git a/src/feed.rs b/src/feed.rs
index 2f94fb6..e15e9fc 100644
--- a/src/feed.rs
+++ b/src/feed.rs
@@ -351,6 +351,46 @@ mod tests {
);
}
+ #[test]
+ fn the_rss_title_always_wins_and_episode_numbers_stay_metadata() {
+ // Some feeds set a different itunes:title. The displayed title is always the RSS
+ // , verbatim -- separators and all -- and season/episode are stored
+ // alongside it rather than folded into it.
+ let xml = br#"
+
+ Showhttps://xd
+
+ Music from a Darkened Room | Session Zero
+ Session Zero
+ sz
+ 8
+ 6720
+
+
+
+ Music from a Darkened Room Part 1 | Murphy's Drawer
+ p1
+ 81
+
+
+ "#;
+ let feed = parse(xml).unwrap();
+
+ let sz = &feed.entries[0];
+ assert_eq!(
+ sz.title.as_deref(),
+ Some("Music from a Darkened Room | Session Zero"),
+ "itunes:title must not override the RSS title"
+ );
+ assert_eq!(sz.season, Some(8));
+ assert_eq!(sz.episode, None, "a missing episode number stays missing");
+ assert_eq!(sz.duration, Some(6720));
+
+ let p1 = &feed.entries[1];
+ assert_eq!(p1.title.as_deref(), Some("Music from a Darkened Room Part 1 | Murphy's Drawer"));
+ assert_eq!((p1.season, p1.episode), (Some(8), Some(1)));
+ }
+
#[test]
fn durations_parse_from_seconds_or_a_clock() {
assert_eq!(parse_duration("5649"), Some(5649));