6.2 KiB
6.2 KiB
Architectural Decision Log (ADL)
[2026-08-09] - ADL-001: Distributed Local-First System Baseline
- Status: Accepted
- Context: Design a multi-platform (Windows, Linux, Android, Headless) productivity engine for time, project, and note management without centralized servers.
- Decision: Adopted Rust core with SQLCipher local storage, Automerge CRDT delta sync over libp2p, and Flutter presentation layer bound via C-FFI.
[2026-08-19] - ADL-003: chronogrid_core Crate – SQLCipher 4.x Database Initializer
- Status: Accepted
- Context: Task 1.3 required implementing the
chronogrid_corecrate with SQLCipher 4.x encrypted database initialization matchingdocs/API_CONTRACTS/schema.sql. - Decision:
rusqlitev0.31 withbundled-sqlcipher-vendored-opensslfeature bundles both SQLCipher and OpenSSL, ensuring a hermetic build with no external C library dependencies.- The 32-byte Argon2id-derived master key is passed as a raw hex key via
PRAGMA key = "x'…'", bypassing SQLCipher's internal PBKDF2 derivation since Argon2id already provides equivalent or stronger protection. PRAGMA cipher_compatibility = 4enforces SQLCipher 4.x defaults (AES-256-CBC, HMAC-SHA512 page auth, 64 KiB page size).PRAGMA foreign_keys = ONis set on every connection per the schema specification.- The canonical schema SQL from
docs/API_CONTRACTS/schema.sqlis embedded viainclude_str!at compile time, ensuring single-source-of-truth alignment without runtime file I/O. - Post-initialization validation confirms all 6 expected tables exist (
namespaces,projects,tasks,notes,task_note_links,ingestion_logs) plus 4 indexes. Databasestruct providesopen(path, key)for file-backed andopen_in_memory(key)for test databases; key length is validated at 32 bytes.- 11 unit tests cover: table/index creation, FK enforcement, cascade deletes, wrong-key rejection, key length validation, schema idempotency, and CRUD round-trips across all tables.
[2026-08-20] - ADL-004: chronogrid_core – Automerge CRDT Integration for Task & Note Registers
- Status: Accepted
- Context: Task 1.4 required integrating the Automerge CRDT engine into
chronogrid_coreso task and note entities support offline-first LWW register mutations with HLC-based causal ordering. - Decision:
- Added
automerge = "0.5"(resolved to v0.5.12) anduuid = "1"withv4feature tochronogrid_core/Cargo.toml. - Extended
schema.sqlwithcrdt_docstable (entity_id TEXT PK,entity_type TEXT,doc_bytes BLOB,updated_at INTEGER) andidx_crdt_docs_typeindex. - Implemented
crdt/sub-module:Hlc(Hybrid Logical Clock withtick()/update()/Display/FromStr),CrdtDoc(generic Automerge wrapper with typed scalar accessors),TaskCrdt(11 mutable fields),NoteCrdt(4 mutable fields). - Each entity mutation stamps the document with an advancing HLC timestamp. Fork/merge delegates to Automerge's deterministic conflict resolution.
Databasegainedsave_crdt_doc(),load_crdt_doc(),delete_crdt_doc()for serialized Automerge blob persistence.- Added
CoreError::CrdtandCoreError::HlcParseerror variants. - 45 unit tests (all passing): HLC ordering/parse, all scalar types, save/load/fork/merge round-trips, CRDT doc DB persistence, schema validation with
crdt_docstable. - Full ADR at
docs/ARCHITECTURE/ADR/0004-core-automerge-crdt-integration.md.
- Added
[2026-08-20] - ADL-005: chronogrid_ffi Crate – Flutter Rust Bridge v2 FFI Layer
- Status: Accepted
- Context: Task 1.5 required generating
flutter_rust_bridgeFFI bindings to bridge all Rust storage, CRDT, and cryptographic methods to the Flutter/Dart presentation layer. - Decision:
- Created
crates/chronogrid_ffi/crate withcdylib+staticlib+libtargets, depending onchronogrid_core,chronogrid_crypto,flutter_rust_bridge = "=2.7.0", andanyhow = "1". - API uses a serialized-bytes pattern: CRDT documents cross FFI as
Vec<u8>(Automerge binary); read functions return DTO structs (FfiTaskData,FfiNoteData,FfiDerivedKey). - Global
Enginesingleton (Mutex<Option<Engine>>) holds theDatabaseconnection +Hlcclock. Thread-safewith_engine()/with_engine_mut()helpers provide access from FRB's isolate thread pool. - 38 public FFI functions across 5 API modules:
engine(init/close/status),database(CRDT doc persistence),crypto(key derivation + platform-gated keychain),task_crdt(18 create/read/set/clear/merge ops),note_crdt(8 create/read/set/clear/merge ops). - All fallible functions return
anyhow::Result<T>, which FRB v2 maps to Dart exceptions. - Keychain functions compile on all platforms but return an error on Android (delegated to Flutter KeyStore bridge).
flutter_rust_bridge.yamlconfigures codegen: Rust input fromapi/, Dart output toapps/chronogrid_flutter/lib/src/rust/.- Flutter
pubspec.yamlupdated withflutter_rust_bridge: ^2.7.0,ffi: ^2.1.0,meta: ^1.11.0. - 25 unit tests (all passing): engine lifecycle, DB CRDT doc persistence, task/note CRDT create/read/mutate/merge round-trips, crypto derivation, stateless read validation, no-engine error paths.
- Full ADR at
docs/ARCHITECTURE/ADR/0005-ffi-bridge-flutter-rust-bridge.md.
- Created
[2026-08-09] - ADL-002: chronogrid_crypto Crate – Argon2id KDF & OS Keychain
- Status: Accepted
- Context: Task 1.2 required implementing the
chronogrid_cryptocrate with Argon2id master-key derivation and OS-native keychain bindings perdocs/ARCHITECTURE/02-security-and-crypto.md. - Decision:
- Argon2id parameters pinned: 64 MiB memory, 3 iterations, 4 threads, 16-byte random salt, 32-byte output.
DerivedKeystruct implementsZeroize + Dropto scrub sensitive memory on scope exit.- OS keychain abstracted via
keyringcrate v3 (Windows Credential Manager / DPAPI, Linux SecretService / libsecret). Android keychain is excluded (cfg(not(target_os = "android"))) and will be handled by Flutter KeyStore bridge in Task 1.5. - Raw key material is Base64-encoded before credential-store insertion for UTF-8 backend compatibility.
- Inline Base64 encode/decode helpers avoid adding an external Base64 dependency.