Skip to content

feat(calendar): add bounded read-only tool#5555

Draft
MADPANDA3D wants to merge 1 commit into
odysseus-dev:devfrom
MADPANDA3D:codex/upstream-calendar-voice
Draft

feat(calendar): add bounded read-only tool#5555
MADPANDA3D wants to merge 1 commit into
odysseus-dev:devfrom
MADPANDA3D:codex/upstream-calendar-voice

Conversation

@MADPANDA3D

Copy link
Copy Markdown

Summary

Adds a bounded native read_calendar facade for agent and voice integrations. It supports only list_calendars and list_events, requires the authenticated owner from tool execution, performs the locked owner-scoped CalDAV pull, and reads only owner-scoped Calendar rows.

The tool cannot create, update, delete, or reschedule user events. It is admin-only because Calendar data is privileged. It is also blocked in plan mode because the CalDAV pull may refresh the local SQLite cache; this write boundary is documented explicitly rather than treating the refresh as side-effect-free.

Event ranges must be explicit, ordered, and no longer than 366 days. Results default to 50 and cap at 100, text fields cap at 500 characters, formatted responses cap at 20,000 characters, and arbitrary argument names are never reflected into errors. Sync failures return cached data with fixed freshness metadata and do not leak provider error details.

Target branch

  • This PR targets dev, not main.

Linked Issue

Part of #5549. Related to #4118 and discussion #4439.

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)
  • New feature (non-breaking — adds new behaviour)
  • Breaking change (changes or removes existing behaviour)
  • Refactor / cleanup (behaviour unchanged)
  • Documentation only
  • CI / tooling / configuration

Checklist

  • I searched open issues and pull requests; no existing bounded read-only Calendar facade duplicates this proposal.
  • This PR targets dev.
  • Authentication owner scope and the existing admin tool gate are enforced before Calendar refresh/read.
  • Plan mode blocks the tool before its cache-refresh side effect.
  • Mutation actions and unknown fields fail closed.
  • Calendar text is capped untrusted tool data, not instructions.

How to Test

  1. Run: python -m pytest -q tests/test_read_calendar_tool.py tests/test_plan_mode.py
  2. As an admin, invoke read_calendar with list_calendars and a bounded list_events range.
  3. Confirm a different owner's Calendar rows are absent.
  4. Confirm a non-admin and plan-mode call are blocked before CalDAV refresh.
  5. Force a pull error and confirm cached results begin with the fixed freshness warning without provider details.
  6. Try create_event, an interval over 366 days, and many oversized unknown keys; confirm all fail before refresh.

Validation passed 87 policy/security/tool tests, 71 Calendar CRUD/parsing/owner/recurrence/reminder/read tests, and a final 19-test focused rerun. Ruff, Python compilation, and diff checks passed. A native-function-to-dispatcher SQLite E2E proved owner isolation, result/field caps, injection-looking text remaining data, and no user Calendar mutation. A final independent local rerun of the read-tool and plan-mode files passed 16 tests.

Visual / UI changes

None. This is a server-side tool/schema/policy addition with documentation and tests.

  • Screenshot or short clip attached — no UI is changed.
  • Style match — no visual surface is added.
  • No new component pattern — this is a bounded core tool seam only.
  • I am not an LLM agent submitting a bulk PR — this contribution is coding-agent assisted, disclosed in Proposal: bounded in-tree host seams for voice and UI composition #5549, and intentionally split into an independent seam.

@github-actions github-actions Bot added the ready for review Description complete — ready for maintainer review label Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Description complete — ready for maintainer review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant