# Lore Command Surface Analysis

**Date:** 2026-02-26
**Version:** v0.9.1 (439c20e)
**Scope:** Full command inventory, overlap analysis, consolidation proposals, robot-mode optimization proposals

---

## 1. Command Inventory

34 commands across 6 categories.

| Category | Commands | Count |
|---|---|---|
| Entity Query | `issues`, `mrs`, `notes`, `search`, `count` | 5 |
| Intelligence | `who` (5 modes), `timeline`, `related`, `drift`, `me`, `file-history`, `trace` | 7 (11 with who sub-modes) |
| Data Pipeline | `sync`, `ingest`, `generate-docs`, `embed` | 4 |
| Diagnostics | `health`, `auth`, `doctor`, `status`, `stats` | 5 |
| Setup | `init`, `token`, `cron`, `migrate` | 4 |
| Meta | `version`, `completions`, `robot-docs` | 3 |

### 1.1 Entity Query Commands

#### `issues` (alias: `issue`)

List or show issues from local database.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `[IID]` | positional | — | Omit to list, provide to show detail |
| `-n, --limit` | int | 50 | Max results |
| `--fields` | string | — | Select output columns (preset: `minimal`) |
| `-s, --state` | enum | — | `opened\|closed\|all` |
| `-p, --project` | string | — | Filter by project (fuzzy) |
| `-a, --author` | string | — | Filter by author username |
| `-A, --assignee` | string | — | Filter by assignee username |
| `-l, --label` | string[] | — | Filter by labels (AND logic, repeatable) |
| `-m, --milestone` | string | — | Filter by milestone title |
| `--status` | string[] | — | Filter by work-item status (COLLATE NOCASE, OR logic) |
| `--since` | duration/date | — | Filter by created date (`7d`, `2w`, `YYYY-MM-DD`) |
| `--due-before` | date | — | Filter by due date |
| `--has-due` | flag | — | Show only issues with due dates |
| `--sort` | enum | `updated` | `updated\|created\|iid` |
| `--asc` | flag | — | Sort ascending |
| `-o, --open` | flag | — | Open first match in browser |

**DB tables:** `issues`, `projects`, `issue_assignees`, `issue_labels`, `labels`
**Detail mode adds:** `discussions`, `notes`, `entity_references` (closing MRs)

**Robot output (list):**
```json
{
  "ok": true,
  "data": {
    "issues": [
      {
        "iid": 42, "title": "Fix auth", "state": "opened",
        "author_username": "jdoe", "labels": ["backend"],
        "assignees": ["jdoe"], "discussion_count": 3,
        "unresolved_count": 1, "created_at_iso": "...",
        "updated_at_iso": "...", "web_url": "...",
        "project_path": "group/repo",
        "status_name": "In progress"
      }
    ],
    "total_count": 150, "showing": 50
  },
  "meta": { "elapsed_ms": 40, "available_statuses": ["Open", "In progress", "Closed"] }
}
```

**Minimal preset:** `iid`, `title`, `state`, `updated_at_iso`

---

#### `mrs` (aliases: `mr`, `merge-request`, `merge-requests`)

List or show merge requests.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `[IID]` | positional | — | Omit to list, provide to show detail |
| `-n, --limit` | int | 50 | Max results |
| `--fields` | string | — | Select output columns (preset: `minimal`) |
| `-s, --state` | enum | — | `opened\|merged\|closed\|locked\|all` |
| `-p, --project` | string | — | Filter by project |
| `-a, --author` | string | — | Filter by author |
| `-A, --assignee` | string | — | Filter by assignee |
| `-r, --reviewer` | string | — | Filter by reviewer |
| `-l, --label` | string[] | — | Filter by labels (AND) |
| `--since` | duration/date | — | Filter by created date |
| `-d, --draft` | flag | — | Draft MRs only |
| `-D, --no-draft` | flag | — | Exclude drafts |
| `--target` | string | — | Filter by target branch |
| `--source` | string | — | Filter by source branch |
| `--sort` | enum | `updated` | `updated\|created\|iid` |
| `--asc` | flag | — | Sort ascending |
| `-o, --open` | flag | — | Open in browser |

**DB tables:** `merge_requests`, `projects`, `mr_reviewers`, `mr_labels`, `labels`, `mr_assignees`
**Detail mode adds:** `discussions`, `notes`, `mr_diffs`

**Minimal preset:** `iid`, `title`, `state`, `updated_at_iso`

---

#### `notes` (alias: `note`)

List discussion notes/comments with fine-grained filters.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `-n, --limit` | int | 50 | Max results |
| `--fields` | string | — | Preset: `minimal` |
| `-a, --author` | string | — | Filter by author |
| `--note-type` | enum | — | `DiffNote\|DiscussionNote` |
| `--contains` | string | — | Body text substring filter |
| `--note-id` | int | — | Internal note ID |
| `--gitlab-note-id` | int | — | GitLab note ID |
| `--discussion-id` | string | — | Discussion ID filter |
| `--include-system` | flag | — | Include system notes |
| `--for-issue` | int | — | Notes on specific issue (requires `-p`) |
| `--for-mr` | int | — | Notes on specific MR (requires `-p`) |
| `-p, --project` | string | — | Scope to project |
| `--since` | duration/date | — | Created after |
| `--until` | date | — | Created before (inclusive) |
| `--path` | string | — | File path filter (exact or prefix with `/`) |
| `--resolution` | enum | — | `any\|unresolved\|resolved` |
| `--sort` | enum | `created` | `created\|updated` |
| `--asc` | flag | — | Sort ascending |
| `--open` | flag | — | Open in browser |

**DB tables:** `notes`, `discussions`, `projects`, `issues`, `merge_requests`

**Minimal preset:** `id`, `author_username`, `body`, `created_at_iso`

---

#### `search` (aliases: `find`, `query`)

Semantic + full-text search across indexed documents.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `<QUERY>` | positional | required | Search query string |
| `--mode` | enum | `hybrid` | `lexical\|hybrid\|semantic` |
| `--type` | enum | — | `issue\|mr\|discussion\|note` |
| `--author` | string | — | Filter by author |
| `-p, --project` | string | — | Scope to project |
| `--label` | string[] | — | Filter by labels (AND) |
| `--path` | string | — | File path filter |
| `--since` | duration/date | — | Created after |
| `--updated-since` | duration/date | — | Updated after |
| `-n, --limit` | int | 20 | Max results (max: 100) |
| `--fields` | string | — | Preset: `minimal` |
| `--explain` | flag | — | Show ranking breakdown |
| `--fts-mode` | enum | `safe` | `safe\|raw` |

**DB tables:** `documents`, `documents_fts` (FTS5), `embeddings` (vec0), `document_labels`, `document_paths`, `projects`

**Robot output:**
```json
{
  "data": {
    "query": "authentication bug",
    "mode": "hybrid",
    "total_results": 15,
    "results": [
      {
        "document_id": 1234, "source_type": "issue",
        "title": "Fix SSO auth", "url": "...",
        "author": "jdoe", "project_path": "group/repo",
        "labels": ["auth"], "paths": ["src/auth/"],
        "snippet": "...matching text...",
        "score": 0.85,
        "explain": { "vector_rank": 2, "fts_rank": 1, "rrf_score": 0.85 }
      }
    ],
    "warnings": []
  }
}
```

**Minimal preset:** `document_id`, `title`, `source_type`, `score`

---

#### `count`

Count entities in local database.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `<ENTITY>` | positional | required | `issues\|mrs\|discussions\|notes\|events` |
| `-f, --for` | enum | — | Parent type: `issue\|mr` |

**DB tables:** Conditional aggregation on `issues`, `merge_requests`, `discussions`, `notes`, event tables

**Robot output:**
```json
{
  "data": {
    "entity": "merge_requests",
    "count": 1234,
    "breakdown": { "opened": 100, "closed": 50, "merged": 1084 }
  }
}
```

---

### 1.2 Intelligence Commands

#### `who` (People Intelligence)

Five sub-modes, dispatched by argument shape.

| Mode | Trigger | Purpose |
|---|---|---|
| **expert** | `who <path>` or `who --path <path>` | Who knows about a code area? |
| **workload** | `who @username` | What is this person working on? |
| **reviews** | `who @username --reviews` | Review pattern analysis |
| **active** | `who --active` | Unresolved discussions needing attention |
| **overlap** | `who --overlap <path>` | Who else touches these files? |

**Shared flags:**

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `-p, --project` | string | — | Scope to project |
| `-n, --limit` | int | varies | Max results (1-500) |
| `--fields` | string | — | Preset: `minimal` |
| `--since` | duration/date | — | Time window |
| `--include-bots` | flag | — | Include bot users |
| `--include-closed` | flag | — | Include closed issues/MRs |
| `--all-history` | flag | — | Query all history |

**Expert-only flags:** `--detail` (per-MR breakdown), `--as-of` (score at point in time), `--explain-score` (score breakdown)

**DB tables by mode:**

| Mode | Primary Tables |
|---|---|
| expert | `notes` (INDEXED BY idx_notes_diffnote_path_created), `merge_requests`, `mr_reviewers` |
| workload | `issues`, `merge_requests`, `mr_reviewers` |
| reviews | `merge_requests`, `discussions`, `notes` |
| active | `discussions`, `notes`, `issues`, `merge_requests` |
| overlap | `notes`, `mr_file_changes`, `merge_requests` |

**Robot output (expert):**
```json
{
  "data": {
    "mode": "expert",
    "result": {
      "experts": [
        { "username": "jdoe", "score": 42.5, "detail": { "mr_ids_author": [99, 101] } }
      ]
    }
  }
}
```

**Minimal presets:** expert: `username, score` | workload: `iid, title, state` | reviews: `name, count, percentage` | active: `entity_type, iid, title, participants` | overlap: `username, touch_count`

---

#### `timeline`

Reconstruct chronological event history for a topic/entity with cross-reference expansion.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `<QUERY>` | positional | required | Search text or entity ref (`issue:42`, `mr:99`) |
| `-p, --project` | string | — | Scope to project |
| `--since` | duration/date | — | Filter events after |
| `--depth` | int | 1 | Cross-ref expansion depth (0=none) |
| `--no-mentions` | flag | — | Skip "mentioned" edges, keep "closes"/"related" |
| `-n, --limit` | int | 100 | Max events |
| `--fields` | string | — | Preset: `minimal` |
| `--max-seeds` | int | 10 | Max seed entities from search |
| `--max-entities` | int | 50 | Max expanded entities |
| `--max-evidence` | int | 10 | Max evidence notes |

**Pipeline:** SEED -> HYDRATE -> EXPAND -> COLLECT -> RENDER

**DB tables:** `issues`, `merge_requests`, `discussions`, `notes`, `entity_references`, `resource_state_events`, `resource_label_events`, `resource_milestone_events`, `documents` (for search seeding)

**Robot output:**
```json
{
  "data": {
    "query": "authentication", "event_count": 25,
    "seed_entities": [{ "type": "issue", "iid": 42, "project": "group/repo" }],
    "expanded_entities": [
      { "type": "mr", "iid": 99, "project": "group/repo", "depth": 1,
        "via": { "from": { "type": "issue", "iid": 42 }, "reference_type": "closes" } }
    ],
    "events": [
      {
        "timestamp": "2026-01-15T10:30:00Z", "entity_type": "issue",
        "entity_iid": 42, "project": "group/repo",
        "event_type": "state_changed", "summary": "Reopened",
        "actor": "jdoe", "is_seed": true,
        "evidence_notes": [{ "author": "jdoe", "snippet": "..." }]
      }
    ]
  },
  "meta": {
    "elapsed_ms": 150, "search_mode": "fts",
    "expansion_depth": 1, "include_mentions": true,
    "total_entities": 5, "total_events": 25
  }
}
```

**Minimal preset:** `timestamp`, `type`, `entity_iid`, `detail`

---

#### `me` (Personal Dashboard)

Personal work dashboard with issues, MRs, activity, and since-last-check inbox.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `--issues` | flag | — | Open issues section only |
| `--mrs` | flag | — | MRs section only |
| `--activity` | flag | — | Activity feed only |
| `--since` | duration/date | `30d` | Activity window |
| `-p, --project` | string | — | Scope to one project |
| `--all` | flag | — | All synced projects |
| `--user` | string | — | Override configured username |
| `--fields` | string | — | Preset: `minimal` |
| `--reset-cursor` | flag | — | Clear since-last-check cursor |

**Sections (no flags = all):** Issues, MRs authored, MRs reviewing, Activity feed, Inbox (since last check)

**DB tables:** `issues`, `merge_requests`, `resource_state_events`, `projects`, `issue_labels`, `mr_labels`

**Robot output:**
```json
{
  "data": {
    "username": "jdoe",
    "summary": {
      "project_count": 3, "open_issue_count": 5,
      "authored_mr_count": 2, "reviewing_mr_count": 1,
      "needs_attention_count": 3
    },
    "since_last_check": {
      "cursor_iso": "2026-02-25T18:00:00Z",
      "total_event_count": 8,
      "groups": [
        {
          "entity_type": "issue", "entity_iid": 42,
          "entity_title": "Fix auth", "project": "group/repo",
          "events": [
            { "timestamp_iso": "...", "event_type": "comment",
              "actor": "reviewer", "summary": "New comment" }
          ]
        }
      ]
    },
    "open_issues": [
      { "project": "group/repo", "iid": 42, "title": "Fix auth",
        "state": "opened", "attention_state": "needs_attention",
        "status_name": "In progress", "labels": ["auth"],
        "updated_at_iso": "..." }
    ],
    "open_mrs_authored": [...],
    "reviewing_mrs": [...],
    "activity": [...]
  }
}
```

**Minimal presets:** Items: `iid, title, attention_state, updated_at_iso` | Activity: `timestamp_iso, event_type, entity_iid, actor`

---

#### `file-history`

Show which MRs touched a file, with linked discussions.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `<PATH>` | positional | required | File path to trace |
| `-p, --project` | string | — | Scope to project |
| `--discussions` | flag | — | Include DiffNote snippets |
| `--no-follow-renames` | flag | — | Skip rename chain resolution |
| `--merged` | flag | — | Only merged MRs |
| `-n, --limit` | int | 50 | Max MRs |

**DB tables:** `mr_file_changes`, `merge_requests`, `notes` (DiffNotes), `projects`

**Robot output:**
```json
{
  "data": {
    "path": "src/auth/middleware.rs",
    "rename_chain": [
      { "previous_path": "src/auth.rs", "mr_iid": 55, "merged_at": "..." }
    ],
    "merge_requests": [
      { "iid": 99, "title": "Refactor auth", "state": "merged",
        "author": "jdoe", "merged_at": "...", "change_type": "modified" }
    ],
    "discussions": [
      { "discussion_id": 123, "mr_iid": 99, "author": "reviewer",
        "body_snippet": "...", "path": "src/auth/middleware.rs" }
    ]
  },
  "meta": { "elapsed_ms": 30, "total_mrs": 5, "renames_followed": true }
}
```

---

#### `trace`

File -> MR -> issue -> discussion chain to understand why code was introduced.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `<PATH>` | positional | required | File path (future: `:line` suffix) |
| `-p, --project` | string | — | Scope to project |
| `--discussions` | flag | — | Include DiffNote snippets |
| `--no-follow-renames` | flag | — | Skip rename chain |
| `-n, --limit` | int | 20 | Max chains |

**DB tables:** `mr_file_changes`, `merge_requests`, `issues`, `discussions`, `notes`, `entity_references`

**Robot output:**
```json
{
  "data": {
    "path": "src/auth/middleware.rs",
    "resolved_paths": ["src/auth/middleware.rs", "src/auth.rs"],
    "trace_chains": [
      {
        "mr_iid": 99, "mr_title": "Refactor auth", "mr_state": "merged",
        "mr_author": "jdoe", "change_type": "modified",
        "merged_at_iso": "...", "web_url": "...",
        "issues": [42],
        "discussions": [
          { "discussion_id": 123, "author_username": "reviewer",
            "body_snippet": "...", "path": "src/auth/middleware.rs" }
        ]
      }
    ]
  },
  "meta": { "tier": "api_only", "total_chains": 3, "renames_followed": 1 }
}
```

---

#### `related`

Find semantically related entities via vector search.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `<QUERY_OR_TYPE>` | positional | required | Entity type (`issues`, `mrs`) or free text |
| `[IID]` | positional | — | Entity IID (required with entity type) |
| `-n, --limit` | int | 10 | Max results |
| `-p, --project` | string | — | Scope to project |

**Two modes:**
- Entity mode: `related issues 42` — find entities similar to issue #42
- Query mode: `related "auth flow"` — find entities matching free text

**DB tables:** `documents`, `embeddings` (vec0), `projects`

**Requires:** Ollama running (for query mode embedding)

---

#### `drift`

Detect discussion divergence from original intent.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `<ENTITY_TYPE>` | positional | required | Currently only `issues` |
| `<IID>` | positional | required | Entity IID |
| `--threshold` | f32 | 0.4 | Similarity threshold (0.0-1.0) |
| `-p, --project` | string | — | Scope to project |

**DB tables:** `issues`, `discussions`, `notes`, `embeddings`

**Requires:** Ollama running

---

### 1.3 Data Pipeline Commands

#### `sync` (Full Pipeline)

Complete sync: ingest -> generate-docs -> embed.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `--full` | flag | — | Full re-sync (reset cursors) |
| `-f, --force` | flag | — | Override stale lock |
| `--no-embed` | flag | — | Skip embedding |
| `--no-docs` | flag | — | Skip doc generation |
| `--no-events` | flag | — | Skip resource events |
| `--no-file-changes` | flag | — | Skip MR file changes |
| `--no-status` | flag | — | Skip work-item status enrichment |
| `--dry-run` | flag | — | Preview without changes |
| `-t, --timings` | flag | — | Show timing breakdown |
| `--lock` | flag | — | Acquire file lock |
| `--issue` | int[] | — | Surgically sync specific issues (repeatable) |
| `--mr` | int[] | — | Surgically sync specific MRs (repeatable) |
| `-p, --project` | string | — | Required with `--issue`/`--mr` |
| `--preflight-only` | flag | — | Validate without DB writes |

**Stages:** Ingest -> GraphQL status enrichment -> Generate docs -> Embed

#### `ingest`

Fetch data from GitLab API only.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `[ENTITY]` | positional | — | `issues` or `mrs` (omit for all) |
| `-p, --project` | string | — | Filter to single project |
| `-f, --force` | flag | — | Override stale lock |
| `--full` | flag | — | Full re-sync |
| `--dry-run` | flag | — | Preview |

#### `generate-docs`

Create searchable documents from ingested data.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `--full` | flag | — | Full rebuild |
| `-p, --project` | string | — | Single project rebuild |

#### `embed`

Generate vector embeddings via Ollama.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `--full` | flag | — | Re-embed all |
| `--retry-failed` | flag | — | Retry failed embeddings |

**Requires:** Ollama running with `nomic-embed-text`

---

### 1.4 Diagnostic Commands

#### `health`

Quick pre-flight check. Exit 0 = healthy, exit 19 = unhealthy.

**Checks:** config found, DB found, schema current.

```json
{
  "data": {
    "healthy": true,
    "config_found": true, "db_found": true,
    "schema_current": true, "schema_version": 28
  }
}
```

#### `auth`

Verify GitLab authentication.

**Checks:** token set, GitLab reachable, user identity.

#### `doctor`

Comprehensive environment check.

**Checks:** config validity, token, GitLab connectivity, DB health, migration status, Ollama availability, model status.

```json
{
  "data": {
    "config": { "valid": true, "path": "..." },
    "token": { "set": true, "gitlab": { "reachable": true, "user": "jdoe" } },
    "database": { "exists": true, "version": 28, "tables": 25 },
    "ollama": { "available": true, "model_ready": true }
  }
}
```

#### `status` (alias: `st`)

Show sync state per project (last sync times, cursors).

```json
{
  "data": {
    "projects": [
      { "project_path": "group/repo", "last_synced_at": "...",
        "document_count": 5000, "discussion_count": 2000 }
    ]
  }
}
```

#### `stats` (alias: `stat`)

Document and index statistics with optional integrity checks.

| Flag | Type | Default | Purpose |
|---|---|---|---|
| `--check` | flag | — | Run integrity checks |
| `--repair` | flag | — | Fix issues (implies `--check`) |
| `--dry-run` | flag | — | Preview repairs |

```json
{
  "data": {
    "documents": { "total": 61652, "issues": 5000, "mrs": 2000, "notes": 50000 },
    "embeddings": { "total": 80000, "synced": 79500, "pending": 500 },
    "fts": { "total_docs": 61652 },
    "queues": { "pending": 0, "in_progress": 0, "failed": 0 },
    "integrity": { "ok": true }
  }
}
```

---

### 1.5 Setup Commands

| Command | Purpose |
|---|---|
| `init` | Initialize config + DB (interactive or `--non-interactive`) |
| `token set` | Store GitLab token (interactive or `--token`) |
| `token show` | Display token (`--unmask` for full) |
| `cron install` | Schedule auto-sync (`--interval` minutes, default 8) |
| `cron uninstall` | Remove cron job |
| `cron status` | Check cron installation |
| `migrate` | Run pending DB migrations |

### 1.6 Meta Commands

| Command | Purpose |
|---|---|
| `version` | Show version string |
| `completions <shell>` | Generate shell completions (bash/zsh/fish/powershell) |
| `robot-docs` | Machine-readable command manifest (`--brief` for smaller) |

---

## 2. Shared Data Source Map

Which DB tables power which commands. Higher overlap = more consolidation potential.

| Table | Read By |
|---|---|
| `issues` | issues, me, who-workload, search, timeline, trace, count, stats |
| `merge_requests` | mrs, me, who-workload, search, timeline, trace, file-history, count, stats |
| `notes` | notes, issues-detail, mrs-detail, who-expert, who-active, search, timeline, trace, file-history |
| `discussions` | notes, issues-detail, mrs-detail, who-active, who-reviews, timeline, trace |
| `entity_references` | trace, timeline |
| `mr_file_changes` | trace, file-history, who-overlap |
| `resource_state_events` | timeline, me-activity |
| `resource_label_events` | timeline |
| `resource_milestone_events` | timeline |
| `documents` + FTS | search, stats |
| `embeddings` | search, related, drift |
| `document_labels` | search |
| `document_paths` | search |
| `issue_labels` | issues, me |
| `mr_labels` | mrs, me |
| `mr_reviewers` | mrs, who-expert, who-workload |
| `issue_assignees` | issues, me |
| `sync_cursors` | status |
| `dirty_sources` | stats |

---

## 3. Command Network Graph

### 3.1 Data Flow (command A feeds into command B)

```
                    ┌─────────┐
                    │ search  │─────────────────────────────┐
                    └────┬────┘                             │
                         │ iid                              │ topic
                    ┌────▼────┐                        ┌────▼─────┐
              ┌─────│ issues  │◄───────────────────────│ timeline │
              │     │ mrs     │ (detail)               └──────────┘
              │     └────┬────┘                             ▲
              │          │ iid                              │ entity ref
              │     ┌────▼────┐     ┌──────────────┐       │
              │     │ related │     │ file-history  │───────┘
              │     │ drift   │     └──────┬───────┘
              │     └─────────┘            │ MR iids
              │                       ┌────▼────┐
              │                       │  trace  │──── issues (linked)
              │                       └────┬────┘
              │                            │ paths
              │                       ┌────▼────┐
              │                       │   who   │
              │                       │ (expert)│
              │                       └─────────┘
              │
         file paths                   ┌─────────┐
              │                       │   me    │──── issues, mrs (dashboard)
              ▼                       └─────────┘
        ┌──────────┐                       ▲
        │  notes   │                       │ (same data)
        └──────────┘                  ┌────┴──────┐
                                      │who workload│
                                      └───────────┘
```

### 3.2 Shared-Data Clusters

Commands that read from the same primary tables form natural clusters:

**Cluster A: Issue/MR entities** — `issues`, `mrs`, `me`, `who workload`, `count`
All read from `issues` + `merge_requests` with similar filter patterns.

**Cluster B: Notes/discussions** — `notes`, `issues detail`, `mrs detail`, `who expert`, `who active`, `timeline`
All traverse the `discussions` -> `notes` join path.

**Cluster C: File genealogy** — `trace`, `file-history`, `who overlap`
All use `mr_file_changes` with rename chain BFS.

**Cluster D: Semantic/vector** — `search`, `related`, `drift`
All use `documents` + `embeddings` (require Ollama).

**Cluster E: Diagnostics** — `health`, `auth`, `doctor`, `status`, `stats`
All check system state at various granularities.

---

## 4. Overlap Analysis

### 4.1 High Overlap (>70% functional duplication)

#### `who workload` vs `me`

| Dimension | `who @user` (workload) | `me --user @user` |
|---|---|---|
| Assigned issues | Yes | Yes |
| Authored MRs | Yes | Yes |
| Reviewing MRs | Yes | Yes |
| Attention state | No | **Yes** |
| Activity feed | No | **Yes** |
| Since-last-check inbox | No | **Yes** |
| Cross-project | Yes | **Yes** |

**Verdict:** `who workload` is a strict subset of `me`. 85% overlap.

#### `health` vs `doctor`

| Check | `health` | `doctor` |
|---|---|---|
| Config found | Yes | Yes |
| DB exists | Yes | Yes |
| Schema current | Yes | Yes |
| Token valid | No | **Yes** |
| GitLab reachable | No | **Yes** |
| Ollama available | No | **Yes** |

**Verdict:** `health` is a strict subset of `doctor`. 90% overlap (but `health` is fast pre-flight with different exit code semantics).

#### `file-history` vs `trace`

| Feature | `file-history` | `trace` |
|---|---|---|
| Find MRs for file | Yes | Yes |
| Rename chain BFS | Yes | Yes |
| DiffNote discussions | `--discussions` | `--discussions` |
| Follow to linked issues | No | **Yes** |
| `--merged` filter | **Yes** | No |

**Verdict:** `trace` is a superset minus the `--merged` flag. 75% overlap.

#### `related` (query mode) vs `search --mode semantic`

| Feature | `related "text"` | `search "text" --mode semantic` |
|---|---|---|
| Vector similarity | Yes | Yes |
| FTS component | No | No (semantic mode) |
| Filters (labels, author, since) | No | **Yes** |
| Explain ranking | No | **Yes** |
| Field selection | No | **Yes** |

**Verdict:** `related` query mode is `search --mode semantic` without filters. 80% overlap.

### 4.2 Medium Overlap (40-70%)

| Pair | Overlap % | Notes |
|---|---|---|
| `who expert` vs `who overlap` | ~50% | Both answer "who works on this file"; expert has decay scoring, overlap has raw counts |
| `timeline` vs `trace` | ~45% | Both follow `entity_references`; timeline is entity-centric, trace is file-centric |
| `auth` vs `doctor` | ~100% of auth | auth is fully contained within doctor |
| `count` vs `stats` | ~40% | Both answer "how much data" at different layers (entity vs document index) |
| `notes` vs `issues/mrs detail` | ~50% | Detail embeds notes inline; `notes` adds independent filtering |

### 4.3 No Significant Overlap

| Command | Reason |
|---|---|
| `drift` | Unique: semantic divergence detection |
| `timeline` | Unique: multi-entity chronological reconstruction |
| `search` (hybrid) | Unique: FTS + vector combined ranking |
| `me` (inbox) | Unique: cursor-based since-last-check |
| `who expert` | Unique: half-life decay scoring with signal types |
| `who reviews` | Unique: review pattern analysis |

---

## 5. Agent Workflow Analysis

### 5.1 Common Workflows with Round-Trip Counts

#### Flow 1: "What should I work on?" — 4 round trips

```
me                          → dashboard overview
issues <iid> -p proj       → detail on picked issue
trace src/relevant/file.rs  → understand code context
who src/relevant/file.rs    → find domain experts
```

#### Flow 2: "What happened with this feature?" — 3 round trips

```
search "feature name"       → find relevant entities
timeline "feature name"     → reconstruct chronological history
related issues 42           → discover connected work
```

#### Flow 3: "Why was this code changed?" — 3 round trips

```
trace src/file.rs           → file -> MR -> issue chain
issues <iid> -p proj       → full issue detail
timeline "issue:42"         → full history with cross-refs
```

#### Flow 4: "Is the system healthy?" — 2-4 round trips

```
health                      → quick pre-flight
doctor                      → detailed diagnostics
status                      → sync state per project
stats                       → document/index health
```

#### Flow 5: "Who can review this?" — 2-3 round trips

```
who src/auth/               → find file experts
who @jdoe --reviews         → check reviewer's patterns
```

#### Flow 6: "Find and understand an issue" — 4 round trips

```
search "query"              → discover entities
issues <iid>                → full detail with discussions
timeline "issue:42"         → chronological context
related issues 42           → connected entities
```

### 5.2 Token Cost Profiles

Measured typical response sizes in robot mode:

| Command | Typical Tokens | Notes |
|---|---|---|
| `me` (full) | 2000-5000 | Scales with open items |
| `me --fields minimal` | 500-1500 | Good reduction |
| `issues` (list, n=50) | 1500-3000 | Labels inflate it |
| `issues <iid>` (detail) | 1000-8000 | Discussions dominate |
| `timeline` (limit=100) | 2000-6000 | Events + evidence |
| `search` (n=20) | 1000-3000 | Snippets dominate |
| `who expert` | 300-800 | Compact |
| `trace` | 500-2000 | Depends on chain depth |
| `health` | ~100 | Very compact |
| `stats` | ~500 | Fixed structure |

---

## 6. Proposals

### 6.1 Command Consolidations

#### A. Absorb `file-history` into `trace --shallow`

**Rationale:** 75% code overlap. Both do rename chain BFS on `mr_file_changes`, both optionally include DiffNote discussions. `trace` just follows entity_references one step further.

**Change:**
- `trace <path>` — full chain: file -> MR -> issue -> discussions (existing)
- `trace <path> --shallow` — MR-only, no issue chain (replaces `file-history`)
- Move `--merged` flag from `file-history` to `trace`
- Deprecate `file-history` with alias redirect

**Impact:** -1 command. No functionality lost.

#### B. Absorb `auth` into `doctor`

**Rationale:** `auth` checks token + GitLab connectivity. `doctor` checks the same plus DB + Ollama. `auth` is 100% contained within `doctor`.

**Change:**
- `doctor` — full check (existing)
- `doctor --auth` — token + GitLab only (replaces `auth`)
- Keep `health` separate (fast pre-flight, different exit code contract)
- Deprecate `auth` with alias redirect

**Impact:** -1 command. `health` stays because its ~50ms pre-flight with exit 0/19 contract is valuable for scripting.

#### C. Remove `related` query-mode, keep entity-mode

**Rationale:** `related "auth flow"` is functionally identical to `search "auth flow" --mode semantic` but with fewer filter options.

**Change:**
- `related issues 42` — entity-seeded mode (keep, it's unique)
- `related "free text"` — print deprecation, suggest `search --mode semantic`
- Eventually remove query-mode entirely

**Impact:** -1 mode. Entity-seeded mode stays because it seeds from a specific entity's embedding rather than generating a new one.

#### D. Merge `who overlap` into `who expert` output

**Rationale:** `who overlap` reports who touches a file (raw count). `who expert` reports who knows a file (scored). Overlap is strictly less information.

**Change:**
- `who <path>` (expert) adds `touch_count` and `last_touch_at` fields to each expert row
- `who --overlap <path>` becomes an alias for `who <path> --fields username,touch_count`
- Deprecate `--overlap` flag with redirect

**Impact:** -1 sub-mode. Agents get both perspectives in one call.

#### E. Merge `count` and `status` into `stats`

**Rationale:** Three commands answer "how much data do I have?":
- `count issues` — entity counts with state breakdown
- `status` — sync cursor positions per project
- `stats` — document/index counts + integrity

**Change:**
- `stats` — document/index health (existing)
- `stats --entities` — adds entity counts (replaces `count`)
- `stats --sync` — adds sync cursor positions (replaces `status`)
- `stats --all` — everything
- Bare `stats` keeps current behavior (documents + queues + integrity)
- Deprecate `count` and `status` with alias redirects

**Impact:** -2 commands. Progressive disclosure via flags.

#### Consolidation Summary

| Before | After | Commands Removed |
|---|---|---|
| `file-history`, `trace` | `trace` (+ `--shallow`) | -1 |
| `auth`, `doctor` | `doctor` (+ `--auth`) | -1 |
| `related` query-mode | `search --mode semantic` | -1 mode |
| `who overlap`, `who expert` | `who expert` (+ touch_count) | -1 sub-mode |
| `count`, `status`, `stats` | `stats` (+ `--entities`, `--sync`) | -2 |

**Total: 34 commands -> 29 commands** (5 fewer entry points for agents to learn).

---

### 6.2 Robot-Mode Optimizations

These are additive changes that reduce round trips and token waste without removing commands.

#### A. `--include` flag for embedded sub-queries

The single highest-impact optimization. Agents constantly fetch an entity and then immediately need related context.

**Syntax:**
```bash
lore -J issues 42 -p proj --include timeline,related
lore -J mrs 99 -p proj --include timeline,trace
lore -J trace src/auth/ -p proj --include experts
lore -J me --include detail
```

**Response shape (embedded data uses `_` prefix):**
```json
{
  "ok": true,
  "data": {
    "iid": 42, "title": "Fix auth", "state": "opened",
    "discussions": [...],
    "_timeline": {
      "event_count": 15,
      "events": [...]
    },
    "_related": {
      "similar_entities": [...]
    }
  }
}
```

**Include matrix (which includes are valid on which commands):**

| Base Command | Valid Includes | Default Limits |
|---|---|---|
| `issues <iid>` | `timeline`, `related`, `trace` | 20 events, 5 related, 5 chains |
| `mrs <iid>` | `timeline`, `related`, `file-changes` | 20 events, 5 related |
| `trace <path>` | `experts`, `timeline` | 5 experts, 20 events |
| `me` | `detail` (inline top-N item details) | 3 items detailed |
| `search` | `detail` (inline top-N result details) | 3 results detailed |

**Round-trip savings:**

| Workflow | Before | After | Savings |
|---|---|---|---|
| Understand an issue | 4 calls | 1 call | **75%** |
| Why was code changed | 3 calls | 1 call | **67%** |
| Find and understand | 4 calls | 2 calls | **50%** |

**Implementation notes:**
- Each include runs its sub-query with reduced limits (configurable via `--include-limit`)
- Sub-query errors are non-fatal: returned as `"_timeline_error": "Ollama unavailable"` instead of failing the whole request
- `--fields minimal` applies to included data too
- Timing breakdown in meta: `"_timeline_ms": 45, "_related_ms": 120`

#### B. `--batch` flag for multi-entity detail lookups

After search/timeline, agents typically need detail on multiple entities:

```bash
# Before: N round trips
lore -J issues 42 -p proj
lore -J issues 55 -p proj
lore -J issues 71 -p proj

# After: 1 round trip
lore -J issues --batch 42,55,71 -p proj
```

**Response:**
```json
{
  "data": {
    "results": [
      { "iid": 42, "title": "Fix auth", ... },
      { "iid": 55, "title": "Add SSO", ... },
      { "iid": 71, "title": "Token refresh", ... }
    ],
    "errors": []
  }
}
```

**Constraints:**
- Max 20 IIDs per batch
- Errors for individual items don't fail the batch
- Works with `--include` for maximum efficiency

#### C. `--depth` control on `me`

The `me` command returns everything by default, which is token-wasteful when an agent just wants to check "do I have work?".

```bash
# Counts only (~100 tokens)
lore -J me --depth counts

# Counts + titles (~400 tokens)
lore -J me --depth titles

# Full (current behavior, 2000+ tokens)
lore -J me --depth full
```

**Depth levels:**

| Level | Returns | Typical Tokens |
|---|---|---|
| `counts` | `summary` block only | ~100 |
| `titles` | summary + item lists (iid, title, attention_state only) | ~400 |
| `full` | Everything including discussions, activity, inbox | ~2000+ |

#### D. Composite `context` command

Purpose-built for the most common agent workflow: "give me everything I need to understand this entity."

```bash
lore -J context issues 42 -p proj
lore -J context mrs 99 -p proj
```

**Equivalent to:**
```bash
lore -J issues 42 -p proj --include timeline,related
```

But with optimized defaults:
- Timeline limited to 20 most recent events
- Related limited to top 5
- Discussions truncated after 5 threads
- Evidence notes capped at 3

**Response:** Same shape as `issues <iid> --include timeline,related` but with tighter defaults.

**Rationale:** Rather than teaching agents the `--include` syntax, provide a single "give me full context" command.

#### E. `--max-tokens` response budget

Let the agent cap response size. The server truncates arrays, omits low-priority fields, and uses shorter representations to stay within budget.

```bash
lore -J me --max-tokens 500
lore -J timeline "feature" --max-tokens 1000
lore -J context issues 42 --max-tokens 2000
```

**Truncation strategy (in priority order):**
1. Apply `--fields minimal` if not already set
2. Reduce array lengths (newest/highest-score items survive)
3. Truncate string fields (description, snippets)
4. Omit null/empty fields
5. Drop included sub-queries (if using `--include`)

**Meta includes truncation notice:**
```json
{
  "meta": {
    "elapsed_ms": 50,
    "truncated": true,
    "original_tokens": 3500,
    "budget_tokens": 1000,
    "dropped": ["_related", "discussions[5:]"]
  }
}
```

#### F. `--format tsv` for maximum token efficiency

Beyond JSON, offer a TSV mode for list commands where structured data is simple:

```bash
lore -J issues --format tsv --fields iid,title,state -n 10
```

**Output:**
```
iid	title	state
42	Fix auth	opened
55	Add SSO	opened
71	Token refresh	closed
```

**Estimated savings:** ~60-70% fewer tokens vs JSON for list responses.

**Applicable to:** `issues` (list), `mrs` (list), `notes` (list), `who expert`, `count`.

**Not applicable to:** Detail views, timeline, search (nested structures).

---

### 6.3 Robot-Mode Optimization Impact Matrix

| Optimization | Effort | Round-Trip Savings | Token Savings | Breaking? |
|---|---|---|---|---|
| `--include` flag | High | **50-75%** | Moderate | No (additive) |
| `--batch` flag | Medium | **N-1 per batch** | Moderate | No (additive) |
| `--depth` on `me` | Low | None | **60-80%** | No (additive) |
| `context` command | Medium | **67-75%** | Moderate | No (additive) |
| `--max-tokens` | High | None | **Variable, up to 80%** | No (additive) |
| `--format tsv` | Medium | None | **60-70% on lists** | No (additive) |

---

## 7. Priority Ranking

Ordered by impact on robot-mode efficiency (round-trip reduction x token savings x implementation ease):

| Priority | Proposal | Category | Effort | Impact |
|---|---|---|---|---|
| **P0** | `--include` flag | Robot optimization | High | Eliminates 2-3 round trips per workflow |
| **P0** | `--depth` on `me` | Robot optimization | Low | 60-80% token reduction on most-used command |
| **P1** | `--batch` for detail views | Robot optimization | Medium | Eliminates N+1 after search/timeline |
| **P1** | Absorb `file-history` into `trace` | Consolidation | Low | Cleaner surface, shared code |
| **P1** | Merge `who overlap` into `who expert` | Consolidation | Low | -1 round trip in review flows |
| **P2** | `context` composite command | Robot optimization | Medium | Single entry point for understanding entities |
| **P2** | Merge `count`+`status` into `stats` | Consolidation | Medium | -2 commands, progressive disclosure |
| **P2** | Absorb `auth` into `doctor` | Consolidation | Low | -1 command |
| **P2** | Remove `related` query-mode | Consolidation | Low | -1 confusing choice |
| **P3** | `--max-tokens` budget | Robot optimization | High | Flexible but hard to implement well |
| **P3** | `--format tsv` | Robot optimization | Medium | High savings but limited applicability |

---

## 8. Appendix: Robot Output Envelope

All robot-mode responses follow:

```json
{
  "ok": true,
  "data": { /* command-specific */ },
  "meta": { "elapsed_ms": 42 }
}
```

Errors (to stderr):
```json
{
  "error": {
    "code": "CONFIG_NOT_FOUND",
    "message": "Configuration file not found",
    "suggestion": "Run 'lore init'",
    "actions": ["lore init"]
  }
}
```

Exit codes: 0 (success), 1 (internal), 2 (usage), 3 (config invalid), 4 (token missing), 5 (auth failed), 6 (resource not found), 7 (rate limited), 8 (network), 9 (DB locked), 10 (DB error), 11 (migration), 12 (I/O), 13 (transform), 14 (Ollama unavailable), 15 (model missing), 16 (embedding failed), 17 (not found), 18 (ambiguous match), 19 (health failed), 20 (config not found).

---

## 9. Appendix: Field Selection Presets

The `--fields` flag supports both presets and custom field lists:

```bash
lore -J issues --fields minimal              # Preset
lore -J mrs --fields iid,title,state,draft   # Custom
```

| Command | Minimal Preset Fields |
|---|---|
| `issues` (list) | `iid`, `title`, `state`, `updated_at_iso` |
| `mrs` (list) | `iid`, `title`, `state`, `updated_at_iso` |
| `notes` (list) | `id`, `author_username`, `body`, `created_at_iso` |
| `search` | `document_id`, `title`, `source_type`, `score` |
| `timeline` | `timestamp`, `type`, `entity_iid`, `detail` |
| `who expert` | `username`, `score` |
| `who workload` | `iid`, `title`, `state` |
| `who reviews` | `name`, `count`, `percentage` |
| `who active` | `entity_type`, `iid`, `title`, `participants` |
| `who overlap` | `username`, `touch_count` |
| `me` (items) | `iid`, `title`, `attention_state`, `updated_at_iso` |
| `me` (activity) | `timestamp_iso`, `event_type`, `entity_iid`, `actor` |
