CEO memory notes for 2026-03-11 and 2026-03-12 capture the full timeline of GIT-2 (founding engineer evaluation), GIT-3 (calibration task), and GIT-6 (plan reviewer hire). Founding Engineer: AGENTS.md rewritten from 25-line boilerplate to 3-layer progressive disclosure model (AGENTS.md core -> DOMAIN.md reference -> SOUL.md persona). Adds HEARTBEAT.md checklist, TOOLS.md placeholder. Key changes: memory system reference, async runtime warning, schema gotchas, UTF-8 boundary safety, search import privacy. Plan Reviewer: new agent created with AGENTS.md (review workflow, severity levels, codebase context), HEARTBEAT.md, SOUL.md. Reviews implementation plans in Paperclip issues before code is written.
114 lines
4.7 KiB
Markdown
114 lines
4.7 KiB
Markdown
# 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 <query>` 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 |
|