open-standards/jouleclaw/jouleclaw-rs/crates/jouleclaw-codegraph/src
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 11f52e1d40 jouleclaw-codegraph: Graphify primitive ingest
Absorb the Graphify (safishamsi/graphify, 2026) pattern into
JouleClaw substrate. Graphify turns any folder of code, SQL, R,
shell, docs, papers into a queryable knowledge graph; the load-
bearing claim is "where does billing deduct credits?" returns
the right files in ~1.7k tokens instead of ~123k.

WHY THIS GAP IS REAL

jouleclaw-graph-rag already shipped Entity / Edge /
KnowledgeGraph / InMemoryKnowledgeGraph primitives. What was
missing for the Graphify pattern:

  1. corpus → typed graph
  2. community detection over the graph
  3. token-budgeted subgraph query

All three live in this crate as trait surfaces with deterministic
reference impls. Tree-sitter (real parsing) + Leiden (real
community detection) + LLM semantic labels stay as later
feature-gated extensions; v0 ships the doctrine-clean reference.

WHAT'S IN THE CRATE

GraphBuilder trait + LexicalCodeBuilder
  build(&[(PathBuf, String)]) -> (InMemoryKnowledgeGraph,
                                  CodeGraphReceipt)
  Lexical regex-shaped patterns for Rust / Python / JS-TS /
  Markdown / SQL / Shell / TOML. Each file becomes a `File`
  entity; each detected definition (Function / Struct / Class /
  Trait / Module / Table / Heading / Section) becomes a Symbol
  entity connected to its file via a `contains` edge.

CommunityDetector trait + ConnectedComponents
  detect(graph, ids, max_depth) -> CommunityMap
  Reference: undirected connected-components clustering.
  Deterministic — discovery order = input order. CommunityMap is
  BTreeMap<String, CommunityId> (keyed by EntityId.0 because
  EntityId doesn't impl Ord upstream).

BudgetedQuery trait + LexicalBudgetedQuery
  query(graph, &[Entity], terms, token_budget) -> Subgraph
  Lexical name + kind + description match → top entities, 1-hop
  neighbour expansion, deterministic greedy fill within budget.
  Takes &[Entity] rather than &[EntityId] because the upstream
  KnowledgeGraph trait resolves by display name only and our
  ids (`file:<path>`, `sym:<path>#<name>`) aren't names — the
  caller has the entities, hands them in directly.

CodeGraphReceipt {
  builder_id, corpus_hash, files, nodes, edges, skipped
}
  Auditable shape per build. corpus_hash via canonical JSON of
  sorted (path, content_hash) pairs — same corpus → byte-equal
  hash.

DOCTRINE

- Deterministic-first: lexical patterns + connected components +
  greedy budget fill. No inference in v0.
- No filesystem deps: builders accept &[(PathBuf, String)]; the
  caller chooses the walker (walkdir / ignore / mocked / in-
  memory).
- Reuses upstream Entity / Edge / KnowledgeGraph primitives so
  the L1.25 GraphRagTier can consume this crate's output without
  shim layers.

20 tests covering: corpus_hash stability + path-order
independence; empty-corpus error; builder id stability; receipt
counts + hash anchor; Rust function + struct extraction;
markdown heading extraction; SQL CREATE TABLE (uppercase)
extraction; contains-edge emission; unknown-extension skip
counting; language detection by extension; connected-components
group + singleton + id; budgeted-query top-match + truncation +
determinism; receipt + Subgraph + CommunityMap JSON round-trips.

cargo check --workspace --all-targets clean.

JouleClaw doctrine preserved: INGEST not COMPETE. The Graphify
pattern (codebase → typed graph → community-detected → budgeted
query) is now a typed primitive consumers can compose. Real
Tree-sitter + Leiden + LLM semantic labels remain natural
feature additions on top.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-06-06 16:27:01 -04:00
..
lib.rs jouleclaw-codegraph: Graphify primitive ingest 2026-06-06 16:27:01 -04:00