"""Pin owner-scoping of the autonomous email->calendar event snapshot. The email auto-calendar pass fans out over EVERY user's mailbox and used to feed an *unscoped* upcoming-events snapshot to the extraction LLM, then execute the model's create/update/delete ops via do_manage_calendar with owner=None — so processing one tenant's mail could read AND mutate another tenant's calendar (and leak every tenant's event titles to the LLM endpoint). The fix routes the snapshot through core.database.get_upcoming_events(owner) and passes the account owner to do_manage_calendar. This test pins that get_upcoming_events scopes to the owner; it fails if the owner filter is dropped (the original cross-tenant behavior). """ import ast from pathlib import Path def test_get_upcoming_events_is_owner_scoped(): source = Path("core/database.py").read_text() tree = ast.parse(source) fn = next( node for node in tree.body if isinstance(node, ast.FunctionDef) and node.name == "get_upcoming_events" ) body = ast.unparse(fn) assert "join(CalendarCal)" in body assert "if owner is not None:" in body assert "q.filter(CalendarCal.owner == owner)" in body