Lesson 181: Q1 2027 Cert Intake Rehearsal Calendar Export from Lesson 172 Rubric JSON (2026)

Direct answer: Lesson 172 gave you the seven-dimension rubric and 90-minute tabletop. Lesson 181 turns that rubric into mock_audit_rubric_v1.json, generates ICS calendar holds (T-14 and T-3 per cert window), and ships a GOVERNANCE_REHEARSAL_README.md so Q1 2027 intake rehearsals are on the calendar before October 2026 planning decks steal your only meeting room.

Lesson hero artwork for Q1 2027 cert intake rehearsal calendar export from mock-audit rubric JSON

Why this matters now (October 2026 planning)

October 2026 is when studios lock Q1 2027 partner and platform intake calendars:

  • Leadership books offsites and planning decks without telling engineering—then wonders why the mock audit never happened.
  • Lesson 173 trend boards need dated mock_audit_log rows—not imaginary "we'll rehearse sometime in January."
  • Lesson 174 signer fatigue heat-maps assume cert windows have named rehearsal dates on the calendar.
  • Real rooms (and remote panel Zoom links) need 90-minute blocks reserved twice per window per Lesson 172 cadence.

Calendar export is operations, not paperwork—it prevents double-booked tabletop rooms.

Lesson objectives

You will implement:

  • Canonical mock_audit_rubric_v1.json (seven dimensions, weights, failure-mode tags)
  • cert_rehearsal_calendar_export job producing .ics + README
  • cert_window_calendar table linking cert_window_id to ICS UID
  • Panel role roster embedded in event description
  • Timezone-safe UTC storage with local display notes
  • Publish artifact hash in release-evidence/05-operations/

Prerequisites

  • Lesson 172 — rubric dimensions, weights, failure modes, T-14/T-3 cadence
  • Lesson 173 — consumes dated mock_audit_log (calendar export feeds real dates)
  • Lesson 171 — publish gate; calendar export does not bypass gates
  • Optional: Q3 2026 mock audit tabletop help — blog companion to Lesson 172

mock_audit_rubric_v1.json (source of truth)

Commit under governance/mock_audit_rubric_v1.json:

{
  "rubric_version": "1.0.0",
  "source_lesson": "172-q3-2026-submission-intake-mock-audit-tabletop-scoring-rubric-2026-rpg-live-ops",
  "pass_rule": {
    "weighted_score_min": 90,
    "per_dimension_floor_min": 50
  },
  "tabletop_duration_minutes": 90,
  "panel_roles": ["scribe", "leadership_voice", "partner_voice", "engineering_voice"],
  "dimensions": [
    {
      "number": 1,
      "name": "Leadership vs partner SLA snapshot alignment",
      "weight_percent": 20,
      "source_lessons": ["164", "166"],
      "failure_mode": "partner_lead_variance"
    },
    {
      "number": 2,
      "name": "Carve-out annex presence and signer ack",
      "weight_percent": 10,
      "source_lessons": ["163"],
      "failure_mode": "unsigned_carve_out"
    },
    {
      "number": 3,
      "name": "Footer semver + replay parser contract pin",
      "weight_percent": 10,
      "source_lessons": ["165"],
      "failure_mode": "footer_drift"
    },
    {
      "number": 4,
      "name": "Weekly reconciliation job green",
      "weight_percent": 15,
      "source_lessons": ["166"],
      "failure_mode": "reconciliation_red"
    },
    {
      "number": 5,
      "name": "Synthetic replay diff gate green",
      "weight_percent": 15,
      "source_lessons": ["167"],
      "failure_mode": "replay_diff_red"
    },
    {
      "number": 6,
      "name": "FAQ-bound readback discipline",
      "weight_percent": 15,
      "source_lessons": ["170"],
      "failure_mode": "faq_unsigned"
    },
    {
      "number": 7,
      "name": "Publish-pipeline tuple-drift block clean",
      "weight_percent": 15,
      "source_lessons": ["171"],
      "failure_mode": "tuple_drift_open"
    }
  ],
  "rehearsal_kinds": [
    { "code": "T-14", "days_before_window_open": 14, "deficiency_sla_hours": 168 },
    { "code": "T-3", "days_before_window_open": 3, "deficiency_sla_hours": 48 }
  ]
}

Verification: jq '.dimensions | length' governance/mock_audit_rubric_v1.json prints 7.

cert_window_calendar table

CREATE TABLE cert_window_calendar (
  cert_window_id     TEXT PRIMARY KEY,
  window_label       TEXT NOT NULL,
  window_opens_utc   TIMESTAMPTZ NOT NULL,
  timezone_iana      TEXT NOT NULL DEFAULT 'UTC',
  rubric_json_sha256 TEXT NOT NULL,
  ics_bundle_path    TEXT NOT NULL,
  readme_path        TEXT NOT NULL,
  exported_at_utc    TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE TABLE cert_rehearsal_event (
  event_id           TEXT PRIMARY KEY,
  cert_window_id     TEXT NOT NULL REFERENCES cert_window_calendar(cert_window_id),
  rehearsal_kind     TEXT NOT NULL CHECK (rehearsal_kind IN ('T-14','T-3')),
  starts_at_utc      TIMESTAMPTZ NOT NULL,
  ends_at_utc        TIMESTAMPTZ NOT NULL,
  ics_uid            TEXT NOT NULL UNIQUE,
  location           TEXT NOT NULL,
  panel_roster_json  TEXT NOT NULL
);

Store ICS UID per event so re-exports update the same calendar row instead of duplicating holds.

Step 1 — Define Q1 2027 windows (example)

cert_window_id window_label window_opens_utc (example)
q1-2027-partner-intake-a Q1 2027 Partner intake A 2027-01-15T08:00:00Z
q1-2027-quest-holiday-b Q1 2027 Quest holiday lane B 2027-01-22T08:00:00Z

Adjust dates to your real intake letters—this lesson teaches export mechanics, not guessing partner schedules.

Step 2 — Compute rehearsal instants

For each window:

T-14_start = window_opens_utc - 14 days  (snap to 14:00 UTC Tuesday default)
T-3_start  = window_opens_utc - 3 days   (snap to 14:00 UTC Tuesday default)
duration   = 90 minutes (from rubric JSON)

Document snap rules in README so APAC/EU staff know why invites show UTC.

Step 3 — Generate ICS (Python sketch)

#!/usr/bin/env python3
"""Export cert rehearsal holds from mock_audit_rubric_v1.json."""
import json, hashlib, uuid
from datetime import datetime, timedelta, timezone
from pathlib import Path

RUBRIC = Path("governance/mock_audit_rubric_v1.json")
OUT = Path("release-evidence/05-operations/calendar")

def ics_event(uid, start, end, summary, description, location):
    fmt = "%Y%m%dT%H%M%SZ"
    return "\r\n".join([
        "BEGIN:VEVENT",
        f"UID:{uid}",
        f"DTSTART:{start.strftime(fmt)}",
        f"DTEND:{end.strftime(fmt)}",
        f"SUMMARY:{summary}",
        f"DESCRIPTION:{description.replace(chr(10), '\\n')}",
        f"LOCATION:{location}",
        "END:VEVENT",
    ])

def main():
    rubric = json.loads(RUBRIC.read_text(encoding="utf-8"))
    rubric_hash = hashlib.sha256(RUBRIC.read_bytes()).hexdigest()
    windows = [
        ("q1-2027-partner-intake-a", "Q1 2027 Partner intake A",
         datetime(2027, 1, 15, 8, 0, tzinfo=timezone.utc)),
    ]
    lines = ["BEGIN:VCALENDAR", "VERSION:2.0", "PRODID:-//GamineAI//Cert Rehearsal//EN"]
    for wid, label, opens in windows:
        for kind in rubric["rehearsal_kinds"]:
            days = kind["days_before_window_open"]
            start = opens - timedelta(days=days)
            start = start.replace(hour=14, minute=0)
            end = start + timedelta(minutes=rubric["tabletop_duration_minutes"])
            uid = f"cert-rehearsal-{wid}-{kind['code']}@gamineai.com"
            desc = (
                f"Mock audit tabletop ({kind['code']}). "
                f"Panel: {', '.join(rubric['panel_roles'])}. "
                f"Rubric hash: {rubric_hash[:12]}. "
                f"Lesson 172 seven dimensions — scores only, packet immutable."
            )
            lines.append(ics_event(
                uid, start, end,
                f"[CERT] {label} mock audit {kind['code']}",
                desc,
                "Conference Room A / Zoom link in runbook",
            ))
    lines.append("END:VCALENDAR")
    OUT.mkdir(parents=True, exist_ok=True)
    ics_path = OUT / "q1-2027-cert-rehearsal-holds.ics"
    ics_path.write_text("\r\n".join(lines) + "\r\n", encoding="utf-8")
    print("wrote", ics_path, "rubric_sha256", rubric_hash)

if __name__ == "__main__":
    main()

Verification: Import .ics into Google Calendar or Outlook—two events per window, 90 minutes each, descriptions list panel roles.

Step 4 — GOVERNANCE_REHEARSAL_README.md

Template section list:

  1. Purpose — link Lesson 172 rubric JSON path
  2. Q1 2027 windows — table of cert_window_id + opens date
  3. Rehearsal cadence — T-14 systemic, T-3 last-touch (copy from Lesson 172)
  4. Panel roster — named humans for scribe / three voices
  5. Room / Zoom — physical room + backup link
  6. Packet prepmock_audit_packets/{window}/T-14-rehearsal/manifest.json checklist
  7. After tabletop — insert mock_audit_log + tickets (Lesson 172 step 4)
  8. Trend consumer — export CSV for Lesson 173 board Friday block
  9. ICS UID map — table correlating DB ics_uid to calendar event

Commit README beside ICS under release-evidence/05-operations/calendar/.

Step 5 — Wire export hash to BUILD_RECEIPT

Extend receipt JSON:

"calendar_export": {
  "rubric_sha256": "<from rubric file>",
  "ics_path": "release-evidence/05-operations/calendar/q1-2027-cert-rehearsal-holds.ics",
  "exported_at_utc": "2026-05-20T18:00:00Z"
}

Partners asking "how do you rehearse intake?" get a hash-pinned artifact, not a verbal promise.

Alternative paths

A — Manual calendar entry

If Python is unavailable, create two recurring-style manual events per window using README times—still record ics_uid as manual-{uuid} in SQL for audit trail.

B — Multiple timezones

Duplicate events with X-WR-TIMEZONE per office—store UTC in DB; generate one ICS per IANA zone if leadership insists on local labels.

C — Remote-only panel

Set LOCATION to Zoom URL; require engineering voice to share screen for SQL evidence rows (Lesson 172 step 3 schedule).

Prevention checklist

  1. Re-export calendar when rubric_version bumps—never edit ICS by hand without version bump.
  2. Block leadership offsites that overlap T-3 without carve-out (Lesson 163).
  3. Attach ICS to partner intake prep email as optional evidence.
  4. Run Lesson 173 only after both rehearsals per window have mock_audit_log rows.
  5. Store export job logs in WORM prefix from Lesson 175.

Common mistakes

  • Exporting calendar after window opens (rehearsals missed).
  • One combined ICS for unrelated cert windows (Lesson 172 forbids merged packets—same for calendars).
  • Missing scribe role on invite (scores become arguments).
  • Local timezone drift without UTC column in SQL.
  • Regenerating ICS with new UIDs every week (calendar spam).
  • Skipping README (new PM books over your holds).

Verification checklist

  • [ ] mock_audit_rubric_v1.json committed with seven dimensions summing to 100% weight
  • [ ] .ics imports with two events per Q1 2027 window
  • [ ] Each event duration = 90 minutes
  • [ ] cert_rehearsal_event rows match ICS UIDs
  • [ ] README lists panel names and packet paths
  • [ ] rubric_json_sha256 stored on cert_window_calendar
  • [ ] Lesson 173 owner knows which Fridays consume recurrence exports

Mini exercise (30 minutes)

  1. Pick one real or hypothetical January 2027 window date.
  2. Run export script (or manual ICS).
  3. Import calendar invite.
  4. Write one-sentence scribe duty reminder in event description.
  5. Paste rubric_json_sha256 into team runbook.

Continuity

  • Lesson 172 — rubric source; this lesson does not change scoring rules.
  • Lesson 173 — needs dated audits from booked rehearsals.
  • Lesson 174 — signer fatigue assumes cert cadence on calendar.
  • Lesson 180 — red-team runs before tabletop, not instead of calendar holds.
  • Next: Lesson 182 — attendance receipts + gated mock_audit_log bootstrap from completed ICS holds.
  • Help: OpenXR governance partner SLA snapshot mismatch — dimension 1 still applies in Q1 2027.
  • Resource: 15 free Q3 submission intake mock audit packet templates — packet folder layout for rehearsal directories.
  • Paired Unity guide chapter (next Guide-Create): Unity 6.6 LTS OpenXR governance cert rehearsal calendar exporter preflight — ScriptableObject window list + ICS path validator.

FAQ

Do we export ICS for Q3 2026 retroactively?
Optional. This lesson targets forward Q1 2027 holds. Backfill mock_audit_log dates in Lesson 173 separately.

Can one person play all four panel roles?
Not for the first rehearsal—muscle memory needs distinct voices. T-3 may combine roles only if roster documents the compromise.

What if the rubric changes?
Bump rubric_version minor, re-export ICS with same UIDs, update README changelog.

Does ICS replace Friday Block 5?
No. Calendar books the 90-minute tabletop; Friday Block 5 maintains evidence folders.

October 2026 deadline real?
Partner planning decks for Q1 2027 circulate now—booking in October 2026 avoids January surprise.


The governance stack is only as real as the calendar invites. Export the rubric, book the rooms, and let Lesson 173 count rehearsals that actually happened—not rehearsals you meant to schedule.