ingest: derive code kinds and class-qualified names from graph structure (#17, step 1) - #88
Merged
Merged
Conversation
…structure (#17) graphify has no class/method kinds, and tpk mapped every non-callable code node to kind=file. On proton-enterprise that is 102k 'file' nodes of which 13k are files: an out-of-class C++ definition (BlockIO Foo::execute() {...}, the dominant form) comes out of graphify non-callable with a bare label, merged into its header declaration -- so InterpreterInsertQuery::execute was stored as ('execute', kind=file), with 73 other 'execute's. Its calls edges were intact. parse_graph_json now reads the edges first and classifies code nodes as function / class / member / file / symbol: _callable_class -> class; a node a class 'defines' with a body in the graph (a file 'contains' it, or it calls) -> function; defined without a body -> member; label == file basename -> file; either end of 'inherits' -> class; otherwise symbol (String, ContextPtr, ...). Methods and members are named Class::name from the owning class. Two functions sharing file::name (overloads) no longer collide on one id. On src/Interpreters (14,202 nodes): function 4523 / symbol 4517 / member 2911 / class 1517 / file 734; every node that makes a call is now a function; 0 id collisions. Agent prompt, Explorer kind filter and docs list the new vocabulary. Takes effect on re-ingest (stale rows are deleted per entry). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This was referenced Sep 21, 2026
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.
Step 1 of the plan in #17. Does not close #17.
Problem (measured on
proton-enterprise@v3.3.1)graphify has no class/method kinds; tpk mapped every non-callable
codenode tokind="file": 102,094 "file" nodes, 13,221 real files. An out-of-class C++ definition —BlockIO InterpreterInsertQuery::execute() {…}, the dominant form — comes out of graphify non-callable, with a bare label, merged into its header declaration. So it was stored as("execute", kind=file)next to 73 otherexecutes; 7,393 such nodes make calls (theircallsedges were always intact).search_entities(kinds=["function"])missed them,kinds=["class"]matched nothing, and classes / type aliases were stored asfunction.Change
parse_graph_jsonreads the edges first (_Structure) and classifies code nodes from flags and structure:class_callable_class; or known only as one end of aninheritsedgefunction_callable; or a node a classdefineswhose body is in the graph (a filecontainsit, or it makes calls)memberdefinesit, no body known — a field, or a declared-only / pure-virtual methodfilesymbolString,ContextPtr, …; the graph's biggest hubs)Methods and members are named
Class::namefrom the owning class (.supportsTransactions()→InterpreterInsertQuery::supportsTransactions). Bonus: two functions sharingfile::name(overloads, ~3% on proton) no longer collapse onto one id — the second falls back to…#<graphify id>.The rules were designed against real raw output (graphify on
src/Interpreters, 763 files): only classes emitdefines(4,690/4,690), and every out-of-class method is "defined by a class + contained by its .cpp".Result on
src/Interpreters(14,202 nodes, 27,506 edges)function(1,877; previously a third werefile).InterpreterInsertQuery.*: all 11 methods areInterpreterInsertQuery::…functions, 5 fields are members, 4 classes, 2 files..; most common bare names are nowTEST/main, notexecute×74.Also updated: agent prompt
kindslist, Explorer kind filter, the parser's documented vocabulary,docs/FEATURES.md.Rollout
Takes effect only on re-ingest of each corpus entry (node ids change with the kind;
ingest_repoalready deletes an entry's stale rows). proton repos need the app at ≥ 8 Gi for ingest. Until then old and new entries just coexist with the old vocabulary.Testing
symbol, not afile).pytest: 318 passed, 10 skipped, 1 failed —tests/test_ingest.py::test_ingest_repo_passes_extraction_and_backend, environment-dependent, failing onmaintoo. Web build clean.src/Interpretersextraction instead). Known limit: a declared-only method and a field are bothmember— graphify gives no signal to tell them apart.Next: step 2 — make
path_betweena directed, call-like, hub-skipping traversal (the newsymbolkind makes the hub filter trivial).🤖 Generated with Claude Code