feat(kg): memory↔code join surface — recall code-context (#206)#208
Merged
Conversation
Implements design §5: fuse the native code KG (code_files/code_nodes)
with the memory FTS tables (decisions_fts/learnings_fts) in the one
recall.db — a join no external code-intelligence tool can run.
- src/lib/code-context.ts: codeContextForFile (file → decisions/learnings
that mention its symbols) + symbolSearchWithDiscussion (symbol search
fused with where each symbol was discussed). Join key is `project`;
no hard FK (deferred, §5/Q3).
- §9-C5 injection guard: the symbol name is fed to MATCH as a quoted
phrase ('"' || name || '"'), so a symbol named OR/NEAR/AND parses as a
literal phrase, never FTS5 syntax.
- recall code-context <relpath>: project-scoped, token-cheap output.
- tests seed BOTH indexed code AND decisions/learnings and assert the
join, project scoping, an adversarial `OR` symbol (proving the raw
unquoted MATCH throws while the quoted impl does not), and the fused
symbol-search path.
Closes #206
…-context * origin/main: feat(kg): add code graph query verbs (#209) # Conflicts: # src/index.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Phase 2b of the native code-KG epic (#196). Phase 1 merged the code KG itself (
code_files/code_nodes/code_edges+ the tree-sitter indexer +recall index). This PR adds the surface that makes building it native worth it: the join between code structure and memory that lives in the samerecall.db, so no external code-intelligence tool can run it.For a source file, it answers: "which decisions and learnings were made about the symbols defined here?" — by correlating
code_nodeswithdecisions_fts/learnings_ftson the symbol name, scoped byproject(design §5).Changes
src/lib/code-context.tscodeContextForFile(db, {project, path})— design §5 query 1: the decisions/learnings whose text mentions a symbol defined in the file, with the matched symbol names reported so the caller sees why each record surfaced. The syntheticmodulenode is excluded so we match real symbols, not the filename.symbolSearchWithDiscussion(db, {project, query})— design §5 query 2: symbol search fused with where each found symbol was discussed.src/commands/code-context.ts+ wired intosrc/index.ts** —recall code-context: project-scoped (auto-detected or--project`), repo-relative-path normalization, token-cheap grouped output.Security — FTS5 injection guard (design §9-C5)
The symbol name is fed to
MATCHas a quoted phrase ('"' || name || '"'), never raw. A symbol legitimately namedOR,NEAR, orANDwould otherwise be parsed as FTS5 query syntax. Binding alone is not sufficient — FTS5 parses a bound string as a query — so the quoting is the actual guard. A test proves it: the same join with the name fed raw toMATCHthrows on a symbol namedOR, while the quoted implementation does not and returns the right record.Project scoping
Join key is
project(the column every memory table andcode_files/code_nodescarry). Edges inherit scope viasrc_id(§9-C2). No hard FK between code and memory — deferred per §5/Q3.Validation
bun run build✅ ·bun run lint(tsc) ✅ ·bun test✅ 1207 pass / 0 fail (5 new tests intests/lib/code-context.test.ts).indexCode) and real decisions/learnings against the production schema (CREATE_TABLES+CREATE_FTS+ triggers — zero drift), then assert:ORsymbol is injection-safe (rawMATCHthrows, quoted does not);ORsymbol.RECALL_DB_PATH(recall init→index src→add decision→code-context):Closes #206