chronogrid/DECISION_LOG.md

8.1 KiB
Raw Blame History

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-09] - ADL-002: chronogrid_crypto Crate – Argon2id KDF & OS Keychain

  • Status: Accepted
  • Context: Task 1.2 required implementing the chronogrid_crypto crate with Argon2id master-key derivation and OS-native keychain bindings per docs/ARCHITECTURE/02-security-and-crypto.md.
  • Decision:
    • Argon2id parameters pinned: 64 MiB memory, 3 iterations, 4 threads, 16-byte random salt, 32-byte output.
    • DerivedKey struct implements Zeroize + Drop to scrub sensitive memory on scope exit.
    • OS keychain abstracted via keyring crate 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.

[2026-08-19] - ADL-003: chronogrid_core Crate – SQLCipher 4.x Database Initializer

  • Status: Accepted
  • Context: Task 1.3 required implementing the chronogrid_core crate with SQLCipher 4.x encrypted database initialization matching docs/API_CONTRACTS/schema.sql.
  • Decision:
    • rusqlite v0.31 with bundled-sqlcipher-vendored-openssl feature 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 = 4 enforces SQLCipher 4.x defaults (AES-256-CBC, HMAC-SHA512 page auth, 64 KiB page size).
    • PRAGMA foreign_keys = ON is set on every connection per the schema specification.
    • The canonical schema SQL from docs/API_CONTRACTS/schema.sql is embedded via include_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.
    • Database struct provides open(path, key) for file-backed and open_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_core so 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) and uuid = "1" with v4 feature to chronogrid_core/Cargo.toml.
    • Extended schema.sql with crdt_docs table (entity_id TEXT PK, entity_type TEXT, doc_bytes BLOB, updated_at INTEGER) and idx_crdt_docs_type index.
    • Implemented crdt/ sub-module: Hlc (Hybrid Logical Clock with tick()/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.
    • Database gained save_crdt_doc(), load_crdt_doc(), delete_crdt_doc() for serialized Automerge blob persistence.
    • Added CoreError::Crdt and CoreError::HlcParse error 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_docs table.
    • Full ADR at docs/ARCHITECTURE/ADR/0004-core-automerge-crdt-integration.md.

[2026-08-20] - ADL-005: chronogrid_ffi Crate – Flutter Rust Bridge v2 FFI Layer

  • Status: Accepted
  • Context: Task 1.5 required generating flutter_rust_bridge FFI bindings to bridge all Rust storage, CRDT, and cryptographic methods to the Flutter/Dart presentation layer.
  • Decision:
    • Created crates/chronogrid_ffi/ crate with cdylib + staticlib + lib targets, depending on chronogrid_core, chronogrid_crypto, flutter_rust_bridge = "=2.7.0", and anyhow = "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 Engine singleton (Mutex<Option<Engine>>) holds the Database connection + Hlc clock. Thread-safe with_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.yaml configures codegen: Rust input from api/, Dart output to apps/chronogrid_flutter/lib/src/rust/.
    • Flutter pubspec.yaml updated with flutter_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.

[2026-08-22] - ADL-006: Architecture Review Board Assessment & Master Development Plan v2

  • Status: Accepted
  • Context: A comprehensive senior architecture review was conducted covering all crates, documentation, task structure, and the development plan. Phase 1 is complete and production-quality. Phases 2–5 require a structured execution plan to enable automated agent development.
  • Decision:
    • Created docs/ARCHITECTURE/05-architecture-review-assessment.md — full ARB assessment with gap analysis, risk register, and recommendations.
    • Created docs/ARCHITECTURE/06-master-development-plan.md — authoritative execution plan superseding OSAD Section 8, with 37 tasks across Phases 2–5, quality gates, and acceptance criteria traceability.
    • Created docs/TASKS/phase_2_networking_and_schema.md — 9 tasks for libp2p networking, schema extension, daemon scaffold, and verification pipeline hardening.
    • Created docs/TASKS/phase_3_flutter_ui_shell.md — 10 tasks for Flutter BLoC architecture, all 4 primary views, FRB codegen, and build scripts.
    • Created docs/TASKS/phase_4_ai_and_automation.md — 9 tasks for NLP engine, IMAP ingestion, file watchers, CalDAV server, and automation rules engine.
    • Created docs/TASKS/phase_5_headless_and_release.md — 9 tasks for daemon completion, integration testing, performance testing, and release packaging.
    • Fixed documentation typos in docs/UI_UX/02-calendar-timeblocking.md and docs/UI_UX/03-kanban-gantt-views.md.
    • Expanded docs/WORKFLOWS/01-master-user-story.md from a stub to a substantive workflow reference document.
    • Identified critical gaps: 6 missing schema tables, FFI type mismatch (due_date: i64 vs u64), incomplete verification script, missing build scripts, unscaffolded daemon crate.
    • Confirmed all Phase 1 architectural decisions as correct — no reversals required.
    • Next task for automated execution: Task 2.1 — Extend Schema with Missing Entities.