I excluded the two items in your `## Rejected Recommendations` and focused on net-new improvements.  
These are the highest-impact revisions I’d make.

### 1. Fix the package graph now (avoid a hard Cargo cycle)
Your current plan has `root -> optional lore-tui` and `lore-tui -> lore (root)`, which creates a cyclic dependency risk. Split shared logic into a dedicated core crate so CLI and TUI both depend downward.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 9.1 Dependency Changes
-[workspace]
-members = [".", "crates/lore-tui"]
+[workspace]
+members = [".", "crates/lore-core", "crates/lore-tui"]

@@
-[dependencies]
-lore-tui = { path = "crates/lore-tui", optional = true }
+[dependencies]
+lore-core = { path = "crates/lore-core" }
+lore-tui = { path = "crates/lore-tui", optional = true }

@@ # crates/lore-tui/Cargo.toml
-lore = { path = "../.." }  # Core lore library
+lore-core = { path = "../lore-core" }  # Shared domain/query crate (acyclic graph)
```

### 2. Stop coupling TUI to `cli/commands/*` internals
Calling CLI command modules from TUI is brittle and will drift. Introduce a shared query/service layer with DTOs owned by core.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 4.1 Module Structure
-    action.rs                     # Async action runners (DB queries, GitLab calls)
+    action.rs                     # Task dispatch only
+    service/
+      mod.rs
+      query.rs                    # Shared read services (CLI + TUI)
+      sync.rs                     # Shared sync orchestration facade
+      dto.rs                      # UI-agnostic data contracts

@@ ## 10.2 Modified Files
-src/cli/commands/list.rs               # Extract query_issues(), query_mrs() as pub fns
-src/cli/commands/show.rs               # Extract query_issue_detail(), query_mr_detail() as pub fns
-src/cli/commands/who.rs                # Extract query_experts(), etc. as pub fns
-src/cli/commands/search.rs             # Extract run_search_query() as pub fn
+crates/lore-core/src/query/issues.rs   # Canonical issue queries
+crates/lore-core/src/query/mrs.rs      # Canonical MR queries
+crates/lore-core/src/query/show.rs     # Canonical detail queries
+crates/lore-core/src/query/who.rs      # Canonical people queries
+crates/lore-core/src/query/search.rs   # Canonical search queries
+src/cli/commands/*.rs                  # Consume lore-core query services
+crates/lore-tui/src/action.rs          # Consume lore-core query services
```

### 3. Add a real task supervisor (dedupe + cancellation + priority)
Right now tasks are ad hoc and can overrun each other. Add a scheduler keyed by screen+intent.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 4.5 Async Action System
-The `Cmd::task(|| { ... })` pattern runs a blocking closure on a background thread pool.
+The TUI uses a `TaskSupervisor`:
+- Keyed tasks (`TaskKey`) to dedupe redundant requests
+- Priority lanes (`Input`, `Navigation`, `Background`)
+- Cooperative cancellation tokens per task
+- Late-result drop via generation IDs (not just search)

@@ ## 4.3 Core Types
+pub enum TaskKey {
+    LoadScreen(Screen),
+    Search { generation: u64 },
+    SyncStream,
+}
```

### 4. Correct sync streaming architecture (current sketch loses streamed events)
The sample creates `tx/rx` then drops `rx`; events never reach update loop. Define an explicit stream subscription with bounded queue and backpressure policy.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 4.4 App — Implementing the Model Trait
-        let (tx, _rx) = std::sync::mpsc::channel::<Msg>();
+        let (tx, rx) = std::sync::mpsc::sync_channel::<Msg>(1024);
+        // rx is registered via Subscription::from_receiver("sync-stream", rx)

@@
-            let result = crate::ingestion::orchestrator::run_sync(
+            let result = crate::ingestion::orchestrator::run_sync(
                 &config,
                 &conn,
                 |event| {
@@
-                    let _ = tx.send(Msg::SyncProgress(event.clone()));
-                    let _ = tx.send(Msg::SyncLogLine(format!("{event:?}")));
+                    if tx.try_send(Msg::SyncProgress(event.clone())).is_err() {
+                        let _ = tx.try_send(Msg::SyncBackpressureDrop);
+                    }
+                    let _ = tx.try_send(Msg::SyncLogLine(format!("{event:?}")));
                 },
             );
```

### 5. Upgrade data-plane performance plan (keyset pagination + index contracts)
Virtualized list without keyset paging still forces expensive scans. Add explicit keyset pagination and query-plan CI checks.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 9.3 Phase 0 — Toolchain Gate
-7. p95 list query latency < 75ms on synthetic fixture (10k issues, 5k MRs)
+7. p95 list page fetch latency < 75ms using keyset pagination (10k issues, 5k MRs)
+8. EXPLAIN QUERY PLAN must show index usage for top 10 TUI queries
+9. No full table scan on issues/MRs/discussions under default filters

@@
-8. p95 search latency < 200ms on synthetic fixture (50k documents, lexical mode)
+10. p95 search latency < 200ms on synthetic fixture (50k documents, lexical mode)

+## 9.4 Required Indexes (GA blocker)
+- `issues(project_id, state, updated_at DESC, iid DESC)`
+- `merge_requests(project_id, state, updated_at DESC, iid DESC)`
+- `discussions(project_id, entity_type, entity_iid, created_at DESC)`
+- `notes(discussion_id, created_at ASC)`
```

### 6. Enforce `EntityKey` everywhere (remove bare IID paths)
You correctly identified multi-project IID collisions, but many message/state signatures still use `i64`. Make `EntityKey` mandatory in all navigation and detail loaders.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 4.3 Core Types
-    IssueSelected(i64),
+    IssueSelected(EntityKey),
@@
-    MrSelected(i64),
+    MrSelected(EntityKey),
@@
-    IssueDetailLoaded(IssueDetail),
+    IssueDetailLoaded { key: EntityKey, detail: IssueDetail },
@@
-    MrDetailLoaded(MrDetail),
+    MrDetailLoaded { key: EntityKey, detail: MrDetail },

@@ ## 10.10 State Module — Complete
-                Cmd::msg(Msg::NavigateTo(Screen::IssueDetail(iid)))
+                Cmd::msg(Msg::NavigateTo(Screen::IssueDetail(entity_key)))
```

### 7. Harden filter/search semantics (strict parser + inline diagnostics + explain scores)
Current filter parser silently ignores unknown fields; that causes hidden mistakes. Add strict parse diagnostics and search score explainability.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 10.12.1 Filter Bar Widget
-                _ => {} // Unknown fields silently ignored
+                _ => self.errors.push(format!("Unknown filter field: {}", token.field))

+    pub errors: Vec<String>,   // inline parse/validation errors
+    pub warnings: Vec<String>, // non-fatal coercions

@@ ## 5.6 Search
-- **Live preview:** Selected result shows snippet + metadata in right pane
+- **Live preview:** Selected result shows snippet + metadata in right pane
+- **Explain score:** Optional breakdown (lexical, semantic, recency, boosts) for trust/debug
```

### 8. Add operational resilience: safe mode + panic report + startup fallback
TUI failures should degrade gracefully, not block usage.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 3.1 Risk Matrix
+| Runtime panic leaves user blocked | High | Medium | Panic hook writes crash report, restores terminal, offers fallback CLI command |

@@ ## 10.3 Entry Point
+pub fn launch_tui(config: Config, db_path: &Path) -> Result<(), LoreError> {
+    install_panic_hook_for_tui(); // terminal restore + crash dump path
+    ...
+}

@@ ## 8.1 Global (Available Everywhere)
+| `:` | Show fallback equivalent CLI command for current screen/action |
```

### 9. Add a “jump list” (forward/back navigation, not only stack pop)
Current model has only push/pop and reset. Add browser-like history for investigation workflows.

```diff
diff --git a/PRD.md b/PRD.md
@@ ## 4.7 Navigation Stack Implementation
 pub struct NavigationStack {
-    stack: Vec<Screen>,
+    back_stack: Vec<Screen>,
+    current: Screen,
+    forward_stack: Vec<Screen>,
+    jump_list: Vec<Screen>, // recent entity/detail hops
 }

@@ ## 8.1 Global (Available Everywhere)
+| `Ctrl+o` | Jump backward in jump list |
+| `Ctrl+i` | Jump forward in jump list |
```

If you want, I can produce a single consolidated “PRD v2.1” patch that applies all nine revisions coherently section-by-section.