types

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: AGPL-3.0 Imports: 1 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Confidence

type Confidence string

Confidence labels (spec §4.8).

const (
	ConfExtracted Confidence = "EXTRACTED"
	ConfInferred  Confidence = "INFERRED"
	ConfAmbiguous Confidence = "AMBIGUOUS"
)

func (Confidence) Valid

func (c Confidence) Valid() bool

Valid reports whether c is one of the three known confidence labels.

type Edge

type Edge struct {
	ID           int64      `json:"id,omitempty"`
	Src          string     `json:"src"        validate:"required,len=16"`
	Dst          string     `json:"dst"        validate:"required,len=16"`
	Type         EdgeType   `json:"type"       validate:"required"`
	FilePath     string     `json:"file_path,omitempty"`
	Line         int        `json:"line,omitempty"`
	Count        int        `json:"count"      validate:"min=1"`
	Confidence   Confidence `json:"confidence" validate:"required"`
	DispatchKind string     `json:"dispatch_kind,omitempty"`
	// Order (W-C W7.3, 2026-05-18): source-order index for edges where
	// position is part of the relationship. Currently used by
	// EdgeHasModifier so multi-modifier functions preserve the
	// application sequence (Solidity applies modifiers outer-to-inner
	// in source order — `nonReentrant onlyOwner` wraps differently
	// from `onlyOwner nonReentrant`). Zero is omitted from JSON so
	// other edge types stay unaffected.
	Order int `json:"order,omitempty"`
}

Edge mirrors the SQLite edges row (spec §5.3).

DispatchKind (schema 1.7, Track C P1b): optional metadata column for the `invokes` edge type that disambiguates the dispatch mechanism. Valid values:

"interface_method" — callee is an interface method (virtual dispatch via
                     types.Selection on a *types.Interface receiver)
"func_value"       — callee is a function-typed variable / parameter
"method_value"     — callee is a struct field of function type
"closure"          — inline closure literal call: `func(){...}()`

Empty string for every non-`invokes` edge AND for `invokes` edges that resolve as static (which shouldn't happen by construction — invokes is reserved for non-static dispatch). Old readers (schema ≤1.6) ignore the column gracefully because the SQLite ALTER ADD COLUMN keeps it nullable and SELECT projections in those readers don't reference it.

type EdgeType

type EdgeType string

EdgeType enumerates the 41 edge kinds (spec §5.2; v0.2 schema 1.1 added 3 lock edges; schema 1.3 appended listens_on / handles_message / rpc_calls for CKS G5 Distributed; schema 1.4 appended changed_in / blame for CKS G6 Temporal — git history derived; schema 1.6 appended timeout_path / cancellation_path for CKS G3 dogfood P2 — Go context.With* propagation; schema 1.8 appended has_hunk / adjacent for the Hunk-graph H1 stage, then `modifies` for the H2 AST-overlap stage; schema 1.9 W2 appended `http_calls` — caller Function → Endpoint (HTTP client call sites); schema 1.9 W3b appended `grpc_listens_on` + `grpc_calls` — Go gRPC server/client detection; schema 1.10 appended `awaits` (W-B, TS async suspension flow) + `overrides` (W-C, Solidity virtual/override semantics) for within-language semantics Phase 4 — slots reserved 2026-05-11, detectors land in Phase 5).

const (
	EdgeContains      EdgeType = "contains"
	EdgeDefines       EdgeType = "defines"
	EdgeCalls         EdgeType = "calls"
	EdgeInvokes       EdgeType = "invokes"
	EdgeUsesType      EdgeType = "uses_type"
	EdgeInstantiates  EdgeType = "instantiates"
	EdgeReferences    EdgeType = "references"
	EdgeReadsField    EdgeType = "reads_field"
	EdgeWritesField   EdgeType = "writes_field"
	EdgeImports       EdgeType = "imports"
	EdgeExports       EdgeType = "exports"
	EdgeImplements    EdgeType = "implements"
	EdgeExtends       EdgeType = "extends"
	EdgeHasModifier   EdgeType = "has_modifier"
	EdgeEmitsEvent    EdgeType = "emits_event"
	EdgeReadsMapping  EdgeType = "reads_mapping"
	EdgeWritesMapping EdgeType = "writes_mapping"
	EdgeHasDecorator  EdgeType = "has_decorator"
	EdgeSpawns        EdgeType = "spawns"
	EdgeSendsTo       EdgeType = "sends_to"
	EdgeRecvsFrom     EdgeType = "recvs_from"
	EdgeBindsTo       EdgeType = "binds_to"
	// Schema 1.1 (concurrency lock semantics) — emitted by the Go
	// concurrency pass:
	//   acquires_lock / releases_lock: from
	//     internal/parse/golang/concurrency.go:maybeEmitLockEdge — matches
	//     sync.Mutex.Lock/Unlock/RLock/RUnlock by object-identity on the
	//     receiver (types.Info path, EXTRACTED) or by name match (AST-only,
	//     INFERRED). False-positive guarded against user-defined Lock() on
	//     non-mutex types (spec §2 R2.1).
	//   accessed_under_lock: from
	//     internal/parse/golang/concurrency_underlock.go — intra-function
	//     lexical heuristic (any field access in a body that holds any lock
	//     gets one edge per (field, mutex) pair). Cross-function chain
	//     propagation is deferred to D1 — see
	//     docs/design/go-cross-function-lock-propagation.md (decisions
	//     resolved 2026-05-11, --lock-propagation opt-in flag).
	// Appended (not interleaved) so existing edge-type hash positions /
	// test snapshots stay stable.
	EdgeAcquiresLock      EdgeType = "acquires_lock"
	EdgeReleasesLock      EdgeType = "releases_lock"
	EdgeAccessedUnderLock EdgeType = "accessed_under_lock"
	// Schema 1.3 (E3 — CKS G5 Distributed): handler/RPC topology edges.
	// listens_on:      handler function/method → endpoint route
	// handles_message: handler function/method → message type it dispatches on
	// rpc_calls:       caller function → server method (or message-type placeholder)
	// Appended (not interleaved) so existing edge-type hash positions / test
	// snapshots stay stable.
	EdgeListensOn      EdgeType = "listens_on"
	EdgeHandlesMessage EdgeType = "handles_message"
	EdgeRPCCalls       EdgeType = "rpc_calls"
	// Schema 1.4 (E4 — CKS G6 Temporal): git-history derived edges.
	// changed_in: any symbol whose file was touched by a commit → that
	//             commit. Heuristic — file-level (not line-level). Bounded
	//             by Options.TemporalDepth (default 10) most-recent commits
	//             per file. Line-level blame is deferred (G6 Phase 2).
	// blame:      File node → most-recent commit touching that file
	//             (V0 simplification of `file:line → commit`).
	// Appended (not interleaved) so existing edge-type hash positions /
	// test snapshots stay stable.
	EdgeChangedIn EdgeType = "changed_in"
	EdgeBlame     EdgeType = "blame"
	// Schema 1.6 (P2 — CKS G3 control-flow context propagation): Go
	// context.With* creation sites. Self-loop edges anchored on the
	// enclosing Function/Method:
	//   timeout_path:      context.WithTimeout / context.WithDeadline call
	//                      site. Deadline is treated as a timeout variant —
	//                      both express "this work is bounded by a wall-clock
	//                      budget" and consumers (graph queries / viewer)
	//                      benefit from collapsing them.
	//   cancellation_path: context.WithCancel / context.WithCancelCause call
	//                      site (Go 1.20+ for the latter). Distinct from
	//                      timeout_path because cancellation is event-driven,
	//                      not deadline-driven.
	// TODO: retry_path is intentionally NOT emitted in V0 — the heuristic
	// (loops around RPC calls? error-handling branches?) is too noisy to
	// ship without false-positive cleanup. Reserved for a follow-up once
	// we have a typed retry pattern (e.g. detecting backoff libraries
	// like cenkalti/backoff or built-in `for { ...err... }` loops with
	// rpc_calls inside).
	// Appended (not interleaved) so existing edge-type hash positions /
	// test snapshots stay stable.
	EdgeTimeoutPath      EdgeType = "timeout_path"
	EdgeCancellationPath EdgeType = "cancellation_path"
	// Schema 1.8 (Hunk-graph H1 — CKS G6 Temporal extension):
	//   has_hunk: Commit → Hunk. One per Hunk; "this commit produced this
	//             block of changed lines". Confidence mirrors the Hunk's
	//             own (EXTRACTED for HEAD-reachable, AMBIGUOUS for
	//             unreachable hunks added by a future reflog-collection PR).
	//   adjacent: Hunk → Hunk between same-commit, same-file hunks
	//             ordered by their @@ header start line. Provides a
	//             deterministic "next-in-this-file" traversal so the
	//             EvidencePack assembler can stitch a multi-hunk view
	//             of a commit's edits without a separate ORDER BY query.
	//             Emitted only between hunks within one (commit, file)
	//             pair — never across commits or files. Out-of-scope edges:
	//             modifies (Hunk → CodeNode interval overlap) lands in H2;
	//             same_logical_change clustering across commits is out of
	//             scope (see hunk-graph.md §11.5 decision).
	// Appended (not interleaved) so existing edge-type hash positions /
	// test snapshots stay stable.
	EdgeHasHunk  EdgeType = "has_hunk"
	EdgeAdjacent EdgeType = "adjacent"
	// Schema 1.8 (Hunk-graph H2 — CKS G6 Temporal extension):
	//   modifies: Hunk → CodeNode (Function/Method/Struct/Interface/Field
	//             /etc) when the hunk's [start_line, end_line] interval
	//             overlaps the CodeNode's interval inside the same file.
	//             Whitelisted to "FunctionLike + TypeLike + Field-ish" so
	//             noise-level statement nodes (CallSite / IfStmt / ...)
	//             don't blow up the edge count without retrieval signal.
	//             See docs/design/hunk-graph.md §4.
	// Appended at the end so existing hash positions stay stable.
	EdgeModifies EdgeType = "modifies"
	// Schema 1.9 W2 (CKS G5 Distributed cross-language interop expansion):
	//   http_calls: caller Function/Method → Endpoint when the function
	//               invokes an HTTP client (TS: fetch / axios / useSWR /
	//               useQuery; Go: http.Get / http.Post / http.NewRequest /
	//               (*http.Client).Get/Post/Do).
	//
	// Target resolution uses 2-stage cascade (schema-1.9-spec §6.9):
	//   1. Specific-verb lookup: `http:METHOD /path` exact match.
	//   2. Wildcard fallback: `http:* /path` exact match.
	// On miss the matcher synthesises an AMBIGUOUS placeholder Endpoint
	// (schema-1.9-spec §6.3 (B)) so the call site stays surfaceable for
	// monorepo external-API audits. Path matching is EXACT (schema-1.9-spec
	// §3.3 decision: V0 chooses exact-match over suffix-match because
	// false-positives across distinct services with overlapping path
	// suffixes are far worse than the false-negatives exact-match incurs
	// in well-curated monorepos).
	//
	// Appended at the end so existing edge-type hash positions / test
	// snapshots stay stable.
	EdgeHTTPCalls EdgeType = "http_calls"
	// Schema 1.9 W3b (CKS G5 Distributed cross-language interop expansion —
	// Go gRPC server/client detection):
	//   grpc_listens_on: server impl Method → Endpoint when the file calls
	//                    `pb.RegisterXXXServer(s, &impl{})`. Each method on
	//                    the impl receiver type whose name matches an rpc
	//                    method on the generated XServer interface emits
	//                    one edge to a `grpc:Service.Method` Endpoint
	//                    (language="go", sub_kind="grpc").
	//   grpc_calls:      caller Function/Method → Endpoint when the body
	//                    calls `<stub>.RpcMethod(ctx, req)` where `stub`
	//                    was assigned from `pb.NewXXXClient(conn)`. Like
	//                    http_calls, on miss the matcher synthesises an
	//                    AMBIGUOUS placeholder Endpoint (language="external")
	//                    so external-API call sites stay surfaceable.
	//
	// Confidence split (schema-1.9-spec §6.5 (C) Both with split confidence):
	//   - typesInfo available + method matches generated XServer interface
	//     → EXTRACTED.
	//   - AST-only (no typesInfo) suffix-matcher on RegisterXXXServer →
	//     INFERRED.
	//   - Miss / unresolved stub var type → AMBIGUOUS placeholder.
	//
	// Appended at the end so existing edge-type hash positions / test
	// snapshots stay stable.
	EdgeGRPCListensOn EdgeType = "grpc_listens_on"
	EdgeGRPCCalls     EdgeType = "grpc_calls"
	// Schema 1.10 (within-language semantics Phase 4 — slots reserved
	// 2026-05-11; detectors land in Phase 5):
	//   awaits   (W-B): Function/Method → AwaitPoint, and AwaitPoint →
	//                   AsyncCallSite. Marks async suspension flow in
	//                   TypeScript source so graph queries can answer
	//                   "where does control yield, and what call awaits
	//                   here?". See docs/design/ts-async-await-and-interface.md
	//                   §2.1 + §3.2.
	//   overrides (W-C): Method → Method between a child contract's method
	//                   that overrides a parent's `virtual` method in
	//                   Solidity. Direction = child → parent (Q4 decision
	//                   in solidity-inheritance spec §5.0). Distinct from
	//                   `implements` (interface satisfaction) because
	//                   `overrides` is concrete-to-concrete virtual
	//                   dispatch resolution. See
	//                   docs/design/solidity-inheritance-and-interface-dispatch.md
	//                   §2.1 + §3.3.
	//   using_for (W-C W6): Contract → Library binding emitted from
	//                   `using SafeMath for uint256` directives. First-class
	//                   so binding queries can run as a single edge-type
	//                   filter (matches the extends/implements/overrides/
	//                   has_modifier idiom — every other Sol-specific
	//                   semantic relation is already first-class). Q9-1 (b)
	//                   decision (2026-05-12). Direction = contract →
	//                   library; the call site of `balance.add(...)` still
	//                   produces a separate EdgeCalls into the library
	//                   function. See solidity-inheritance-and-interface-
	//                   dispatch.md §4.6.
	//
	// Appended at the end so existing edge-type hash positions / test
	// snapshots stay stable.
	EdgeAwaits    EdgeType = "awaits"
	EdgeOverrides EdgeType = "overrides"
	EdgeUsesFor   EdgeType = "using_for"
	// Schema 1.14 (P1 #4 — policy metadata): code symbol → Policy node.
	// Emitted from pkg/policy.Resolve when a YAML policy entry's
	// governs[].qname matches an existing Function/Method/Field/Struct/
	// Constant/Variable in the parsed graph. Direction = governed node
	// → policy that constrains it, matching the natural query "what
	// rules apply to this symbol?". Multiple policies can govern the
	// same symbol; the Policy node side fans in.
	EdgeGovernedBy EdgeType = "governed_by"
	// Schema 1.15 (P1 #5 — security pattern annotations): code symbol
	// → SecurityPattern node. Emitted from pkg/security.Resolve when
	// a YAML security pattern's matches[].qname hits an existing
	// Function/Method/Field/Struct/Modifier in the parsed graph.
	// Direction = at-risk code symbol → pattern label so an LLM
	// modifying X can read "what security patterns does X exhibit?"
	// as a single edge-type lookup on src.
	EdgeHasSecurityPattern EdgeType = "has_security_pattern"
)

func AllEdgeTypes

func AllEdgeTypes() []EdgeType

AllEdgeTypes returns all 43 edge types in stable order. Append-only: existing positions are load-bearing for hash-derived IDs. EdgeAwaits (W-B) + EdgeOverrides (W-C) are appended at indices 38-39 for schema 1.10 (slot-only; detectors land in Phase 5). EdgeUsesFor (W-C W6) is appended at index 40 (schema 1.10 W6 — using For library extension; first-class binding edge per Q9-1 (b) 2026-05-12). EdgeGovernedBy (P1 #4) is appended at index 41 (schema 1.14 — code symbol → external Policy node loaded from YAML; first-class so policy queries can run as a single edge-type filter). EdgeHasSecurityPattern (P1 #5) is appended at index 42 (schema 1.15 — code symbol → SecurityPattern node loaded from YAML).

type Node

type Node struct {
	ID            string   `json:"id"             validate:"required,len=16"`
	Type          NodeType `json:"type"           validate:"required"`
	Name          string   `json:"name"           validate:"required"`
	QualifiedName string   `json:"qualified_name" validate:"required"`
	// CanonicalID is the globally-unique, import-path-qualified identity of the
	// symbol (e.g. "github.com/ethereum/go-ethereum/core/vm.(*EVM).Call"),
	// receiver- and signature-aware, used for exact resolution. QualifiedName
	// stays the short, suffix-searchable display form. Empty when type info is
	// unavailable (AST-only mode) or for node kinds not yet wired. See
	// code-knowledge-system docs/symbol-identity-design.md.
	CanonicalID string     `json:"canonical_id,omitempty"`
	FilePath    string     `json:"file_path"      validate:"required"`
	StartLine   int        `json:"start_line"     validate:"min=1"`
	EndLine     int        `json:"end_line"       validate:"min=1"`
	StartByte   int        `json:"start_byte"     validate:"min=0"`
	EndByte     int        `json:"end_byte"       validate:"gtfield=StartByte"`
	Language    string     `json:"language"       validate:"required,oneof=go ts sol proto"`
	Visibility  string     `json:"visibility,omitempty"`
	Signature   string     `json:"signature,omitempty"`
	DocComment  string     `json:"doc_comment,omitempty"`
	Complexity  int        `json:"complexity,omitempty"`
	InDegree    int        `json:"in_degree"`
	OutDegree   int        `json:"out_degree"`
	PageRank    float64    `json:"pagerank"`
	UsageScore  float64    `json:"usage_score"`
	Confidence  Confidence `json:"confidence"     validate:"required"`
	SubKind     string     `json:"sub_kind,omitempty"`
	// SlotIndex (W-C W9 V0, 2026-05-18): EVM storage slot index for
	// Solidity state variables (NodeField). V0 is per-contract
	// declaration-order index (0, 1, 2, ...) — bit-packing and
	// inheritance offsets are deferred to V1+. Omitted from JSON for
	// non-state-var nodes and for NodeField rows where the value is
	// the zero default.
	SlotIndex int `json:"slot_index,omitempty"`
	// HasAssembly (W-C W10 V0, 2026-05-18): true when a Solidity
	// callable (function / modifier / constructor / fallback) contains
	// at least one `assembly { ... }` block in its body. Lets
	// downstream consumers run a basic "show me all functions with
	// inline assembly" query without re-parsing source. V0 detects
	// presence only; Yul-internal op detection (delegatecall, sstore,
	// selfdestruct, …) and receiver resolution are deferred to V1+.
	HasAssembly bool `json:"has_assembly,omitempty"`
	// HasLowLevelCall (W-C W8 V1, 2026-05-18): true when a Solidity
	// callable contains at least one `.call` / `.delegatecall` /
	// `.staticcall` invocation, regardless of whether the receiver
	// resolves to a concrete contract / interface. W7.1 V0 emits an
	// EdgeInvokes only when the receiver is a state-var / parameter
	// typed as Contract or Interface; this marker additionally surfaces
	// dynamic-address receivers (e.g. `address(target).call(...)`)
	// where no static target exists.
	HasLowLevelCall bool `json:"has_low_level_call,omitempty"`
	// HasValueTransfer (W-C W8 V1, 2026-05-18): true when a Solidity
	// callable contains at least one `.send` or `.transfer` value-
	// transfer. Distinct from low-level method calls — Sol semantics
	// for send/transfer are ETH transfer with limited gas, not method
	// dispatch. Security tooling commonly differentiates these.
	HasValueTransfer bool `json:"has_value_transfer,omitempty"`
	// YulBuiltins (W-C W10 V1.1, 2026-05-18): security-relevant EVM
	// opcodes that appear inside the callable's `assembly { ... }`
	// blocks. Sorted, deduped, lower-case identifiers — the slice is
	// the canonical set of Yul builtin names tree-sitter exposes
	// under `yul_evm_builtin` (e.g. "delegatecall", "sstore", "sload",
	// "selfdestruct", "call", "staticcall"). Empty for callables with
	// no assembly or only non-critical Yul ops.
	YulBuiltins []string `json:"yul_builtins,omitempty"`
	// IsFunctionTyped (W-C W8 V2, 2026-05-18): true when a NodeField
	// is a Solidity state variable declared with a function type
	// (e.g. `function(uint256) external returns (uint256) handler;`).
	// V0 marker only — call-site resolution `stored(args)` against
	// function-typed state vars is deferred. Empty for non-field
	// nodes and for fields whose type is anything but a function.
	IsFunctionTyped bool `json:"is_function_typed,omitempty"`
	// HasFunctionTypedVar (W-C W8 V3, 2026-05-19): true when a
	// Solidity callable (NodeFunction / NodeModifier) has at least
	// one parameter or local variable declared with a function type.
	// Indirect dispatch through function pointers is a control-flow
	// integrity signal — security tooling commonly flags callables
	// that load and invoke caller-supplied callbacks. The marker is
	// presence-only; the V0 dispatch path does not resolve the
	// concrete target since function-typed locals can be reassigned
	// across paths.
	HasFunctionTypedVar bool `json:"has_function_typed_var,omitempty"`
	// HasFunctionPointerCall (W-C W8 V4, 2026-05-19): true when a
	// callable invokes a function pointer — a call_expression whose
	// callee identifier resolves to a function-typed parameter or
	// local variable in the same callable. Complements
	// HasFunctionTypedVar: a function may declare a function-typed
	// var without invoking it, or invoke a function-typed pointer
	// passed from another scope. Together the two markers locate
	// every callable involved in indirect dispatch.
	HasFunctionPointerCall bool `json:"has_function_pointer_call,omitempty"`
	// HasExternalCall (W-C W10 V4, 2026-05-19): true when a callable
	// performs at least one low-level call (Sol .call /
	// .delegatecall / .staticcall or the Yul equivalents) whose
	// receiver resolves to an address-typed Sol scope variable
	// rather than a Contract / Interface. Distinguishes "arbitrary-
	// address dispatch" from the resolved-receiver shape that lands
	// as a concrete EdgeInvokes, which security tooling commonly
	// flags for re-entrancy / external-call risk analysis.
	HasExternalCall bool `json:"has_external_call,omitempty"`
	// HasInheritanceMROFallback (W-C W9 V8, 2026-05-19): true when
	// a NodeContract / NodeInterface declared an inheritance graph
	// that has no consistent C3 linearization. Sol's reference
	// compiler rejects such hierarchies; the parser falls back to a
	// deterministic depth-first walk so layout stays computable,
	// but downstream tooling should surface the diagnostic so the
	// developer notices the would-be-rejected hierarchy.
	HasInheritanceMROFallback bool `json:"has_inheritance_mro_fallback,omitempty"`
	// HasFunctionPointerPropagation (W-C W8 V8, 2026-05-19): true
	// when a callable propagates a function-typed value without
	// invoking it — assigning it to a state variable, passing it
	// as an argument to another call, or both. Distinct from
	// HasFunctionPointerCall (which marks invocation) and from
	// HasFunctionTypedVar (which marks declaration). Security
	// tooling tracking indirect-dispatch surfaces uses all three
	// together: declaration + propagation + invocation = the full
	// life-cycle of a function pointer through the contract.
	HasFunctionPointerPropagation bool `json:"has_function_pointer_propagation,omitempty"`
	// HasSelfReentrantCall (W-C W10 V8, 2026-05-19): true when a
	// callable performs a low-level call whose receiver is a self
	// cast — `payable(this).call(...)` or `address(this).call(...)`.
	// The receiver is the same contract, so this isn't arbitrary-
	// address dispatch (HasExternalCall would mislead); it IS a
	// reentrancy surface because the call re-enters the contract's
	// fallback() / receive() path. Security tooling that scans for
	// the two surfaces separately consumes both markers.
	HasSelfReentrantCall bool `json:"has_self_reentrant_call,omitempty"`
	// HasSelfDelegatecallDead (W-C W10 V9, 2026-05-19): true when a
	// callable performs `address(this).delegatecall(...)` or
	// `payable(this).delegatecall(...)`. Sol semantics make this
	// effectively dead — delegatecall executes the target's code
	// against the caller's storage, and the target IS the caller,
	// so the operation reduces to re-running the contract's own
	// dispatch with the same calldata. Almost always a bug or a
	// confused re-implementation of an internal call. The marker
	// rides alongside HasSelfReentrantCall (the cast still re-
	// enters fallback / receive on certain edge paths) so security
	// tooling can pick either signal.
	HasSelfDelegatecallDead bool `json:"has_self_delegatecall_dead,omitempty"`
	// HasHighLevelSelfCall (W-C W10 V19, 2026-05-21): true when a
	// callable performs a *typed* self-call — `this.foo()`,
	// `MyContract(address(this)).foo()`, or `IFoo(address(this)).bar()`
	// (and equivalents through cast chains). Unlike
	// HasSelfReentrantCall (which keys on low-level `.call /
	// .delegatecall / .transfer / .send` to a self-cast receiver),
	// this marker surfaces *high-level* dispatch self-calls: typed
	// invocations through the EVM message-call boundary that still
	// allow re-entrancy. The two markers are independent — a callable
	// can have either, both, or neither — and security tooling
	// consumes both to characterise the full re-entrancy surface.
	HasHighLevelSelfCall bool `json:"has_high_level_self_call,omitempty"`
	// RecentPRs (ckg-NEW-2, schema 1.12, 2026-05-26): build-time-
	// derived list of pull requests whose merge commit touched lines
	// overlapping this node's [StartLine, EndLine] range. Populated
	// on demand — the canonical fetch path is
	// store.Reader.GetNodePRs (ckg-NEW-4) with an explicit cutoff,
	// not eager joining on every nodes read. JSON omits the field
	// when nil so existing payloads (HTTP / MCP / chunked export)
	// stay byte-identical until a caller asks for breadcrumbs.
	RecentPRs []PRRef `json:"recent_prs,omitempty"`
}

Node mirrors the SQLite nodes row plus runtime fields (spec §5.3).

type NodeType

type NodeType string

NodeType enumerates the 35 node kinds (spec §5.1; v0.2 schema 1.1 added Mutex; schema 1.3 appended Endpoint + MessageType for CKS G5 Distributed; schema 1.4 appended Commit for CKS G6 Temporal — git history nodes; schema 1.8 appended Hunk for CKS G6 Temporal Hunk-graph — one block of changed lines per (commit, file); schema 1.10 appended AwaitPoint for within-language semantics Phase 4 — W-B TS async/await suspension points (slot reserved; detector lands in Phase 5)).

const (
	NodePackage       NodeType = "Package"
	NodeFile          NodeType = "File"
	NodeStruct        NodeType = "Struct"
	NodeInterface     NodeType = "Interface"
	NodeClass         NodeType = "Class"
	NodeTypeAlias     NodeType = "TypeAlias"
	NodeEnum          NodeType = "Enum"
	NodeContract      NodeType = "Contract"
	NodeMapping       NodeType = "Mapping"
	NodeEvent         NodeType = "Event"
	NodeFunction      NodeType = "Function"
	NodeMethod        NodeType = "Method"
	NodeModifier      NodeType = "Modifier"
	NodeConstructor   NodeType = "Constructor"
	NodeConstant      NodeType = "Constant"
	NodeVariable      NodeType = "Variable"
	NodeField         NodeType = "Field"
	NodeParameter     NodeType = "Parameter"
	NodeLocalVariable NodeType = "LocalVariable"
	NodeImport        NodeType = "Import"
	NodeExport        NodeType = "Export"
	NodeDecorator     NodeType = "Decorator"
	NodeGoroutine     NodeType = "Goroutine"
	NodeChannel       NodeType = "Channel"
	// NodeMutex: schema 1.1 slot — emitted by B1 Phase 1 of the Go
	// concurrency pass for sync.Mutex / sync.RWMutex fields, package-level
	// vars, and function-local vars. See
	// internal/parse/golang/concurrency.go:emitMutexNode. Cross-function
	// lock chain propagation (caller holds X, callee touches field) is
	// deferred to D1 — see
	// docs/design/go-cross-function-lock-propagation.md (decisions resolved
	// 2026-05-11). Kept adjacent to the other concurrency nodes
	// (Goroutine/Channel) for grouping.
	NodeMutex      NodeType = "Mutex"
	NodeIfStmt     NodeType = "IfStmt"
	NodeLoopStmt   NodeType = "LoopStmt"
	NodeCallSite   NodeType = "CallSite"
	NodeReturnStmt NodeType = "ReturnStmt"
	NodeSwitchStmt NodeType = "SwitchStmt"
	// Schema 1.3 (E3 — CKS G5 Distributed): handler/route topology entries.
	// NodeEndpoint  : an HTTP/RPC route literal. Qname follows protocol-
	//                  specific format (schema 1.9 §6.2):
	//                    - http  : `http:METHOD /route`   (METHOD=`*` for any)
	//                    - rpc   : `rpc:Service.Method`
	//                    - grpc  : `grpc:pkg.Service.Method`  (W3)
	//                    - ws    : `ws:/route[#msg]`          (later)
	// NodeMessageType: a request/response message type a handler dispatches on
	//                  (e.g. `pkg.MyRequest`). Appended at the end so existing
	//                  positional indices stay stable (see TestAllNodeTypes_Stable).
	NodeEndpoint    NodeType = "Endpoint"
	NodeMessageType NodeType = "MessageType"
	// Schema 1.4 (E4 — CKS G6 Temporal): a git commit that touched one or
	// more source files. Name = first 12 chars of SHA, QualifiedName =
	// `commit:<full-sha>`. SubKind = "git". StartLine/EndLine = 1 (commits
	// have no source range). Appended at the end so existing positional
	// indices stay stable (TestAllNodeTypes_Stable).
	NodeCommit NodeType = "Commit"
	// Schema 1.8 (Hunk-graph H1 — CKS G6 Temporal extension): one contiguous
	// block of changed lines in one file in one commit, as defined by
	// unified-diff `@@` headers. Name = "<sha12>:<file>:<idx>",
	// QualifiedName = `hunk:<full-sha>:<file>:<idx>` (idx = 0-based per-commit
	// hunk position so multiple hunks per commit get distinct IDs via MakeID).
	// SubKind = "git". StartLine/EndLine = the hunk's @@ header new-file
	// line range; StartByte = 0 / EndByte = 1 sentinels (the patch text
	// lives in blobs.source, gzip-compressed; see hunk-graph.md §2.2-2.3).
	// Confidence semantics (hunk-graph.md §11.3 — finalised 2026-05-09):
	//   - EXTRACTED: HEAD-reachable hunks (the only kind H1 collects).
	//   - AMBIGUOUS: reserved for unreachable hunks that a future PR will
	//                collect via reflog/fsck. The H3 EvidencePack assembler
	//                MUST filter to confidence='EXTRACTED' so the LLM never
	//                sees code paths that were rolled back by force-push.
	// Appended at the end so existing positional indices stay stable
	// (TestAllNodeTypes_Stable).
	NodeHunk NodeType = "Hunk"
	// Schema 1.10 (within-language semantics Phase 4 — W-B TS async/await):
	// statement-level node emitted at each `await` expression in TypeScript
	// source. Marks an async suspension point so graph queries can answer
	// "where does control yield, and to which AsyncCallSite?". Slot
	// reserved 2026-05-11; detector lands in Phase 5 (W-B W2). See
	// docs/design/ts-async-await-and-interface.md §2.1 + §3.2 and
	// docs/DISPATCH-WITHIN-LANG-SEMANTICS.md §2 Phase 4. Appended at the
	// end so existing positional indices stay stable
	// (TestAllNodeTypes_Stable).
	NodeAwaitPoint NodeType = "AwaitPoint"

	// NodePolicy (schema 1.14, P1 #4) — governance/protocol policy
	// metadata loaded from an external YAML rather than the parsed
	// source tree. Surfaces "why does this code exist?" — fork blocks,
	// gas schedules, consensus parameters, security policies — so an
	// LLM can answer policy-driven questions ("which fork activated
	// this?", "what gas schedule governs this?") without first
	// searching the code itself. See docs/PROJECT-BLUEPRINT-ALIGNMENT.md
	// §4.2 P1 #4 and pkg/policy for the YAML loader. FilePath /
	// StartLine cite the YAML entry's source location so citations
	// stay grounded.
	NodePolicy NodeType = "Policy"

	// NodeSecurityPattern (schema 1.15, P1 #5) — security risk
	// pattern annotations loaded from an external YAML. Captures
	// "this symbol is reachable in a reentrancy / access-control /
	// Byzantine / overflow scenario" so an LLM modifying the code
	// can see the risk surface at retrieval time instead of having
	// to run a separate static analyser. SubKind carries the
	// category (reentrancy / access-control / …), the attrs JSON
	// blob carries severity (info / low / medium / high / critical)
	// and an optional remediation hint. See pkg/security for the
	// YAML loader and PROJECT-BLUEPRINT-ALIGNMENT.md §4.2 P1 #5.
	NodeSecurityPattern NodeType = "SecurityPattern"
)

func AllNodeTypes

func AllNodeTypes() []NodeType

AllNodeTypes returns all 35 node types in a stable order. NOTE: identifier names are stable; positional indices are load-bearing only for tests that snapshot the full slice (TestAllNodeTypes_Stable). NodeMutex was inserted at index 24 to keep the concurrency family (Goroutine/Channel/Mutex) contiguous, which shifted the statement nodes (NodeIfStmt..NodeSwitchStmt) from indices 24-28 to 25-29 — no callers key on those indices, so the shift is safe; future additions should prefer append over insert when no grouping reason argues otherwise. NodeEndpoint + NodeMessageType (schema 1.3, E3) are appended (indices 30-31) — distributed topology is a distinct family from concurrency / statements, no grouping argument applied. NodeCommit (schema 1.4, E4) is appended at index 32 — temporal/git history is a distinct family from everything above. NodeHunk (schema 1.8, Hunk-graph H1) is appended at index 33 — same temporal family as NodeCommit but finer-grained (one block of changed lines, not a whole commit). NodeAwaitPoint (schema 1.10, W-B) is appended at index 34 — TS async suspension family, slot reserved before the Phase 5 detector lands. NodePolicy (schema 1.14, P1 #4) is appended at index 35 — domain governance/protocol policy metadata loaded from an external YAML. NodeSecurityPattern (schema 1.15, P1 #5) is appended at index 36 — security risk pattern annotations loaded from an external YAML.

func SymbolNodeTypes

func SymbolNodeTypes() []NodeType

SymbolNodeTypes returns the symbol-level subset of AllNodeTypes — the default whitelist for search_text when no explicit NodeKinds is supplied. Stable ordering tracks AllNodeTypes (callers must not key on positional indices; see TestAllNodeTypes_Stable for the invariant).

func (NodeType) IsSymbol

func (t NodeType) IsSymbol() bool

IsSymbol reports whether t is a "symbol-level" node — a code unit (function, type, field, package, file, endpoint, …) that a coding agent's keyword search would normally want to surface. Returns false for:

  • Statement nodes (IfStmt, LoopStmt, CallSite, ReturnStmt, SwitchStmt, AwaitPoint) — control-flow markers whose qname carries the enclosing function's prefix, which makes them false-positive FTS hits on a keyword that names the enclosing symbol.
  • Meta nodes (Commit, Hunk) — git-history rows surfaced via evidence_for_intent, not the symbol search path.
  • Path-only nodes (Import, Export) — their FTS columns carry module paths, so a query like "Vault" matches every import of contracts/Vault even when the consumer wanted the class itself.

search_text (pkg/mcphandlers + internal/persist.SearchFTS) uses IsSymbol as the default whitelist when SearchFTSOptions.NodeKinds is nil. Callers that want the full surface (statement nodes included) pass an explicit NodeKinds slice — typically types.AllNodeTypes().

type PRRef

type PRRef struct {
	Number      int       `json:"number"`
	Title       string    `json:"title,omitempty"`
	Summary     string    `json:"summary,omitempty"`
	BaseSHA     string    `json:"base_sha,omitempty"`
	HeadSHA     string    `json:"head_sha,omitempty"`
	MergedAtUTC time.Time `json:"merged_at"`
	Repo        string    `json:"repo,omitempty"`
}

PRRef is a build-time-derived reference from a graph node to a PR whose merge commit touched lines overlapping that node's source range. Surfaces "the recent changes around this symbol" — and, crucially, the *reason* for those changes — without dragging the agent through `git log` itself.

Built by internal/buildpipe.ScanPRHistory from `git log --merges` output: the merge commit's title is parsed for the canonical (#NNN) suffix; merge-commit timestamp + parent SHAs supply the remaining fields. PR title + the cleaned commit body (description with git trailers stripped) come from the commit message itself — no gh API call is required for the 80% case (squash-merge workflows). Future iterations may opt in to gh enrichment for fuller summaries.

Temporal slicing

MergedAtUTC drives the [store.Reader.GetNodePRs] cutoff filter (ckg-NEW-3). A cks scenario evaluating "what did the agent know at base_sha?" must not be allowed to see PRs merged after that timestamp, even though ckg's index aggregated every PR in history. The cutoff is applied at the SQL layer (`WHERE merged_at < ?`) so leakage is structurally impossible from the consumer's vantage point.

Field semantics

  • Number: PR number from the (#NNN) match. 0 when the parser couldn't extract one — emit the row anyway so consumers can still see the merge commit (Title + summary carry context).
  • Title: PR title — first non-empty line of the merge commit message after the conventional "Merge pull request #NNN from …" prefix is stripped, or the raw subject when the prefix isn't present.
  • Summary: cleaned commit body — the "왜 이렇게 짰지?" history that CKV's semantic search ingests (docs/PROJECT-BLUEPRINT- ALIGNMENT.md §4.2 P0). Git trailers (Signed-off-by:, Co-authored-by:, Generated with…) are stripped; the result is capped at 2 KB on a line boundary so a runaway PR template can't bloat node_prs rows. Empty when the merge commit has no body or the body was entirely trailers.
  • BaseSHA / HeadSHA: parents of the merge commit (BaseSHA is the first parent — the branch being merged into; HeadSHA is the second parent — the feature branch's tip). Both empty for non-merge fallbacks (rare; included for API completeness).
  • MergedAtUTC: committer time of the merge commit, UTC.
  • Repo: "owner/name" derived from the build root's git remote `origin` URL when available; empty otherwise.

Jump to

Keyboard shortcuts

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