# DOMAIN.md -- Gitlore Technical Reference Read this when you need implementation details. AGENTS.md has the summary; this has the depth. ## Architecture Map ``` src/ main.rs # Entry: RuntimeBuilder -> block_on(async main) http.rs # HTTP client wrapping asupersync::http::h1::HttpClient lib.rs # Crate root test_support.rs # Shared test helpers cli/ mod.rs # Clap app (derive), global flags, subcommand dispatch args.rs # Shared argument types robot.rs # Robot mode JSON envelope: {ok, data, meta} render.rs # Human output (lipgloss/console) progress.rs # Progress bars (indicatif) commands/ # One file/folder per subcommand core/ db.rs # SQLite connection, MIGRATIONS array, LATEST_SCHEMA_VERSION error.rs # LoreError (thiserror), ErrorCode, exit codes 0-21 config.rs # Config structs (serde) shutdown.rs # Cooperative cancellation (ctrl_c + RuntimeHandle::spawn) timeline.rs # Timeline types (5-stage pipeline) timeline_seed.rs # SEED stage timeline_expand.rs # EXPAND stage timeline_collect.rs # COLLECT stage trace.rs # File -> MR -> issue -> discussion trace file_history.rs # File-level MR history path_resolver.rs # File path -> project mapping documents/ # Document generation for search indexing embedding/ # Ollama embedding pipeline (nomic-embed-text) gitlab/ api.rs # REST API client graphql.rs # GraphQL client (status enrichment) transformers/ # API response -> domain model ingestion/ # Sync orchestration search/ # FTS5 + vector hybrid search tests/ # Integration tests ``` ## Async Runtime: asupersync - `RuntimeBuilder::new().build()?.block_on(async { ... })` -- no proc macros - HTTP: `src/http.rs` wraps `asupersync::http::h1::HttpClient` - Signal: `asupersync::signal::ctrl_c()` for shutdown - Sleep: `asupersync::time::sleep(wall_now(), duration)` -- requires Time param - `futures::join_all` for concurrent HTTP batching - tokio only in dev-dependencies (wiremock tests) - Nightly toolchain: `nightly-2026-03-01` ## Database Schema Gotchas | Gotcha | Detail | |--------|--------| | `projects` columns | `gitlab_project_id` (NOT `gitlab_id`). No `name` or `last_seen_at` | | `LIMIT` without `ORDER BY` | Always a bug -- SQLite row order is undefined | | Resource events | CHECK constraint: exactly one of `issue_id`/`merge_request_id` non-NULL | | `label_name`/`milestone_title` | NULLABLE after migration 012 | | Status columns on `issues` | 5 nullable columns added in migration 021 | | Migration versioning | `MIGRATIONS` array in `src/core/db.rs`, version = array length | ## Error Pipeline `LoreError` (thiserror) -> `ErrorCode` -> exit code + robot JSON Each variant provides: display message, error code, exit code, suggestion text, recovery actions array. Robot errors go to stderr. Clap parsing errors -> exit 2. ## Embedding Pipeline - Model: `nomic-embed-text`, context_length ~1500 bytes - CHUNK_MAX_BYTES=1500, BATCH_SIZE=32 - `floor_char_boundary()` on ALL byte offsets, with forward-progress check - Box-drawing chars (U+2500, 3 bytes), smart quotes, em-dashes trigger boundary issues ## Pipelines **Timeline:** SEED -> HYDRATE -> EXPAND -> COLLECT -> RENDER - CLI: `lore timeline ` with --depth, --since, --expand-mentions, --max-seeds, --max-entities, --limit **GraphQL status enrichment:** Bearer auth (not PRIVATE-TOKEN), adaptive page sizes [100, 50, 25, 10], graceful 404/403 handling. **Search:** FTS5 + vector hybrid. Import: `crate::search::{FtsQueryMode, to_fts_query}`. FTS count: use `documents_fts_docsize` shadow table (19x faster). ## Test Infrastructure Helpers in `src/test_support.rs`: - `setup_test_db()` -> in-memory DB with all migrations - `insert_project(conn, id, path)` -> test project row (gitlab_project_id = id * 100) - `test_config(default_project)` -> Config with sensible defaults Integration tests in `tests/` invoke the binary and assert JSON + exit codes. Unit tests inline with `#[cfg(test)]`. ## Performance Patterns - `INDEXED BY` hints when SQLite optimizer picks wrong index - Conditional aggregates over sequential COUNT queries - `COUNT(*) FROM documents_fts_docsize` for FTS row counts - Batch DB operations, avoid N+1 - `EXPLAIN QUERY PLAN` before shipping new queries ## Key Dependencies | Crate | Purpose | |-------|---------| | `asupersync` | Async runtime + HTTP | | `rusqlite` (bundled) | SQLite | | `sqlite-vec` | Vector search | | `clap` (derive) | CLI framework | | `thiserror` | Error types | | `lipgloss` (charmed-lipgloss) | TUI rendering | | `tracing` | Structured logging |