Outlook Calendar harvest — LCDL dual architecture

Cockpit consumer doc: outlook-calendar-dual-architecture.md. Operator flow: outlook-calendar-harvest.md. Read strategies: OUTLOOK-CALENDAR-READ-STRATEGIES.md.

Updated

Stable state boundary: LCDL returns wire JSON + collect proof fields only. Cockpit owns compute_calendar_day_fully_saved, event_identity_key, harvest_manifest.json phases, message_scan_day.day_fully_saved, SQLite upsert, and Downloads CSV adopt. LCDL never writes Cockpit disk or DB. See OUTLOOK-CALENDAR-DAY-CLOSURE.md.

End-to-end (LCDL steps)

session_ref registered by Cockpit
  → outlook_probe_calendar_health
  → outlook_calendar_goto_month (YYYY-MM)
  → outlook_calendar_probe_month_surface
  → outlook_calendar_collect_month_events
  → per scan_date: outlook_calendar_expand_day_overflow
  → per event index:
       outlook_calendar_open_event_expand
       outlook_calendar_read_detail_wire
       outlook_calendar_download_tracking_csv (optional when Tracking visible)
       outlook_calendar_dismiss_flyouts

Task catalog

Task Input Output
outlook_probe_calendar_health session_ref ok, month_view, page_url
outlook_calendar_goto_month session_ref, year, month ok, label
outlook_calendar_focus_day session_ref, scan_date ok, cell_label
outlook_calendar_collect_day_events session_ref, scan_date, max_events events[], overflow_clicked
outlook_calendar_probe_month_surface session_ref, year, month month_surface_ok, filter_applied, loaded_events_hint
outlook_calendar_collect_month_events session_ref, year, month, max_events events[] with scan_date, collect_proof
outlook_calendar_expand_day_overflow session_ref, scan_date, max_events events[], overflow_resolved, dom_count_for_day
outlook_calendar_open_event_expand session_ref, event_index, scan_date ok, item_id, page_url
outlook_calendar_read_detail_wire session_ref detail wire dict
outlook_calendar_download_tracking_csv session_ref ok, menu_clicked
outlook_calendar_dismiss_flyouts session_ref, press_count ok

All tasks: read_only: true.

Responsibility matrix

Concern Cockpit forge-lcdl Edge
DOM evaluate / clicks Forbidden in calendar/ harvest scripts/outlook_calendar_readonly.py, connectors/outlook_calendar.py
Item ID extraction event_identity_key hash outlook_extract_calendar_item_id(url) URL after expand
+N flyout merge/dedupe events click +N, scroll flyout list
Tracking CSV menu adopt file from Downloads menu path only Download to ~/Downloads
Day closure message_scan_day

Implementation modules

  • src/forge_lcdl/playwright/scripts/outlook_calendar_readonly.py — JS evaluate atoms
  • src/forge_lcdl/playwright/connectors/outlook_calendar.pyOutlookCalendarReader
  • src/forge_lcdl/playwright/connectors/outlook_urls.pyoutlook_extract_calendar_item_id
  • src/forge_lcdl/tasks/calendar_read_v1.py — governed task entrypoints
  • src/forge_lcdl/playwright/edge_cdp_attach.pypick_calendar_cdp_page_target

Read-only policy

See READONLY_POLICY.md. Calendar harvest allowlist: navigation, event read, Expand, Tracking → Download as CSV, Escape. Deny Save, Edit, Cancel, RSVP.