codegraph

package
v1.39.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: Apache-2.0 Imports: 45 Imported by: 0

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

View Source
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

View Source
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

func CacheStatus(ctx context.Context, store *Store, root string) (bool, error)

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

func ExtractTestedByEdges(root string, symbols []*parser.Symbol) []edgeData

ExtractTestedByEdges creates TESTED_BY edges mapping test functions to tested symbols.

func GenerateCypher

func GenerateCypher(ctx context.Context, client llm.Completer, query string) (string, error)

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

func GraphNameFor(repoPath string) string

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

func IndexSurpriseEdges(ctx context.Context, store *Store, graphName string) error

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

func IndexSurpriseNodes(ctx context.Context, store *Store, graphName string) error

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

func IsGraphMissingError(err error) bool

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

func PostProcessSurprises(rows [][]string, limit int) ([][]string, string)

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

func RerankDeadCode(_ context.Context, rows [][]string) [][]string

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

func SnapshotBeforeRebuild(ctx context.Context, store *Store, repoKey, graphName string)

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.

func Classify

func Classify(ctx context.Context, client llm.Completer, query string) (*Classification, error)

Classify sends a natural-language query to the LLM and returns a Classification. On JSON parse failure it returns a freeform fallback rather than an error.

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

type CypherWriter interface {
	ExecCypherWrite(ctx context.Context, graph, cypher string) error
}

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

type DeadCodeCandidate struct {
	Name  string
	File  string
	Score float32
}

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

func DiffGraphs(old, new_ Snapshot) GraphDiff

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

func ListMeta(ctx context.Context, store *Store) ([]GraphMeta, error)

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:

  1. Classify(query) → template or freeform fallback
  2. Template path: GetTemplate + Render + ExecCypher
  3. Freeform path: GenerateCypher + ExecCypher
  4. On freeform exec error: GenerateCypherWithRetry + retry ExecCypher
  5. 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

type SnapshotEdge struct {
	From  string `json:"s"`
	To    string `json:"t"`
	Label string `json:"l"`
}

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 NewStore

func NewStore(pool *pgxpool.Pool) *Store

NewStore creates a Store backed by the given pool.

func (*Store) AssertSchemaDrift added in v1.21.0

func (s *Store) AssertSchemaDrift(ctx context.Context)

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

func (s *Store) CheckAGEPreloaded(ctx context.Context) error

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

func (s *Store) DeleteFileMtimes(ctx context.Context, repoKey string) error

DeleteFileMtimes removes stored file modification times for a repo.

func (*Store) DropGraph

func (s *Store) DropGraph(ctx context.Context, name, repoKey string) error

DropGraph drops the AGE graph and removes the meta row for the given repoKey.

func (*Store) EnsureFlowsTable added in v1.21.0

func (s *Store) EnsureFlowsTable(ctx context.Context) error

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

func (s *Store) EnsureGraph(ctx context.Context, name string) error

EnsureGraph creates the AGE graph if it does not exist and ensures the code_graph_meta bookkeeping table is present.

func (*Store) EnsureGraphExistsForRead

func (s *Store) EnsureGraphExistsForRead(ctx context.Context, graphName string) error

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

func (s *Store) EnsureHealthCacheTable(ctx context.Context) error

EnsureHealthCacheTable creates the code_health_cache table if it doesn't exist.

func (*Store) EnsureIndexes

func (s *Store) EnsureIndexes(ctx context.Context, name string) error

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

func (s *Store) EnsureLabels(ctx context.Context, gname string) error

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

func (s *Store) ExecCypher(ctx context.Context, graph, cypher string, cols int) ([][]string, error)

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

func (s *Store) ExecCypherWrite(ctx context.Context, graph, cypher string) error

ExecCypherWrite executes a write Cypher statement (MERGE/CREATE/SET/DELETE) and drains any returned rows without collecting them.

func (*Store) GetFileMtimes

func (s *Store) GetFileMtimes(ctx context.Context, repoKey string) (map[string]time.Time, error)

GetFileMtimes retrieves stored file modification times for a repo.

func (*Store) GraphExists

func (s *Store) GraphExists(ctx context.Context, graphName string) (bool, error)

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

func (s *Store) HasAGE(ctx context.Context) bool

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

func (s *Store) ListFlows(ctx context.Context, repoKey string) ([]Flow, error)

ListFlows returns all flows for repoKey ordered by priority descending.

func (*Store) LoadDeadCodeScore

func (s *Store) LoadDeadCodeScore(ctx context.Context, root, name, file string) (float32, bool)

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

func (s *Store) LoadDeadCodeScores(ctx context.Context, repoKey string, rows [][]string) [][]string

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) Pool

func (s *Store) Pool() *pgxpool.Pool

Pool returns the underlying connection pool (for testing and diagnostics).

func (*Store) Preflight added in v1.20.0

func (s *Store) Preflight(ctx context.Context) error

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:

  1. USAGE on schema ag_catalog — needed by LOAD age and every cypher() call. Fix: GRANT USAGE ON SCHEMA ag_catalog TO <role>;

  2. 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

func (s *Store) UpsertFlows(ctx context.Context, repoKey string, flows []Flow) error

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.

func (*Store) UpsertHealthCache

func (s *Store) UpsertHealthCache(ctx context.Context, repoKey, repoPath, grade, resultXML string, score int, ttl int) error

UpsertHealthCache stores a code_health XML result.

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

type Template struct {
	ID          string
	Description string
	Params      []string
	Cypher      string
	Cols        int
}

Template is a named Cypher query template with parameter substitution.

func GetTemplate

func GetTemplate(id string) *Template

GetTemplate returns the template with the given ID, or nil if not found.

func (*Template) Render

func (t *Template) Render(params map[string]string) string

Render substitutes {param} placeholders with escaped values from params. Uses curly-brace syntax to avoid conflicts with AGE's $-parameter references.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL