--- key: sched.clock-padding-schedule-toggle title: 2026-07-22 — per-schedule clock-boundary padding is a synthetic content-less Pad over the existing per-episode machinery (#392) status: active since: '2026-07-22' supersedes: none superseded-by: none rule: A `ProgramSchedule.PadToNearestMinute` (nullable int; null = off) makes the Classic builder pad every content item up to the next N-minute clock boundary without a hand-wired Pad `FillerPreset`, by reusing the existing per-content-item Pad path in `PlayoutModeSchedulerBase.AddFiller`. It extends — does not supersede — `sched.clock-padding-existing` (#77/#388). signals: 'per-schedule clock padding, PadToNearestMinute on ProgramSchedule, offline gap on pad, ClockPadOfflineTarget, synthetic Pad without FillerPreset · paths: `PlayoutModeSchedulerBase.AddFiller`, `PlayoutSchedulerResult.ClockPadOfflineTarget`, `FallbackFillerForPad`, `/app/schedules` · issues: #392, #77, #388' mechanics: '`PlayoutBuildGoldenTests` (One/Flood/Duration/Multiple clock-pad cases), midnight-crossing invariant tests' --- A `ProgramSchedule.PadToNearestMinute` (nullable int; null = off) makes the Classic builder pad every content item up to the next N-minute clock boundary WITHOUT a hand-wired Pad `FillerPreset`. It reuses the existing per-content-item Pad path (`PlayoutModeSchedulerBase.AddFiller`, already called once per emitted item): a self-contained synthetic branch engages only when the item has no own `FillerMode.Pad` filler (the item's Pad wins — no double-pad) and the parent schedule declares a positive divisor. The gap fills with the schedule item's `FallbackFiller` via the existing `FallbackFillerForPad`; when no fallback content exists, the branch records an offline target and the four schedulers advance `PlayoutBuilderState.CurrentTime` to the boundary, leaving an implicit offline gap (the same representation fixed-start items use — absence of a `PlayoutItem`, rendered as "Channel is Offline" at stream time). That advance is carried by a transient per-build `PlayoutSchedulerResult.ClockPadOfflineTarget` (never serialized — no anchor schema, no migration); the day-seam anchor clamp is exempted by exact equality with that target. This is the per-schedule convenience layer deferred behind #388 in `sched.clock-padding-existing`; that record's per-item Pad-preset behavior is unchanged. Determinism needs no new anchor/seed state (the pad math is a pure function of offsets). Coverage is per-scheduler-mode (One/Flood/Duration/Multiple) via golden and invariant tests across midnight crossings. The SPA schedule editor exposes it as a 5/10/15/30/60 minute picker; TZ-independence holds only for divisors of 60. See #77 (prior art) and #392.