Lesson 184: ICS Rehearsal Hold Conflict Detector vs Leadership Offsite Calendar (2026)

Direct answer: Lesson 181 exported ICS rehearsal holds into shared calendars. Lesson 184 imports leadership offsite blocks, runs a mechanical overlap detector, and blocks publish while any cert_rehearsal_hold row overlaps an offsite event on the same room resource—so October 2026 planning decks cannot silently delete your only tabletop slot.

Lesson hero for ICS rehearsal hold conflict detector versus leadership offsite calendar

Why this matters now (October 2026 leadership offsites)

October 2026 is when companies book annual planning offsites—often the same conference room engineering reserved for Q1 2027 mock-audit rehearsals:

  • Leadership calendars show “Strategy offsite — all day” while engineering still has a T-14 rehearsal UID from Lesson 181.
  • Lesson 182 attendance receipts never fire because nobody showed up—the room was physically booked for slides, not tabletop.
  • Lesson 183 exports deficiencies from scored logs that never happened—garbage-in for Block 6.
  • Partner readbacks ask “show the calendar evidence”—not “we forgot.”

A conflict detector turns calendar politics into a red dashboard row before cert week.

Lesson objectives

You will implement:

  • leadership_offsite_event ingest table (ICS VEVENT subset)
  • cert_rehearsal_hold view aligned to Lesson 181 cert_window_calendar
  • rehearsal_hold_conflict materialized view + nightly refresh
  • rehearsal_hold_conflict_run job metadata
  • Publish-gate rehearsal_hold_conflict_open
  • Waive path with signer_ack_event + conflict_waive_id

Prerequisites

  • Lesson 181 — ICS export + stable ics_uid per hold
  • Lesson 182 — attendance only after holds are real
  • Lesson 171 — publish gate extension pattern
  • Optional: Operating review template blog — Friday calendar hygiene

leadership_offsite_event table

CREATE TABLE leadership_offsite_event (
  offsite_id        UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  ics_uid           TEXT NOT NULL UNIQUE,
  summary           TEXT NOT NULL,
  location_resource TEXT NOT NULL,  -- e.g. 'conf-room-a', 'zoom-bridge-1'
  starts_at_utc     TIMESTAMPTZ NOT NULL,
  ends_at_utc       TIMESTAMPTZ NOT NULL,
  organizer_email   TEXT NOT NULL,
  imported_at_utc   TIMESTAMPTZ NOT NULL DEFAULT now(),
  source_calendar   TEXT NOT NULL
    CHECK (source_calendar IN ('leadership_exec','facilities_shared'))
);

Ingest weekly from leadership’s exported .ics (read-only feed). Do not mutate engineering holds here—detect only.

cert_rehearsal_hold view

CREATE VIEW cert_rehearsal_hold AS
SELECT
  c.cert_window_id,
  c.ics_uid,
  c.hold_type,  -- 'T-14' | 'T-3'
  c.starts_at_utc,
  c.ends_at_utc,
  c.location_resource,
  c.rubric_version
FROM cert_window_calendar c
WHERE c.hold_status = 'active';

location_resource must match facilities naming—normalize in Lesson 181 README (GOVERNANCE_REHEARSAL_README.md).

Overlap detector

CREATE MATERIALIZED VIEW rehearsal_hold_conflict AS
SELECT
  h.cert_window_id,
  h.ics_uid AS rehearsal_ics_uid,
  o.offsite_id,
  o.ics_uid AS offsite_ics_uid,
  h.location_resource,
  GREATEST(h.starts_at_utc, o.starts_at_utc) AS overlap_start_utc,
  LEAST(h.ends_at_utc, o.ends_at_utc) AS overlap_end_utc,
  EXTRACT(EPOCH FROM (
    LEAST(h.ends_at_utc, o.ends_at_utc) -
    GREATEST(h.starts_at_utc, o.starts_at_utc)
  )) / 60 AS overlap_minutes
FROM cert_rehearsal_hold h
JOIN leadership_offsite_event o
  ON h.location_resource = o.location_resource
 AND h.starts_at_utc < o.ends_at_utc
 AND h.ends_at_utc > o.starts_at_utc
WHERE EXTRACT(EPOCH FROM (
        LEAST(h.ends_at_utc, o.ends_at_utc) -
        GREATEST(h.starts_at_utc, o.starts_at_utc)
      )) / 60 >= 15;

15-minute floor ignores back-to-back buffer noise; tabletop needs 90 minutes contiguous—flag any overlap ≥ 15 until human review.

Refresh after each offsite import:

REFRESH MATERIALIZED VIEW CONCURRENTLY rehearsal_hold_conflict;

Waive path (rare, audited)

When leadership intentionally shares the room (split morning/afternoon):

INSERT INTO rehearsal_hold_conflict_waive (
  conflict_key, conflict_waive_id, signer_role, ack_at_utc, rationale
) VALUES (
  'h.ics_uid|o.ics_uid', 'waive-2026-10-12-a',
  'governance_owner', now(), 'Offsite ends 12:00 UTC; T-14 starts 13:00 — facilities confirmed flip'
);

Publish gate ignores waived rows only when conflict_waive_id present and overlap_minutes < 90 after waive review.

Publish-gate extension

Add to Lesson 171 block_reason allow-list:

  • rehearsal_hold_conflict_open — any non-waived row in rehearsal_hold_conflict for the publishing cert_window_id.

Conflict resolution procedure (same day)

Step Owner Action
1 Governance owner Run import + REFRESH after leadership calendar publish
2 Scribe Open conflict export JSON in evidence folder
3 Leadership delegate Rebook offsite or move rehearsal hold (new ICS UID → Lesson 181 re-export)
4 Engineering Verify rehearsal_hold_conflict count = 0
5 Governance owner Clear publish gate; notify Lesson 182 scribe

Target same business day—do not let conflicts sit over a weekend before October room locks.

Export artifact

release-evidence/05-operations/REHEARSAL_CONFLICT_YYYYMMDD.json:

{
  "schema": "rehearsal_hold_conflict_v1",
  "run_at_utc": "2026-10-05T18:00:00Z",
  "conflicts": [
    {
      "cert_window_id": "q1_2027_meta",
      "rehearsal_ics_uid": "uid-t14-q1-meta",
      "offsite_ics_uid": "uid-offsite-strategy-oct",
      "location_resource": "conf-room-a",
      "overlap_minutes": 120
    }
  ],
  "sha256": "…"
}

Integration chain

flowchart LR
  L181[Lesson 181 ICS holds] --> HOLD[cert_rehearsal_hold]
  OFF[Leadership offsite ICS] --> DETECT[rehearsal_hold_conflict]
  HOLD --> DETECT
  DETECT -->|open| GATE[Publish blocked]
  DETECT -->|clear| L182[Lesson 182 attendance]
  L182 --> L183[Lesson 183 CSV export]

Common mistakes

  • Comparing calendars in local time without UTC storage.
  • Different location_resource strings (Conference Room A vs conf-room-a).
  • Waiving without signer ack—partner readback treats as silent drop.
  • Re-exporting Lesson 181 ICS without new UID when moving holds (Lesson 182 receipt breaks).
  • Ignoring Zoom bridge offsites that still block the physical room resource.

Troubleshooting

Symptom Likely cause Fix
False green, room empty Offsite on wrong calendar feed Import leadership_exec not facilities_shared
Conflict never clears Stale materialized view REFRESH CONCURRENTLY
14-minute overlap flagged Floor too low Keep 15m; document waive for buffers only
Gate blocks whole quarter One window conflict Filter publish by cert_window_id
Duplicate offsite rows Re-imported ICS UNIQUE (ics_uid) upsert

Verification checklist

  • [ ] Overlapping test events produce a conflict row
  • [ ] Non-overlapping same-room back-to-back (14m gap) does not fire
  • [ ] Waive + signer ack suppresses gate for approved case
  • [ ] REHEARSAL_CONFLICT_*.json in evidence with SHA-256
  • [ ] Lesson 182 bootstrap blocked while conflict open (deliberate test)

Mini exercise (25 minutes)

  1. Create two fake ICS events sharing conf-room-a with 60-minute overlap.
  2. Insert into leadership_offsite_event + cert_window_calendar stub rows.
  3. Write expected rehearsal_hold_conflict output row.
  4. Draft one waive JSON with rationale for a split-day resolution.

Continuity

  • Lesson 181 — source holds; re-export when rescheduling.
  • Lesson 182 — do not bootstrap attendance while conflicts open.
  • Lesson 183 — export only after scored tabletop exists.
  • Next: Lesson 185 — rubric semver drift blocks calendar re-export.
  • Guide: Spline embed preflight unrelated; calendar discipline pairs Friday Block 5 ritual blog.

FAQ

Can we use Google Calendar API instead of ICS files?
Yes—normalize into the same tables. Keep ICS export as disaster recovery.

Remote-only panels?
Set location_resource = 'zoom-bridge-1' for rehearsals; only compare offsites that claim the same bridge resource.

Does this replace facilities booking?
No—it detects drift between leadership and engineering calendars; facilities may still be source of truth for keys.

Conflict on T-3 only—block T-14?
Gate is per cert_window_id; any hold overlap blocks the window until cleared.


Calendar silence killed more 2026 mock audits than bad rubric scores. Detect overlaps mechanically, rebook before October offsites freeze, then let Lessons 182–183 run on real tabletop proof.