QUILL Cast 2.0 – Release Notes

QUILL Cast 1.1 made the app do things without being asked. 2.0 is about the places it could not reach: another directory, another device, another app, and the episodes whose publishers never wrote a chapter list.

Two of those are new kinds of thing for Cast entirely. It has never before been able to hand anything to another program, and it has never before known where you got to on a machine that is not this one.

And two more arrived late in the release, both about the same thing: one podcast is not like the others. Settings a podcast can answer for itself – seventy of them, inherited properly through folders at last – and Episode Filters, rules for the episodes you did not want in the first place. Those two come first below, because between them they change what using a large library feels like.


A podcast can answer for itself

Almost every complaint a podcast listener has is about one podcast behaving differently from the rest. Keep the newest three ready is right for a daily news show and wrong for a weekly three-hour interview. Check hourly is right for the news show and wasteful for an archive that stopped publishing in 2019. Say the podcast’s name in every row is right for a mixed list and noise inside that podcast’s own.

Cast has always had per-show settings. It had about a dozen. It now has around seventy, and – more importantly – it can finally tell the difference between “I have no opinion about this” and “I want exactly this”.

The bug underneath, worth naming

Until now, giving one podcast its own answer to one setting made a complete copy of every setting it had. So the moment you set a playback speed for one show, that show also acquired its own private copy of your retention rule, your download count, your Inbox caps and everything else – frozen at whatever your shared defaults happened to be that afternoon. Change a shared default a month later and it would reach every podcast except the ones you had ever bothered to adjust.

Folders had the same shape of problem. Folder Settings wrote its values into each member podcast and then forgot them, so a podcast you filed into that folder afterwards inherited nothing at all.

Both are gone. Settings now resolve through four levels – your shared defaults, then any folder the podcast is in, outermost first, then the podcast – and each level stores only the settings it actually has an opinion about. Set “check hourly” on your News folder and everything in it and beneath it checks hourly, including podcasts you file there next year. Move one out and it stops. Nothing was copied, so nothing drifts.

Your existing settings are converted the first time this version opens your library: each frozen copy is compared against your shared defaults, and only the values that genuinely differ are kept as that podcast’s own. Anything that matched is read as “no opinion”, which is almost always what was meant.

The window

Settings for This Podcast… now shows one category at a time – Arrival, Playback, Storage, Announcements, Curation – because seventy controls in a single scroll is not a window anybody can work through by ear.

Three things are true of every control in it. It shows the value actually in force, whether that came from this podcast, from its folder or from your shared defaults – and F1 says which: “Every 60 minutes, from the folder News.” Saving writes only what you changed, so everything you left alone keeps following the levels above it. And where a podcast has an answer of its own, a Follow button appears beside that control; pressing it drops that one answer rather than writing today’s default over it.

What Have I Changed? lists only the settings this podcast answers for itself, out of all of them. It is the question a window full of controls cannot answer, and it is how you find out why one podcast is behaving oddly without reading seventy rows.

The ones that matter most by ear

Tidy episode titles. A great many podcasts prefix every episode with the same thing: Ep. 412 -, MyShow Presents:, [Bonus]. Read by eye that is noise you skip past. Read by ear it is the first thing said on every row, two hundred times, and it destroys first-letter navigation completely – arrowing to “S” in a list where every row begins “Ep.” finds nothing at all, because the part of the title that differs is never where the reader starts. Patterns you set here are removed when a title is shown and spoken. The feed’s own title is untouched, nothing is renamed, and Rename… is still a different verb. Preview shows exactly which of the 50 newest titles would change, and a rule can never empty a title.

Say this podcast’s name as. One spelling used only when the name is spoken, for a title your speech engine mangles – an initialism, a word from another language, a run of punctuation. The podcast keeps its own name everywhere it is written.

What each row says is yours now. A screen reader reads every row of every list out loud, in full. Cast’s answer to that had been a single switch – put the podcast name before the episode title – over a question with at least seven answers. Now there is a named order (title, podcast or date first: whichever comes first is what you can skim by first letter) and independent switches for the podcast’s name, the date, the length or how much is left, the download state, the season and episode number, whether the episode has chapters or a transcript, and the description at off, brief or full. Per podcast as well as globally, because a daily show with the date in every title should not have the date read to you again. And the podcast’s name is never repeated inside its own episode list, whatever the switch says.

Urgent, normal or quiet. New-episode announcements had a switch, over a question with three answers: tell me by name, count it in the summary, say nothing at all. All three are now available per podcast. A quiet podcast still downloads, queues and files exactly as it would; it simply says nothing. One podcast can also be allowed through quiet hours by name, for a live or news feed you asked to be told about, and can have a sound of its own when it publishes.

Arrival, storage, and the rest

Per-podcast check cadence, so a daily briefing checks hourly while a weekly show checks daily and a dormant archive is never checked at all. Backfill on subscribe – nothing, the newest few, the last few months, or everything – which is a separate question from the automatic download count, because that one only ever looks forward. Off-peak download windows that wrap midnight, beside the metered-connection guard. Auto-Queue from the oldest unplayed episode, which is how you start a series at the beginning rather than at today.

Sort by season and episode number. Serial fiction is meant to be heard in order, and its published dates are the least reliable thing about it – bulk-imported, or re-stamped every time the feed is rebuilt. Where a publisher numbered their episodes, Cast now reads that numbering out of the feed, sorts on it, and can say it. An episode the feed did not number is not episode zero: it sorts to the end and says nothing.

Never delete this podcast’s downloads exempts one podcast from the storage cap, the age rule and delete-after-playing. It exists because the alternative was worse: without it, the only way to protect the one podcast you genuinely archive was to switch the automatic sweeps off for everything, which is what most people did.

Show at most N episodes is a view over a four-thousand-episode archive feed, not a trim. Nothing is deleted, search still finds everything, and raising the number brings it all back.

Labels are your own words for a podcast, as many as you like, and a Smart Playlist can ask for one. A folder is one home; a label is not a home at all, so labelling never moves anything.

Tell me if this podcast goes quiet says something when a podcast you follow stops publishing for as long as you choose – a podcast that ends does so silently, and the absence is exactly the thing nobody notices. Its companion speaks up after a run of failed checks. Both say plainly that Cast has not unsubscribed you and has not given up.

And, more briefly: transcript policy including opt-in local transcription, chapter-title skip rules for the advert breaks a publisher marked, a preferred audio variant when a feed offers more than one, a per-podcast disk budget, silence-trim strength, a default playlist new episodes join, a sleep-timer default, redirect and re-publish policy, and an artwork override.

Nothing added here deletes anything. Everything fails open: a value Cast cannot read means “carry on as before”, never “do less”.


Rules for the episodes you did not want

Some podcasts publish more than one thing. A show you follow also runs a daily two-minute segment; or trailers for its sister show; or a members-only strand mixed into the public feed. Until now every one of those arrived, was dismissed by hand, and counted against an Inbox limit you had set for a completely different reason.

Episode Filters is the missing decision, per podcast: rules that say which of a show’s episodes you actually want, and where that answer counts.

Each rule has your own name for it and its own on and off. It can match on the title – wildcards, where * is any run of text and ? is one character, and every other punctuation mark means itself, so Q+A* finds the segment actually called “Q+A” – or on a full regular expression if you want one. It can also match on a minimum length. Both tests in one rule have to match; several rules need match only one. An episode whose feed does not say how long it is never matches a length rule, because a missing length is not a short episode.

Two modes: keep everything except episodes a rule matches, which is the everyday one, and keep only episodes a rule matches, which is how you follow a single strand of a feed that carries several.

Eight places to mean it

This is the half that makes one feature do the work of eight. A rule set says what an episode is; the tick boxes say where that means anything – the Inbox, Auto-Queue, automatic downloads, the new-episode announcement, the podcast’s own episode list, New Episodes and Continue Listening, smart playlists, and Search Everywhere.

They are independent, so “keep it out of my Inbox but still tell me about it” and “just do not spend my bandwidth on it” are both things you can actually have. A new filter starts with the four routing places ticked and the four hiding ones clear: declining to route an episode is invisible and reversible, and hiding one changes what you can find.

It never deletes anything

A filtered episode keeps its place in the podcast’s episode list, its played mark, its position, its downloaded file, its notes and its bookmarks. Filtering is a routing decision, and every message the feature speaks says so.

Everything except the Play Queue takes effect the moment you save, including on episodes you already had – the lists ask the filter as they are drawn, so unticking a place later brings those episodes straight back. The Play Queue is the exception, because it is the one list you built by hand: saving offers, separately, to clear this podcast’s matching episodes out of it, and the episode playing right now keeps its place.

Look before you leap, and two ways back

Preview tries the rules against the 50 newest episodes you already have and reports what each would be – Filtered or Kept first, then the title and the length. It changes nothing, and it works while the filter itself is switched off, which is the only safe way to write a keep-only rule.

Saving is gated rather than merely checked. Cast refuses a filter that is switched on with no rule switched on, one whose regular expression cannot be read (it quotes the reason), one with nowhere to apply, and a minimum-length rule against a feed where not one of the 50 newest episodes publishes a length. Where only some do, it says exactly how many and asks.

And there are always two ways back. Filtered out is a new entry in the episode list’s own filter, present for every podcast rather than appearing only for filtered ones, and it lists exactly what the rules are catching – every episode action still works from there. Any single episode’s menu also offers Always Keep This Episode, which exempts that one episode everywhere the filter applies and is not undone by editing the rules afterwards.

Finally: if a keep-only filter rejects every single new episode of one refresh, Cast says so and remembers it, so a background check that ran while you were away still has something waiting for you in Episode Filters when you get back.


Your place follows you, and not only between QUILL machines

Cast has carried your listening position between two copies of itself for a while, encrypted, through a folder you already sync. That works, and it will only ever work QUILL-to-QUILL.

Listening Places is the other half: a small, published, plain-text format that any podcast app can read and write, in the same folder. Turn on a plain file other apps can read in Carry My Place Between Machines…, and Cast keeps one file up to date with where you are in every episode – and reads whatever the other apps have left there.

There is no account, no server, and no signup. You pick a folder inside Dropbox, OneDrive, Google Drive, iCloud Drive, Nextcloud, Syncthing, or a network share, and the cloud provider you already pay for does the syncing. QUILL runs nothing and holds nobody’s listening history.

Four decisions in that design are worth knowing about, because each of them rules out a specific way this could have gone wrong.

Every device writes exactly one file and reads everyone else’s. Cloud drives resolve two devices editing the same file by leaving positions (Jeff's conflicted copy).json lying around, which is the single worst failure available here. If no two devices ever write the same file, that cannot happen – and it scales past two devices for nothing: phone, laptop and desktop each drop one file, and every device merges across all of them.

The most recent position wins, not the furthest one. If you jump back twenty minutes to hear something again and then open the episode on the laptop, “furthest” is exactly the wrong answer.

Reading happens at launch and when you press Sync Now. Never otherwise. Not on a timer, not when the window gains focus. If a read landed mid-session and found that another device had moved you to 52 minutes in the episode you are listening to at 40, every available behaviour would be bad – and moving the playhead under somebody with no visual cue that it happened is the worst of them. At launch nothing is playing, so there is nothing to disturb. The cost is that a change made elsewhere while Cast is open does not appear until next launch; the promise being kept is that your place is right when you sit down.

Nothing in the folder says what you listen to. Every episode is identified by a hash of its feed’s own GUID, so somebody with access to the folder learns how many things you listen to and roughly when, and nothing about what. Episode names are a separate switch, on by default because a message that says “you and your phone disagree about Episode 214” is worth far more than one that reads out a hash – and off for anybody who would rather the folder learned less.

The format is written down in docs/engineering/listening-places-spec.md, with JSON conformance fixtures both implementations test against, so two apps cannot quietly drift into disagreeing about somebody’s data.

Share the moment, not the file

Cast could copy an episode’s audio address and save its audio to a file. Neither of those is what somebody means when they say listen to this bit.

Share This Moment (any episode’s menu) copies two things at once: a link that reopens the episode at the second you shared it from, and a plain English sentence saying the same thing – “Blind Abilities, Episode 214, at 41 minutes 12 seconds”. The sentence is not an afterthought. A link nobody can open is worse than a sentence anybody can paste, and the person you are sending it to very often does not have QUILL Cast at all. The sentence works in an email, in a text message, and read down the phone.

The installer registers quill-cast:// so a link opens the app at the right place. Opening one is treated as what it is – somebody else’s input – so it resolves to a feed address and an episode GUID, both of which are looked up in the library you already subscribe to. A link for a podcast you do not follow says so and does nothing. Cast never fetches a web address because a link asked it to, and never adds a subscription because a link asked it to.

A second podcast directory

Add Podcast has searched Apple’s directory and nothing else. Apple’s is a good default – free, keyless, and it indexes very nearly everything – but it knows nothing about the Podcasting 2.0 tags Cast has built a great deal on: chapter documents, transcripts, marked moments, credits, funding.

Podcast Index does, because it is the index those tags were defined for. Add Podcast now has a Directory picker: iTunes, Podcast Index, or both. Searching both merges the results by feed address and says where they came from – “12 results: 9 from iTunes, 3 from Podcast Index” – and a directory that fails does not fail the search: you get the results that did arrive, and a sentence about the one that did not.

Podcast Index needs a free key, which is why iTunes stays the default and why the option is simply absent until you add one (Subscriptions > Podcast Index Credentials…). The key and secret go into Windows’ own credential store, never into a settings file, and they are scrubbed out of crash reports.

Look before you subscribe

A search result is a title. Subscribing to a title is how you end up unsubscribing from a title.

Preview (and Enter on a result, which now previews rather than subscribing) opens the podcast read-only first: what it is, who makes it, how many episodes, its own description as text you can arrow through, and its ten most recent episode titles with dates. Between them those answer is this the show I meant, is it still going, and is it in my language. Subscribe is right there when the answer is yes.

Folders you can listen from

Cast has had a folder tree for a long time and has never had a single action on a folder. Forty shows filed into “News” made the list tidier and did nothing whatever for the listening.

A folder’s menu now offers:

A folder always means its whole subtree, everywhere: playing “News” plays what is in “News/Local” too, because that is what somebody looking at the tree means.

The Play Queue can be grouped by folder as well as by podcast (Group by, in the Play Queue). Grouping never changes the play order – only how it reads – and a group header announces itself as one (“News, group, 4 episodes”), so no action can act on a header by accident.

Moving several podcasts at once

Filing was one show at a time, so tidying forty into six folders was forty trips through a picker. Move Several Podcasts to Folder… lists your podcasts in a multiple-selection list – arrows move, Shift and arrow extend, Ctrl and Space toggles – with Select All, a running count, and then the same folder picker once for the lot.

The subscription tree itself is deliberately not multi-select. That would change how every existing selection in it behaves, and multi-select trees are markedly harder to drive with a screen reader, for a job most people do twice in the life of a library.

Smart playlists that can express what you mean

PlaylistRules had six filters and ANDed all of them. That is right for narrowing and useless for the other half of what people want: anything from these three shows, or anything I have bookmarked cannot be said with AND at all.

Smart playlists now also filter on: match all or any, a library folder (subtree aware), downloaded or not, has a note of mine, title or show notes contain, where the playhead is (not started, started, finished – which is genuinely different from the played mark), and at most N episodes, applied after sorting so “the ten newest” is the ten newest.

Beside them is the thing that makes a rule builder usable: “Matches 23 episodes right now”, recomputed as you change the rules. Without it, checking what a filter did meant saving, closing, reopening and reading – four steps to answer did I mean that.

And because a blank rule builder is where most people stop, Add Starter Playlists creates five worth having: Continue Listening, New This Week, Quick Listens, Downloaded and Unplayed, Long Reads. They arrive as ordinary editable playlists rather than built-ins, so renaming, retuning or deleting one works exactly as it does for a playlist you wrote yourself.

Chapters for the episodes nobody wrote chapters for

Most podcasts publish no chapter list. A good many of them do something almost as useful and Cast was throwing it away: they describe their running order in prose.

“high school student Tyler Juranek begins a series of short reviews he calls Techie Tidbits … Next, we visit with Gerry Chevalier about the newest release of the Victor Reader Stream … Finally, Matt Roberts brings us part one of a demonstration on accessing DVR from Dish Network”

That is a running order: four segments, named, in sequence, written by a person. Cast now takes each described topic and finds where in the episode its distinctive words actually arrive, giving chapters whose titles a human wrote and whose times were worked out. Measured against hand-built reference chapter lists, the marks landed within 9 and 15 seconds.

Two details decided the design. The phrases are matched in order, because show notes are written in the order the programme runs, so it is a sequence-alignment problem rather than a series of independent guesses. And a topic anchors where it starts, not where it is densest – a thirty-five-minute interview mentions its guest most often in the middle, and matching on density put one episode’s main segment at 30:00 when it began at 1:09.

Thorough no longer offers to listen for pauses. Measured against those same reference lists, the pause scan scored 0.06 where cutting the episode into equal slices with no knowledge of it at all scored 0.15. An answer worse than dividing by n is not an answer, and offering it by default spent tens of seconds making the list worse. Thorough fetches a transcript and works the sections out of the words; if there is no transcript it says so. Deep still offers the pause scan, because somebody who chose Deep has said they would rather have a weak answer than none, and a recording off the radio still uses it, because for a recording there is nothing else.

Deep can now transcribe an episode on your own machine, which it has always advertised and never actually done. The engine ships in the box – 40 MB, CPU-only – so chapters work the first time you ask, with no download and no network. It was chosen over models thirty-five times its size on measurement: it scored better (0.372 against 0.316) and ran 4.7 times faster, and the reason is not transcription quality at all. Its cues break at natural pauses, so its edges are already plausible section starts.

And every chapters setting now has a control. All six were live and all six were invisible, which is worse than absent: a listener whose chapters were slow, missing, or being worked out when they did not want them to be had no way to find the switch that said so. There is now a Chapters group in Podcast Settings, led by the one question most people will ever want to answer – how hard should I look? – with the consequence of that choice spelled out beneath it in a sentence.

The columns are yours now

This one is a speech setting wearing a display setting’s clothes. An episode list is read out one column at a time, so the columns are the sentence you hear on every row – and that sentence had been chosen once, in code, for everybody. If you work through one show at a time you never needed its name; if you queue by length you wanted the duration first, not third.

Subscriptions > Choose Columns… (Ctrl+Alt+Shift+C) hands it over, for the episode list, for Downloads, and for Add Podcast’s results. There are two lists in the window – what is shown, in the order it is read, and what is hidden – with Move Up and Move Down between them. Not checkboxes: a checkbox in a list is a state your screen reader has to be asked for, while a position is a place you land on, and moving something says where it is now.

Hiding a column takes it out of the row rather than to the end of it, because a screen reader reads every column it is given and “last” is still read. It keeps its place while hidden, so bringing it back later does not send it to the end of a row you already arranged. Underneath, one line reads out exactly what a row will say, so you can hear the effect of a change before pressing OK.

Each list offers more than it shows. The episode list can add Podcast – worth having in the Inbox or a playlist where the rows come from several shows, and pure noise in a list of one show, which is why it is off to begin with – Time Left on an episode you have started, and Downloaded. Add Podcast can add the Feed Address, which is what tells two shows with the same name apart. One column in each list cannot be hidden – the episode’s title, the podcast’s name – and asking to says so, and why.

Change it while the Manager is open and the list rearranges under you there and then. Quill Radio gets the same window on its own lists, from the same code: Quick Actions, listening statistics and folder actions all had to be carried across from one app to the other after being built twice, and this one was shared on the first day.

A first launch that says hello

Three screens on a genuinely first launch: welcome, add your first podcast, you’re set. One window with the words in a read-only text area you can arrow through and copy, and Back / Next / Skip beneath it.

Skip is a first-class button, not a small link. Somebody who already knows what a podcast player is should be able to leave in one keystroke, and making that awkward is a way of insisting they read something they do not need. Skipping counts as done – you chose it, and asking again next launch would be overriding that choice with a guess about what you meant.

It stays away entirely from anybody who already has podcasts, however they got there: an imported OPML, a restored setup, an upgrade. Explaining how to add a first podcast to somebody with two hundred is a way of saying nobody checked.

These screens were written for 1.1 and never once shown, because nothing in the app ever called them. That is the kind of thing tests do not catch: every one of them passed, on a feature nobody could reach.

When something goes wrong, or you change your mind

Everything above is about places Cast could not reach. This part is about moments it handled badly – and none of them are features anybody goes looking for. Each is something Cast owed you and was quietly not paying.

You can take it back

Press Ctrl+Z.

Unsubscribe, Remove All Episodes, Mark All as Played, Remove All Downloads – the last one comes back, and Cast says what came back: “Undid Unsubscribe. Brought back The Daily, with 412 episodes and 3 downloaded files.”

The alternative, and the thing this deliberately is not, was asking you first every single time. A confirmation prompt costs a keystroke and a sentence on every one of the nine hundred occasions you meant it, and it cannot help you on the one occasion that matters – because on that occasion you read the question, thought about a different show, and pressed Yes. The prompt was never protecting you from a slip of the finger; it was protecting you from a slip of attention, which is the thing it cannot see.

Deleted files genuinely come back. A downloaded episode Cast removes on your behalf is moved aside rather than unlinked, so an undo restores the audio rather than the intention to fetch it again. That includes the ones removed for you: if marking a show played fired your delete-after-play rule, those files come back too.

It is one step, not a stack – press Ctrl+Z twice and the second press says “Nothing to undo” rather than quietly rewinding something older. And it says what it cannot bring back: unsubscribing from a private feed deletes the password stored for it, deliberately, so no orphaned secret is left behind, and the offer says the password has to be entered again.

Every action that can be undone ends its announcement with “Ctrl+Z undoes this”, so you never have to remember which ones were on the list.

Recent Problems

Help > Recent Problems… (Ctrl+Alt+Shift+P).

Cast talks. A feed fails, a download dies overnight, and it tells you – once, at the moment it happens. That is right almost always, and completely wrong the one time the sentence went past while you were in another window, or asleep.

This was the one place this app was not built the way the rest of it is. Somebody who can see the screen still had a list to scroll back through. Somebody listening had nothing: the announcement had been made, so as far as the app was concerned the job was done.

Every failure worth a second look is now written down as well as spoken – what failed, why, when, newest first. Retry re-reads the feed or re-queues the download. Copy All takes the list as text for a bug report; it carries addresses and error messages, never passwords. A feed that has failed on each of the last six checks reads as one row with a fresh time, but a different reason gets its own row, because “404 Not Found” and “timed out” are not the same news.

Nothing in this list leaves your computer.

Quiet hours

Help > Quiet Hours… (Ctrl+Alt+Shift+Z), 22:00 to 07:00 by default, and a window may cross midnight.

Inside it, Cast stops speaking on its own: the heartbeat of a feed check, “three new episodes of The Daily”, a download landing.

Three things it does not mean, all of which the window says out loud:

One override, for the one thing people legitimately want through a quiet window: reminders can be let through anyway.

The window is shared with Quill Radio and the rest of the family, so you set it once.

Move your setup to another machine

Help > Export My Setup… (Ctrl+Alt+Shift+X) writes one file; Import My Setup… (Ctrl+Alt+Shift+N) reads it on the other machine.

Inside it: your subscriptions, your folders, your playlists, your settings, your Quick Action order, the confirmations you asked not to see again, your bookmarks, and any keys you rebound.

OPML has always moved subscriptions and nothing else – the part that was easy to standardise, leaving behind the part you had actually built.

The file is an ordinary ZIP with a readable manifest, deliberately: you should be able to see what you are carrying between machines. It holds a declared list of files rather than whatever happens to be in the data folder, because a sweep of a folder eventually carries a cache, a lock file, or a credential nobody meant to move.

Passwords are not in it, and the confirmation says so before it acts. Importing replaces what is on the other machine rather than merging with it, and says that too: merging two libraries is a different job with different questions.

Your place follows you into Quill Radio, and back

Both apps can play the same subscribed episode. Until now half an episode heard in Radio reached Cast at Cast’s next launch – the one moment you are least likely to be mid-episode – and nothing went the other way at all.

They now share one place per episode on this computer, written when you pause as well as on stop, switch and shutdown. Open an episode you were part-way through in the other app and it picks up where you left off, and says so.

The later decision wins, not the furthest through the episode. Somebody who skipped to the outro to check something and went back to the middle has decided the middle is where they are; an app that dragged them forward again on the grounds that it was further in would be overruling them with arithmetic. An episode either app has finished stays finished.

Find an episode inside one show

The episode list has a Find box beside its filter.

There was a filter by state and there was Search Everywhere across the whole library, and nothing in between – so which episode of this show was the one about the harbour had no answer except arrowing two hundred rows.

It matches titles and show notes, because a podcast that numbers its episodes and describes them in the notes – most interview shows – is exactly the one a title-only search cannot help with. It narrows what the filter and sort already chose rather than replacing them, so “unplayed episodes about the harbour, newest first” is three controls you set independently.

Typing narrows the list quietly, so nothing talks over you. Enter says how many matched out of how many were searched. A search that found nothing says so and tells you the filter above may be the reason, rather than announcing a zero and leaving you to work out why.

Skip Silence, while you are listening

Ctrl+Shift+9.

Cast has had this as Smart Speed for a long time – a per-show setting in Podcast Settings. What it did not have was any way to reach it while an episode was playing, which is the only moment anybody forms an opinion about it. It applies to the playing show (or, with nothing playing, to every podcast), takes effect on the episode in progress, and keeps your place: somebody forty minutes in who turns it on is not sent back to the beginning to get it.

Quill Radio gained the same key for the same thing.

Go to Position

Ctrl+Alt+J, or Episode > Go to Position…

Cast could already jump to a typed time – from a Winamp letter key, which means it existed for whoever had those keys turned on and knew about them, and for nobody else. It is a menu item and a command palette entry now, over the same labelled Hours / Minutes / Seconds window Quill Radio opens.

1:02:03, 62:03 and 3723 all mean the same moment, in both apps. They did not: the two apps had two parsers that disagreed about what you could type.

Smaller things that were quietly wrong

F1 answers with Cast’s own words. Press F1 anywhere and the help opens with what that window is for, the way Quill Radio’s has since its 3.0. Every Cast window had been answering with a generic sentence: true, and useless. A build gate now means a new Cast window cannot ship without one.

A dimmed menu item tells you why. Cast dims a great deal on purpose – Analyse Chapters on an episode whose audio is not here yet, Mark All as Played with nothing unheard – and a screen reader says “dimmed” and stops. Each now carries its reason: “Analyse Chapters: this episode is not downloaded yet, so there is nothing to analyse.” Pressing a Quick Action number on a dimmed row says the same rather than “that Quick Action is not available”, and so does the command palette.

Adding a podcast you already follow says which one, out loud, and goes to it. The refusal was a line of text in the dialog, which a screen reader does not read when it changes – so in practice it was nothing happening. It now names the show, announces it, and moves the Podcast Manager’s cursor to the row you already have.

Pause All Downloads says how many are waiting, and that the one already transferring will finish.

Smaller things that were missing

Six things Quill Radio had and QUILL Cast did not

Two apps, one audience, and a list of small things that had only ever been built once. None of them are new ideas – they are all Radio’s, brought across where the reasoning applies equally to podcasts.

A Keyboard Shortcuts Sheet (Ctrl+Alt+Shift+K). Cast had the shortcuts editor, which is for changing a key you can already name. The sheet is for finding out which keys exist. It is generated from the menus you actually have, so it includes anything you rebound and cannot go stale, and a filter box narrows 130 rows to the eight about recording – or downloading, or chapters.

Go To (Ctrl+G). A short numbered list of places – Podcast Manager, Continue Listening, Play Queue, Downloads, Bookmarks, Statistics – where the numbering never moves. That is what makes it different from the Window menu, which renumbers itself every time something opens. You choose which ten places are on the list and in what order; anything a later release adds lands in a pool rather than in your menu, so an update cannot renumber what you have learned. Cast’s only “Go To” until now jumped to a time inside an episode, which is a different feature that happens to share two words.

Something to say when FFmpeg is missing. Cast needs it for four things: trimming silence off a download, evening out its volume, working out chapters for an episode that has none, and Sound Enhancements while playing. Every one of them fails by producing a plausible result – the download completes and is simply not trimmed; the chapter analysis finishes and finds nothing, which is what an episode with no chapters looks like. So it is now said once at launch, naming what is lost, and silence means all is well. Help > Media Tools (Ctrl+Alt+Shift+M) answers the same question whenever you ask.

Three answers to closing the window. Cast exited, and had one narrow escape from it in the Alt+F4 checkbox – so the titlebar X ended an hour of listening with no way to say otherwise. Preferences now carries When closing the window: Ask every time, Exit, or Minimize to Tray. Exit stays the shipped answer, because an upgrade that starts asking a question has changed your Alt+F4 under you. Ask only asks when there is something to lose, and names it: “An episode is playing and 2 downloads are in progress.”

Search Everywhere remembers. The box is a combo now: press the down arrow for the last fifteen searches, newest first, and choosing one runs it. The episode about the harbour is a thing people look for several times across a week, from a different place in the library each time.

Back Up My Podcasts (Ctrl+Alt+Shift+B) and Restore from a Backup (Ctrl+Alt+Shift+R). Cast had Export My Data – a readable snapshot you can look at but cannot put back – and the shared setup transfer. Neither is a restore, and Cast’s library is the more painful of the two apps’ to lose: subscriptions, folders, playlists, positions, notes and statistics are years of accumulated choices, where a station list can be rebuilt from a directory in an afternoon. The backup is one file; downloaded episodes are optional and left out by default, because they are the part that can always be fetched again. A restore names the date and the size of what it is about to put back before it does anything, stops playback first, and leaves your library live without a restart.

And one thing Earshot had

Three per-show settings you can reach in one keystroke. How many downloads to keep, how long an episode waits in the queue, and how fast this particular host talks are the settings people change over and over – and each of them lived in a window of two dozen controls. Each now has its own row on a show’s context menu, opening a window with one control and the cursor already in it. They are Quick Actions too, so if you adjust speed constantly you can put Playback Speed first and reach it with Ctrl+1.

One fix worth naming

Ctrl+Shift+P opened nothing, in every window. The Command Palette key rides the shared transport keyboard that both QUILL Cast and Quill Radio install on every window, and it resolved to nothing in either app: the palette belongs to the window, and the key was only ever asking the player. It was silent about it, which is why nobody reported it – a key that quietly does nothing looks exactly like a key that was never bound. It opens the palette now, from anywhere.

The reason it went unnoticed for so long is worth writing down too: every test either app had was an app’s test, and this was broken in both, identically, for the same reason. There is now one that walks the shared table verb by verb and asks whether each app can actually perform it.


The app teaches itself

Help > Tutorials… (Ctrl+Alt+F1) opens 24 guided tutorials – 149 steps, a little over two hours of material – covering every feature QUILL Cast has, in the order somebody would actually learn it. A fifth track, One podcast at a time, arrived with the per-podcast settings: how a setting is decided, what arrives and when, what every row says, how to fix a podcast that reads badly, and who is allowed to interrupt you.

They are not a second copy of the user guide. A guide answers “what does this do”. It cannot answer “what do I do now”, because a document cannot see what you have already done. This window can.

What the set is shaped like

Four tracks, and the shape of them is the shape of the problem.

Your first hour (3 lessons) – subscribe by search, by feed address, by OPML or by taking ACB Media’s whole directory in one step; work the player; meet the Podcast Manager, which is where episode-level life happens and where most people never go until somebody shows them.

Keeping up (5 lessons, and the longest track on purpose) – the hard part of podcasting is not playing an episode, it is deciding which of the four hundred waiting ones you will play. Finding what is new, triaging with the Inbox, lining up the Play Queue, automatic downloads and the caps that keep the disk honest, and playlists both hand-built and rule-based. These are one system and they only make sense together, which is why they are one track rather than five scattered pages.

Listening well (5) – chapters and skipping the parts you did not come for, shaping the sound, keeping a moment, reading what the publisher actually sent, and how much of your life this has taken.

Making it yours (5) – a library that has grown, what a row says and what Enter does, the settings that differ per show, private feeds and audio of your own, and the backup you will be glad of exactly once.

The three things that make it more than a document

A step names a command, not a key. The key is rendered when the step is drawn, from your own keymap, so a rebinding changes every lesson that mentions it. It is the same rule that makes the Keyboard Shortcuts Sheet trustworthy: a second list of keys, maintained beside the first, is a list that is wrong by the next release.

Try it runs the step, exactly as its key would – so a lesson can open the Podcast Manager for you and then talk you through what you are standing in.

Follow me notices when you have done one. While a lesson is open the window asks the app, once a second, the question the step declared – did your subscriptions grow, is something playing, did the queue change – and when the answer changes it says what it noticed and reads the next step:

Done: you have a new subscription.

Subscribe to your first podcast – step 4 of 8: Or bring a whole library across…

It watches state, not keystrokes, so subscribing from the menu, the palette or the Add Podcast window all count equally. It compares against a baseline taken when the step was shown, so somebody with forty subscriptions has not already passed “subscribe to one”. And anything it cannot read answers “cannot tell”, which the window treats exactly like a step with no check on it.

Nothing is graded, nothing is blocked, there is no score and no streak, and every step still has Next. A check that never comes true costs you one keypress.

It is a window, not a wizard

The Tutorials window is a real window. Leave it open, move to the app, do the step there, and hear the lesson move on behind you. A modal wizard could not do that: it would own the keyboard for the whole lesson, which is precisely the wrong shape for teaching somebody to use the thing underneath it.

Typing here in the filter box narrows the contents to the tutorials about the window you came from, and the window says how many those are as it opens.

Your place is kept

Close a lesson half way through and it opens there again. Finishing one is remembered separately from where you are in it, so re-reading something you have done does not throw away the fact that you did it. Forget my progress clears the lot, asks first, and changes nothing else. Nothing about your progress leaves this computer – there is no telemetry here and no completion badge.

Reading rather than doing

Read it all shows a whole tutorial as one page of text. The whole book as a document opens all 18 as one page, generated from the same lessons the window teaches from, so the two cannot disagree – it ships as tutorials beside this document. (The book states the keys QUILL Cast ships with. Only the window can know the ones you rebound.)

The same window in every app

Quill Radio, Quill Weather and QUILL have their own lessons, in the same window, on the same key: Ctrl+Alt+F1 opens the tutorials wherever you are in the family. Each app keeps its own progress file, because a lesson slug is only unique within its own set and forgetting your place in one app must never forget it in another.

For anybody keeping score on the format

listening-places/1 is deliberately not a QUILL thing. It is documented, versioned, and small enough to implement in an afternoon; the identity scheme is the only part that is hard to change once data exists in the wild, which is why it is the part the specification is most careful about. If you write a podcast app and want your users’ places to travel to and from QUILL Cast, the whole of what you need is in docs/engineering/listening-places-spec.md and the fixtures beside it.