/** * Shared types for the semantic layer (issue #1556). * * Tagged failures follow rule 34 — every entry point returns a * discriminated union so a caller that switches on `result.code` never * observes a thrown error from the semantic layer. */ /** * A persisted symbol vector. `vector` is the float32 embedding; `dims` * is its dimensionality; `modelId` identifies the provider+model that * produced it (so a provider swap invalidates the cache); `contentHash` * is the canonical-text hash (so a canonical-text change invalidates the * cache — rule 37). */ export interface SymbolVector { readonly nodeId: string; readonly qualifiedName: string; readonly vector: Float32Array; readonly dims: number; readonly modelId: string; readonly contentHash: string; } /** * A row read back from the vectors table for brute-force cosine. */ export interface SymbolVectorRow { readonly nodeId: string; readonly qualifiedName: string; readonly vector: Float32Array; readonly dims: number; readonly modelId: string; readonly contentHash: string; readonly filePath: string; } /** * Tagged-failure codes shared across the semantic layer. * * - `semantic_disabled`: the master gate is off (rule 30/48). No provider * call, no vectors-table write, no edge emitted. * - `provider_unavailable`: no host embedding provider registered for the * given scope. * - `provider_timeout`: the provider exceeded the lookup budget. * - `malformed_vector`: `normalizeHostEmbeddingVector` returned null. * - `repo_root_unset`: the store was opened without a repoRoot, so source * text cannot be read. * - `store_closed`: the store is closed. * - `db_error`: an underlying SQLite error. * - `no_vectors`: semantic_query ran but the vectors table is empty. * - `invalid_query`: malformed query input. */ export type SemanticFailureCode = | "semantic_disabled" | "provider_unavailable" | "provider_timeout" | "malformed_vector" | "repo_root_unset" | "store_closed" | "db_error" | "no_vectors" | "invalid_query"; export interface SemanticFailure { readonly ok: false; readonly code: SemanticFailureCode; readonly message?: string; } /** * Result of indexing vectors for a batch of symbols. */ export interface IndexVectorsResult { readonly ok: true; readonly embedded: number; readonly cached: number; readonly skipped: number; } /** * A SIMILAR_TO candidate pair from the MinHash/LSH pass. */ export interface SimilarCandidate { readonly aNodeId: string; readonly bNodeId: string; readonly aQualifiedName: string; readonly bQualifiedName: string; readonly jaccard: number; } /** * A confirmed SIMILAR_TO edge (after cosine confirmation when available). * * Carries the content-derived node ids (`nodes.id`) of both endpoints so * the persisted edge resolves unambiguously even when the two symbols share * a qualified name across files (issue #1677). The qualified-name fields * remain for diagnostics / stable-sort tie-breaking. */ export interface SimilarEdge { readonly srcNodeId: string; readonly dstNodeId: string; readonly srcQualifiedName: string; readonly dstQualifiedName: string; readonly confidence: number; readonly confirmed: boolean; } /** * Result of the SIMILAR_TO pipeline. */ export interface SimilarToResult { readonly ok: true; readonly edges: readonly SimilarEdge[]; readonly candidates: number; readonly confirmed: number; readonly minhashOnly: number; } /** * A hydrated semantic_query hit — graph context attached so the agent * gets structure, not just a snippet. */ export interface SemanticQueryHit { readonly qualifiedName: string; readonly filePath: string; readonly kind: string; readonly score: number; readonly snippet: string; readonly callers: readonly string[]; readonly callees: readonly string[]; } /** * Result of semantic_query. When degraded, `ok: true` still carries the * (possibly empty) hits plus a `degraded` tag so the caller never * mistakes "no matches" for "backend broken" (rule 34). */ export interface SemanticQuerySuccess { readonly ok: true; readonly hits: readonly SemanticQueryHit[]; readonly degraded?: "provider_unavailable" | "provider_timeout" | "malformed_vector"; } export type SemanticQueryOutcome = SemanticQuerySuccess | SemanticFailure;