feat(privacy-host): add signed native calendar contacts and reminders host

Add the owner-only AF_UNIX Reyna CLI privacy host, strict signed-app installation, and typed native routing for Calendar, Contacts, and Reminders.\n\nAdd bounded system-status paths and config-only direct local-service wrappers. Preserve MacMiniMCP pending explicit cutover approval.\n\nApple Notes is intentionally deferred: no native Notes operations, Apple Events declaration, or Automation helper are included; legacy Notes handling remains untouched.
This commit is contained in:
Adolfo Reyna
2026-08-03 20:27:54 -04:00
parent 6e2117188e
commit 9fd04b0ce4
56 changed files with 14239 additions and 50 deletions
+294
View File
@@ -0,0 +1,294 @@
"""Tests for calendar event list/create native wrappers and CLI routing – TDD, no live calls."""
from pathlib import Path
import json
import pytest
from typer.testing import CliRunner
from reyna_cli.cli import app
runner = CliRunner()
def test_native_calendar_events_list_success(monkeypatch):
from reyna_cli import privacy_host as ph_mod
captured = {}
class FakeClient:
def call(self, op, args):
captured["op"] = op
captured["args"] = args
return {"id": "abc", "ok": True, "result": {"protocol_version": "1.0.0", "operation": "calendar.events.list", "events": []}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
result = ph_mod.native_calendar_events_list(start="2026-01-01T00:00:00Z", end="2026-01-02T00:00:00Z", calendar="Home", limit=25)
assert captured["op"] == "calendar.events.list"
assert captured["args"]["start"] == "2026-01-01T00:00:00Z"
assert captured["args"]["end"] == "2026-01-02T00:00:00Z"
assert captured["args"]["calendar"] == "Home"
assert captured["args"]["limit"] == 25
assert result["ok"] is True
assert result["source"] == "native_privacy_host"
def test_native_calendar_events_list_with_calendar_id(monkeypatch):
from reyna_cli import privacy_host as ph_mod
captured = {}
class FakeClient:
def call(self, op, args):
captured["args"] = args
return {"id": "abc", "ok": True, "result": {"events": []}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
ph_mod.native_calendar_events_list(start="2026-01-01T00:00:00Z", end="2026-01-02T00:00:00Z", calendar_id="stable-id-123", limit=50)
assert captured["args"]["calendar_id"] == "stable-id-123"
assert "calendar" not in captured["args"] or captured["args"].get("calendar") is None
def test_native_calendar_events_list_failure_surfaces(monkeypatch):
from reyna_cli import privacy_host as ph_mod
from reyna_cli.privacy_client import PrivacyClientError
class FakeFail:
def call(self, op, args):
raise PrivacyClientError("privacy RPC returned ok=false: permission_required")
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeFail)
with pytest.raises(PrivacyClientError):
ph_mod.native_calendar_events_list(start="2026-01-01T00:00:00Z", end="2026-01-02T00:00:00Z")
def test_native_calendar_event_create_success(monkeypatch):
from reyna_cli import privacy_host as ph_mod
captured = {}
class FakeClient:
def call(self, op, args):
captured["op"] = op
captured["args"] = args
return {"id": "c", "ok": True, "result": {"protocol_version": "1.0.0", "operation": "calendar.event.create", "event": {"id": "new"}}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
result = ph_mod.native_calendar_event_create(
title="Meeting",
start="2026-01-01T10:00:00Z",
end="2026-01-01T11:00:00Z",
all_day=False,
notes="bring docs",
location="Room 1",
calendar_id="cal-id-1",
calendar=None,
)
assert captured["op"] == "calendar.event.create"
assert captured["args"]["title"] == "Meeting"
assert captured["args"]["start"] == "2026-01-01T10:00:00Z"
assert captured["args"]["end"] == "2026-01-01T11:00:00Z"
assert captured["args"]["all_day"] is False
assert captured["args"]["notes"] == "bring docs"
assert captured["args"]["calendar_id"] == "cal-id-1"
assert result["ok"] is True
def test_native_calendar_event_create_with_calendar_title(monkeypatch):
from reyna_cli import privacy_host as ph_mod
captured = {}
class FakeClient:
def call(self, op, args):
captured["args"] = args
return {"id": "c", "ok": True, "result": {"event": {"id": "new"}}}
monkeypatch.setattr(ph_mod, "PrivacyClient", FakeClient)
ph_mod.native_calendar_event_create(title="T", start="2026-01-01T10:00:00Z", end="2026-01-01T11:00:00Z", calendar="Home")
assert captured["args"]["calendar"] == "Home"
assert "calendar_id" not in captured["args"]
def test_no_mcp_in_new_wrappers():
from reyna_cli import privacy_host as ph_mod
src = Path(ph_mod.__file__).read_text()
# wrappers must still not contain MCP fallback
assert "call_macmini_tool" not in src
assert "MCPClient" not in src
def test_cli_events_uses_native_wrapper(monkeypatch):
calls = {"count": 0, "args": None}
def fake_events(start, end, calendar_id=None, calendar=None, limit=50):
calls["count"] += 1
calls["args"] = {"start": start, "end": end, "calendar_id": calendar_id, "calendar": calendar, "limit": limit}
return {"ok": True, "source": "native_privacy_host", "result": {"events": []}}
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_events_list", fake_events)
result = runner.invoke(app, ["macmini", "calendar", "events", "2026-01-01T00:00:00Z", "2026-01-02T00:00:00Z", "--json"])
assert result.exit_code == 0, result.stdout + result.stderr
payload = json.loads(result.stdout)
assert payload["ok"] is True
assert calls["count"] == 1
assert calls["args"]["start"] == "2026-01-01T00:00:00Z"
def test_cli_events_with_calendar_title(monkeypatch):
captured = {}
def fake_events(start, end, calendar_id=None, calendar=None, limit=50):
captured["calendar"] = calendar
captured["calendar_id"] = calendar_id
return {"ok": True, "source": "native_privacy_host", "result": {"events": []}}
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_events_list", fake_events)
result = runner.invoke(app, ["macmini", "calendar", "events", "2026-01-01T00:00:00Z", "2026-01-02T00:00:00Z", "--calendar", "Home", "--json"])
assert result.exit_code == 0, result.stdout + result.stderr
assert captured["calendar"] == "Home"
assert captured["calendar_id"] is None
def test_cli_events_with_calendar_index_resolves_once(monkeypatch):
# Track how many times native_calendar_list is called – must be exactly once for index compat
list_calls = {"count": 0}
events_calls = {"args": None}
def fake_list():
list_calls["count"] += 1
return {
"ok": True,
"source": "native_privacy_host",
"result": {
"protocol_version": "1.0.0",
"operation": "calendar.list",
"calendars": [
{"id": "id-0", "title": "Home", "source": "iCloud", "type": "caldav"},
{"id": "id-1", "title": "Work", "source": "iCloud", "type": "caldav"},
],
},
}
def fake_events(start, end, calendar_id=None, calendar=None, limit=50):
events_calls["args"] = {"calendar_id": calendar_id, "calendar": calendar}
return {"ok": True, "source": "native_privacy_host", "result": {"events": []}}
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_list", fake_list)
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_events_list", fake_events)
result = runner.invoke(app, ["macmini", "calendar", "events", "2026-01-01T00:00:00Z", "2026-01-02T00:00:00Z", "--calendar-index", "1", "--json"])
assert result.exit_code == 0, result.stdout + result.stderr
assert list_calls["count"] == 1, "must resolve calendar list exactly once"
assert events_calls["args"]["calendar_id"] == "id-1"
assert events_calls["args"]["calendar"] is None
def test_cli_events_invalid_calendar_index_returns_error(monkeypatch):
def fake_list():
return {
"ok": True,
"source": "native_privacy_host",
"result": {
"calendars": [
{"id": "id-0", "title": "Home", "source": "iCloud", "type": "caldav"},
]
},
}
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_list", fake_list)
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_events_list", lambda **kwargs: {"ok": True, "source": "native", "result": {}})
result = runner.invoke(app, ["macmini", "calendar", "events", "2026-01-01T00:00:00Z", "2026-01-02T00:00:00Z", "--calendar-index", "5", "--json"])
assert result.exit_code != 0
# fail() with json_output should emit ok:false payload
assert "out of range" in result.stdout or "out of range" in result.stderr or "ok" in result.stdout.lower()
def test_cli_create_uses_native_wrapper(monkeypatch):
captured = {}
def fake_create(title, start, end, all_day=False, notes=None, location=None, calendar_id=None, calendar=None):
captured["title"] = title
captured["calendar"] = calendar
captured["calendar_id"] = calendar_id
captured["notes"] = notes
return {"ok": True, "source": "native_privacy_host", "result": {"event": {"id": "new"}}}
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_event_create", fake_create)
result = runner.invoke(app, ["macmini", "calendar", "create", "Meeting", "2026-01-01T10:00:00Z", "2026-01-01T11:00:00Z", "--calendar", "Home", "--notes", "bring docs", "--json"])
assert result.exit_code == 0, result.stdout + result.stderr
assert captured["title"] == "Meeting"
assert captured["calendar"] == "Home"
assert captured["notes"] == "bring docs"
def test_cli_create_with_calendar_index(monkeypatch):
list_calls = {"count": 0}
create_calls = {}
def fake_list():
list_calls["count"] += 1
return {
"ok": True,
"source": "native_privacy_host",
"result": {"calendars": [{"id": "id-xyz", "title": "Home", "source": "iCloud", "type": "caldav"}]},
}
def fake_create(title, start, end, all_day=False, notes=None, location=None, calendar_id=None, calendar=None):
create_calls["calendar_id"] = calendar_id
create_calls["calendar"] = calendar
return {"ok": True, "source": "native_privacy_host", "result": {"event": {"id": "new"}}}
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_list", fake_list)
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_event_create", fake_create)
result = runner.invoke(app, ["macmini", "calendar", "create", "T", "2026-01-01T10:00:00Z", "2026-01-01T11:00:00Z", "--calendar-index", "0", "--json"])
assert result.exit_code == 0, result.stdout + result.stderr
assert list_calls["count"] == 1
assert create_calls["calendar_id"] == "id-xyz"
assert create_calls["calendar"] is None
def test_cli_create_no_default_calendar_first_arbitrary(monkeypatch):
# When no calendar specified, wrapper should receive None for both and then host will reject (no default)
captured = {}
def fake_create(title, start, end, all_day=False, notes=None, location=None, calendar_id=None, calendar=None):
captured["calendar_id"] = calendar_id
captured["calendar"] = calendar
return {"ok": True, "source": "native_privacy_host", "result": {"event": {"id": "new"}}}
monkeypatch.setattr("reyna_cli.privacy_host.native_calendar_event_create", fake_create)
result = runner.invoke(app, ["macmini", "calendar", "create", "Title", "2026-01-01T10:00:00Z", "2026-01-01T11:00:00Z", "--json"])
assert result.exit_code == 0, result.stdout + result.stderr
assert captured["calendar_id"] is None
assert captured["calendar"] is None
def test_cli_events_no_mcp_tool_call(monkeypatch):
# Prove no call_macmini_tool present in file after change
from reyna_cli import cli as cli_mod
src = Path(cli_mod.__file__).read_text()
# Find events function section – must not contain call_macmini_tool for calendar_list_events
# Overall file still may have call_macmini_tool for contacts etc, but our two commands must not use it
# So check that native wrappers are used
assert "native_calendar_events_list" in src
assert "native_calendar_event_create" in src
# Ensure the old patterns are gone from those specific functions by checking surrounding lines
# Simpler: assert the literal string call_macmini_tool("calendar_list_events" not present
assert 'calendar_list_events' not in src or 'call_macmini_tool(\"calendar_list_events\"' not in src
assert 'calendar_create_event' not in src or 'call_macmini_tool(\"calendar_create_event\"' not in src