Documentation
¶
Overview ¶
Package codegraph sparse retrieval — Phase P1 stub.
This file vendors go-kit/sparse and declares the SparseEmbedder interface alias used by the SPLADE RRF arm (Phase P1). Implementation is in Phase P1; this stub exists so go mod vendor includes the sparse package.
Package codegraph — surprise_index.go
Two-phase surprise persistence. Run IndexSurpriseEdges first to score and write r.surprise on every CALLS edge; then run IndexSurpriseNodes to aggregate per-symbol scores. Both functions are safe to re-run: they overwrite previously persisted scores rather than accumulating them.
Index ¶
- Constants
- Variables
- func CacheStatus(ctx context.Context, store *Store, root string) (bool, error)
- func ExtractTestedByEdges(root string, symbols []*parser.Symbol) []edgeData
- func GenerateCypher(ctx context.Context, client llm.Completer, query string) (string, error)
- func GenerateCypherWithRetry(ctx context.Context, client llm.Completer, query, firstErr string) (string, error)
- func GraphNameFor(repoPath string) string
- func GraphSchemaText() string
- func IndexSurpriseEdges(ctx context.Context, store *Store, graphName string) error
- func IndexSurpriseNodes(ctx context.Context, store *Store, graphName string) error
- func IsGraphMissingError(err error) bool
- func MemGuardWatchdog(ctx context.Context, cancel context.CancelFunc)
- func NewAnalyticsAdapter(s *Store, mappings []analyze.PathMapping) graphx.Analytics
- func NewCrossRefsAdapter(s *Store, mappings []analyze.PathMapping) graphx.CrossRefs
- func PersistInsights(ctx context.Context, store learningsStore, repoKey, template string, ...) int
- func PostProcessSurprises(rows [][]string, limit int) ([][]string, string)
- func RecordSemanticDupCollapsed(path string)
- func RerankDeadCode(_ context.Context, rows [][]string) [][]string
- func RerankSemanticResults(ctx context.Context, root string, query string, ...) []embeddings.SearchResult
- func SnapshotBeforeRebuild(ctx context.Context, store *Store, repoKey, graphName string)
- func TemplateList() string
- func TraceFromAGE(ctx context.Context, store *Store, graphName, symbolName, direction string, ...) (*callgraph.TraceResult, error)
- type BulkWriter
- type Classification
- type CommunityChange
- type ComplexityChange
- type CypherWriter
- type DeadCodeCandidate
- type Flow
- type GraphDiff
- type GraphMeta
- type GraphStats
- type HealthCacheEntry
- type IndexConfig
- type MemoryStatus
- type QueryResult
- type Snapshot
- type SnapshotEdge
- type SnapshotSymbol
- type SparseEmbedder
- type Store
- func (s *Store) AssertSchemaDrift(ctx context.Context)
- func (s *Store) BulkCopyInsert(ctx context.Context, gname string, vertices []vertexData, edges []edgeData) error
- func (s *Store) CheckAGEPreloaded(ctx context.Context) error
- func (s *Store) DeleteFileMtimes(ctx context.Context, repoKey string) error
- func (s *Store) DropGraph(ctx context.Context, name, repoKey string) error
- func (s *Store) EnsureFlowsTable(ctx context.Context) error
- func (s *Store) EnsureGraph(ctx context.Context, name string) error
- func (s *Store) EnsureGraphExistsForRead(ctx context.Context, graphName string) error
- func (s *Store) EnsureHealthCacheTable(ctx context.Context) error
- func (s *Store) EnsureIndexes(ctx context.Context, name string) error
- func (s *Store) EnsureLabels(ctx context.Context, gname string) error
- func (s *Store) ExecCypher(ctx context.Context, graph, cypher string, cols int) ([][]string, error)
- func (s *Store) ExecCypherWrite(ctx context.Context, graph, cypher string) error
- func (s *Store) GetFileMtimes(ctx context.Context, repoKey string) (map[string]time.Time, error)
- func (s *Store) GraphExists(ctx context.Context, graphName string) (bool, error)
- func (s *Store) HasAGE(ctx context.Context) bool
- func (s *Store) ListFlows(ctx context.Context, repoKey string) ([]Flow, error)
- func (s *Store) LoadDeadCodeScore(ctx context.Context, root, name, file string) (float32, bool)
- func (s *Store) LoadDeadCodeScores(ctx context.Context, repoKey string, rows [][]string) [][]string
- func (s *Store) LoadHealthCache(ctx context.Context, repoKey string) *HealthCacheEntry
- func (s *Store) LoadTopDeadCodeCandidates(ctx context.Context, repoKey string, minScore float32, limit int) ([]DeadCodeCandidate, error)
- func (s *Store) NewBulkWriter(ctx context.Context) (*BulkWriter, error)
- func (s *Store) Pool() *pgxpool.Pool
- func (s *Store) Preflight(ctx context.Context) error
- func (s *Store) ScoreDeadCodeCandidates(ctx context.Context, gname, repoKey string, symbolCount int) error
- func (s *Store) SymbolStructuralRank(ctx context.Context, repoKey, name, file string, pagerank float64) string
- func (s *Store) UpsertFileMtimes(ctx context.Context, repoKey string, mtimes map[string]time.Time) error
- func (s *Store) UpsertFlows(ctx context.Context, repoKey string, flows []Flow) error
- func (s *Store) UpsertHealthCache(ctx context.Context, repoKey, repoPath, grade, resultXML string, score int, ...) error
- type SurpriseResult
- type Template
Constants ¶
const ( // TemplateInsightSurprises is the template that surfaces hidden // cross-package coupling scored by community/pagerank distance. TemplateInsightSurprises = "surprises" // TemplateInsightDeadCode is the template that finds uncalled functions. TemplateInsightDeadCode = "dead_code" )
Variables ¶
var ErrGraphNotIndexed = errors.New("graph not indexed: run code_graph first to build the graph for this repo")
ErrGraphNotIndexed is returned when a read-path tool is called against a repo that has not been indexed yet (no AGE graph exists). Callers should surface the "run code_graph first" message to the user.
Functions ¶
func CacheStatus ¶
CacheStatus checks if a valid cached graph exists for root. Returns (true, nil) if cached and fresh, (false, nil) if not present or stale.
func ExtractTestedByEdges ¶
ExtractTestedByEdges creates TESTED_BY edges mapping test functions to tested symbols.
func GenerateCypher ¶
GenerateCypher asks the LLM to produce a read-only Cypher query for the given natural-language question. It extracts the query from any markdown code block returned by the model and rejects queries containing write operations.
func GenerateCypherWithRetry ¶
func GenerateCypherWithRetry(ctx context.Context, client llm.Completer, query, firstErr string) (string, error)
GenerateCypherWithRetry retries Cypher generation with the previous error attached to the prompt so the model can self-correct.
func GraphNameFor ¶
GraphNameFor returns the deterministic AGE graph name for the given repo path. Exported for callers that need the name without a Store instance.
func GraphSchemaText ¶
func GraphSchemaText() string
GraphSchemaText returns a human-readable description of the full code knowledge graph schema (vertex labels, edge labels, and their properties). It is injected into the freeform Cypher generation prompt so the LLM knows about every node and relationship type, including cross-language constructs.
func IndexSurpriseEdges ¶
IndexSurpriseEdges fetches every CALLS edge joined with endpoint pagerank, community, file, and degree; scores each via scoreSurprise; and writes r.surprise = score on edges with score > 0. Edges scoring 0 are skipped to keep writes bounded.
Safe to run multiple times — overwrites stale scores. Call BEFORE IndexSurpriseNodes so that node aggregation sees fresh edge values.
func IndexSurpriseNodes ¶
IndexSurpriseNodes aggregates: for each Symbol, finds the maximum surprise score across all adjacent CALLS edges (incoming or outgoing), normalises to [0, 1] by dividing by maxSurpriseScore, and writes s.surprise = normalised.
Must be called AFTER IndexSurpriseEdges so that r.surprise values are already persisted on edges. Safe to re-run — overwrites stale node scores.
func IsGraphMissingError ¶
IsGraphMissingError reports whether err indicates that an AGE graph does not exist. AGE raises one of three SQLSTATE codes depending on context:
- 3F000 — invalid_schema_name (AGE cannot set search_path to a missing schema)
- 42P01 — undefined_table (label tables absent inside missing schema)
- 42704 — undefined_object (graph object not found in catalog)
String-contains fallbacks are included for AGE versions that surface the code only inside the message text (observed in AGE 1.3/1.4 on PG 14).
func MemGuardWatchdog ¶ added in v1.32.1
func MemGuardWatchdog(ctx context.Context, cancel context.CancelFunc)
memGuardWatchdog runs in a goroutine alongside IndexRepo, periodically checking memory pressure. If pressure exceeds thresholds, it cancels the context via the cancel function so the build aborts gracefully instead of pushing the host into OOM.
The watchdog is a second line of defense: the pre-build CheckMemoryPressure gate catches the common case (host already under pressure). The watchdog catches the case where pressure develops DURING the build (e.g. another container spikes while we're inserting).
func NewAnalyticsAdapter ¶
func NewAnalyticsAdapter(s *Store, mappings []analyze.PathMapping) graphx.Analytics
NewAnalyticsAdapter wraps a Store as a graphx.Analytics. mappings converts []analyze.PathMapping (External->Internal) into a simple map used by repoKeyToHostPath for host<->container path rewriting. The returned value is safe to use concurrently; it inherits the pool's concurrency.
func NewCrossRefsAdapter ¶
func NewCrossRefsAdapter(s *Store, mappings []analyze.PathMapping) graphx.CrossRefs
NewCrossRefsAdapter wraps a Store as a graphx.CrossRefs. mappings converts []analyze.PathMapping into a simple map for path rewriting.
func PersistInsights ¶
func PersistInsights(ctx context.Context, store learningsStore, repoKey, template string, rows [][]string) int
PersistInsights writes per-symbol learnings Records for structural insights surfaced by a QueryResult. It is a no-op when store is nil, the template is unsupported, or rows is empty.
Returns the count of Records successfully upserted. All errors are swallowed via slog.Debug — the caller's user-visible response must never fail because persistence failed.
Supported templates:
- "surprises": emits two records per edge (FromName + ToName) for post-processed rows with Score >= minSurpriseScoreForPersist. Post-processed cols: [FromName, FromFile, ToName, ToFile, Score, Reasons]
- "dead_code": emits one record per row (symbol col 0, AGE node string).
func PostProcessSurprises ¶
PostProcessSurprises scores raw cross-package edge rows and returns top-N with a narrative summary. Input cols: fromName, fromFile, fromCommunity, toName, toFile, toCommunity, fromPageRank, toPageRank. Output cols (6): FromName, FromFile, ToName, ToFile, Score, Reasons — the shape expected by PersistInsights for the "surprises" template.
func RecordSemanticDupCollapsed ¶ added in v1.21.0
func RecordSemanticDupCollapsed(path string)
RecordSemanticDupCollapsed bumps the dup-collapsed counter for the given path ("semantic_only" or "ce_rerank"). Exported so cmd/go-code can call it from semanticOnlyResult (which already imports codegraph for RerankSemanticResults).
func RerankDeadCode ¶
RerankDeadCode reranks dead_code Cypher rows by likelihood of being actual dead code (not entrypoints or test utilities).
Pre-filters to top rerankPreFilterN rows by complexity before calling the reranker — gte-multi-rerank takes ~0.2s/doc on ARM, so 20 docs ≈ 4s total.
Returns the top rerankTopN rows sorted by relevance_score DESC. Falls back to original rows (capped at rerankTopN) when the reranker is not configured or any error occurs (non-fatal).
func RerankSemanticResults ¶
func RerankSemanticResults( ctx context.Context, root string, query string, results []embeddings.SearchResult, topK int, ) []embeddings.SearchResult
RerankSemanticResults applies CE reranking to semantic search results. Takes the merged results from hybrid RRF, sends top semanticRerankTopN to gte-multi-rerank, returns reranked in order of relevance (highest first).
Falls back to original order on any error (non-fatal, logs warning). The caller's topK is applied AFTER reranking so the best topK are returned.
func SnapshotBeforeRebuild ¶
SnapshotBeforeRebuild captures the current graph state before a rebuild. Non-fatal: failures log warnings but don't block the rebuild. Exported for use by tool handlers (e.g. refresh=true path).
func TemplateList ¶
func TemplateList() string
TemplateList returns a formatted list of all templates suitable for a classifier prompt. Templates are sorted alphabetically by ID for deterministic prompt generation.
func TraceFromAGE ¶ added in v1.33.0
func TraceFromAGE(ctx context.Context, store *Store, graphName, symbolName, direction string, maxDepth int) (*callgraph.TraceResult, error)
TraceFromAGE builds a call trace by querying CALLS edges directly from the AGE property graph, avoiding the need to re-parse the entire repo (which callgraph.TraceRepo does on cache miss, taking 2-60s depending on repo size).
Uses iterative BFS: for each depth level, queries direct CALLS neighbors of all nodes at that depth. This avoids AGE's lack of support for list comprehension in variable-length path queries (nodes(path) works but [node IN nodes(path) | node.name] does not).
Returns a TraceResult compatible with callgraph.Trace. If the graph is not indexed, the symbol is not found, or any query error occurs, returns (nil, error) so the caller can fall back to BuildFromRepo.
Types ¶
type BulkWriter ¶
type BulkWriter struct {
// contains filtered or unexported fields
}
BulkWriter holds a dedicated pool connection with synchronous_commit=off for the duration of a graph insert operation. Benchmarks show 5x speedup over per-call pool acquire/release. Close() MUST always be called (defer it).
func (*BulkWriter) Close ¶
func (bw *BulkWriter) Close(ctx context.Context)
Close resets synchronous_commit and returns the connection to the pool.
func (*BulkWriter) ExecCypherWrite ¶
func (bw *BulkWriter) ExecCypherWrite(ctx context.Context, graph, cypher string) error
ExecCypherWrite runs a write Cypher on the held connection (implements CypherWriter).
type Classification ¶
type Classification struct {
Template string `json:"template"`
Params map[string]string `json:"params"`
}
Classification holds the result of classifying a natural-language query.
type CommunityChange ¶
type CommunityChange struct {
Name string `json:"name"`
File string `json:"file"`
OldCommunity int `json:"old_community"`
NewCommunity int `json:"new_community"`
}
CommunityChange records a symbol that moved between communities.
type ComplexityChange ¶
type ComplexityChange struct {
Name string `json:"name"`
File string `json:"file"`
OldComplexity int `json:"old_complexity"`
NewComplexity int `json:"new_complexity"`
}
ComplexityChange records a symbol whose complexity score changed.
type CypherWriter ¶
CypherWriter is implemented by *Store and *BulkWriter. insertBatches and insertEdgeBatches accept this interface so they can work with either a pooled connection (Store) or a dedicated bulk session (BulkWriter).
type DeadCodeCandidate ¶
DeadCodeCandidate is a high-confidence dead code function from code_dead_code_scores.
type Flow ¶ added in v1.21.0
type Flow struct {
FlowID string // random hex ID, unique within an index run
Name string // "<entry> → <leaf>" e.g. "handleSearch → MergeRRF"
EntrySym string // entry-point symbol name
EntryFile string // relative file path of the entry symbol
LeafSym string // dominant-leaf symbol name (highest PageRank along chain)
MemberSyms []string // all symbols in the chain (ordered, entry first)
Priority float64 // max PageRank along the chain; used for ranking
Community string // Louvain community id string ("0", "1", …)
}
Flow is a named execution path extracted at index time. One Flow maps to one row in the code_flows relational table (ADR-001).
func ExtractFlows ¶ added in v1.21.0
func ExtractFlows( root string, cg *callgraph.CallGraph, communities map[string]int, pagerank map[string]float64, handlesTargets map[string]bool, maxFlows int, dfsDepth int, ) []Flow
ExtractFlows derives named execution flows from the in-memory call graph.
Must be called AFTER injectCommunities and computeSymbolPageRank so both maps are fully populated. No AGE I/O — pure in-memory DFS.
- root — repo root; used to normalise symbol keys to relFile form consistent with the pagerank map ("name\x00relFile")
- cg — in-memory call graph (CALLS edges + symbol list)
- communities — map[symKey]communityID (symKey = "name\x00relFile")
- pagerank — map[symKey]score
- handlesTargets — set of symKeys that are HANDLES targets; always treated as entry-points regardless of in-degree
- maxFlows — cap on the total number of flows (≤0 uses default flowsMax)
- dfsDepth — DFS traversal depth bound (≤0 uses default flowsDFSDepth)
type GraphDiff ¶
type GraphDiff struct {
AddedSymbols []SnapshotSymbol `json:"added_symbols"`
RemovedSymbols []SnapshotSymbol `json:"removed_symbols"`
AddedEdges []SnapshotEdge `json:"added_edges"`
RemovedEdges []SnapshotEdge `json:"removed_edges"`
CommunityMigrations []CommunityChange `json:"community_migrations,omitempty"`
ComplexityChanges []ComplexityChange `json:"complexity_changes,omitempty"`
Summary string `json:"summary"`
}
GraphDiff holds the result of comparing two code graph snapshots.
func DiffGraphs ¶
DiffGraphs compares two snapshots and returns the diff.
type GraphMeta ¶
type GraphMeta struct {
RepoKey string `json:"repo_key"`
RepoPath string `json:"repo_path"`
GraphName string `json:"graph_name"`
FileCount int `json:"file_count"`
SymbolCount int `json:"symbol_count"`
EdgeCount int `json:"edge_count"`
BuiltAt time.Time `json:"built_at"`
TTLSeconds int `json:"ttl_seconds"`
}
GraphMeta describes a built code graph stored in code_graph_meta.
func IndexRepo ¶
func IndexRepo(ctx context.Context, store *Store, root string, isRemote bool, cfg IndexConfig) (*GraphMeta, error)
IndexRepo builds (or returns cached) a code graph for the repo at root.
func ListMeta ¶ added in v1.22.2
ListMeta returns every stored GraphMeta row — one per repo that has ever completed a successful build. Used at boot to seed gocode_code_graph_age_seconds with the REAL age of each repo's last build (see cmd/go-code's publishCodeGraphAgeGauge) instead of leaving the series absent — and therefore invisible to GocodeCodeGraphStale — until the next build cycle completes.
Returns (nil, nil) when code_graph_meta does not exist yet, matching getMeta's cold-path treatment: an uninitialised schema is "no repos known yet", not an error.
type GraphStats ¶
type GraphStats struct {
Vertices int `json:"vertices"`
Edges int `json:"edges"`
Cached bool `json:"cached"`
}
GraphStats reports graph metadata attached to a query result.
type HealthCacheEntry ¶
type HealthCacheEntry struct {
ResultXML string
Score int
Grade string
ComputedAt time.Time
TTLSeconds int
}
HealthCacheEntry holds a cached code_health result.
type IndexConfig ¶
type IndexConfig struct {
TTLLocal int
TTLRemote int
BatchSize int
// EnableSurpriseIndex triggers the two-phase surprise persistence pass
// (IndexSurpriseEdges + IndexSurpriseNodes) after the pagerank/community
// pass. Gated behind CODEGRAPH_SURPRISE_INDEX=1 (default off).
EnableSurpriseIndex bool
// FlowsMax caps the total number of flows extracted per repo.
// Env: FLOWS_MAX (default 50). Zero means use default.
FlowsMax int
// FlowsDFSDepth bounds the DFS traversal depth per flow.
// Env: FLOWS_DFS_DEPTH (default 8). Zero means use default.
FlowsDFSDepth int
}
IndexConfig controls caching behaviour for IndexRepo.
type MemoryStatus ¶ added in v1.32.1
type MemoryStatus struct {
AvailableBytes uint64
PSIAvg10 float64
PSIAvg60 float64
Sufficient bool
Reason string // non-empty when Sufficient=false
}
MemoryStatus describes the host's memory pressure at a point in time.
func CheckMemoryPressure ¶ added in v1.32.1
func CheckMemoryPressure() MemoryStatus
CheckMemoryPressure reads /proc/meminfo and /proc/pressure/memory to decide whether it is safe to start a memory-intensive graph build.
On non-Linux platforms (or when the files are unreadable, e.g. inside a container without /proc mounted) it returns Sufficient=true — the guard is a no-op so tests and dev environments are not blocked.
type QueryResult ¶
type QueryResult struct {
Repo string `json:"repo"`
Query string `json:"query"`
Template string `json:"template"`
Cypher string `json:"cypher"`
Results [][]string `json:"results"`
Narrative string `json:"narrative,omitempty"`
GraphStats GraphStats `json:"graph_stats"`
}
QueryResult is the full output of a QueryGraph call.
func QueryGraph ¶
func QueryGraph(ctx context.Context, store *Store, llmClient llm.Completer, graphName, query string, meta *GraphMeta, narrativeEnabled bool) (*QueryResult, error)
QueryGraph classifies a natural-language query, executes Cypher against the named AGE graph, and optionally generates a narrative using the LLM.
Flow:
- Classify(query) → template or freeform fallback
- Template path: GetTemplate + Render + ExecCypher
- Freeform path: GenerateCypher + ExecCypher
- On freeform exec error: GenerateCypherWithRetry + retry ExecCypher
- LLM narrative (non-fatal, skipped when results are empty)
type Snapshot ¶
type Snapshot struct {
RepoKey string `json:"repo_key"`
SnapshotAt time.Time `json:"snapshot_at"`
Symbols []SnapshotSymbol `json:"symbols"`
Edges []SnapshotEdge `json:"edges"`
}
Snapshot is a point-in-time capture of a code graph for diff purposes.
type SnapshotEdge ¶
SnapshotEdge holds a single directed edge entry in a snapshot.
type SnapshotSymbol ¶
type SnapshotSymbol struct {
Name string `json:"n"`
Kind string `json:"k"`
File string `json:"f"`
Community int `json:"c"`
Complexity int `json:"x,omitempty"`
}
SnapshotSymbol holds a single symbol entry in a snapshot.
type SparseEmbedder ¶ added in v1.21.0
type SparseEmbedder = sparse.SparseEmbedder
SparseEmbedder is the interface satisfied by *sparse.Client (go-kit/sparse). Declared here so Phase P1 can wire it without importing the concrete type in every call site.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store wraps a pgxpool for Apache AGE graph operations on code repositories.
func (*Store) AssertSchemaDrift ¶ added in v1.21.0
AssertSchemaDrift checks that none of the three data tables (code_repo_state, code_embeddings, code_health_cache) exist in the ag_catalog schema. If any are found there it logs an error and increments gocode_schema_drift_total{table}.
Call once at startup, after Preflight, to detect search_path leak regressions. The counters are pre-touched at 0 for all three tables regardless of findings so Prometheus always exports the series.
func (*Store) BulkCopyInsert ¶
func (s *Store) BulkCopyInsert(ctx context.Context, gname string, vertices []vertexData, edges []edgeData) error
BulkCopyInsert inserts all vertices and edges directly into AGE's internal PostgreSQL tables using text-format COPY FROM STDIN — bypassing the Cypher parser and executor entirely.
graphid formula: (label_id << 48) | seq_num, seq starts at 1 per label. Both graphid and agtype accept string input in text-format COPY.
Returns an error on failure; the caller should fall back to UNWIND inserts.
func (*Store) CheckAGEPreloaded ¶ added in v1.20.0
CheckAGEPreloaded verifies that the AGE extension is loaded in PostgreSQL. Call once at service startup — before any Cypher query — to fail fast if shared_preload_libraries does not include 'age'. Without server-side preloading AGE types/operators are unavailable and all graph operations will fail.
func (*Store) DeleteFileMtimes ¶
DeleteFileMtimes removes stored file modification times for a repo.
func (*Store) DropGraph ¶
DropGraph drops the AGE graph and removes the meta row for the given repoKey.
func (*Store) EnsureFlowsTable ¶ added in v1.21.0
EnsureFlowsTable creates the code_flows table if it does not exist. Safe to call on every IndexRepo pass (idempotent CREATE IF NOT EXISTS). Uses a plain dataPool connection — code_flows lives in public, not ag_catalog.
func (*Store) EnsureGraph ¶
EnsureGraph creates the AGE graph if it does not exist and ensures the code_graph_meta bookkeeping table is present.
func (*Store) EnsureGraphExistsForRead ¶
EnsureGraphExistsForRead is the cheap preflight for read-path callers. Returns ErrGraphNotIndexed without hitting AGE if the graph is known to be absent. Returns nil if the graph exists.
Cache: positive checks are valid for graphExistsCacheTTL (30s); on cache miss it hits ag_catalog.ag_graph via SELECT EXISTS (cheap). Negative results are NOT cached — a graph may be created by IndexRepo at any moment.
func (*Store) EnsureHealthCacheTable ¶
EnsureHealthCacheTable creates the code_health_cache table if it doesn't exist.
func (*Store) EnsureIndexes ¶
EnsureIndexes creates Postgres indexes on AGE vertex tables to speed up property-filter queries (e.g. WHERE s.kind = 'interface').
AGE stores vertices as rows in per-label tables with an `agtype` properties column. Filters like `s.kind = 'interface'` translate to `properties->>'kind' = 'interface'` which requires a sequential scan without an index. Adding expression indexes speeds these queries up 5-10x on large graphs (>2000 symbols).
Indexes are created with IF NOT EXISTS and are safe to run on every graph rebuild. Non-fatal: index failures log a warning and continue.
func (*Store) EnsureLabels ¶
EnsureLabels pre-creates all known vertex and edge labels for gname. Safe to call when labels already exist; "already exists" errors are ignored.
func (*Store) ExecCypher ¶
ExecCypher executes a read-only Cypher query against the named graph and returns string rows. cols is the number of projected columns in the query. Returns an error if the Cypher contains write operations.
func (*Store) ExecCypherWrite ¶
ExecCypherWrite executes a write Cypher statement (MERGE/CREATE/SET/DELETE) and drains any returned rows without collecting them.
func (*Store) GetFileMtimes ¶
GetFileMtimes retrieves stored file modification times for a repo.
func (*Store) GraphExists ¶
GraphExists returns true if the named AGE graph exists. Used as preflight before cypher queries on read-path to avoid generating "graph does not exist" errors in postgres logs when the repo was never indexed.
func (*Store) HasAGE ¶
HasAGE checks if Apache AGE extension is available in this PostgreSQL instance. A positive result is cached permanently. Failures are retried on subsequent calls so that a temporary DB outage at startup does not permanently disable AGE.
func (*Store) ListFlows ¶ added in v1.21.0
ListFlows returns all flows for repoKey ordered by priority descending.
func (*Store) LoadDeadCodeScore ¶
LoadDeadCodeScore returns the pre-computed CE dead-code probability [0..1]. Higher = more likely genuine dead code. Returns (0, false) if not scored.
func (*Store) LoadDeadCodeScores ¶
LoadDeadCodeScores fetches pre-computed reranker scores for dead_code rows. Returns rows sorted by score DESC if scores exist; nil if no scores stored.
func (*Store) LoadHealthCache ¶
func (s *Store) LoadHealthCache(ctx context.Context, repoKey string) *HealthCacheEntry
LoadHealthCache returns the cached health result if fresh. Returns nil if not cached or stale.
func (*Store) LoadTopDeadCodeCandidates ¶
func (s *Store) LoadTopDeadCodeCandidates( ctx context.Context, repoKey string, minScore float32, limit int, ) ([]DeadCodeCandidate, error)
LoadTopDeadCodeCandidates returns the top N dead-code candidates for a repo with CE probability above minScore (0..1). Returns nil, nil when no candidates exist (graph not indexed or no orphans).
func (*Store) NewBulkWriter ¶
func (s *Store) NewBulkWriter(ctx context.Context) (*BulkWriter, error)
NewBulkWriter acquires a connection and sets synchronous_commit=off. Returns (nil, nil) on acquire failure — callers should fall back to Store.
func (*Store) Preflight ¶ added in v1.20.0
Preflight checks that the connected role has the minimum database-level privileges go-code cannot acquire for itself. Call once at startup before registering any tools; return the error to the caller to log and exit(1).
Two privileges CANNOT be self-granted without being the database owner or having GRANT OPTION:
USAGE on schema ag_catalog — needed by LOAD age and every cypher() call. Fix: GRANT USAGE ON SCHEMA ag_catalog TO <role>;
CREATE on the current database — needed because ag_catalog.create_graph() issues CREATE SCHEMA internally. Fix: GRANT CREATE ON DATABASE <db> TO <role>;
If AGE is not installed, both checks are skipped (go-code degrades to SQL-only mode without graph features).
func (*Store) ScoreDeadCodeCandidates ¶
func (s *Store) ScoreDeadCodeCandidates(ctx context.Context, gname, repoKey string, symbolCount int) error
ScoreDeadCodeCandidates finds orphan functions in the graph, reranks them via the CE reranker, and persists scores to code_dead_code_scores. Non-fatal: logging only on any error. Scores are available immediately for the next dead_code query on this repo.
func (*Store) SymbolStructuralRank ¶
func (s *Store) SymbolStructuralRank(ctx context.Context, repoKey, name, file string, pagerank float64) string
SymbolStructuralRank returns a human-readable PageRank percentile for a symbol. e.g. "Top 2% (6th of 4040 symbols by structural centrality)" Returns "" when graph unavailable, symbol not found, or PageRank is 0. The caller may pass the already-fetched pagerank value to avoid re-querying.
func (*Store) UpsertFileMtimes ¶
func (s *Store) UpsertFileMtimes(ctx context.Context, repoKey string, mtimes map[string]time.Time) error
UpsertFileMtimes stores file modification times for a repo. It replaces all existing entries for the given repoKey.
func (*Store) UpsertFlows ¶ added in v1.21.0
UpsertFlows replaces all flows for repoKey with the provided slice. Uses DELETE + batch-INSERT within a single transaction (reconcile pattern). Non-fatal: logs on error and bumps flowsDBErrorTotal so alerts fire.
type SurpriseResult ¶
type SurpriseResult struct {
FromName string `json:"from_name"`
FromFile string `json:"from_file"`
ToName string `json:"to_name"`
ToFile string `json:"to_file"`
Score int `json:"score"`
Reasons []string `json:"reasons"`
}
SurpriseResult is a scored surprise edge with human-readable reasons.
type Template ¶
Template is a named Cypher query template with parameter substitution.
func GetTemplate ¶
GetTemplate returns the template with the given ID, or nil if not found.
Source Files
¶
- adapter.go
- adapter_crossrefs.go
- bootstrap.go
- classify.go
- community.go
- config.go
- copy_insert.go
- cypher_batch.go
- diff.go
- errors.go
- flows.go
- flows_metrics.go
- generate.go
- graph_build.go
- graph_build_rels.go
- graph_exists_cache.go
- impls_unify.go
- incremental.go
- index.go
- index_helpers.go
- index_layers.go
- memguard.go
- meta.go
- metrics.go
- pagerank.go
- parse.go
- persist_insights.go
- persist_insights_util.go
- query.go
- query_surprise.go
- rerank.go
- route_metrics.go
- schema.go
- semantic_rerank.go
- snapshot.go
- snapshot_age.go
- sparse.go
- store.go
- store_dead_code.go
- store_flows.go
- store_graph.go
- store_helpers.go
- surprise.go
- surprise_index.go
- templates.go
- templates_community.go
- tested_by.go
- trace_age.go