2026-03-28 10:05:23 +01:00
# Architecture Decision Records
This folder contains Architecture Decision Records (ADRs) for the Laputa app.
## Format
2026-03-28 10:13:23 +01:00
Each ADR is a markdown note with YAML frontmatter. Template:
2026-03-28 10:05:23 +01:00
```markdown
---
type: ADR
id: "0001"
title: "Short decision title"
2026-03-28 10:13:23 +01:00
status: proposed # proposed | active | superseded | retired
2026-03-28 10:05:23 +01:00
date: YYYY-MM-DD
superseded_by: "0007" # only if status: superseded
---
## Context
2026-03-28 10:13:23 +01:00
What situation led to this decision? What forces and constraints are at play?
2026-03-28 10:05:23 +01:00
## Decision
2026-03-28 10:13:23 +01:00
**What was decided.** State it clearly in one or two sentences — bold so it stands out.
2026-03-28 10:05:23 +01:00
2026-03-28 10:13:23 +01:00
## Options considered
- **Option A** (chosen): brief description — pros / cons
- **Option B**: brief description — pros / cons
- **Option C**: brief description — pros / cons
2026-03-28 10:05:23 +01:00
## Consequences
2026-03-28 10:13:23 +01:00
What becomes easier or harder as a result?
What are the positive and negative ramifications?
What would trigger re-evaluation of this decision?
## Advice
*(optional)* Input received before making this decision — who was consulted, what they said, when.
Omit if the decision was made unilaterally with no external input.
```
### Status lifecycle
```
proposed → active → superseded
↘ retired (decision no longer relevant, not replaced)
2026-03-28 10:05:23 +01:00
```
## Rules
- One decision per file
- Files named `NNNN-short-title.md` (monotonic numbering)
- Once `active` , never edit — supersede instead
- When superseded: update `status: superseded` and add `superseded_by: "NNNN"`
- ARCHITECTURE.md reflects the current state (active decisions only)
## Index
| ID | Title | Status |
|----|-------|--------|
| [0001 ](0001-tauri-react-stack.md ) | Tauri v2 + React as application stack | active |
| [0002 ](0002-filesystem-source-of-truth.md ) | Filesystem as the single source of truth | active |
| [0003 ](0003-single-note-model.md ) | Single note open at a time (no tabs) | active |
| [0004 ](0004-vault-vs-app-settings-storage.md ) | Vault vs app settings for state storage | active |
| [0005 ](0005-tauri-ios-for-ipad.md ) | Tauri v2 iOS for iPad support (vs SwiftUI rewrite) | active |
2026-03-28 10:53:06 +01:00
| [0006 ](0006-flat-vault-structure.md ) | Flat vault structure (no type-based folders) | active |
2026-03-28 10:57:55 +01:00
| [0007 ](0007-title-filename-sync.md ) | Title equals filename (slug sync) | active |
| [0008 ](0008-underscore-system-properties.md ) | Underscore convention for system properties | active |
| [0009 ](0009-keyword-only-search.md ) | Keyword-only search (remove semantic indexing) | active |
| [0010 ](0010-dynamic-wikilink-relationship-detection.md ) | Dynamic wikilink relationship detection | active |
2026-04-22 19:18:52 +02:00
| [0011 ](0011-mcp-server-for-ai-integration.md ) | MCP server for AI tool integration | superseded → [0074 ](0074-explicit-external-ai-tool-setup-and-least-privilege-desktop-scope.md ) |
2026-03-28 10:57:55 +01:00
| [0012 ](0012-claude-cli-for-ai-agent.md ) | Claude CLI subprocess for AI agent | active |
2026-04-24 22:26:07 +02:00
| [0013 ](0013-remove-theming-system.md ) | Remove vault-based theming system | superseded -> [0081 ](0081-internal-light-dark-theme-runtime.md ) |
2026-03-28 10:57:55 +01:00
| [0014 ](0014-git-based-vault-cache.md ) | Git-based incremental vault cache | active |
2026-04-30 19:36:10 +02:00
| [0015 ](0015-auto-save-with-debounce.md ) | Auto-save with 500ms debounce | superseded → [0102 ](0102-low-end-safe-autosave-idle-window.md ) |
2026-03-28 10:57:55 +01:00
| [0016 ](0016-sentry-posthog-telemetry.md ) | Sentry + PostHog telemetry with consent | active |
2026-04-12 22:14:53 +02:00
| [0017 ](canary-release-channel-and-local-feature-flags.md ) | Canary release channel and feature flags | superseded → [0057 ](0057-alpha-stable-release-channels-and-beta-cohorts.md ) |
2026-04-14 10:11:05 +02:00
| [0018 ](0018-codescene-code-health-gates.md ) | CodeScene code health gates in CI | superseded → [0064 ](0064-ratcheted-codescene-thresholds.md ) |
2026-04-12 17:08:07 +02:00
| [0019 ](0019-github-device-flow-oauth.md ) | GitHub device flow OAuth for vault sync | superseded → [0056 ](0056-system-git-cli-auth-no-provider-oauth.md ) |
2026-03-28 10:57:55 +01:00
| [0020 ](0020-keyboard-first-design.md ) | Keyboard-first design principle | active |
| [0021 ](0021-push-to-main-workflow.md ) | Push directly to main (no PRs) | active |
| [0022 ](0022-blocknote-rich-text-editor.md ) | BlockNote as the rich text editor | active |
| [0023 ](0023-repair-vault-auto-bootstrap.md ) | Repair Vault auto-bootstrap pattern | active |
| [0024 ](0024-cache-outside-vault.md ) | Vault cache stored outside vault directory | active |
| [0025 ](0025-type-field-canonical.md ) | type: as canonical field (replacing Is A:) | active |
| [0026 ](0026-props-down-no-global-state.md ) | Props-down callbacks-up (no global state) | active |
2026-03-30 08:01:55 +02:00
| [0027 ](0027-dual-ai-architecture.md ) | Dual AI architecture (API chat + CLI agent) | superseded |
| [0028 ](0028-cli-agent-only-no-api-key.md ) | CLI agent only — no direct Anthropic API key | active |
| [0029 ](0029-domain-command-builder-pattern.md ) | Domain command builder pattern for useCommandRegistry | active |
| [0030 ](0030-rust-commands-module-split.md ) | Rust commands/ module split by domain | active |
2026-03-31 08:01:19 +02:00
| [0031 ](0031-full-app-for-note-windows.md ) | Full App instance for secondary note windows | active |
| [0032 ](0032-status-bar-for-git-actions.md ) | Git actions (Changes, Pulse, Commit) in status bar, not sidebar | active |
2026-03-31 11:19:31 +02:00
| [0033 ](0033-subfolder-scanning-and-folder-tree.md ) | Subfolder scanning and folder tree navigation | active |
2026-04-26 17:08:14 +02:00
| [0034 ](0034-git-repo-required-for-vault.md ) | Git repo required — blocking modal enforces vault prerequisite | superseded → [0085 ](0085-non-git-vault-support.md ) |
2026-04-01 10:33:40 +02:00
| [0035 ](0035-path-suffix-wikilink-resolution.md ) | Path-suffix wikilink resolution for subfolder vaults | active |
| [0036 ](0036-external-rename-detection-via-git-diff.md ) | External rename detection via git diff on focus regain | active |
| [0037 ](0037-codemirror-language-markdown-highlighting.md ) | Language-based markdown syntax highlighting in raw editor | active |
2026-04-03 11:47:26 +02:00
| [0038 ](0038-frontmatter-backed-favorites.md ) | Frontmatter-backed favorites (_favorite, _favorite_index) | active |
| [0039 ](0039-git-history-for-note-dates.md ) | Git history as source of truth for note creation/modification dates | active |
| [0040 ](0040-custom-views-yml-filter-engine.md ) | Custom Views — .laputa/views/*.yml with YAML filter engine | active |
| [0041 ](0041-filekind-all-files-in-vault-scanner.md ) | fileKind field — scan all vault files, not just markdown | active |
2026-04-07 08:02:31 +02:00
| [0042 ](0042-trash-auto-purge-safety-model.md ) | Trash auto-purge safety model | superseded → [0045 ](0045-permanent-delete-no-trash.md ) |
| [0043 ](0043-reactive-vault-state-on-save.md ) | Reactive vault state: editor changes propagate immediately to all UI | active |
2026-04-11 23:51:58 +02:00
| [0044 ](0044-h1-as-title-primary-source.md ) | H1 as primary title source — filename as stable identifier | superseded → [0055 ](0055-h1-is-the-only-editor-title-surface.md ) |
2026-04-07 08:02:31 +02:00
| [0045 ](0045-permanent-delete-no-trash.md ) | Permanent delete with confirm modal — no Trash system | active |
2026-04-08 08:02:06 +02:00
| [0046 ](0046-starter-vault-cloned-from-github.md ) | Starter vault cloned from GitHub at runtime — no bundled content | active |
| [0047 ](0047-regex-mode-for-view-filter-conditions.md ) | Regex mode for view filter conditions | active |
| [0048 ](0048-relative-date-expressions-in-view-filters.md ) | Relative date expressions in view filter conditions | active |
| [0049 ](0049-per-note-icon-property.md ) | Per-note icon property (_icon on individual notes) | active |
2026-04-11 12:59:11 +02:00
| [0050 ](0050-deterministic-shortcut-command-routing.md ) | Deterministic shortcut command routing | superseded → [0051 ](0051-shared-shortcut-manifest-for-testable-routing.md ) |
2026-04-11 15:42:53 +02:00
| [0051 ](0051-shared-shortcut-manifest-for-testable-routing.md ) | Shared shortcut manifest for testable routing | superseded → [0052 ](0052-renderer-first-shortcut-execution-with-native-menu-dedupe.md ) |
| [0052 ](0052-renderer-first-shortcut-execution-with-native-menu-dedupe.md ) | Renderer-first shortcut execution with native-menu dedupe | active |
2026-04-11 18:34:39 +02:00
| [0053 ](0053-webview-init-prevention-for-browser-reserved-shortcuts.md ) | Webview-init prevention for browser-reserved shortcuts | active |
2026-04-11 19:03:15 +02:00
| [0054 ](0054-deterministic-shortcut-qa-matrix.md ) | Deterministic shortcut QA matrix | active |
2026-04-17 08:04:36 +02:00
| [0055 ](0055-h1-is-the-only-editor-title-surface.md ) | H1 is the only editor title surface | superseded → [0068 ](0068-h1-only-title-surface-with-optional-untitled-auto-rename.md ) |
2026-04-12 17:08:07 +02:00
| [0056 ](0056-system-git-cli-auth-no-provider-oauth.md ) | System git auth only — no provider-specific OAuth or repo APIs | active |
2026-04-17 08:04:36 +02:00
| [0057 ](0057-alpha-stable-release-channels-and-beta-cohorts.md ) | Alpha/stable release channels with PostHog beta cohorts | superseded → [0066 ](0066-calendar-semver-versioning-for-alpha-and-stable-releases.md ) |
2026-04-13 19:37:59 +02:00
| [0058 ](0058-claude-code-first-launch-onboarding-gate.md ) | Claude Code first-launch onboarding gate | superseded → [0062 ](0062-selectable-cli-ai-agents.md ) |
2026-04-13 08:01:24 +02:00
| [0059 ](0059-local-only-git-commits-without-remote.md ) | Local-only git commits for vaults without a remote | active |
2026-04-13 08:09:28 +02:00
| [0060 ](0060-network-aware-ui-gating-for-remote-features.md ) | Network-aware UI gating for remote-dependent features | active |
| [0061 ](0061-ai-prompt-bridge-event-bus.md ) | AI prompt bridge — module-level event bus for cross-component prompt routing | active |
2026-04-13 19:37:59 +02:00
| [0062 ](0062-selectable-cli-ai-agents.md ) | Selectable CLI AI agents with a shared panel architecture | active |
2026-04-13 22:00:50 +02:00
| [0063 ](0063-blocknote-code-block-package-for-editor-highlighting.md ) | BlockNote code-block package for editor syntax highlighting | active |
2026-04-14 10:11:05 +02:00
| [0064 ](0064-ratcheted-codescene-thresholds.md ) | Ratcheted CodeScene thresholds as the quality gate baseline | active |
2026-04-15 10:23:24 +02:00
| [0065 ](0065-root-managed-ai-guidance-files.md ) | Root-managed AI guidance files with Claude shim | active |
2026-04-17 08:04:36 +02:00
| [0066 ](0066-calendar-semver-versioning-for-alpha-and-stable-releases.md ) | Calendar-semver versioning for alpha and stable releases | active |
| [0067 ](0067-autogit-idle-and-inactive-checkpoints.md ) | AutoGit idle and inactive checkpoints | active |
| [0068 ](0068-h1-only-title-surface-with-optional-untitled-auto-rename.md ) | H1-only title surface with optional untitled auto-rename | active |
2026-04-19 03:37:33 +02:00
| [0069 ](0069-neighborhood-mode-for-note-list-relationship-browsing.md ) | Neighborhood mode for note-list relationship browsing | active |
2026-04-20 10:24:11 +02:00
| [0070 ](0070-starter-vaults-local-first-with-explicit-remote-connection.md ) | Starter vaults are local-first with explicit remote connection | active |
2026-05-05 08:08:45 +02:00
| [0071 ](0071-external-vault-refresh-and-clean-tab-reopen.md ) | External vault updates reload derived state and reopen the clean active note | superseded → [0111 ](0111-path-aware-external-vault-refresh-with-focused-editor-preservation.md ) |
2026-04-22 15:09:45 +02:00
| [0072 ](0072-confirmed-vault-paths-gate-startup-state.md ) | Confirmed vault paths gate startup state | active |
| [0073 ](0073-persistent-linkify-protocol-registry-across-editor-remounts.md ) | Persistent linkify protocol registry across editor remounts | active |
2026-04-22 19:18:52 +02:00
| [0074 ](0074-explicit-external-ai-tool-setup-and-least-privilege-desktop-scope.md ) | Explicit external AI tool setup and least-privilege desktop scope | active |
2026-04-23 08:07:56 +02:00
| [0075 ](0075-crash-safe-note-rename-transactions.md ) | Crash-safe note rename transactions | active |
| [0076 ](0076-note-retargeting-separates-type-and-folder-moves.md ) | Note retargeting separates type changes from folder moves | active |
2026-04-24 08:03:58 +02:00
| [0077 ](0077-concurrent-safe-vault-cache-replacement.md ) | Concurrent-safe vault cache replacement | active |
| [0078 ](0078-scoped-unsigned-fallback-for-app-managed-git-commits.md ) | Scoped unsigned fallback for app-managed git commits | active |
2026-04-24 18:45:17 +02:00
| [0079 ](0079-linux-window-chrome-and-menu-reuse.md ) | Linux window chrome and menu reuse | active |
2026-04-26 06:07:33 +02:00
| [0080 ](0080-cross-platform-desktop-release-artifacts-and-portable-vault-names.md ) | Cross-platform desktop release artifacts and portable vault names | superseded → [0083 ](0083-dual-architecture-macos-release-artifacts.md ) |
2026-04-24 22:26:07 +02:00
| [0081 ](0081-internal-light-dark-theme-runtime.md ) | Internal light and dark theme runtime | active |
2026-04-26 03:52:10 +02:00
| [0082 ](0082-markdown-durable-math-notes.md ) | Markdown-durable math in notes | active |
2026-04-26 06:07:33 +02:00
| [0083 ](0083-dual-architecture-macos-release-artifacts.md ) | Dual-architecture macOS release artifacts | active |
2026-04-26 17:08:14 +02:00
| [0085 ](0085-non-git-vault-support.md ) | Non-git vaults open with explicit later Git initialization | active |
2026-04-27 22:14:23 +02:00
| [0088 ](0088-markdown-durable-mermaid-diagrams.md ) | Markdown-durable Mermaid diagrams in notes | active |
2026-04-27 23:54:50 +02:00
| [0089 ](0089-active-vault-filesystem-watcher.md ) | Active vault filesystem watcher | active |
2026-04-28 18:30:14 +02:00
| [0090 ](0090-pi-cli-agent-adapter.md ) | Pi CLI agent adapter | active |
| [0091 ](0091-gemini-cli-external-ai-setup.md ) | Gemini CLI external AI setup | active |
2026-04-30 21:01:09 +02:00
| [0092 ](0092-vault-ai-agent-permission-modes.md ) | Vault-scoped AI agent permission modes | superseded -> [0103 ](0103-adapter-specific-ai-permission-semantics.md ) |
2026-04-29 04:47:16 +02:00
| [0093 ](0093-shared-cli-agent-runtime-adapters.md ) | Shared CLI agent runtime adapters | active |
2026-04-29 08:03:17 +02:00
| [0094 ](0094-gitignored-content-visibility-boundary-filter.md ) | Gitignored content visibility as a command-boundary filter | active |
| [0095 ](0095-saved-view-order-field.md ) | Saved views use an explicit YAML order field | active |
2026-04-29 20:56:07 +02:00
| [0096 ](0096-root-created-type-documents.md ) | Root-created type documents | active |
2026-04-29 11:16:52 +02:00
| [0097 ](0097-gemini-cli-agent-adapter.md ) | Gemini CLI agent adapter | active |
2026-05-05 08:08:45 +02:00
| [0098 ](0098-in-app-image-and-pdf-file-previews.md ) | In-app image and PDF previews for binary vault files | superseded → [0110 ](0110-in-app-media-and-pdf-file-previews.md ) |
2026-04-29 21:33:20 +02:00
| [0099 ](0099-cumulative-vault-asset-scope.md ) | Cumulative vault asset scope for previews | active |
2026-04-30 08:03:04 +02:00
| [0100 ](0100-synthetic-vault-root-folder-row.md ) | Synthetic vault-root row in folder navigation | active |
| [0101 ](0101-categorical-product-analytics-events.md ) | Categorical product analytics events | active |
2026-04-30 19:36:10 +02:00
| [0102 ](0102-low-end-safe-autosave-idle-window.md ) | Low-end-safe autosave idle window | active |
2026-04-30 21:01:09 +02:00
| [0103 ](0103-adapter-specific-ai-permission-semantics.md ) | Adapter-specific AI permission semantics | active |
2026-05-01 08:03:02 +02:00
| [0104 ](0104-tauri-frontend-readiness-watchdog.md ) | Tauri frontend readiness watchdog | active |
2026-05-01 23:14:36 +02:00
| [0105 ](0105-editor-correctness-and-responsiveness-contract.md ) | Editor correctness and responsiveness contract | active |
2026-05-02 02:57:45 +02:00
| [0106 ](0106-shared-app-command-manifest.md ) | Shared app command manifest | active |
2026-05-03 12:04:38 +02:00
| [0107 ](0107-markdown-durable-tldraw-whiteboards.md ) | Markdown-durable tldraw whiteboards in notes | active |
2026-05-02 12:06:38 +02:00
| [0107 ](0107-pointer-owned-editor-block-reordering.md ) | Pointer-owned editor block reordering | active |
2026-05-03 17:00:21 +02:00
| [0108 ](0108-sanitized-rendered-markup-and-safe-regex.md ) | Sanitized rendered markup and safe user regex | active |
2026-05-04 12:37:30 +02:00
| [0109 ](0109-debounced-worker-derived-editor-indexes.md ) | Debounced worker-derived editor indexes | active |
2026-05-15 08:03:35 +02:00
| [0110 ](0110-in-app-media-and-pdf-file-previews.md ) | In-app media and PDF previews for binary vault files | superseded → [0121 ](0121-appimage-external-fallback-for-audio-and-video-previews.md ) |
2026-05-05 08:08:45 +02:00
| [0111 ](0111-path-aware-external-vault-refresh-with-focused-editor-preservation.md ) | Path-aware external vault refresh with focused-editor preservation | active |
2026-05-05 15:00:24 +02:00
| [0112 ](0112-system-theme-mode.md ) | System theme mode | active |
2026-05-07 08:07:20 +02:00
| [0113 ](0113-shared-renderer-attachment-path-normalization.md ) | Shared renderer attachment path normalization | active |
2026-05-08 00:45:21 +02:00
| [0114 ](0114-mounted-workspaces-unified-graph.md ) | Mounted workspaces unified graph | active |
2026-05-13 08:03:41 +02:00
| [0116 ](0116-rich-raw-transition-and-serialization-ownership.md ) | Rich/raw transition and serialization ownership | active |
2026-05-14 08:05:28 +02:00
| [0118 ](0118-entry-scoped-note-windows-without-vault-index-scans.md ) | Entry-scoped note windows without vault index scans | active |
2026-05-14 13:02:40 +02:00
| [0119 ](0119-vault-neutral-mcp-registration-with-mounted-workspace-guidance.md ) | Vault-neutral MCP registration with mounted workspace guidance | active |
2026-05-14 15:22:47 +02:00
| [0120 ](0120-stable-appimage-mcp-server-path-with-opencode-registration.md ) | Stable AppImage MCP server path with OpenCode registration | active |
2026-05-15 08:03:35 +02:00
| [0121 ](0121-appimage-external-fallback-for-audio-and-video-previews.md ) | AppImage external fallback for audio and video previews | active |
2026-05-15 08:33:17 +02:00
| [0122 ](0122-scalar-array-frontmatter-properties.md ) | Scalar array frontmatter properties | active |