Documentation
¶
Index ¶
- Constants
- Variables
- func BindMemoryReferenceEdge(edge types.Edge, liveNodes []types.Node) types.Edge
- func BindMemoryReferences(edges []types.Edge, liveNodes []types.Node) []types.Edge
- func Canonicalize(nodes []types.Node, edges []types.Edge) ([]types.Node, []types.Edge)
- func GodNodes(g *Graph, topN int) []types.Node
- func MergeContract(repoNodes []types.Node, repoEdges []types.Edge, contractNodes []types.Node, ...) ([]types.Node, []types.Edge)
- func RunLeiden(g *Graph) (map[string]int, error)
- func SuggestedQuestions(nodes []types.Node, edges []types.Edge) []string
- func SurpriseEdges(g *Graph, topN int) []types.Edge
- func WorkspaceDomainID(name string) string
- func WorkspacePackageID(name string) string
- func WorkspaceRepoID(name string) string
- func WorkspaceServiceID(name string) string
- type ClusteringEnvironment
- type FreshnessStats
- type Graph
- type GraphLock
- type HealthMetrics
- type MemoryReferenceBinding
- type NodeRank
- type ProjectStatus
- type RegistryStatusSnapshot
- type RegistrySummary
- type RepoOverrides
- type RepoRouteHit
- type RepoStatusSnapshot
- type StatusSnapshot
- type WorkspaceGraph
Constants ¶
const ( MemoryEvidenceReference = "reference" RefRepoFile = "repo:file:" RefRepoSymbol = "repo:symbol:" RefWorkspaceRepo = "workspace:repo:" )
const ( // Workspace edge relations. WorkspaceRelExposes = "exposes" // repo -> service WorkspaceRelHosts = "hosts" // repo -> package WorkspaceRelOwns = "owns" // repo -> domain WorkspaceRelDependsOn = "depends_on" // repo -> repo )
Variables ¶
var ErrClusteringDepsMissing = errors.New("python clustering dependencies are not installed")
var ErrGraphLocked = errors.New("graph is locked by another process (daemon running?); stop the daemon first")
ErrGraphLocked is returned when another process holds the graph lock.
var ErrGraspologicMissing = errors.New("graspologic is not installed")
Functions ¶
func BindMemoryReferenceEdge ¶ added in v1.4.0
BindMemoryReferenceEdge binds a single memory reference edge against the current graph state.
func BindMemoryReferences ¶ added in v1.4.0
BindMemoryReferences projects memory reference edges onto the current live code/workspace nodes. Current and redirected bindings are rewritten to point at the live node ID; stale and ambiguous references keep their original canonical target and carry queryable binder metadata instead.
func Canonicalize ¶ added in v1.4.0
Canonicalize removes duplicate node IDs and duplicate/orphaned edges while preserving the first occurrence order for stable graph exports.
func GodNodes ¶
GodNodes returns the topN nodes sorted by total degree (in + out). These are the most-connected concepts in the graph — architectural hubs.
func MergeContract ¶ added in v1.4.0
func MergeContract( repoNodes []types.Node, repoEdges []types.Edge, contractNodes []types.Node, contractEdges []types.Edge, ) ([]types.Node, []types.Edge)
MergeContract folds a contract-layer graph (nodes + edges) on top of a repo-layer graph while preserving the declared > derived invariant.
Guarantees:
- Repo and contract nodes live side-by-side. Contract nodes keep their "contract:*" identity; they are never merged into repo-local entities.
- When a derived edge and a declared edge claim the same (source, target, relation) triple, the derived edge is dropped — declared truth wins.
- Duplicate declared edges are deduplicated on (source, target, relation) so ingesting the same artifact twice is idempotent.
This helper stays structural: it does not inspect evidence scores beyond the `layer` and `evidence_confidence` metadata that extractors stamp. That keeps the invariant easy to audit in tests and keeps the contract layer from quietly reaching into repo ranking logic.
func RunLeiden ¶
RunLeiden runs Leiden community detection on the graph by delegating to the bundled Python script (scripts/leiden.py). Returns a map of node ID → community ID (0-indexed integers).
If Python or the script is unavailable, a clear error is returned (no panic). The script itself falls back to connected-components if graspologic is missing.
func SuggestedQuestions ¶
SuggestedQuestions returns 4–5 question templates populated with the names of the top god nodes. These are questions the graph is uniquely positioned to answer through path-finding and community analysis.
func SurpriseEdges ¶
SurpriseEdges returns the topN edges that cross community boundaries, ranked by the product of the degrees of their endpoints (a proxy for betweenness centrality: high-degree nodes in different communities that are directly connected are architecturally "surprising").
func WorkspaceDomainID ¶ added in v1.4.0
WorkspaceDomainID returns the canonical workspace ID for a domain tag.
func WorkspacePackageID ¶ added in v1.4.0
WorkspacePackageID returns the canonical workspace ID for a package.
func WorkspaceRepoID ¶ added in v1.4.0
WorkspaceRepoID returns the canonical workspace ID for a repo.
func WorkspaceServiceID ¶ added in v1.4.0
WorkspaceServiceID returns the canonical workspace ID for a service. The identity mirrors the contract-layer service so routing and contract views can share identity without a cross-layer join.
Types ¶
type ClusteringEnvironment ¶ added in v1.7.2
type ClusteringEnvironment struct {
PythonFound bool `json:"python_found"`
PythonPath string `json:"python_path,omitempty"`
NetworkXAvailable bool `json:"networkx_available"`
GraspologicAvailable bool `json:"graspologic_available"`
BaseInstallCommand string `json:"base_install_command"`
LeidenInstallCommand string `json:"leiden_install_command"`
}
func LoadClusteringEnvironment ¶ added in v1.7.2
func LoadClusteringEnvironment() ClusteringEnvironment
type FreshnessStats ¶ added in v1.7.1
type Graph ¶
type Graph struct {
Directed *simple.DirectedGraph
NodeIndex map[string]int64 // node ID string → gonum int64 ID
NodeByID map[int64]types.Node // gonum int64 ID → types.Node
ResolvedEdges []types.Edge // only edges where both endpoints resolved
Nodes []types.Node
}
Graph wraps a gonum directed graph with auxiliary indexes for fast lookup.
func Build ¶
Build constructs a Graph from the provided nodes and edges.
Edge resolution:
- e.Source must match a node ID exactly (it is always in "<file>:<name>" format).
- e.Target is first tried as an exact ID, then as a bare label via labelIndex.
Only edges where BOTH endpoints resolve to known nodes are stored in ResolvedEdges and added to the gonum graph. Dangling edges (targeting stdlib/external symbols) are silently dropped — they add noise and break Obsidian graph view by creating isolated satellite dots.
func (*Graph) ApplyCommunities ¶
ApplyCommunities writes community IDs back onto the graph's node metadata and populates the community → []nodeID index for report generation.
func (*Graph) Communities ¶
Communities returns a map of communityID → list of node IDs (empty until clustering is run).
func (*Graph) Degree ¶
Degree returns the total degree (in + out) of the node with the given ID string.
type GraphLock ¶ added in v1.3.0
type GraphLock struct {
// contains filtered or unexported fields
}
GraphLock holds an exclusive advisory lock on ~/.vela/graph.lock so the daemon and vela extract cannot write graph.json concurrently.
func AcquireGraphLock ¶ added in v1.3.0
AcquireGraphLock opens the lock file and acquires a non-blocking exclusive lock. Returns ErrGraphLocked if another process already holds the lock.
type HealthMetrics ¶ added in v1.2.0
type HealthMetrics struct {
Path string `json:"path"`
GeneratedAt string `json:"generated_at,omitempty"`
// Size
Nodes int `json:"nodes"`
Edges int `json:"edges"`
// Coverage — breakdowns
NodesByKind map[string]int `json:"nodes_by_kind"`
EdgesByRelation map[string]int `json:"edges_by_relation"`
// Quality / resolution
BrokenEdges int `json:"broken_edges"`
SelfLoops int `json:"self_loops"`
DuplicateEdges int `json:"duplicate_edges"`
ResolutionRate float64 `json:"resolution_rate"` // 0..1
// Confidence
ConfidenceDist map[string]int `json:"confidence_dist"`
ExtractedRate float64 `json:"extracted_rate"` // 0..1
// Degree
AvgDegree float64 `json:"avg_degree"`
MedianDegree int `json:"median_degree"`
P95Degree int `json:"p95_degree"`
MaxDegree int `json:"max_degree"`
IsolatedNodes int `json:"isolated_nodes"`
HubNodes int `json:"hub_nodes"` // total degree >= 10
LeafNodes int `json:"leaf_nodes"` // total degree == 1
ConnectedPct int `json:"connected_pct"`
// Communities
Communities int `json:"communities"`
LargestCommunitySize int `json:"largest_community_size"`
SingletonCommunities int `json:"singleton_communities"`
Modularity float64 `json:"modularity"`
// Top nodes (length fixed via TopN when loading)
TopByOutDegree []NodeRank `json:"top_by_out_degree"`
}
HealthMetrics is the full set of graph-health signals computed from an on-disk graph.json. It is the single source of truth consumed by both `vela bench` and the TUI Graph Status screen.
func LoadHealthMetrics ¶ added in v1.2.0
func LoadHealthMetrics(path string, topN int) (HealthMetrics, error)
LoadHealthMetrics reads graph.json at path and computes every signal. topN controls the length of TopByOutDegree (5 is a reasonable default).
type MemoryReferenceBinding ¶ added in v1.4.0
type MemoryReferenceBinding struct {
State types.VerificationState
BoundTarget string
Suggestions []string
Evidence string
}
MemoryReferenceBinding captures the live binding state for a memory reference. The original reference target is preserved separately so history does not get silently rewritten when code moves.
type NodeRank ¶ added in v1.2.0
type NodeRank struct {
ID string `json:"id"`
Label string `json:"label"`
File string `json:"file,omitempty"`
Kind string `json:"kind,omitempty"`
OutDeg int `json:"out_degree"`
InDeg int `json:"in_degree"`
}
NodeRank is a compact row used in metric leaderboards (top-N by degree).
type ProjectStatus ¶ added in v1.7.1
type RegistryStatusSnapshot ¶ added in v1.7.1
type RegistryStatusSnapshot struct {
Summary RegistrySummary `json:"summary"`
Repos []RepoStatusSnapshot `json:"repos"`
}
func LoadRegistryStatusSnapshot ¶ added in v1.7.1
func LoadRegistryStatusSnapshot(entries []registry.Entry, topN int) RegistryStatusSnapshot
type RegistrySummary ¶ added in v1.7.1
type RegistrySummary struct {
Repositories int `json:"repositories"`
HealthyGraphs int `json:"healthy_graphs"`
MissingGraphs int `json:"missing_graphs"`
InstalledHooks int `json:"installed_hooks"`
MissingHooks int `json:"missing_hooks"`
MissingManifest int `json:"missing_manifest"`
MissingReport int `json:"missing_report"`
Nodes int `json:"nodes"`
Edges int `json:"edges"`
BrokenEdges int `json:"broken_edges"`
LatestGraphUTC time.Time `json:"latest_graph_utc"`
}
type RepoOverrides ¶ added in v1.4.0
type RepoOverrides struct {
Domains []string
Packages []string
Dependencies []string // other repo names this repo depends on
}
RepoOverrides carries declarative routing hints the caller wants to stamp onto a repo that cannot be derived from the merged graph alone (domain tags from repo config, declared dependencies from manifests, language packages, etc.). All fields are optional.
type RepoRouteHit ¶ added in v1.4.0
RepoRouteHit is one ranked repo candidate returned by SelectRepos. Reasons explains why the repo matched so the orchestrator can surface provenance.
type RepoStatusSnapshot ¶ added in v1.7.1
type RepoStatusSnapshot struct {
RepoRoot string `json:"repo_root"`
Name string `json:"name"`
Remote string `json:"remote,omitempty"`
GraphPath string `json:"graph_path,omitempty"`
HookInstalled bool `json:"hook_installed"`
HookStatus string `json:"hook_status"`
Snapshot StatusSnapshot `json:"snapshot"`
LoadError string `json:"load_error,omitempty"`
TrackedAt time.Time `json:"tracked_at,omitempty"`
ManifestPath string `json:"manifest_path,omitempty"`
ReportPath string `json:"report_path,omitempty"`
}
type StatusSnapshot ¶ added in v1.7.1
type StatusSnapshot struct {
GraphPath string `json:"graph_path"`
Metrics HealthMetrics `json:"metrics"`
Freshness FreshnessStats `json:"freshness"`
Projects []ProjectStatus `json:"projects"`
}
func LoadStatusSnapshot ¶ added in v1.7.1
func LoadStatusSnapshot(path string, topN int) (StatusSnapshot, error)
type WorkspaceGraph ¶ added in v1.4.0
type WorkspaceGraph struct {
Nodes []types.Node
Edges []types.Edge
// contains filtered or unexported fields
}
WorkspaceGraph is the routing-only derived graph. It exposes its nodes and edges for persistence alongside the repo+contract graph, plus the indexes needed for SelectRepos.
func BuildWorkspace ¶ added in v1.4.0
func BuildWorkspace(nodes []types.Node, edges []types.Edge, overrides map[string]RepoOverrides) *WorkspaceGraph
BuildWorkspace derives a workspace graph from the merged repo+contract graph plus optional per-repo overrides. Inputs follow the same shape that MergeContract produces.
Derivation rules (lightweight by design):
- one workspace:repo node per project node
- one workspace:service node per contract:service node
- repo -> service ("exposes") edges inferred from contract "declared_in" edges (declared evidence flows through unchanged)
- repo -> package ("hosts"), repo -> domain ("owns"), repo -> repo ("depends_on") edges from the caller-supplied overrides
BuildWorkspace is idempotent: running it twice on the same inputs produces the same output. It makes no attempt to mine code structure — packages, domains, and dependencies must come from declared sources (overrides) to keep routing trustworthy.
func LoadWorkspace ¶ added in v1.4.0
func LoadWorkspace(nodes []types.Node, edges []types.Edge) *WorkspaceGraph
LoadWorkspace rebuilds routing indexes from persisted workspace-layer nodes and edges already present in a merged graph.
func (*WorkspaceGraph) Repos ¶ added in v1.4.0
func (w *WorkspaceGraph) Repos() []string
Repos returns the repo names known to the workspace graph, sorted.
func (*WorkspaceGraph) ReposExposing ¶ added in v1.4.0
func (w *WorkspaceGraph) ReposExposing(service string) []string
ReposExposing returns the repo names that expose a given service.
func (*WorkspaceGraph) SelectRepos ¶ added in v1.4.0
func (w *WorkspaceGraph) SelectRepos(tokens []string, limit int) []RepoRouteHit
SelectRepos ranks repos against a set of query tokens. Matching is case-insensitive and token-wise. The returned slice is sorted by descending score; limit<=0 returns all non-zero hits.
Scoring is intentionally coarse — the workspace layer is a prefilter, not a ranker. Declared evidence (service name matches) outranks derived hints (domain/package tags) so contract truth flows through routing.