Skip to content

Fix/graph completeness and blast - #11

Merged
Naseem77 merged 14 commits into
mainfrom
fix/graph-completeness-and-blast
Oct 16, 2026
Merged

Naseem77 merged 14 commits into
mainfrom
fix/graph-completeness-and-blast

Conversation

@Naseem77

Copy link
Copy Markdown
Owner

No description provided.

Naseem77 and others added 14 commits October 17, 2026 01:22
… wiping the graph

'graphora index /typo --project X' collected no files, cleared X's graph,
and exited 0. index_repository now validates the root and that it holds
source files before opening or clearing the store, and the CLI reports
the error with exit code 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Missing diff files, bad git ranges, and an unreachable FalkorDB print
  'graphora: error: ...' and exit 1 instead of a traceback.
- Output piped into 'head' no longer raises BrokenPipeError.
- --depth must be at least 1.
- 'breaks'/'blast' exit 1 when no named symbol exists; a diff that
  touches no symbol says so instead of 'No definition found for nothing'.
- Read commands (stats, blast, breaks, review, benchmark) on an empty
  graph fail with exit 1, and check FalkorDB's graph list first: a
  query would create the graph, so 'stats --project typo' left an empty
  graph behind.
- install-skill refuses a --repo that does not exist instead of creating it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
'FalkorDB.select_graph' matched both the sync and async definitions and
the hint to 'pass a qualified name' could not separate them. breaks,
blast, and the MCP tools now accept 'path/to/file.py:Class.method' (any
path suffix works), plus 'ns::name' for C++/Rust-style names, and the
hint shows a ready-to-copy example.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 'from . import mod; mod.f()' (and 'from .. import mod') produced no
  edge: '.' joined with 'mod' became '..mod', one directory too high.
- 'import logging; logging.info()' linked to app/handlers/logging.py as
  certain. Absolute Python imports no longer match a file nested inside
  a package, and standard-library names only resolve at the repo root
  or src/.
- Go: go.mod is now read; only imports under its module path are local,
  so encoding/json and github.com/pkg/errors no longer link to
  internal/json or pkg/errors. Without go.mod, a single matching path
  segment is no longer enough.
- Imports carry their scope: a function-local import shadows a module
  one, and try/except fallbacks all count (reported as X or Y).
- An import from a repo module that does not define the name no longer
  falls back to an unrelated same-named function as INFERRED.
- 'from ....x' climbing above the repository resolves nowhere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Cargo.toml is read: 'use my_crate::Client' (and crate::/self::/super::)
  resolve inside the crate's src/, other crates (std, tokio) are
  external. On text-to-cypher, the four example callers of
  TextToCypherClient::new were missing; they are now certain edges.
- A CamelCase receiver that names no class in the repository is a
  library type: String::new(), Runtime::new(), Math.max(), Path.home(),
  Collections.sort() no longer fan out to every same-named repo method
  (text-to-cypher: 83 bogus 'might break' entries -> 0).
- Rust #[cfg(test)] modules and #[test] functions are test code, so they
  are listed under tests instead of 'will break'.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Option<T>, Result<T>, Future<T> are no longer read as T (their methods
  are their own); Promise<T>/Awaitable[T] are unwrapped only as return
  types, where the value is awaited; Optional[T] and Box/Rc/Arc still are.
- Untyped parameters, loop variables, and unknown assignments shadow an
  outer variable of the same name, so 'def run(x): x.go()' no longer
  inherits a module-level 'x = A()'.
- On an unknown receiver, methods of the language's own containers and
  strings (get, append, items, push, map, unwrap, ...) are not linked to
  same-named repo methods. Typed receivers still resolve.
- Classes record their typed fields (dataclass/class-body annotations,
  self.x = ..., TS/Java fields), and obj.field.method() / make().field
  .method() resolve through them.

GraphRAG-SDK, EvidenceLedger.get: 263 'might break' + 612 'tests' (dict
.get noise) -> 1 caller + the 2 tests that really call it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- JS/TS describe/it/test/beforeEach blocks become test symbols named
  after their label (describe_Graph.it_runs_a_query), so calls inside
  their callbacks are test callers; they were attributed to nothing
  (falkordb-ts Graph.query: 1 test found -> 77).
- e2e/ and cypress/ folders are test code, and the walk continues
  through test helpers (page objects, fixtures) so the specs behind
  them are listed (QueryWeaver: a Playwright helper reported 86
  'will break' callers and 0 tests -> 0 and 143).
- Production code never resolves into another file's test code unless
  it imports it, whatever rule found the candidate (namespace and
  return-type rules bypassed the old filter). Object literals in other
  JS/Python files are only matched when imported.
- Ruby paren-less calls ('helper', 'x = helper3') are recorded; method
  parameters and assigned locals are not mistaken for calls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- JS/TS: $-prefixed names ($http, $el) and #private methods; $foo()
  is no longer read as a call to foo. export default function/class,
  module.exports = function x(), exports.foo = function, and class
  expressions (const K = class {}) are definitions.
- Anonymous classes (JS class expressions, PHP new class {}) scope their
  methods instead of turning them into top-level functions.
- PHP $helper() calls a variable, not function helper.
- Identifiers in any script (Ñ, π, método).
- Rust impl blocks for references/generics (impl<'a> Tr for &'a Foo<T>).
- C functions returning function pointers; C++ operators (operator+,
  operator==) and template specialisations (template<> f<int>).
- Go generic composite literals (&S[int]{}) keep their type.
- Lone surrogates in a source string no longer raise UnicodeEncodeError.

Python coverage against ast stays 100% on all four Python repos.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- One unified-diff parser (parse_unified_diff) tracks hunk line counts,
  so a removed line starting with '--' is content, not a file header;
  GNU 'path<TAB>timestamp' headers and git's quoted paths work.
- A deletion is attributed to the line before it: deleting a function's
  last lines targets that function, not the next one. Blank-line
  removals target nothing, and deleting a method no longer flags its
  whole class.
- When the graph is built from the new code, a function the diff
  deletes is reported as 'Deleted: name' together with the call sites
  that still call it (certain for bare calls, uncertain when a
  same-named method survives elsewhere). falkordb-py: deleting
  Graph.drop_edge_vector_index now reports test_edge_index_drop and not
  the async test that still works.
- Re-export resolution is breadth-first with a visited set and a cache;
  30 modules star-importing each other no longer take 13 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…od borrowing

Classes record their base classes (Python Foo(Base), JS/TS/Java/PHP
extends, Ruby '< Base', C++ ': public Base'). A method not defined on a
class is looked up on its bases, resolved as written in the class's
file, so self.save() and f.save() reach Base.save as certain edges.

Methods are only taken from the class's own file (Go: same package;
Rust: any impl block in the crate), so 'class Foo' in another file no
longer lends its methods. blast labels its direct-only test count
'tests (direct)'.

Shiftory: certain call edges 97% -> 99%.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The library-type rule (a CamelCase receiver that names no class is
external) also dropped calls through repo type aliases such as
'GraphBackend = Union[GraphStore, EmbeddedGraphStore]', losing the
X-or-Y answer for every store call. Union aliases (Union[A, B], A | B,
TS 'type X = A | B') are now type symbols whose members are the union's
classes, and a receiver imported from a repo module is never treated
as a library type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Fix the README skill example (claude-code, not claude) and replace the
  abridged 'real output' with an exact capture.
- Benchmarks re-measured on each repo's committed code (git archive):
  adds QueryWeaver (Python+TS), falkordb-ts (TS), and text-to-cypher
  (Rust); speed re-measured 0.2.1 vs 0.3.0; new correctness checks from
  the end-to-end review.
- Use cases recaptured; the session-memory example now runs on the
  synthetic store from the test suite and shows the current output
  shape (per-source counts, agent column) instead of a personal path.
- Document path:name selectors, deleted functions, inheritance, test
  blocks, go.mod/Cargo.toml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bug-fix release for the issues found reviewing 0.3.0: index path
safety, CLI errors and exit codes, import/type/inheritance resolution,
Rust crates, test detection, missed definitions, diff parsing and
deleted-function callers, plus path:name selectors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…deletion parity

Twenty-one new tests: CommonJS require, TS path aliases, index files,
Rust use lists/aliases/wildcards/self/super and external crates, Java
static and wildcard imports, Ruby library requires, PHP PSR-4 paths, Go
module-root packages; the regex fallback parser in all languages; the
sessions and benchmark CLI commands; deleted-function callers on
FalkorDB vs embedded.

They found two bugs, fixed here:
- Rust 'use super::x' in a file module (circle.rs) pointed at the file
  itself instead of its parent module (shapes/mod.rs); self/super now
  follow Rust's module layout.
- Java 'import static a.b.Util.trim' never resolved: the imported name
  is a method of the class the import names.

Coverage 92% -> 95%; 272 tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Naseem77
Naseem77 merged commit 352527d into main Oct 16, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant