graph

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

@index Materialized cross-namespace annotation references for federated graph analysis.

@index Persisted parser-result cache entries scoped by namespace and source path.

@index GORM models for runtime schema compatibility checks.

@index Durable unresolved-edge reverse index for semi-naive incremental resolution.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildInheritsFingerprintV2

func BuildInheritsFingerprintV2(filePath, child, parent string) string

BuildInheritsFingerprintV2 encodes inherits edges with a versioned JSON payload. @intent provide an unambiguous fingerprint contract for inheritance edges across languages.

func CompareIdentity added in v0.13.1

func CompareIdentity(a, b Identity) int

CompareIdentity orders two nodes by who they are, for the callers that have run out of reasons to prefer one over the other.

File path comes first so a tie group reads as whole files, matching how an evidence list groups it anyway. Namespace is in there because federated search can hold the same file in two repositories, and start line because one file can declare the same qualified name twice. @intent give every layer of search one tie-break, so two layers cannot disagree about who comes first.

func IsCallKind

func IsCallKind(kind EdgeKind) bool

IsCallKind reports whether kind represents a call edge.

This helper keeps fallback call-kind handling centralized for traversal and filtering paths. @intent centralize call-kind handling for traversal and filtering paths.

func ParseInheritsFingerprint

func ParseInheritsFingerprint(filePath, fingerprint string) (child, parent string, ok bool)

ParseInheritsFingerprint decodes v2 fingerprints first and falls back to the legacy contract. @intent keep resolver compatibility while parsers migrate to the unambiguous inherits fingerprint format.

Types

type Annotation

type Annotation struct {
	ID        uint   `gorm:"primaryKey"`
	NodeID    uint   `gorm:"uniqueIndex;not null"`
	Summary   string `gorm:"type:text"`
	Context   string `gorm:"type:text"`
	RawText   string `gorm:"type:text"`
	CreatedAt time.Time
	UpdatedAt time.Time

	Tags []DocTag `gorm:"foreignKey:AnnotationID"`
}

Annotation은 코드 선언에 연결된 구조화된 주석이다. @intent 노드에 연결된 요약과 태그 메타데이터를 영속화한다.

type Community

type Community struct {
	ID          uint   `gorm:"primaryKey"`
	Namespace   string `gorm:"type:text;not null;default:'default';uniqueIndex:idx_community_ns_key"`
	Key         string `gorm:"type:text;not null;uniqueIndex:idx_community_ns_key"`
	Label       string `gorm:"type:text;not null"`
	Strategy    string `gorm:"type:text;not null;index"`
	Description string `gorm:"type:text"`
	CreatedAt   time.Time
	UpdatedAt   time.Time

	Members []CommunityMembership `gorm:"foreignKey:CommunityID"`
}

Community는 커뮤니티 분석 결과의 그룹 메타데이터를 저장한다. @intent 연관된 노드 집합을 전략별 커뮤니티 단위로 표현한다.

type CommunityMembership

type CommunityMembership struct {
	ID          uint `gorm:"primaryKey"`
	CommunityID uint `gorm:"not null;uniqueIndex:idx_community_node"`
	NodeID      uint `gorm:"not null;uniqueIndex:idx_community_node;index"`
	CreatedAt   time.Time
}

CommunityMembership는 노드와 커뮤니티의 소속 관계를 저장한다. @intent 특정 노드가 어떤 커뮤니티에 속하는지 연결한다.

type CrossRef added in v0.12.0

type CrossRef struct {
	ID             uint           `gorm:"primaryKey"`
	FromNamespace  string         `gorm:"type:text;not null;index:idx_crossref_from_ns"`
	FromNodeID     uint           `gorm:"not null;index:idx_crossref_from_node"`
	Raw            string         `gorm:"type:text;not null"`
	ToNamespace    string         `gorm:"type:text;not null;index:idx_crossref_to_ns"`
	ToPath         string         `gorm:"type:text;not null;default:''"`
	ToSymbol       string         `gorm:"type:text;not null;default:''"`
	ResolvedNodeID *uint          `gorm:"index:idx_crossref_resolved_node"`
	Status         CrossRefStatus `gorm:"type:text;not null"`
	Source         CrossRefSource `gorm:"type:text;not null;default:'annotation'"`
	CreatedAt      time.Time
	UpdatedAt      time.Time
}

CrossRef materializes one @see ccg:// annotation tag as queryable cross-namespace graph state. @intent make annotation-declared repository links traversable and listable instead of plain tag text. @domainRule target identity is symbolic (namespace, path, symbol); resolved_node_id is derived state that rebuilds change. @domainRule rows for one source namespace are fully replaced on each build, so no uniqueness constraint is required.

type CrossRefSource added in v0.12.0

type CrossRefSource string

CrossRefSource records which signal produced a cross-namespace reference. @intent keep room for future non-annotation signals (e.g. import mapping) without schema rework.

const CrossRefSourceAnnotation CrossRefSource = "annotation"

type CrossRefStatus added in v0.12.0

type CrossRefStatus string

CrossRefStatus describes whether a cross-namespace reference currently resolves to a node. @intent distinguish navigable references from dangling ones without deleting authored links.

const (
	CrossRefStatusResolved CrossRefStatus = "resolved"
	CrossRefStatusDead     CrossRefStatus = "dead"
)

type DocTag

type DocTag struct {
	ID           uint    `gorm:"primaryKey"`
	AnnotationID uint    `gorm:"not null;index"`
	Kind         TagKind `gorm:"type:text;not null;index"`
	Type         string  `gorm:"type:text"`
	Name         string  `gorm:"type:text"`
	Value        string  `gorm:"type:text;not null"`
	Ordinal      int     `gorm:"not null"`
	CreatedAt    time.Time
}

DocTag는 Annotation 내의 개별 태그이다. @intent 어노테이션의 단일 구조화 태그 항목을 표현한다. Type 필드는 YARD `@param [String] name ...` 또는 JSDoc `@param {string} name ...`에서 추출한 타입 문자열을 보관한다 (param/throws/return에서 사용). TypeScript/JSDoc 복합 타입(`Record<string, Array<{id: number, name: string}>>`)이 수백 바이트에 이를 수 있어 text로 지정.

type Edge

type Edge struct {
	ID          uint     `gorm:"primaryKey"`
	Namespace   string   `gorm:"type:text;not null;default:'default';index;uniqueIndex:idx_edges_namespace_fingerprint"`
	FromNodeID  uint     `gorm:"index"`
	ToNodeID    uint     `gorm:"index"`
	Kind        EdgeKind `gorm:"type:text;not null;index"`
	FilePath    string   `gorm:"type:text;index"`
	Line        int
	Fingerprint string `gorm:"type:text;not null;uniqueIndex:idx_edges_namespace_fingerprint"`
	CreatedAt   time.Time

	FromNode Node `gorm:"foreignKey:FromNodeID;constraint:-"`
	ToNode   Node `gorm:"foreignKey:ToNodeID;constraint:-"`
}

Edge는 두 노드 사이의 방향성 관계를 저장한다. @intent 코드 그래프에서 선언 간 연결과 그 출처를 영속화한다.

type EdgeKind

type EdgeKind string

EdgeKind는 노드 간 관계의 종류를 나타낸다. @intent 그래프 엣지의 의미를 일관된 관계 타입으로 구분한다.

const (
	EdgeKindCalls         EdgeKind = "calls"
	EdgeKindFallbackCalls EdgeKind = "fallback_calls"
	EdgeKindImportsFrom   EdgeKind = "imports_from"
	EdgeKindInherits      EdgeKind = "inherits"
	EdgeKindImplements    EdgeKind = "implements"
	EdgeKindContains      EdgeKind = "contains"
	EdgeKindTestedBy      EdgeKind = "tested_by"
	EdgeKindDependsOn     EdgeKind = "depends_on"
	EdgeKindReferences    EdgeKind = "references"

	// EdgeKindCrossRef marks a synthetic traversal edge derived from a resolved cross-namespace
	// annotation reference. It is never persisted in the edges table; cross-namespace readers
	// materialize it from cross_refs rows at query time.
	EdgeKindCrossRef EdgeKind = "cross_ref"
)

func CallEdgeKinds

func CallEdgeKinds() []EdgeKind

CallEdgeKinds returns edge kinds that represent a callable relationship.

Fallback call resolution stores low-confidence edges as EdgeKindFallbackCalls, but callers that want to traverse call behavior should usually include both values. @intent centralize call-kind handling for traversal and filtering paths.

type Flow

type Flow struct {
	ID          uint   `gorm:"primaryKey"`
	Namespace   string `gorm:"type:text;not null;default:'default';index"`
	Name        string `gorm:"type:text;not null"`
	Description string `gorm:"type:text"`
	CreatedAt   time.Time

	Members []FlowMembership `gorm:"foreignKey:FlowID"`
}

Flow는 추적된 호출 흐름의 메타데이터를 저장한다. @intent 의미 있는 실행 흐름을 이름과 설명으로 식별한다.

type FlowMembership

type FlowMembership struct {
	ID        uint   `gorm:"primaryKey"`
	Namespace string `gorm:"type:text;not null;default:'default';index"`
	FlowID    uint   `gorm:"not null;index"`
	NodeID    uint   `gorm:"not null;index"`
	Ordinal   int    `gorm:"not null"`
}

FlowMembership는 흐름에 포함된 노드의 순서를 저장한다. @intent 특정 플로우를 구성하는 노드와 그 위치를 연결한다.

type Identity added in v0.13.1

type Identity struct {
	FilePath      string
	QualifiedName string
	Kind          NodeKind
	Namespace     string
	StartLine     int
}

Identity is who a node is, told apart from which row it happens to be.

The database gives every node an id in the order the rows were written, so an id says when a node was indexed, not what it is. Re-index the same repository from a clean checkout and every id can differ while every Identity here stays the same. Anything that has to produce the same answer twice — a tie-break, a stable sort, a comparison across two databases — belongs on this and not on the id.

The five fields are the four columns of the node table's uniqueness index (namespace, qualified_name, file_path, start_line) plus the kind, so two different nodes cannot share one Identity. @intent give ranking a key that survives re-indexing, which the node id does not.

type Node

type Node struct {
	ID            uint     `gorm:"primaryKey"`
	Namespace     string   `gorm:"type:text;not null;default:'default';uniqueIndex:idx_ns_qn_fp_sl;index:idx_nodes_ns_file_path,priority:1"`
	QualifiedName string   `gorm:"type:text;not null;uniqueIndex:idx_ns_qn_fp_sl"`
	Kind          NodeKind `gorm:"type:text;not null;index"`
	Name          string   `gorm:"type:text;not null"`
	FilePath      string   `gorm:"type:text;not null;index;uniqueIndex:idx_ns_qn_fp_sl;index:idx_nodes_ns_file_path,priority:2"`
	StartLine     int      `gorm:"not null;uniqueIndex:idx_ns_qn_fp_sl"`
	EndLine       int      `gorm:"not null"`
	Hash          string   `gorm:"type:text"`
	Language      string   `gorm:"type:text;index"`
	CreatedAt     time.Time
	UpdatedAt     time.Time

	Annotation *Annotation `gorm:"foreignKey:NodeID"`
}

Node는 코드 그래프의 단일 선언 엔티티를 저장한다. @intent 파일 내 선언의 정체성과 위치 정보를 영속화한다.

func (Node) Identity added in v0.13.1

func (n Node) Identity() Identity

Identity says who this node is. @intent read a node's stable identity without repeating which fields make it up.

func (Node) Intent added in v0.12.2

func (n Node) Intent() string

Intent returns what the author said this declaration is for, or an empty string when nobody wrote it down.

It is the one annotation field search puts in front of a reader, because it carries what the identifier cannot. `Shutdown` already says it stops something; its intent says it exists to give in-flight webhook syncs a bounded way out. The summary field mostly restates the name.

@requires the node's Annotation and its Tags are loaded; an unloaded association reads as absent. @ensures returns the first intent tag's value, so repeated calls agree. @intent give search one line of author-written purpose to show beside a result.

func (Node) RecordedReason added in v0.13.1

func (n Node) RecordedReason() string

RecordedReason returns the line that could have earned this node its place in the recorded-reason index.

It mirrors what that index is built from — @intent and @domainRule. Reading back only @intent would drop a node indexed on a domain rule alone, and that node did not fail to record a reason; it recorded a different kind of one. @intent still wins when both are present, because it says why the code exists and a domain rule says what it must hold to.

It lives beside Intent so the text a search *matches* and the text it *shows* are read by one function. Two copies is how they diverged: the matching side read Intent alone and dropped the domain-rule-only nodes the index had already admitted.

@requires the node's Annotation and its Tags are loaded; an unloaded association reads as absent. @ensures a node carrying both tags reads back its @intent. @intent read back the same tags the recorded-reason index was built from.

type NodeKind

type NodeKind string

NodeKind는 그래프 노드의 선언 분류를 나타낸다. @intent 파싱된 선언을 검색과 분석에 필요한 종류로 구분한다.

const (
	NodeKindFile     NodeKind = "file"
	NodeKindPackage  NodeKind = "package"
	NodeKindClass    NodeKind = "class"
	NodeKindFunction NodeKind = "function"
	NodeKindType     NodeKind = "type"
	NodeKindTest     NodeKind = "test"
)

type ParseCacheEntry added in v0.11.2

type ParseCacheEntry struct {
	ID            uint   `gorm:"primaryKey"`
	Namespace     string `gorm:"type:text;not null;default:'default';uniqueIndex:idx_parse_cache_ns_file"`
	FilePath      string `gorm:"type:text;not null;uniqueIndex:idx_parse_cache_ns_file"`
	SourceHash    string `gorm:"type:text;not null;index"`
	ParserVersion string `gorm:"type:text;not null"`
	ContextHash   string `gorm:"type:text;not null"`
	Payload       []byte `gorm:"not null"`
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

ParseCacheEntry stores the latest serialized parse result for one namespace/file path. @intent bound cache growth per active source path while validating the complete semantic cache identity.

type SchemaVersion

type SchemaVersion struct {
	Key       string `gorm:"primaryKey;type:text"`
	Version   int    `gorm:"not null"`
	UpdatedAt time.Time
}

SchemaVersion records the database schema level expected by the binary. @intent let runtime commands fail fast when explicit migrations were not run.

func (SchemaVersion) TableName

func (SchemaVersion) TableName() string

TableName pins SchemaVersion to the migration-managed schema version table. @intent keep runtime schema checks aligned with explicit migration bookkeeping.

type SearchDocument

type SearchDocument struct {
	ID        uint   `gorm:"primaryKey"`
	Namespace string `gorm:"type:text;not null;default:'default';index;uniqueIndex:idx_searchdoc_ns_node"`
	NodeID    uint   `gorm:"not null;uniqueIndex:idx_searchdoc_ns_node"`
	Content   string `gorm:"type:text;not null"`
	Language  string `gorm:"type:text;index"`
}

SearchDocument는 노드 검색용 색인 문서를 저장한다. @intent 전문 검색 백엔드가 사용할 노드별 검색 본문을 유지한다.

type SearchReason added in v0.13.1

type SearchReason struct {
	ID        uint   `gorm:"primaryKey"`
	Namespace string `gorm:"type:text;not null;default:'default';index:idx_searchreason_ns_node"`
	NodeID    uint   `gorm:"not null;index:idx_searchreason_ns_node"`
	Content   string `gorm:"type:text;not null"`
}

SearchReason holds one recorded reason a node exists: the text of a single @intent or @domainRule tag.

It is a row per reason, not a column on SearchDocument, because scoring reads each row as one document. A node that recorded three domain rules is three rows here, so a question matching its @intent is scored on that sentence's length and not on the length of three rules it never touched. It is also kept out of SearchDocument.Content, so a question about why the code exists is never scored against what the code happens to be called.

NodeID stays on every row, which is what lets a caller count declarations rather than reasons — annotation coverage is a fraction of declarations, and counting rows would report a heavily annotated node several times. @intent give every recorded reason its own scored document while keeping the declaration it belongs to countable. Rows are written in the order the author wrote the tags, so reading them back by id restores that order.

type TagKind

type TagKind string

TagKind는 DocTag의 종류를 나타낸다. @intent 구조화된 문서 태그의 의미 분류를 표준화한다.

const (
	TagParam      TagKind = "param"
	TagReturn     TagKind = "return"
	TagSee        TagKind = "see"
	TagIntent     TagKind = "intent"
	TagDomainRule TagKind = "domainRule"
	TagSideEffect TagKind = "sideEffect"
	TagMutates    TagKind = "mutates"
	TagRequires   TagKind = "requires"
	TagEnsures    TagKind = "ensures"
	TagIndex      TagKind = "index"
	TagThrows     TagKind = "throws"
	TagTypedef    TagKind = "typedef"
)

type UnresolvedEdgeCandidate added in v0.11.2

type UnresolvedEdgeCandidate struct {
	ID              uint     `gorm:"primaryKey"`
	Namespace       string   `gorm:"type:text;not null;default:'default';uniqueIndex:idx_unresolved_ns_fp_hash"`
	LookupKey       string   `gorm:"type:text;not null"`
	LookupKeyHash   string   `gorm:"type:text;not null;index:idx_unresolved_lookup_hash"`
	Fingerprint     string   `gorm:"type:text;not null"`
	FingerprintHash string   `gorm:"type:text;not null;uniqueIndex:idx_unresolved_ns_fp_hash"`
	FilePath        string   `gorm:"type:text;not null;index"`
	Kind            EdgeKind `gorm:"type:text;not null"`
	Line            int
	CreatedAt       time.Time
}

UnresolvedEdgeCandidate stores one lookup key for a syntax edge that lacks a graph endpoint. @intent let newly added symbols select affected unchanged callers without reparsing the whole graph.

func (UnresolvedEdgeCandidate) Edge added in v0.11.2

func (c UnresolvedEdgeCandidate) Edge() Edge

Edge converts the durable candidate back into resolver input. @intent keep unresolved storage separate from traversable graph edges while reusing the resolver contract.

type UnresolvedIndexState added in v0.11.2

type UnresolvedIndexState struct {
	Namespace string `gorm:"primaryKey;type:text"`
	Version   string `gorm:"type:text;not null;default:''"`
	UpdatedAt time.Time
}

UnresolvedIndexState marks a namespace whose last full build populated the unresolved reverse index. @intent prevent upgraded databases with an empty, uninitialized index from taking an unsafe incremental shortcut.

Jump to

Keyboard shortcuts

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