Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Architecture Decision Records

ADR-001: Hybrid Architecture (Concrete + Ports)

Decision: Use concrete types everywhere except for LLM access, which gets a port trait.

Context: Full hexagonal architecture with 15 port traits is overhead for a solo builder maintaining 8 crates. Only LLM access genuinely benefits from abstraction (swappable providers).

Consequence: Only LlmPort is abstract. Database, filesystem, and config access use concrete types. This can be expanded later if needed.


ADR-002: Single SQLite Database

Decision: Store everything in one SQLite database at ~/.local/share/nexus/nexus.db.

Context: Separate databases would complicate joins and backups. SQLite WAL mode handles concurrent reads well.

Consequence: Config snapshots stored as gzip-compressed BLOBs. Portable — copy one file to provision a new machine.


ADR-003: Feature Crate Isolation

Decision: Feature crates depend only on nexus-core, never on each other.

Context: Prevents circular dependencies and allows independent compilation.

Consequence: If configs needs search, it goes through core types, not by importing discovery.


ADR-004: FTS5 with Path Indexing

Decision: Include file paths in the FTS5 index, not just names.

Context: Users search by directory context (“rust projects”, “nvim config”). Path-aware search is significantly more useful.

Consequence: Larger FTS index, but home directories are manageable in size.


ADR-005: Config Snapshots as Compressed BLOBs

Decision: Store config file contents as gzip-compressed BLOBs in SQLite.

Context: Alternatives considered: git repo for dotfiles, tar archives. SQLite BLOBs are simplest — no external dependencies, self-contained, easy to restore.

Consequence: Git-backed versioning is a future enhancement, not a requirement.


ADR-006: Three Surfaces, One Core

Decision: CLI, TUI, and Web server all compose the same feature crates.

Context: Each surface has different UX needs but identical data access patterns. Sharing core logic prevents divergence.

Consequence: Feature crates must be surface-agnostic. No stdout printing in library code.


ADR-007: Known Tool Registry

Decision: Hard-code definitions for 20 known config tools rather than auto-detecting.

Context: Auto-detection would require heuristics and produce false positives. A curated registry is more reliable.

Consequence: Adding a new tool requires a code change. Acceptable — the list changes rarely.


ADR-008: Claude-First AI

Decision: Ship with Claude API only, use LlmPort trait for future providers.

Context: Adding Ollama/OpenAI support can come later through the trait abstraction without changing calling code.

Consequence: Requires ANTHROPIC_API_KEY for AI features. All other features work without it.


ADR-009: CI/CD from Day One

Decision: Ship with GitHub Actions CI (fmt, clippy, test, build, coverage) and multi-platform release automation.

Consequence: Every PR runs the full pipeline. Releases triggered by git tags (v*).