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>
9.2 KiB
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:
- A new
--todossection inlore me - Enrichment of the activity feed in
lore me - A standalone
lore todoscommand
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 todoscommand - Todo-based attention state boosting
- Notification settings API integration (deferred to separate plan)
Acceptance Criteria
AC-1: Database Schema
- AC-1.1: Create
todostable with columns:idINTEGER PRIMARY KEYgitlab_todo_idINTEGER NOT NULL UNIQUEproject_idINTEGER REFERENCES projects(id) ON DELETE SET NULL (nullable for non-synced)target_typeTEXT NOT NULL (Issue, MergeRequest, Commit, Epic, etc.)target_idINTEGER (GitLab ID of target entity)target_iidINTEGER (IID for issues/MRs, nullable)target_urlTEXT NOT NULLtarget_titleTEXTaction_nameTEXT NOT NULL (assigned, mentioned, etc.)author_idINTEGERauthor_usernameTEXTbodyTEXT (the todo message/snippet)stateTEXT NOT NULL (pending)created_atINTEGER NOT NULL (epoch ms)updated_atINTEGER NOT NULL (epoch ms)synced_atINTEGER NOT NULL (epoch ms)project_pathTEXT (for display even if project not synced)
- AC-1.2: Create index
idx_todos_state_actionon(state, action_name) - AC-1.3: Create index
idx_todos_targeton(target_type, target_id) - AC-1.4: Create index
idx_todos_createdon(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=pendingtodos - 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_urlfor non-synced projects
AC-3: Sync Pipeline
- AC-3.1: Add todos sync step to
lore syncpipeline - 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_attimestamp - AC-3.5: Log todo sync stats: fetched, inserted, updated, deleted
- AC-3.6: Add
--no-todosflag 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/MRmentioned— @mentioned in commentdirectly_addressed— @mentioned at start of commentapproval_required— approval needed on MRbuild_failed— CI failed on your MRunmergeable— 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
--todosflag toMeArgs - AC-6.2: When no section flags: show todos in full dashboard
- AC-6.3: When
--todosflag 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
todosarray in dashboard response
AC-7: lore me Summary Header
- AC-7.1: Add
pending_todo_counttoMeSummarystruct - AC-7.2: Display todo count in summary line (human mode)
- AC-7.3: Include
pending_todo_countin 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::Todovariant - 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
--sincefilter on todocreated_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 --robotreturns:{ "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 --robotincludestodosandpending_todo_countin response - AC-11.3: Support
--fields minimalfor token efficiency
AC-12: Documentation
- AC-12.1: Update CLAUDE.md with
lore todoscommand reference - AC-12.2: Update
lore robot-docsmanifest with todos schema - AC-12.3: Add todos to CLI help output
AC-13: Quality Gates
- AC-13.1:
cargo check --all-targetspasses - AC-13.2:
cargo clippy --all-targets -- -D warningspasses - AC-13.3:
cargo fmt --checkpasses - AC-13.4:
cargo testpasses 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
GitLabTodotypefetch_todos()client method- Unit tests for deserialization
Slice B: Sync Integration
src/ingestion/todos.rs- Integrate into
lore sync --no-todosflag- Sync stats
Slice C: lore todos Command
- CLI args + dispatch
- Human + robot rendering
- Autocorrect aliases
Slice D: lore me Integration
--todosflag- Summary count
- Activity feed enrichment
Slice E: Polish
- Edge case tests
- Documentation updates
robot-docsmanifest