# Known Issues & Deferred Work Tracked at source via `@remarks` JSDoc tags. This file consolidates them for planning. Last updated: 2026-06-22 (D4). Paths are relative to repo root. --- ## Cross-file links / rename ### 1. `[[link]]` targets stale after rename **Files:** `apps/tauri/src/components/PageView.vue:26`, `apps/tauri/src/composables/usePageNavigation.ts:33`, `apps/tauri/src/composables/useSidebarIndex.ts:10` Renaming a page does not update existing `[[links]]` in other files that reference the old title. Backlink counts also reflect the stale title. - **Risk:** Users navigate to dead pages via stale links - **Fix:** After rename, query SQLite for all `links.target = oldTitle`, update file contents and re-index - **Deferred because:** No cross-file mutation pattern exists yet ### 2. Block ref scroll target not implemented **File:** `apps/tauri/src/pages/[...slug].vue:43` `#block-{id}` is appended to the URL when navigating to a block ref (`((block-id))`), but the receiving PageView has no `onMounted` scroll-to logic. The hash fragment is in the URL for future use only. - **Risk:** Low — user lands at top of page instead of scrolled to block - **Fix:** `onMounted` → check `route.hash`, query DOM for `[data-block-id]`, `scrollIntoView()` - **Deferred because:** Block refs are not yet first-class navigation targets --- ## Data integrity ### 3. No mtime check on save **Files:** `apps/tauri/src/pages/[...slug].vue:36`, `components/JournalDay.vue` Auto-save always overwrites the file on disk regardless of whether an external editor changed it between debounce triggers. - **Risk:** Silent data loss if user edits the same file externally - **Fix:** Compare file mtime before writing; show conflict dialog on mismatch - **Deferred because:** Low probability in practice (single-user app) ### 4. `modified_at` is index-time, not file mtime **Files:** `apps/tauri/src/components/TagView.vue:19`, `apps/tauri/src/lib/indexer.ts:70` `blocks.modified_at` is set to `Date.now() / 1000` during indexing, not the file's mtime from `fs::metadata`. Blocks from the same file indexed in the same pass share the same timestamp, making `ORDER BY modified_at` unreliable. - **Risk:** Tag view and block-ref ordering appear random within a single index pass - **Fix:** Store file mtime from `fs::metadata` during indexing - **Deferred because:** Requires plumbing `mtime` through the indexer's incremental update path ### 5. Existing workspaces may have empty-page-title rows **File:** `apps/tauri/src/lib/indexer.ts:67` Workspaces indexed before the `computePageTitle` fallback was added (D4) may have `pages.title = ''` for pages without an `# H1`. These won't be fixed until a `fullReindex` (app restart) or incremental re-index on file change. - **Risk:** Some pages invisible in sidebar, some `[[links]]` don't resolve - **Fix:** One-time SQL migration: `UPDATE pages SET title = ... WHERE title = ''` - **Deferred because:** Existing test workspaces are small; no user data yet --- ## Rendering / display edge cases ### 6. Excerpt `String.slice()` can split multi-byte characters **Files:** `components/PageView.vue:22`, `apps/tauri/src/pages/[...slug].vue:40` Excerpt extraction uses `String.slice()` (UTF-16 code units). If a `[[link]]` offset falls inside a 4-byte character (e.g. emoji), the excerpt may be truncated mid-character, producing a replacement character (�). - **Risk:** Cosmetic — garbled excerpt text in backlinks panel - **Fix:** Code-point-aware iteration via `Array.from()` or `Intl.Segmenter` - **Deferred because:** Low frequency; emoji in page titles is rare ### 7. TagView has no pagination (50-result limit) **File:** `components/TagView.vue:24` The tag aggregation query uses `LIMIT 50` with no cursor/offset pagination. If a tag has hundreds of references, only the last 50 are returned. - **Risk:** Incomplete tag results for popular tags - **Fix:** Add cursor-based pagination with "load more" button - **Deferred because:** No workspace has tags with >50 references yet ### 8. `safeName()` doesn't handle all Unicode edge cases **File:** `apps/tauri/src/composables/usePageNavigation.ts:35` `safeName` strips `<>:?*"\` characters but doesn't handle zero-width spaces, RTL markers, or other Unicode control characters. These are rare in page names but could produce surprising URL paths. - **Risk:** Very low — edge-case Unicode in filenames is uncommon - **Fix:** Normalize via `.normalize('NFC')` and filter Unicode control character ranges - **Deferred because:** Not encountered in practice ### 9. Tag names lowercased during extraction **File:** `components/TagView.vue:23` Links are extracted with lowercased tag names (see `extractLinks` in `parse.ts`). Mixed-case tags from a prior index version may not match. - **Risk:** Low — consistent lowercasing since D1 means all tags are already lowercased - **Fix:** One-time `UPDATE tags SET name = LOWER(name)` migration - **Deferred because:** Already consistent in current data --- ## Editor — Indent/Outdent ### 13. Shift+Tab / Tab outdent-indent doesn't reach the handler **Files:** `packages/editor/src/composables/useBlockKeyboardHandlers.ts:132`, `packages/editor/src/components/EditorBlock.vue:668`, `packages/editor/src/components/Editor.vue:1085` Tab/Shift+Tab indent/outdent handling is wired end-to-end (handler in `useBlockKeyboardHandlers`, pure operations in `editor-operations.ts`, event handling in `Editor.vue`) but the browser may capture the Tab key for focus navigation before it reaches the ProseMirror `handleKeyDown` prop, which is set at `EditorBlock.vue:668`. - **Risk:** Blocks can't be outdented. Deeply nested lists can only go deeper via Tab (if it happens to work) but can never come back up. - **Fix options:** - **Shift+Tab via `handleKeyDown`:** Ensure `event.preventDefault()` is called and the PM `EditorView` DOM element captures Tab — check `tabindex` and `contenteditable` interaction. - **Alternative — Enter on empty indented block:** If a block has `depth > 0` and its content is empty when Enter is pressed, outdent one level instead of creating a new empty block at the same depth. This is how many outliners (Logseq, Roam, Workflowy) handle it. - **Explorer-style wrap at depth 0:** If Tab at depth 0 cycles to depth 0 (no-op), reconsider to start indenting. - **Diagnosis needed:** Whether `handleKeyDown` fires at all for Tab, or if the browser / PM default captures it first. - **Deferred because:** Not yet diagnosed. --- ## Missing features ### 10. Block ID stamp creation not wired **File:** `apps/tauri/src/lib/indexer.ts:74` The indexer tracks `has_id_stamp` per block but the stamp creation (`id:: ` written to the file when a `((ref))` is created) is deferred to D2. The indexer is read-only and never modifies files. - **Risk:** Block refs can't be created; `((ref))` syntax works in the editor but there's no way to assign a stable ID to a block yet - **Deferred because:** D2 scope (read-only index) was prioritised over write ### 11. No search UI wired to FTS5 index **File:** Sidebar (`apps/tauri/src/components/AppSidebar.vue`, not yet implemented) Full-text search via SQLite FTS5 is built into the schema (`pages_fts`, `blocks_fts`) and the indexer populates it. No search input or results UI exists in the sidebar yet. - **Risk:** Users can't search their notes - **Deferred because:** D6 scope ### 12. Insertion zones still stubbed **File:** `packages/editor/src/components/EditorBlock.vue` (core editor) Click targets between blocks (`FIXME: Replace with Editor shell insertion zone`) are not yet materialised as visual insertion zones. Boundary navigation (ArrowUp from first block, ArrowDown from last) creates paragraphs inline as a temporary workaround. - **Risk:** None functional, but UX is rougher than final design - **Deferred because:** Part of the Editor shell redesign, not the page model --- ## Future enhancements (not bugs) These are tracked for completeness but not yet scoped into any milestone. | Item | Area | Notes | |---|---|---| | Automatic `[[link]]` update on rename | Cross-file | Requires write-lock pattern | | Conflict dialog on external file change | Auto-save | Low priority for single-user | | Paginated backlinks / tag view | UI | Simple cursor pattern | | Block ref scroll-to | Navigation | Depends on block ID stamp | | Full-text search UI | Sidebar | FTS5 already built | | File-mtime-based block ordering | Indexer | Requires fs::metadata |