Files
teernisse da576cb276 chore(agents): add CEO daily notes and rewrite founding-engineer/plan-reviewer configs
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.
2026-03-12 10:08:22 -04:00

4.7 KiB

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