4.9 KiB
Context
The change started on codex/macos-support at bd35ebc. Verification includes the later fast-forward to 1164c26846, which adds existing macOS CI and shutdown improvements. Existing OpenSpec requirements and local TDD policy own this work; no additional tracker or AGENTS scaffolding is needed. The user approved native notifications plus a menu-bar pending-request list. The interview exit audit found no remaining material product decision; packaging and transport are implementation choices.
Goals / Non-Goals
Goals: restore bidirectional macOS user decisions for existing approvals, inactivity and calendar prompts, preserve pending decisions when OS notifications are hidden, and start independent approved workflow conversations.
Non-goals: microphone enumeration/recovery, new audio backends, unrelated chat rendering, remote notifications, changes to Windows behavior, production deployment or OpenSpec archival.
Decisions
- A small managed DesktopUserRequestStore owns process-local pending requests, allowed action IDs, deadlines and cancellation. Producers provide callbacks; the store has no recording/agent business dependencies. Approvals await decisions, while calendar/inactivity prompts enqueue and return immediately. Windows adapters remain unchanged.
- GET /desktop/requests lists pending requests; POST /desktop/requests/{id}/respond submits an action. Native buttons and menu actions use the same endpoint. Response IDs are consumed once; invalid, canceled and expired responses cannot trigger work. Accepted callbacks use the originating lifetime rather than HTTP cancellation. Shutdown removes all requests. No answer never grants approval.
- Package the existing AppKit desktop helper as Native/MeetingAssistantDesktopControls.app with stable identifier cloud.schweigert.meeting-assistant.desktop-controls. The launcher retains service supervision. The helper polls requests, schedules notifications once per ID, removes stale notifications and always offers pending-menu actions. Notification dismissal alone leaves the central request pending. Notification authorization is requested on first needed delivery; denied authorization still permits the menu fallback.
- A managed macOS session store preserves the default interactive session and creates independent sessions for approved workflow prompts. GET /desktop/agent-windows announces requested native windows; the helper opens each session independently once. The detailed prompt starts once server-side. Session-aware chat snapshots and sends never restart the original prompt on page reload.
- The helper decodes the existing numeric recording enum; the HTTP contract stays unchanged. Native self-tests exercise decoding and request/action handling without touching the live instance.
- Keep current deadlines: approvals ten minutes, inactivity notifications one minute, calendar notifications five minutes capped at appointment end. Requests do not persist across application shutdown. Reopening a notification after shutdown cannot recreate an approval.
- Resolve workflow sessions lazily when an approved prompt opens a window. Eagerly resolving sessions from the window service creates a dependency cycle through the agent pipeline, meeting coordinator and summary workflow service. The default window does not need to resolve this graph; application-owned session execution still observes shutdown.
Risks / Trade-offs
- OS notifications can be hidden by Focus or screen sharing -> independent menu list retains actionable requests until their original deadline.
- Multiple callbacks and polling race -> atomic action validation/removal and idempotent stale-response rejection; cancellation registrations are disposed outside store locks.
- Awaiting a user decision could stall calendar or inactivity processing -> nonblocking prompt adapters with tests at their existing interfaces.
- Native app identity/direct launch may affect notification delivery -> build/signature/native checks and isolated operational verification; do not claim delivery without observing it.
- Background sessions and UI polling race -> immutable published snapshots and per-session send serialization.
- Existing active macOS specs describe unavailable automatic approvals -> update that scenario to refer to a genuinely unavailable communication channel, while the new capability defines menu fallback behavior.
Migration Plan
Build and verify the portable target, complete behavioral tests and OpenSpec validation, then build the Windows target to check isolation. Any production replacement remains a separate delivery action and must occur only while the application is idle. Rollback uses the previous complete signed application bundle.
Open Questions
No unresolved product decisions. Actual notification permission, delivery and response routing must be checked on macOS; unavailable permission is an operational verification limit, not a reason to remove menu access.