Repository navigation
A quiet spell: no breaks for the next few records #8
Replies: 2 comments
|
Status check, 2026-09-22 (main at 23b983e) Shape 1 is built (0ed2394): the |
|
Closing: all three phases are built, in #768, and the
One departure from phase 1, on this discussion's own point about units. The open question is answered with the default: the quiet survives a stand-down and a fresh broadcast. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Status (2026-10-10)
The bug this was opened for is fixed. Removing a break from the running order leaves a
removeditem in place rather than splicing it out (0ed2394), so the planner's walk counts from it and does
not plant a replacement a boundary later.
DirectorService.collectRemovedfails the segment rowbehind it with a reason,
committedThroughno longer reads a cut as the committed head,StationItemStategained the arm through the.ck, the SDK and the stored-row validator, and theconsole draws a removed row grey.
retireSegmentsindirector/director.service.tsis now the oneretirement every edit that drops a break goes through.
A MOVED break was left alone on purpose: it is still in the order, so filling the gap behind it is
the planner answering a true order rather than forgetting an edit.
What is left is the quiet spell below, and the
rotation.breaks-off-mid-air wart it settles. Neitheris built.
deadair.station_airhas no quiet column (only 0007 and 0046 touch it), there is no/station/quiet, andBreakPlanner.plantstill returns early on!rules.breakswhile the breaksalready planted in the tail go on to air.
What it is
A suppression the operator sets, expressed in records rather than in items ("no breaks for the next
hour" or "the next N records"). Independent of the running order, so it survives an extend and a
regenerate, and it is what the listening session that found the removal bug actually wanted. Wants a
home:
deadair.settingsis wrong for something with an expiry, and the lineup's ownStationLineupRulesoverrides are right for "this lineup" but not for "for a while".What it is for
The failure mode of
rotation.breaks = falseis not that it fails to work, it is that it has noexpiry. An operator turns it off for an album and the station never says its own name again until
they remember. Every property below follows from that one: the operator's standing preference is
left untouched, and the quiet ends by itself.
Records, not the wall clock
The ask offers both. What the audience gate rules out is the CLOCK: in
audiencemode astation nobody is connected to is silent on purpose, so a wall-clock hour spent with no listeners
burns the whole suppression in silence and the operator comes back to a talking station. A count of
records only advances while somebody is hearing them, which is why it was chosen.
The grain argument this once rested on has moved, and it is worth knowing which way. Spacing was
counted in records when this was written, so records were also what everything else here was cut on.
It is now
breakEveryMinutes, and the minutes it counts are AIRTIME (the durations of the items inthe order, never the wall clock), so the property that rules out an hour of silence is one both
units have, and the audience gate no longer decides between them. What is left is the reconciliation
this paragraph wanted to avoid: a suppression in records beside a spacing in minutes has to be
converted at the one place they meet, which is the walk that lifts the quiet. Whoever builds this
should count both in the same unit, and the planner's is the one with a setting behind it. The
console can still SAY either from the order's own durations, because saying it is presentation.
Where it lives:
deadair.station_airThe two homes the note rules out are ruled out for good reasons, and this is what is left. That row
holds the one fact about the BROADCAST rather than about the programming or the station's
configuration, which is exactly what a quiet spell is. One integer column beside
active(
breaks_quiet_records,0meaning not quiet), andStationAirRepositorygrows a writer for itwhile
getreturns it.Stored rather than held in the director's memory, by the argument that made
activea column: anapp restarted mid-quiet must not come back talking.
deadair.settingsis also the thing a quiet spell must not touch. Writingrotation.breakstoexpress "quiet for ten records" would silently rewrite the standing preference it exists to leave
alone.
Where it decrements:
DirectorService.rememberIt already hangs off the rundown's confirmation that a record actually STARTED rather than off the
commit lead, and it already drops segments through
isRenderItem. That is precisely the filter thecountdown needs, for the same reason: a break the station airs is not a record the listener is
counting. One
set breaks_quiet_records = greatest(0, breaks_quiet_records - 1)on a path thatalready writes a row per record, and it may fail as harmlessly as play history does.
What being quiet does
Three behaviours, and only the first is obvious.
plantreturns early. One more clause besideif (!rules.breaks). Note that the intervalitself is no longer part of that guard:
breakEveryMinutes <= 0now only stands the station'sown spacing down inside
slotsFor, and leaves the operator's clock bands planting on their ownschedule. So a quiet spell has to be checked where breaks are turned off wholesale rather than
where the floor's interval is read, or an anchored bulletin will air through it. Cheap, and by
itself not enough.
at the moment quiet is asked for there are already three or four breaks laid out across the next
hour. Without this, "no breaks for the next ten records" is not heard until the tail runs out,
which is the same defect logged below against
rotation.breakstoggled off mid-air. Onemechanism settles both.
ripenonly offers what is still in the order.The committed head is untouched throughout. A break already handed to the player airs, quiet or not,
for the same reason an operator cannot remove one.
The retirement SPLICES rather than marking
removed, and the asymmetry with an operator's cut isthe load-bearing part.
removedmeans "this slot is cut, do not refill it", and it works byresetting the planner's count where it sits. A suppression is the opposite instruction: withdraw the
whole break structure now, and rebuild it from scratch when the quiet ends. Leave
removedmarksacross the tail and the walk counts from the last one when it lifts, so the station stays quiet for
an interval beyond what was asked and by an amount nobody can predict from the number they typed.
Splicing is safe here for the reason it was unsafe in the removal bug: nothing
replants while
plantis gated, and when the gate opens the walk sees a clean tail. The segment rowsgo through the same collection as a cut, and that shared piece now exists:
retireSegments, whichevery edit that drops a break already calls.
What it survives
An extend, a regenerate and a restart, deliberately: it is a fact about the room rather than about
the hour of programming that happened to be loaded when it was asked for. That is what makes it not
a lineup rule.
One open question, and the default is to survive: a stand-down followed by a fresh
putOnAir.Keeping it costs an operator who wanted a clean start one confused minute; dropping it costs the
operator who stopped the station to change playlists their quiet. Both are small, and the count
expires either way.
Surface
A command, like everything else that touches the order (
{ kind: 'quiet'; records: number }throughDirectorMailbox), so it serialises against the commit pass rather than racing it.POST /station/quietandDELETE /station/quietin the.ck, andStationAirgainingquietRecordssothe console can draw it.
On the console, a control beside Stop offering something like 3 / 10 / rest of the order, and the
on-air header reading "quiet for the next 8 records" with a cancel. A station that has silently
stopped talking and a station that is quiet on purpose look identical otherwise, which is the same
class of problem the
removedbadge fixed.Phases
plantreads it,rememberdecrements it. Works end to end; the quiet takes up to one interval to be heard,because the planted tail still airs.
rotation.breaksturned off mid-air, which stops being adocumented wart in the same commit.
Each is one commit and one sentence, and 1 is usable without 2.
Also worth settling with it
rotation.breakstoggled off mid-air does not retire breaks already planted. The plannerreturns early, so nothing new goes in, but the ones already in the tail still air. That is
defensible (they are programmed, and the head is committed anyway) but it is not what an operator
who just switched breaks off expects to hear, and it is undocumented either way. Settled by
phase 2 of the quiet spell, which needs the same withdrawal and should do both from one place
rather than growing a second one later.
station will not talk again until N records from now" is the whole of this bug's user-visible
half.
All reactions