# Cursor sync configuration This document describes how the application and Cursor should keep **plans, epics, and tasks** aligned. Implementation is incremental; treat this as the contract the data layer and jobs will follow. ## Goals 1. **App → Cursor**: Tasks and status updates in the app appear as Cursor to-dos / plan items where configured. 2. **Cursor → App**: To-dos created or completed in Cursor are mirrored into the correct plan/epic in the app. 3. **Markdown as source of truth (optional mode)**: Repo markdown can be authoritative; the app imports on change, or the app exports on change—policy is per tenant (see Modes). ## Multitenancy - Each **tenant** has its own: - API credentials or OAuth connection to Cursor (when available). - Mapping table: internal plan/epic/task id ↔ Cursor identifiers ↔ filesystem paths under `plans/`. - No cross-tenant sync or shared Cursor workspace. ## Modes (to implement) | Mode | Behavior | |------|----------| | `markdown_authoritative` | Watch `plans/**`; import on save; push summaries to Cursor. | | `app_authoritative` | UI/API edits win; export markdown + update Cursor on commit or interval. | | `bidirectional` | Reconcile by `updated_at` and explicit conflict rules (last-write-wins per field or manual resolution). | ## API surface (target) Lightweight endpoints or jobs (names indicative): - `POST /api/v1/tenants/:tenantId/plans` — create plan + optional seed markdown paths. - `GET/PATCH /api/v1/tenants/:tenantId/plans/:planId` — read/update metadata and Cursor mapping. - `GET/PATCH /api/v1/.../epics/:epicId`, `.../tasks/:taskId` — same for epics and tasks. - `POST /api/v1/tenants/:tenantId/sync/cursor/pull` — ingest Cursor to-dos into tasks. - `POST /api/v1/tenants/:tenantId/sync/cursor/push` — export task state to Cursor. - Webhook receiver (future): `POST /webhooks/cursor` for push notifications when Cursor exposes them; until then **polling** on a tenant schedule. ## Mapping record (logical schema) Implemented in Postgres as `markdown_backlog_items` plus `cursor_sync_mappings` (see `docs/Glossary.md`). Logical fields: - `tenant_id` → `markdown_backlog_items.workspace_id` (workspace object UUID) - `plan_slug`, `epic_slug`, `slug` (filesystem / frontmatter alignment) - `cursor_plan_id` / `cursor_item_id` → `cursor_sync_mappings` (nullable until connected) - `last_pulled_at`, `last_pushed_at`, `sync_content_hash` on the mapping row - `content_hash` on the backlog row (file body hash for import idempotency) ## Environment variables (placeholder) Document only; wire in app config when implementing. | Variable | Purpose | |----------|---------| | `CURSOR_SYNC_ENABLED` | `true` / `false` per environment. | | `CURSOR_SYNC_POLL_INTERVAL_SEC` | Polling fallback interval. | | `CURSOR_API_BASE_URL` | When a stable API exists for your integration tier. | | `CURSOR_WEBHOOK_SECRET` | Verify inbound webhooks. | ## Security - Store tokens in tenant-scoped secrets (env, vault, or DB encrypted column)—never in markdown. - Audit log for every push/pull with actor (user id or system job). ## References - Backlog layout: `plans/README.md` - Terminology: `docs/Glossary.md` - Templates: `docs/templates/`