Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
scryer-db
Relational persistence layer and database models for Scryer, powered by Turso and Tokio's Toasty ORM.
Architecture & Multi-Tenancy
scryer-db implements logical multi-tenancy within a single Turso database. Data isolation is maintained via mandatory project_id foreign keys and compound indexes across all entities.
Core Models
Project: Root tenant container representing a Git repository or workspace root.SourceFile: Indexed file record with BLAKE3 content hash and language metadata.Scope: Lexical AST scope boundaries (functions, closures, classes, blocks) with line/byte spans.Symbol: Declarations (functions, structs, traits, enums, methods, constants) with signatures and visibility.SymbolReference: Occurrences of symbol usages (calls, types, imports, values) withvia, how the reference was tied to its target (exact,nameormacro).CodeGraphEdge: Directed inter-symbol dependency edges (calls,implements,instantiates,imports), withfile_id, the file of the source symbol, so a file's outgoing edges are purged by one indexed column.ArchitecturalDecision: Architectural Decision Records (ADRs) parsed from documentation.ToolInvocationMetric: Usage telemetry for every MCP tool call: response tokens, truncation flag and latency (no content; ADR 0015).DependencyPackage: Globally shared, immutable external package metadata ((name, version, package_hash)), storing crate root path and checksum.ProjectDependency: Relational link associating aProjectwith aDependencyPackage, capturing direct vs. transitive status and enabled features.IndexStats: One row per project holding the last indexing run's health statistics as JSON (parse failures, syntax-error files, skipped files, unresolved references, Cargo dependency state); replaced by each run that changes the index and read byget_indexing_statusandscryer doctor.UnresolvedReference: A reference or call edge (kind=reference|edge) whose target named no stored symbol when it was indexed: the target as written, its bare name, role, byte range, line,viaand, for an edge, the source symbol and type. A later run or edit that stores a symbol with that bare name links it (BatchIngestionActor::link_deferred) and removes the row; a file's rows go when the file is re-indexed or deleted. Projects only; the dependency project 0 keeps none. Its count (kind = 'reference') is the project'sunresolved_references.
Schema Versioning
SchemaVersion rows record the applied schema version (SCHEMA_VERSION, currently 5: 1 = the baseline, 2 adds index_stats, 3 adds symbol_reference.via, 4 adds tool_invocation_metric.truncated, 5 adds unresolved_reference and code_graph_edge.file_id; the columns and the table come from idempotent statements (apply_column_migrations, TABLE_STATEMENTS) that run before the steps, and step 5 backfills file_id from each edge's source symbol). push_schema only runs for a brand-new database, so a later change to the schema must bump SCHEMA_VERSION and append a (version, statements) step to MIGRATION_STEPS in migration.rs; steps run once, in order, in a transaction. Opening a database stamped with a newer version than the binary knows is refused with an upgrade message rather than risking writes the build doesn't understand. registry.remove deletes every row a project owns (PROJECT_OWNED_TABLES) in the same transaction as the project row.
Composite Indexes
Automated migrations in migration.rs ensure composite indexes exist for sub-millisecond query performance:
idx_symbol_proj_nameonsymbol(project_id, name)idx_symbol_proj_qualifiedonsymbol(project_id, qualified_name)idx_files_proj_pathonsource_file(project_id, path)idx_scope_proj_fileonscope(project_id, file_id, start_line, end_line)idx_ref_proj_symonsymbol_reference(project_id, symbol_id)idx_edge_proj_sourceoncode_graph_edge(project_id, source_symbol_id)idx_edge_proj_targetoncode_graph_edge(project_id, target_symbol_id)idx_dep_pkg_name_ver_hashondependency_package(name, version, package_hash)idx_proj_dep_proj_pkgonproject_dependency(project_id, dependency_package_id)idx_files_dep_pkgonsource_file(dependency_package_id)idx_symbol_dep_pkgonsymbol(dependency_package_id)idx_symbol_dep_pkg_nameonsymbol(dependency_package_id, name)
The embedded engine's planner answers WHERE col = ? from a single-column index but scans for the composites above, so the write path goes by one column: index_code_graph_edge_by_file_id, index_unresolved_reference_by_file_id and index_unresolved_reference_by_bare_name (the names the ORM gives #[index] columns, so a new and an upgraded database end up the same). See docs/learnings/indexing-freshness.md.
In-Memory Project Registry
ProjectRegistry maintains a thread-safe, in-memory cache of registered projects:
- Canonical Path Resolution: Uses longest-prefix matching on canonical filesystem paths to resolve incoming tool file paths to their parent project.
- Slug Lookups: Provides O(1) lookup by project slug for workspace navigation.
- Idempotent Registration: Upserts database records while updating the in-memory cache.
Storage Modes & Connectivity
ScryerDb supports three database operating modes:
- In-Memory (
ScryerDb::new_in_memory()): Fast ephemeral storage (turso::memory:) ideal for automated testing and isolated runs. - File-Backed (
ScryerDb::connect_file(path)): Persistent on-disk SQLite/Turso database with automatic parent directory creation, default (non-MVCC) journal mode, and idempotent schema initialization. MVCC /BEGIN CONCURRENTis intentionally not enabled; seedocs/learnings/codebase-quirks.mdยง3. - URL/Remote (
ScryerDb::connect(url)): Standard Turso connection string support for remote clusters or custom connection configurations.
Timestamps
project.created_at / updated_at and tool_invocation_metric.created_at are RFC 3339 UTC strings with millisecond precision (2026-10-06T21:04:20.123Z, from scryer_db::time::now_rfc3339), so they sort chronologically as text. Older databases stored "<unix secs>.<millis>Z"; upgrade_legacy_timestamps rewrites those rows when the database is opened.