CU-06: Availability engine: weekly rules, overrides, holidays, slot-debug
Priority: P0 Accounts/sessions: P1 host (ravikantguptaofficial@gmail.com) signed into Calendo at https://calendo.dev/dashboard/ via persisted session. No invitee account needed — bookings/L3 not in scope for this suite. Parallel-safe: No. Exclusive (rewrites global host availability?): YES. This suite rewrites P1's GLOBAL default weekly schedule ("Working Hours") plus its overrides/holidays/meeting-limits, which changes slot availability for every host-writing suite. It MUST run alone, and MUST restore the documented baseline at the end (see Cleanup). Estimated time: 35 minutes L3 reality checks: None. All assertions are [L1] UI / [L2] Calendo persistence + slot-debug API. No Google/Outlook calendar or Gmail verification is required for this suite. (Slot-debug reasons 8 google_calendar and 9 outlook_calendar are NOT exercised here — see Manual residue.)
Goal
This suite proves Calendo's availability engine correctly governs which times a public invitee can book. A host sets a known weekly recurring schedule (Mon–Fri 09:00–17:00) and the public booking page must offer ONLY those windows; a date override that blocks a weekday must zero out that day; an override that opens a normally-off day (Saturday) must surface slots; an enabled holiday preset must auto-block the holiday date; per-event-type buffers and min-notice must shrink the offered slots; multiple named schedules must drive different event types independently; and the /api/slot-debug endpoint must explain WHY any specific time is unavailable across its nine reason codes. This is the core scheduling correctness guarantee — if it's wrong, the product double-books or hides valid times. Because it rewrites the host's global schedule, it is the canonical "exclusive" suite that all other host-writing suites depend on for a clean baseline.
Preconditions
- The browser has P1 logged into Calendo with an active dashboard session. Load https://calendo.dev/dashboard/ — the app shell (
#appLayout) and#welcomeHeadermust be visible. If you land on a login screen or the onboarding wizard (#calendarOnboarding) blocks the dashboard, do NOT attempt a cold login — FLAG it as a precondition failure per00-setup-preconditions.mdand STOP. - P1 must already have at least one event type. The default account ships with "30 Minute Meeting" (slug
30-minute-meeting). If no event type exists, FLAG and STOP (creating the baseline is out of scope here). - P1's default schedule is named "Working Hours" and is the
is_defaultschedule. Confirm it exists in the#scheduleSelectdropdown on the Availability tab. If it is missing, FLAG (do not improvise a new default). - BEFORE changing anything, capture the CURRENT baseline so Cleanup can restore it exactly (see Step 1). This suite assumes the documented baseline is Mon–Fri 09:00–17:00, America/Los_Angeles (40.0 hrs/week). If the live baseline differs, record the live values and restore THOSE at the end, and note the discrepancy in evidence.
- No other host-writing suite may run concurrently. If the orchestrator cannot guarantee exclusivity, FLAG and STOP.
Test data
RUNID convention: pick one fresh UTC token at execution start, format YYYYMMDD-HHMM (example 20260601-1530). Embed RUNID in every created artifact so reruns never collide.
- Holiday preset country/year: United States (
#holidayCountryvalueUS), year = current year 2026 (#holidayYear). - Multi-schedule name:
Eve-<RUNID>(e.g.Eve-20260601-1530), timezoneAmerica/New_York. - Multi-schedule event type name:
EvtSched-<RUNID>(slug auto =evtsched-<runid>), duration 30 min. - Buffer/min-notice test event type name:
Buf-<RUNID>(slugbuf-<runid>), duration 30 min, buffer before 30, buffer after 30, min notice 48h. - Override BLOCK target: the first Wednesday at least 7 days from today (a normally-open weekday). Compute and record as
BLOCK_DATE(YYYY-MM-DD). - Override OPEN target: the first Saturday at least 7 days from today (normally closed). Record as
OPEN_DATE, hours 10:00–12:00. - Reference slot for slot-debug probes: use a known-open Tuesday ~14 days out at 14:00 in
America/Los_AngelesasDEBUG_OK_TIME(ISOYYYY-MM-DDT14:00:00). - Host slug
HOST_SLUG: read from#bookingLinkValueon the dashboard (the part afteruser=). Record it; you will need it for booking-page URLs and slot-debug calls.
Steps
Order matters throughout: each phase mutates the schedule, so you must capture the original baseline FIRST (Step 1), then run phases sequentially, then restore in Cleanup. Several saves auto-persist (overrides) while others require an explicit Save button (weekly rules, holidays, meeting limits) — follow exactly.
Phase A — Establish and verify the known weekly schedule
- Action: Go to https://calendo.dev/dashboard/, click the sidebar "Availability" link (
.sidebar-nav a[data-tab="availability"]). Confirm panel#panel-availabilitygets classactive. Ensure the "Schedules" sub-tab is active (.avail-sub-tabwith text "Schedules"; its panel#avail-panel-scheduleshas classactive). In#scheduleSelect, confirm "Working Hours" is selected. Read and RECORD the current state for cleanup: the day circles that are active (#weeklyScheduleEditor [data-day-circle].active), each day's time-select values (.avail-time-selectdata-name="start-N-0"/end-N-0), the value of#totalWeeklyHours, the timezone shown in#scheduleTimezoneDisplay, plus any items in#overridesList,#meetingLimitsList(Advanced settings sub-tab), and#holidaysList. Expect: You can see and record a complete baseline snapshot. Capture screenshot:cu06-01-baseline. [L2]
- Action: Set the schedule to exactly Mon–Fri 09:00–17:00 and weekends off. In
#weeklyScheduleEditor, for each weekday Mon(1)–Fri(5): ensure its circle ([data-day-circle="1"]…[data-day-circle="5"]) isactive; if a day shows "Unavailable", click its circle to enable it (defaults to 09:00–17:00). For each weekday confirm the first window's start select (.avail-time-select[data-name="start-N-0"]) =09:00and end (end-N-0) =17:00; if a day has extra windows, remove them via the window's×([data-remove-window="N-i"]). Ensure Saturday(6) and Sunday(0) circles ([data-day-circle="6"],[data-day-circle="0"]) are NOT active (click to disable if they show times). Expect: Mon–Fri each show one 09:00–17:00 window; Sat/Sun show "Unavailable";#totalWeeklyHoursreads40.0 hrs/week. Capture screenshot:cu06-02-weekly-set. [L1]
- Action: Click "Save Schedule" (
#saveScheduleBtn). Wait for the toast "Schedule saved". Expect: A success toast appears; button returns to label "Save Schedule". [L1]
- Action: Reload the page (F5), navigate back to Availability, confirm "Working Hours" selected. Expect: Mon–Fri still 09:00–17:00, Sat/Sun off,
#totalWeeklyHours=40.0 hrs/week— i.e. the save persisted across reload. [L2]
- Action: Open the public booking page in a new tab:
https://calendo.dev/booking/?user=<HOST_SLUG>&event=30-minute-meeting. Wait for#booking-viewto be visible (give the calendar ~1.5s to render). Expect: The month calendar shows weekday cells with class.calendar-day.available(count > 0) and weekend cells with class.calendar-day.unavailable(count > 0). [L2]
- Action: Click the first available weekday cell (
.calendar-day.available). Expect: Time slots (.time-slot) appear; the earliest visible slot corresponds to 09:00 host time (rendered in the invitee's timezone) and the latest fits before 17:00 (a 30-min event => last start 16:30 host time). Hover/read a couple of slots to confirm they fall inside 09:00–16:30 host-equivalent. Capture screenshot:cu06-03-booking-weekday-slots. [L2]
- Action: Navigate the booking calendar to land on a Saturday or Sunday cell. Expect: Weekend cells carry
.calendar-day.unavailableand NOT.available; clicking does not surface.time-slotelements. [L2]
Phase B — Date override that BLOCKS a weekday
- Action: Back in the dashboard Availability "Schedules" sub-panel, in the date-override mini calendar (
#overrideCalendar), use the nav arrows ([data-cal-nav="1"]) to reach the month containingBLOCK_DATE, then click that day cell ([data-cal-date="<BLOCK_DATE>"]). The override dialog#overrideDialogopens. Expect: Dialog title "Add Override";#overrideDialogDateshows the long-form date ofBLOCK_DATE; "Block entire day" (#overrideBlockDay) is checked. [L1]
- Action: Leave "Block entire day" checked and click "Save Override" (
#saveOverride). Expect: Toast "Override saved" (overrides auto-save via PUT). TheBLOCK_DATEcell in#overrideCalendarnow shows the blocked styling (classhas-override), and#overridesListlists the date with a "Blocked" badge (.avail-override-blocked). Capture screenshot:cu06-04-block-override-saved. [L1]
- Action: Reload the booking page tab at
...&event=30-minute-meeting, navigate to the month ofBLOCK_DATE, and locate that date's cell. Expect:BLOCK_DATEis.calendar-day.unavailable(not.available); clicking it surfaces no.time-slot. The surrounding weekdays remain available. Capture screenshot:cu06-05-booking-block-date. [L2]
Phase C — Date override that OPENS a normally-off Saturday
- Action: In
#overrideCalendar, reach the month ofOPEN_DATE(a Saturday) and click its cell ([data-cal-date="<OPEN_DATE>"]). In the dialog, UNCHECK "Block entire day" (#overrideBlockDay) — the custom-hours block (#overrideCustomHours) appears. Set#overrideStart=10:00and#overrideEnd=12:00. Click "Save Override" (#saveOverride). Expect: Toast "Override saved";OPEN_DATEcell shows custom-hours styling (classhas-override-custom);#overridesListshowsOPEN_DATEwith "10:00 AM - 12:00 PM". [L1]
- Action: Reload the booking page, navigate to the month of
OPEN_DATE. Expect:OPEN_DATE(a Saturday, normally closed) is now.calendar-day.available. Click it;.time-slotelements appear, bounded by 10:00–12:00 host time (for a 30-min event, exactly four starts: 10:00, 10:30, 11:00, 11:30 host time). Capture screenshot:cu06-06-booking-open-saturday. [L2]
Phase D — Holiday preset auto-blocks a holiday
- Action: In the Availability tab, click the "Advanced settings" sub-tab (
.avail-sub-tabtext "Advanced settings"; panel#avail-panel-advanced-settingsbecomesactive). In the Holidays section set#holidayCountry= "United States" (valueUS) and#holidayYear=2026, then click "Load Presets" (#loadHolidayPresetsBtn). Expect: Toast "Loaded N holidays for US 2026";#holidaysListpopulates with.holiday-toggle-rowentries (e.g. "Independence Day", "Thanksgiving Day", "Christmas Day"), each with an enabled toggle ([data-toggle-holiday]). [L1]
- Action: Identify an UPCOMING US holiday at least a few days out (e.g. Independence Day 2026 =
2026-07-04, or the next holiday after today). Confirm its toggle is ON (checked). Click "Save Holidays" (#saveHolidaysBtn). Expect: Toast "Holidays saved". RECORD which holiday date you will assert asHOLIDAY_DATE. Capture screenshot:cu06-07-holidays-saved. [L1]
- Action: Switch back to the "Schedules" sub-tab; in
#overrideCalendarnavigate to the month ofHOLIDAY_DATE. Expect: TheHOLIDAY_DATEcell shows blocked styling (classhas-override) with a tooltip "Holiday: <name>" (holidays render red even without an explicit override). [L1]
- Action: Reload the booking page, navigate to the month of
HOLIDAY_DATE. Expect:HOLIDAY_DATEis.calendar-day.unavailable; no.time-sloton click — the holiday auto-blocked the day. Capture screenshot:cu06-08-booking-holiday-blocked. [L2]
Phase E — Buffer + min-notice interaction (per-event-type)
- Action: Create a dedicated event type so buffers/min-notice don't pollute the default. Go to the dashboard Overview (sidebar "Overview"), click "+ New" (
#overviewCreateEtBtn); the edit modal#editEtModalopens. Set#editEtName=Buf-<RUNID>,#editEtDuration= 30. Open the "Limits & Buffers" section and set#editEtBufferBefore=30,#editEtBufferAfter=30,#editEtMinNotice=48. Leave its availability schedule = default ("Working Hours") via#etSchedule. Click the save button (#editEtSaveBtn, labeled "Create"). Expect: Modal closes;Buf-<RUNID>appears in#overviewEventTypes. Record slugbuf-<runid>. [L1]
- Action: Open
https://calendo.dev/booking/?user=<HOST_SLUG>&event=buf-<runid>. Expect: Because min-notice is 48h, all slots within the next 48 hours are suppressed; the earliest bookable day/time is ≥48h from now. Compare against the30-minute-meetingpage (default 4h notice) opened side by side: theBuf-<RUNID>page offers strictly FEWER near-term slots. [L2]
- Action: On the
Buf-<RUNID>page, pick any open weekday and inspect its.time-slotlist. Expect: With 30-min buffers before/after, adjacent slots are spaced so a booked slot would block its neighbors; the slot grid is sparser than the buffer-free default event. (Exact count depends on existing bookings; the key assertion is fewer slots than the no-buffer default for the same day.) Capture screenshot:cu06-09-buffer-minnotice-slots. [L2]
Phase F — Multiple schedules drive different event types
- Action: Go to Availability → "Schedules" sub-tab, click "+ New Schedule" (
#createScheduleBtn); form#newScheduleFormappears. Set#newScheduleName=Eve-<RUNID>,#newScheduleTimezone=America/New_York. Click the form's "Create" submit (#scheduleCreateForm button[type="submit"]). Expect: Form hides;#scheduleSelectnow contains and has selectedEve-<RUNID>; the new schedule starts empty (all days "Unavailable",#totalWeeklyHours=0.0 hrs/week). The "Delete Schedule" button (#deleteScheduleBtn) is now visible (non-default). [L1]
- Action: With
Eve-<RUNID>selected, enable a DISTINCT window: click the Wednesday circle ([data-day-circle="3"]) to enable, set its window to start18:00/ end21:00(.avail-time-select[data-name="start-3-0"]/end-3-0). Click "Save Schedule" (#saveScheduleBtn). Expect: Toast "Schedule saved";#totalWeeklyHoursreflects 3.0 hrs/week. [L1]
- Action: Create an event type bound to this schedule. Overview → "+ New" (
#overviewCreateEtBtn); set#editEtName=EvtSched-<RUNID>,#editEtDuration= 30, and set#etScheduletoEve-<RUNID>. Click "Create" (#editEtSaveBtn). Expect: Modal closes;EvtSched-<RUNID>appears in overview. Record slugevtsched-<runid>. [L1]
- Action: Open
https://calendo.dev/booking/?user=<HOST_SLUG>&event=evtsched-<runid>and navigate to an upcoming Wednesday. Expect: Only Wednesdays offer slots, and those slots fall in the 18:00–21:00 New York window (rendered in invitee tz), NOT the default 09:00–17:00 LA window. Cross-check: the30-minute-meetingpage still shows Mon–Fri 09:00–17:00 LA — proving the two event types use independent schedules. Capture screenshot:cu06-10-multi-schedule-booking. [L2]
Phase G — Meeting limits (daily/weekly)
- Action: Re-select "Working Hours" in
#scheduleSelect. Go to "Advanced settings" sub-tab. In Meeting limits, click "+ Add a meeting limit" (#addMeetingLimitBtn). A.meeting-limit-rowappears with type select ([data-limit-type="0"]) defaulting to "Daily" and a max input ([data-limit-max="0"]) defaulting to 5. Leave type "daily", set max =1. Click "Save Limits" (#saveMeetingLimitsBtn). Expect: Toast "Meeting limits saved". [L1]
- Action: Reload the page, return to Availability → Advanced settings → Meeting limits. Expect: The daily-max-1 limit persisted (row present, type "Daily", max 1) — confirming [L2] persistence of the meeting-limits write. (Full behavioral enforcement — a day going empty after 1 booking — is covered by unit tests
tests/unit/worker/availability-meeting-limits.test.js; in-browser we verify persistence and that slot-debug reportsdaily_capwhen applicable in Phase H.) Capture screenshot:cu06-11-meeting-limit-saved. [L2]
Phase H — Slot-debug "why is this time unavailable?" (all 9 reasons)
The endpoint is GET https://calendo.dev/api/slot-debug/<HOST_SLUG>/<EVENT_SLUG>?time=<ISO>&timezone=<TZ>. It returns JSON { slot, date, time, timezone, available, reasons: [{reason, detail}] }. Drive it by typing the URL into the browser address bar (you are authenticated, but this is a public endpoint) and reading the rendered JSON. The nine reason codes the engine can emit are: holiday, date_override, no_schedule, outside_hours, min_notice, max_future, booking_conflict, daily_cap, google_calendar, outlook_calendar.
- Action: Probe an OPEN time. Open
…/api/slot-debug/<HOST_SLUG>/30-minute-meeting?time=<DEBUG_OK_TIME>&timezone=America/Los_Angeles. Expect:"available": trueand"reasons": []. [L2]
- Action: Probe a weekend (no-schedule) time, e.g. an upcoming Sunday 14:00:
…/30-minute-meeting?time=<SUNDAY>T14:00:00&timezone=America/Los_Angeles. Expect:available:false; a reason with"reason":"no_schedule"(detail mentions no availability rules for that weekday). [L2]
- Action: Probe an out-of-hours weekday time, e.g. a normal Tuesday at 20:00:
…/30-minute-meeting?time=<TUESDAY>T20:00:00&timezone=America/Los_Angeles. Expect:available:false; reason"outside_hours"(detail cites scheduled hours 09:00-17:00). [L2]
- Action: Probe the BLOCK override date at 14:00:
…/30-minute-meeting?time=<BLOCK_DATE>T14:00:00&timezone=America/Los_Angeles. Expect:available:false; reason"date_override"(detail: date blocked by a date override). [L2]
- Action: Probe a HOLIDAY date at 14:00:
…/30-minute-meeting?time=<HOLIDAY_DATE>T14:00:00&timezone=America/Los_Angeles. Expect:available:false; reason"holiday"(detail names the holiday). [L2]
- Action: Probe a too-soon time using the high-min-notice event
Buf-<RUNID>: a valid open weekday/time only ~2 hours from now:…/buf-<runid>?time=<SOON_ISO>&timezone=America/Los_Angeles. Expect:available:false; reason"min_notice"(detail: requires 48h notice). [L2]
- Action: Probe a far-future time beyond max_future_days (default 60) on the default event, e.g. ~120 days out at 14:00:
…/30-minute-meeting?time=<FAR_ISO>&timezone=America/Los_Angeles. Expect:available:false; reason"max_future"(detail: more than 60 days in the future). [L2]
- Action: (booking_conflict) If a confirmed booking exists at a known time for
30-minute-meeting, probe that exact slot. Expect:available:false; reason"booking_conflict"with the conflicting booking's times. If no booking exists in this clean run, RECORD thatbooking_conflictwas not exercised in-browser (it is covered by unit teststests/unit/worker/availability.test.js); do not fabricate. [L2]
- Action: (daily_cap) The daily-max-1 limit set in Phase G is a SCHEDULE-level meeting limit (it empties days in slot computation), distinct from the event-type
max_bookings_per_daycap that slot-debug'sdaily_capreason reads. If P1's30-minute-meetinghas amax_bookings_per_dayset AND that many confirmed bookings exist on a day, probe a time on that day to elicit"daily_cap". Otherwise RECORD thatdaily_capwas not reproducible in-browser this run (covered by unit tests). [L2]
- Action: RECORD the slot-debug coverage matrix: which of the nine reasons were observed live ({no_schedule, outside_hours, date_override, holiday, min_notice, max_future} are reliably reproducible; {booking_conflict, daily_cap} depend on existing data; {google_calendar, outlook_calendar} are out of scope for this suite). Capture screenshot of the slot-debug JSON for at least four distinct reasons:
cu06-12-slotdebug-reasons. [L2]
L3 reality checks
None — see Pass/Fail. This suite makes no external calendar or email assertions. (Slot-debug reasons google_calendar and outlook_calendar would require connected external calendars with conflicting events; they are deliberately deferred to the calendar-integration suites and listed in Manual residue.)
Cleanup
Restore P1 to the documented baseline so other host-writing suites see Mon–Fri 09:00–17:00 with no test residue. Do these in order:
- Remove test overrides. Availability → Schedules sub-tab →
#overridesList: click the×([data-remove-override="<BLOCK_DATE>"]) forBLOCK_DATEand forOPEN_DATE; each auto-saves ("Override removed" toast). Confirm#overridesListshows "No date overrides" (unless the recorded baseline had overrides — in that case restore exactly those). - Clear holidays (only if the baseline had none). Advanced settings → Holidays → click "Clear All" (
#clearHolidaysBtn), then "Save Holidays" (#saveHolidaysBtn). If the baseline had holidays, re-load and re-save that exact set instead. - Remove the meeting limit. Advanced settings → Meeting limits → click the
×([data-remove-limit="0"]) on the daily-max-1 row, then "Save Limits" (#saveMeetingLimitsBtn). Confirm "No meeting limits configured" (unless baseline had limits — restore those). - Delete the test event types. Overview → for
Buf-<RUNID>andEvtSched-<RUNID>, open each and delete it (event-type delete control / confirm dialog#dialogConfirm). Confirm both are gone from#overviewEventTypes. - Delete the test schedule. Availability → select
Eve-<RUNID>in#scheduleSelect→ click "Delete Schedule" (#deleteScheduleBtn) → confirm in#confirmDialogvia#dialogConfirm. Confirm#scheduleSelectno longer listsEve-<RUNID>and falls back to "Working Hours". - Restore the default weekly schedule. Select "Working Hours"; set days/windows back to the Step 1 baseline snapshot (default = Mon–Fri 09:00–17:00, weekends off, America/Los_Angeles); click "Save Schedule" (
#saveScheduleBtn). Confirm#totalWeeklyHours=40.0 hrs/week(or the recorded baseline value). - Final verification. Reload, open
…/api/slot-debug/<HOST_SLUG>/30-minute-meeting?time=<DEBUG_OK_TIME>&timezone=America/Los_Angelesand confirmavailable:true, reasons:[]. Capture screenshot:cu06-13-baseline-restored.
Pass/Fail criteria
The run PASSES only if ALL of the following hold:
- After setting Mon–Fri 09:00–17:00,
#totalWeeklyHoursshows40.0 hrs/week, the save persists across reload, and the booking page shows weekday.calendar-day.availablecells with slots inside 09:00–16:30 host time and weekend cells.calendar-day.unavailable. - A blocking override on
BLOCK_DATEmakes that date.calendar-day.unavailablewith zero.time-sloton the booking page, and appears as "Blocked" in#overridesList. - An opening override on
OPEN_DATE(Saturday) makes it.calendar-day.availablewith exactly the 10:00–12:00 host-time slots. - Loading + saving the US holiday preset auto-blocks
HOLIDAY_DATEon the booking page (.calendar-day.unavailable, no slots) and shows the "Holiday:" tooltip in#overrideCalendar. - The
Buf-<RUNID>event (30/30 buffer, 48h notice) offers strictly fewer near-term slots than the default 4h-notice event, and no slots within 48h. EvtSched-<RUNID>(bound toEve-<RUNID>) offers only Wednesday 18:00–21:00 NY-window slots while30-minute-meetingstill offers Mon–Fri 09:00–17:00 LA — proving independent schedules.- The daily meeting limit persists across reload.
- slot-debug returns
available:true,reasons:[]for an open time AND emits the correct distinct reason code for at least these six probes:no_schedule,outside_hours,date_override,holiday,min_notice,max_future. (booking_conflict/daily_cappass if reproducible or are explicitly recorded as not-exercised;google_calendar/outlook_calendarare out of scope.) - Cleanup completes: all test overrides/holidays/limits/event-types/schedules removed and "Working Hours" restored to baseline, with the final slot-debug probe returning
available:true,reasons:[].
FAILS if any availability mutation does not reflect on the public booking page, any slot-debug probe returns the wrong reason or a 4xx/5xx, persistence does not survive reload, or cleanup leaves residue / a non-baseline default schedule.
Evidence to capture
cu06-01-baseline— recorded original weekly schedule, overrides, holidays, limits, timezone.cu06-02-weekly-set— Mon–Fri 09:00–17:00 editor at 40.0 hrs/week.cu06-03-booking-weekday-slots— booking page weekday slots.cu06-04-block-override-saved/cu06-05-booking-block-date— block override and its effect.cu06-06-booking-open-saturday— Saturday opened via override.cu06-07-holidays-saved/cu06-08-booking-holiday-blocked— holiday preset and auto-block.cu06-09-buffer-minnotice-slots— sparser slots for the buffered/min-notice event.cu06-10-multi-schedule-booking— Wednesday-only NY-window slots for the bound event.cu06-11-meeting-limit-saved— persisted daily limit.cu06-12-slotdebug-reasons— slot-debug JSON for ≥4 distinct reason codes, plus the recorded 9-reason coverage matrix.cu06-13-baseline-restored— post-cleanup baseline + final slot-debugavailable:true.- Notes: RUNID used, computed
BLOCK_DATE/OPEN_DATE/HOLIDAY_DATE/DEBUG_OK_TIME,HOST_SLUG, which slot-debug reasons were and were not exercised live.
Manual residue / cannot-verify
- slot-debug reasons 8 (
google_calendar) and 9 (outlook_calendar) require P1's Google/Outlook calendars connected WITH a conflicting external event at the probed time; that belongs to the calendar-integration suites, not here. A human (or those suites) must confirm those two reason codes fire. booking_conflictand event-type-leveldaily_caponly fire when confirmed bookings already exist; in a clean run they may not be reproducible in-browser. They are covered by unit tests (tests/unit/worker/availability.test.js,availability-meeting-limits.test.js) — note whether they were exercised live.- Full behavioral enforcement of schedule-level meeting limits (a day going empty after the Nth booking) is asserted by unit tests, not directly bookable-out within this suite's time budget; in-browser we verify persistence + slot-debug only.
- DST-boundary correctness of timezone conversion is covered by unit tests; this suite does not deliberately probe a DST transition date.