Handbook
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 atomssrc/forge_lcdl/playwright/connectors/outlook_calendar.py—OutlookCalendarReadersrc/forge_lcdl/playwright/connectors/outlook_urls.py—outlook_extract_calendar_item_idsrc/forge_lcdl/tasks/calendar_read_v1.py— governed task entrypointssrc/forge_lcdl/playwright/edge_cdp_attach.py—pick_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.