Files
gitlore/plans/gitlab-todos-notifications-integration.md
teernisse 0fe3737035 docs(plan): add GitLab TODOs integration design document
Captures design decisions and acceptance criteria for adding GitLab
TODO support to lore. This plan was developed through user interview
to ensure the feature aligns with actual workflows.

Key design decisions:
- Read-only scope (no mark-as-done operations)
- Three integration points: --todos flag, activity enrichment, lore todos
- Account-wide: --project does NOT filter todos (unlike issues/MRs)
- Separate signal: todos don't affect attention state calculation
- Snapshot sync: missing todos = marked done elsewhere = delete locally

The plan covers:
- Database schema (todos table + indexes)
- GitLab API client extensions
- Sync pipeline integration
- Action type handling and grouping
- CLI commands and robot mode schemas
- Non-synced project handling with [external] indicator

Implementation is organized into 5 rollout slices:
A: Schema + Client, B: Sync, C: lore todos, D: lore me, E: Polish

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-25 10:02:55 -05:00

9.2 KiB

plan, title, status, iteration, target_iterations, beads_revision, related_plans, created, updated
plan title status iteration target_iterations beads_revision related_plans created updated
true GitLab TODOs Integration proposed 1 3 1
2026-02-23 2026-02-23

GitLab TODOs Integration

Summary

Add GitLab TODO support to lore. Todos are fetched during sync, stored locally, and surfaced through:

  1. A new --todos section in lore me
  2. Enrichment of the activity feed in lore me
  3. A standalone lore todos command

Scope: Read-only. No mark-as-done operations.


Design Decisions (from interview)

Decision Choice
Write operations Read-only — no mark-as-done
Storage Persist locally in SQLite
Integration Three-way: activity enrichment + --todos flag + lore todos
Action types Core only: assigned, mentioned, directly_addressed, approval_required, build_failed, unmergeable
Niche actions Skip display (but store): merge_train_removed, member_access_requested, marked
Project filter Always account-wide--project does NOT filter todos
Sync timing During normal lore sync
Non-synced projects Include with [external] indicator
Attention state Separate signal — todos don't boost attention
Summary header Include pending todo count
Grouping By action type: Assignments | Mentions | Approvals | Build Issues
History Pending only — done todos not tracked
lore todos filters None — show all pending, simple
Robot mode Yes, standard envelope
Target types All GitLab supports (Issue, MR, Epic, Commit, etc.)

Out of Scope

  • Write operations (mark as done)
  • Done todo history tracking
  • Filters on lore todos command
  • Todo-based attention state boosting
  • Notification settings API integration (deferred to separate plan)

Acceptance Criteria

AC-1: Database Schema

  • AC-1.1: Create todos table with columns:
    • id INTEGER PRIMARY KEY
    • gitlab_todo_id INTEGER NOT NULL UNIQUE
    • project_id INTEGER REFERENCES projects(id) ON DELETE SET NULL (nullable for non-synced)
    • target_type TEXT NOT NULL (Issue, MergeRequest, Commit, Epic, etc.)
    • target_id INTEGER (GitLab ID of target entity)
    • target_iid INTEGER (IID for issues/MRs, nullable)
    • target_url TEXT NOT NULL
    • target_title TEXT
    • action_name TEXT NOT NULL (assigned, mentioned, etc.)
    • author_id INTEGER
    • author_username TEXT
    • body TEXT (the todo message/snippet)
    • state TEXT NOT NULL (pending)
    • created_at INTEGER NOT NULL (epoch ms)
    • updated_at INTEGER NOT NULL (epoch ms)
    • synced_at INTEGER NOT NULL (epoch ms)
    • project_path TEXT (for display even if project not synced)
  • AC-1.2: Create index idx_todos_state_action on (state, action_name)
  • AC-1.3: Create index idx_todos_target on (target_type, target_id)
  • AC-1.4: Create index idx_todos_created on (created_at DESC)
  • AC-1.5: Migration increments schema version

AC-2: GitLab API Client

  • AC-2.1: Add fetch_todos() method to GitLab client
  • AC-2.2: Fetch only state=pending todos
  • AC-2.3: Handle pagination (use existing pagination pattern)
  • AC-2.4: Parse all target types GitLab returns
  • AC-2.5: Extract project path from target_url for non-synced projects

AC-3: Sync Pipeline

  • AC-3.1: Add todos sync step to lore sync pipeline
  • AC-3.2: Sync todos AFTER issues/MRs (ordering consistency)
  • AC-3.3: Snapshot semantics: fetch all pending, upsert, delete missing (= marked done elsewhere)
  • AC-3.4: Track synced_at timestamp
  • AC-3.5: Log todo sync stats: fetched, inserted, updated, deleted
  • AC-3.6: Add --no-todos flag to skip todo sync

AC-4: Action Type Handling

  • AC-4.1: Store ALL action types from GitLab
  • AC-4.2: Display only core actions:
    • assigned — assigned to issue/MR
    • mentioned — @mentioned in comment
    • directly_addressed — @mentioned at start of comment
    • approval_required — approval needed on MR
    • build_failed — CI failed on your MR
    • unmergeable — merge conflicts on your MR
  • AC-4.3: Skip display (but store) niche actions: merge_train_removed, member_access_requested, marked

AC-5: lore todos Command

  • AC-5.1: New subcommand lore todos (alias: todo)
  • AC-5.2: Display all pending todos, no filters
  • AC-5.3: Group by action type: Assignments | Mentions | Approvals | Build Issues
  • AC-5.4: Per-todo display: target title, project path, author, age, action
  • AC-5.5: Flag non-synced project todos with [external] indicator
  • AC-5.6: Human-readable output with colors/icons
  • AC-5.7: Robot mode: standard {ok, data, meta} envelope

AC-6: lore me --todos Section

  • AC-6.1: Add --todos flag to MeArgs
  • AC-6.2: When no section flags: show todos in full dashboard
  • AC-6.3: When --todos flag only: show only todos section
  • AC-6.4: Todos section grouped by action type
  • AC-6.5: Todos NOT filtered by --project (always account-wide)
  • AC-6.6: Robot mode includes todos array in dashboard response

AC-7: lore me Summary Header

  • AC-7.1: Add pending_todo_count to MeSummary struct
  • AC-7.2: Display todo count in summary line (human mode)
  • AC-7.3: Include pending_todo_count in robot mode summary

AC-8: Activity Feed Enrichment

  • AC-8.1: Todos with local issue/MR target appear in activity feed
  • AC-8.2: New ActivityEventType::Todo variant
  • AC-8.3: Todo events show: action type, author, target in summary
  • AC-8.4: Sorted chronologically with other activity events
  • AC-8.5: Respect --since filter on todo created_at

AC-9: Non-Synced Project Handling

  • AC-9.1: Store todos even if target project not in config
  • AC-9.2: Display [external] indicator for non-synced project todos
  • AC-9.3: Show project path (extracted from target URL)
  • AC-9.4: Graceful fallback when target title unavailable

AC-10: Attention State

  • AC-10.1: Attention state calculation remains note-based (unchanged)
  • AC-10.2: Todos are separate signal, do not affect attention state
  • AC-10.3: Document this design decision in code comments

AC-11: Robot Mode Schema

  • AC-11.1: lore todos --robot returns:
    {
      "ok": true,
      "data": {
        "todos": [{
          "id": 123,
          "gitlab_todo_id": 456,
          "action": "mentioned",
          "target_type": "Issue",
          "target_iid": 42,
          "target_title": "Fix login bug",
          "target_url": "https://...",
          "project_path": "group/repo",
          "author_username": "jdoe",
          "body": "Hey @you, can you look at this?",
          "created_at_iso": "2026-02-20T10:00:00Z",
          "is_external": false
        }],
        "counts": {
          "total": 8,
          "assigned": 2,
          "mentioned": 5,
          "approval_required": 1,
          "build_failed": 0,
          "unmergeable": 0
        }
      },
      "meta": {"elapsed_ms": 42}
    }
    
  • AC-11.2: lore me --robot includes todos and pending_todo_count in response
  • AC-11.3: Support --fields minimal for token efficiency

AC-12: Documentation

  • AC-12.1: Update CLAUDE.md with lore todos command reference
  • AC-12.2: Update lore robot-docs manifest with todos schema
  • AC-12.3: Add todos to CLI help output

AC-13: Quality Gates

  • AC-13.1: cargo check --all-targets passes
  • AC-13.2: cargo clippy --all-targets -- -D warnings passes
  • AC-13.3: cargo fmt --check passes
  • AC-13.4: cargo test passes with new tests

Technical Notes

GitLab API Endpoint

GET /api/v4/todos?state=pending

Response fields: id, project, author, action_name, target_type, target, target_url, body, state, created_at, updated_at

Sync Deletion Strategy

Snapshot semantics: a todo disappearing from API response means it was marked done elsewhere. Delete from local DB to stay in sync.

Project Path Extraction

For non-synced projects, extract path from target_url:

https://gitlab.com/group/subgroup/repo/-/issues/42
                  ^^^^^^^^^^^^^^^^^ extract this

Action Type Grouping

Group Actions
Assignments assigned
Mentions mentioned, directly_addressed
Approvals approval_required
Build Issues build_failed, unmergeable

Rollout Slices

Slice A: Schema + Client

  • Migration 028
  • GitLabTodo type
  • fetch_todos() client method
  • Unit tests for deserialization

Slice B: Sync Integration

  • src/ingestion/todos.rs
  • Integrate into lore sync
  • --no-todos flag
  • Sync stats

Slice C: lore todos Command

  • CLI args + dispatch
  • Human + robot rendering
  • Autocorrect aliases

Slice D: lore me Integration

  • --todos flag
  • Summary count
  • Activity feed enrichment

Slice E: Polish

  • Edge case tests
  • Documentation updates
  • robot-docs manifest

References