diff --git a/docs/superpowers/specs/2026-04-04-knowledge-view-design.md b/docs/superpowers/specs/2026-04-04-knowledge-view-design.md
new file mode 100644
index 0000000..1da61e5
--- /dev/null
+++ b/docs/superpowers/specs/2026-04-04-knowledge-view-design.md
@@ -0,0 +1,455 @@
+# Knowledge View — Android App Design Spec
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task.
+
+**Goal:** Replace the Library tab with a typed Knowledge view and add a dedicated Projects tab, bringing the Android app to parity with the web Knowledge view while using the existing backend `/api/knowledge` and `/api/projects` endpoints.
+
+**Architecture:** Two-tier pagination — fetch IDs cheaply (50 at a time), hydrate visible items in batches of 12. Type tabs drive server-side filtering. A new Projects tab replaces the project section formerly in Library. All data access goes through the existing Riverpod/Dio/repository pattern.
+
+**Tech Stack:** Flutter 3, Riverpod 3, GoRouter 17, Dio 5, existing backend REST API (`/api/knowledge`, `/api/projects`, `/api/notes`)
+
+---
+
+## Manifest & Configuration Checklist
+
+These must be verified before any code is written. Failures here cause silent runtime errors.
+
+- [ ] `android/app/src/main/AndroidManifest.xml` — confirm `` is present
+- [ ] `android/app/src/main/AndroidManifest.xml` — confirm `android:usesCleartextTraffic="true"` is set on the `` tag (required for HTTP dev server connections; if already using HTTPS only, leave as-is but document the decision)
+- [ ] `pubspec.yaml` — no new dependencies required for Knowledge View
+- [ ] `android/app/build.gradle` — no changes required for Knowledge View
+
+---
+
+## File Map
+
+### New files
+| Path | Responsibility |
+|---|---|
+| `lib/data/models/knowledge_item.dart` | Unified model for all knowledge types (note, person, place, list, task) |
+| `lib/data/api/knowledge_api.dart` | Two API methods: fetch IDs, batch-hydrate items |
+| `lib/data/repositories/knowledge_repository.dart` | Thin repo wrapping KnowledgeApi |
+| `lib/providers/knowledge_provider.dart` | StateNotifier with two-tier pagination state |
+| `lib/screens/knowledge/knowledge_screen.dart` | Main Knowledge screen with type tabs, tag chips, search, infinite scroll |
+| `lib/widgets/knowledge_item_card.dart` | Type-aware card widget (different icon/subtitle per type) |
+| `lib/screens/projects/projects_screen.dart` | Project list sorted by updated_at desc |
+| `lib/screens/projects/project_edit_screen.dart` | Create/edit project (title, description, goal, status) |
+
+### Modified files
+| Path | Change |
+|---|---|
+| `lib/data/models/note.dart` | Add `noteType` field (String, default `'note'`) |
+| `lib/data/models/project.dart` | Add `status`, `goal`, `color`, `autoSummary`, `updatedAt` fields |
+| `lib/data/api/notes_api.dart` | Pass `note_type` in create and update request bodies |
+| `lib/data/api/projects_api.dart` | Add `sort=updated_at&order=desc` to list call; add `status`, `goal`, `color` to create/update |
+| `lib/screens/notes/note_edit_screen.dart` | Accept optional `noteType` parameter; show type badge in app bar; pass `note_type` to API |
+| `lib/screens/library/project_tasks_screen.dart` | Add edit button in app bar pushing to `ProjectEditScreen` |
+| `lib/app.dart` | Replace `Routes.library` with `Routes.knowledge` + `Routes.projects`; update shell to 4 tabs |
+| `lib/core/constants.dart` | Add `Routes.knowledge`, `Routes.projects`; remove `Routes.library` |
+
+### Retired files
+| Path | Replacement |
+|---|---|
+| `lib/screens/library/library_screen.dart` | `KnowledgeScreen` + `ProjectsScreen` |
+| `lib/widgets/library_item_card.dart` | `KnowledgeItemCard` |
+
+---
+
+## Section 1: Navigation
+
+Four tabs replace the existing three:
+
+```
+Briefing | Knowledge | Chat | Projects
+```
+
+**`lib/core/constants.dart`:**
+- Remove `static const library = '/library'`
+- Add `static const knowledge = '/knowledge'`
+- `projects` already exists as `'/projects'` — no change needed
+- Add `static const projectEdit = '/projects/:id/edit'`
+
+**`lib/app.dart` — `_ShellState`:**
+```dart
+static const _tabs = [
+ Routes.briefing,
+ Routes.knowledge,
+ Routes.conversations,
+ Routes.projects,
+];
+```
+
+Shell `NavigationBar` / `NavigationRail` entries:
+```dart
+// Bottom nav
+NavigationDestination(icon: Icon(Icons.wb_sunny_outlined), selectedIcon: Icon(Icons.wb_sunny), label: 'Briefing'),
+NavigationDestination(icon: Icon(Icons.menu_book_outlined), selectedIcon: Icon(Icons.menu_book), label: 'Knowledge'),
+NavigationDestination(icon: Icon(Icons.chat_bubble_outline), selectedIcon: Icon(Icons.chat_bubble), label: 'Chat'),
+NavigationDestination(icon: Icon(Icons.folder_outlined), selectedIcon: Icon(Icons.folder), label: 'Projects'),
+```
+
+**`_QuickCaptureBar._hintForLocation` update:**
+```dart
+String _hintForLocation(String location) {
+ if (location.startsWith(Routes.knowledge)) return 'Capture a note…';
+ if (location.startsWith(Routes.projects)) return 'Capture a note…';
+ if (location.startsWith(Routes.conversations)) return 'Ask Fabled…';
+ return 'Capture a note…';
+}
+```
+
+**GoRouter shell routes** — replace `Routes.library` route with:
+```dart
+GoRoute(path: Routes.knowledge, builder: (_, _) => const KnowledgeScreen()),
+GoRoute(path: Routes.projects, builder: (_, _) => const ProjectsScreen()),
+```
+
+---
+
+## Section 2: Data Models
+
+### `lib/data/models/knowledge_item.dart`
+```dart
+class KnowledgeItem {
+ final int id;
+ final String noteType; // 'note' | 'person' | 'place' | 'list' | 'task'
+ final String title;
+ final String body;
+ final List tags;
+ final int? projectId;
+ final int? milestoneId;
+ final int? parentId;
+ // Task-only fields (null for non-tasks)
+ final String? status; // 'todo' | 'in_progress' | 'done' | 'cancelled'
+ final String? priority; // 'low' | 'normal' | 'high'
+ final String? dueDate;
+ final DateTime createdAt;
+ final DateTime updatedAt;
+
+ const KnowledgeItem({...});
+
+ factory KnowledgeItem.fromJson(Map json) => KnowledgeItem(
+ id: json['id'] as int,
+ noteType: json['note_type'] as String? ?? 'note',
+ title: json['title'] as String? ?? '',
+ body: json['body'] as String? ?? '',
+ tags: (json['tags'] as List?)?.map((e) => e as String).toList() ?? [],
+ projectId: json['project_id'] as int?,
+ milestoneId: json['milestone_id'] as int?,
+ parentId: json['parent_id'] as int?,
+ status: json['status'] as String?,
+ priority: json['priority'] as String?,
+ dueDate: json['due_date'] as String?,
+ createdAt: DateTime.parse(json['created_at'] as String),
+ updatedAt: DateTime.parse(json['updated_at'] as String),
+ );
+}
+```
+
+### `lib/data/models/note.dart` — add `noteType`
+```dart
+final String noteType; // new field
+
+// In constructor:
+required this.noteType,
+
+// In fromJson:
+noteType: json['note_type'] as String? ?? 'note',
+
+// In toJson:
+'note_type': noteType,
+
+// In copyWith: add noteType parameter
+```
+
+### `lib/data/models/project.dart` — add missing fields
+```dart
+final String status; // 'active' | 'completed' | 'archived'
+final String? goal;
+final String? color;
+final String? autoSummary;
+final DateTime updatedAt;
+
+// In fromJson:
+status: json['status'] as String? ?? 'active',
+goal: json['goal'] as String?,
+color: json['color'] as String?,
+autoSummary: json['auto_summary'] as String?,
+updatedAt: DateTime.parse(json['updated_at'] as String),
+```
+
+---
+
+## Section 3: API Layer
+
+### `lib/data/api/knowledge_api.dart`
+```dart
+class KnowledgeApi {
+ final Dio _dio;
+ const KnowledgeApi(this._dio);
+
+ /// Fetch page of IDs. Returns (ids, total).
+ Future<(List, int)> fetchIds({
+ String? noteType,
+ List tags = const [],
+ String sort = 'modified',
+ String? q,
+ int limit = 50,
+ int offset = 0,
+ }) async {
+ final params = {
+ 'limit': limit,
+ 'offset': offset,
+ 'sort': sort,
+ if (noteType != null) 'type': noteType,
+ if (tags.isNotEmpty) 'tags': tags.join(','),
+ if (q != null && q.isNotEmpty) 'q': q,
+ };
+ final response = await _dio.get('/api/knowledge/ids', queryParameters: params);
+ final data = response.data as Map;
+ final ids = (data['ids'] as List).map((e) => e as int).toList();
+ final total = data['total'] as int;
+ return (ids, total);
+ }
+
+ /// Batch-hydrate up to 100 IDs into full items.
+ Future> fetchBatch(List ids) async {
+ if (ids.isEmpty) return [];
+ final response = await _dio.get(
+ '/api/knowledge/batch',
+ queryParameters: {'ids': ids.join(',')},
+ );
+ final data = response.data as Map;
+ return (data['items'] as List)
+ .map((e) => KnowledgeItem.fromJson(e as Map))
+ .toList();
+ }
+
+ /// Per-type counts for tab labels.
+ Future