@jasperan/ckg
v0.1.3
Published
Code Knowledge Graph (CKG) — structure-aware retrieval for coding agents. Parses codebases into typed graphs (imports/calls/co-edits), stores them in Oracle AI Database 26ai Free PGQ, and injects dependency-aware context into pi, Claude Code & Codex so ag
Maintainers
Readme
CKG is a transparent background plugin. It builds a typed dependency graph of your codebase — import edges, function calls, git co-edits — and injects a compact structure map into the agent's system prompt on every task. The agent sees the dependency cluster it needs to touch before it starts searching the filesystem. No prompt engineering, no user action.
📡 Live HUD Feedback (pi)
CKG doesn't just work silently — it tells you it's working. In the pi TUI, a footer status segment shows exactly what CKG is doing, live, on every task:
Base state — whether CKG is live at all:
| Status | Meaning |
|--------|---------|
| ● CKG on | Injection enabled and the Python CLI is installed |
| ○ CKG off | Injection disabled (CKG_INJECT=0, .ckg/pi.json, or global config) |
| ◐ CKG no CLI | Enabled but the Python CLI is missing (tools degrade) |
Activity — the segment updates in real time while CKG works:
| Moment | Footer shows |
|--------|--------------|
| Structure map being built for your prompt | CKG analyzing… |
| First task in a fresh project (no graph yet) | ⚙ CKG building graph… |
| Map injected into the current task | ✓ CKG map injected (2 anchors) |
| Background build finished | ✓ CKG graph ready |
| ckg_query / ckg_load / ckg_build running | CKG querying… → ✓ CKG query done |
Toasts — once per project per session, CKG confirms the important moments: "CKG injected structure map (2 anchors) into this task." · "CKG graph build finished — the next task gets the structure map." · a warning toast if a background build fails.
The HUD is purely cosmetic and fail-open: every update is try/catch-guarded and a no-op in
headless (pi -p) mode — it can never break or slow the agent loop.
🧠 The Thesis
Structure-aware retrieval helps coding agents find the right files faster.
A codebase is not a flat list of files. It's a graph: files import each other, functions call each other, and git history reveals which files change together. CKG surfaces these relationships so the agent navigates the structure, not the filesystem.
✅ Verified
CKG's hybrid retrieval has been empirically verified twice — once with Claude Code on httpie PRs, once with DeepSeek across 14 real repositories.
Claude Code — httpie PRs (original experiment)
Headless Claude Code, 5 runs per arm per PR, 7 real httpie PRs, via the graphify-verification experiment:
| Metric | Lexical Only (bare repo) | CKG Hybrid | Improvement | |--------|--------------------------|------------|:-----------:| | Gold file recall | 0.20 | 0.72 | +0.52 | | Tool calls to first correct edit | baseline | −36% | fewer | | Total tool calls | baseline | −22% | fewer | | Cost | baseline | −12% | cheaper |
DeepSeek — 14 repositories (replication)
Same protocol, reproduced with a different model at larger scale: 180 runs (90 control / 90
treatment) across httpie + 11 Django + 2 Flask repos. A full report lives in
reports/deepseek-graphify-verification-full.md.
| Metric | Control (90 runs) | CKG (90 runs) | Change | |--------|:-----------------:|:-------------:|:------:| | Time to first correct edit | 4.72 | 4.11 | −12.9% (p = 0.009, significant) | | Total tool calls | 54.1 | 53.3 | −1.4% | | Gold file recall | 0.656 | 0.666 | +1.5% | | Acceptance (tests pass) | 0.347 | 0.340 | −2.0% | | Precision | 0.577 | 0.517 | −10.4% | | Tokens per run | 3.27M | 3.48M | +6.2% | | Cost per run | $0.117 | $0.124 | +6% |
The gains concentrate where structure matters: admin_formset (−52% time-to-edit), the two Flask
tasks (−25% / −23%), httpie (−18%), and django_headersplit (+27% recall — matching the Claude
result). The counter-case: on django_quoting (a vocabulary-gap task with little structural signal),
recall dropped from 0.25 → 0.10 — structure maps help most when the code's shape carries meaning.
🏗 Architecture at a Glance
┌──────────────────────┐
│ Claude Code / Agent │
│ │
│ "implement feature" │
└──────────┬───────────┘
│
system prompt injection
│
┌──────────────────┴──────────────────┐
│ CKG Plugin │
│ │
│ ┌─────────┐ ┌──────────┐ ┌──────┐ │
│ │ Parser │ │ Retrieval│ │Inject│ │
│ │ (AST) │→ │ (Hybrid) │→ │(Map) │ │
│ └─────────┘ └──────────┘ └──────┘ │
│ │ │ │
└───────┼──────────────┼────────────────┘
│ │
┌───────┴──────┐ ┌───┴──────────────┐
│ Source Tree │ │ Oracle AI DB │
│ .py files │ │ PGQ Property │
│ │ │ Graph │
└──────────────┘ └──────────────────┘🛢 Why Oracle PGQ?
CKG uses Oracle's SQL Property Graph (PGQ) to store and query code graphs:
- In-DB traversal —
GRAPH_TABLE ... MATCHfinds dependency neighborhoods in the database, not in Python - Quantified paths —
MATCH (v)-[]->{1,3}(w)for multi-hop reach without recursive queries - Domain-scoped — Multiple projects share the same tables, isolated by
domainkey - ACID — No data loss on crash; idempotent MERGE for repeated builds
The split: Oracle PGQ finds the structural edges. Python's Personalized PageRank scores them.
⚡ Quick Start
One command, every agent: clones CKG, installs the Python CLI, and registers it with pi, Claude Code, and Codex automatically:
curl -fsSL https://raw.githubusercontent.com/jasperan/ckg/main/install.sh | bashOverride install location:
PROJECT_DIR=/opt/ckg curl -fsSL https://raw.githubusercontent.com/jasperan/ckg/main/install.sh | bashRegister with specific agents only (
pi,claude,codex):CKG_AGENTS=pi curl -fsSL https://raw.githubusercontent.com/jasperan/ckg/main/install.sh | bash
Prerequisites
- Python 3.12+ and uv (recommended) or pip
- Oracle AI Database 26ai Free (optional — enables in-DB PGQ retrieval)
Install for pi (recommended)
# One command — npm package (auto-installs the Python core):
pi install npm:@jasperan/ckg
# Or straight from GitHub (works right now, no npm needed):
pi install git:github.com/jasperan/ckg
# Or try it for one session without installing:
pi -e git:github.com/jasperan/ckgCKG is a pi package (pi.dev/packages catalog, pi-package keyword)
and works as a transparent plugin: on every coding prompt it builds (or loads) your codebase's
dependency graph and injects a compact structure map into the system prompt — no user action,
ever. It registers six tools (ckg_status, ckg_build, ckg_load, ckg_query, ckg_inject,
ckg_oracle_status), a /ckg command, and a live HUD status in the footer (see
Live HUD Feedback). pi install npm:@jasperan/ckg runs a postinstall that
sets up the Python CLI in a bundled venv, so there is nothing extra to configure.
Install for Claude Code
claude plugin marketplace add jasperan/ckg
claude plugin install ckgThis installs a marketplace plugin with a UserPromptSubmit hook that injects the structure map on
every prompt, plus six /ckg-* slash commands. (Or claude plugins install ~/ckg/skills/ckg for the
skill-only variant.)
Install for Codex / OpenCode
mkdir -p ~/.config/opencode/skills && cp -r skills/ckg ~/.config/opencode/skills/Install the CLI only
# From this repo:
git clone https://github.com/jasperan/ckg.git && cd ckg && uv sync
# Or straight from git, anywhere:
pip install git+https://github.com/jasperan/ckg.git1. Build a Graph
# From the root of any Python project:
ckg build . --pkg-root mypackage
# Output: .ckg/code_graph.json
# files: 208
# nodes: 1467
# edges: 52012. Query the Graph
ckg query "add JWT authentication middleware"
# Retrieval (memory):
# Anchors: auth.py, middleware.py, config.py
#
# 0.8521 auth.py
# 0.7234 middleware.py
# 0.6891 security.py
# 0.5432 config.py
# ...3. (Optional) Store in Oracle PGQ
# Start Oracle AI Database 26ai Free (one command):
docker run -d --name ckg-oracle -p 1521:1521 \
-e ORACLE_PWD=continual_learning \
container-registry.oracle.com/database/free:latest
export CKG_ORACLE_DSN=localhost:1521/FREEPDB1 \
CKG_ORACLE_USER=dmuser \
CKG_ORACLE_PASSWORD=continual_learning
# Parse + store the graph into PGQ:
ckg load . --pkg-root mypackage --domain myapp
ckg oracle-status # verify connectivity + stored graphWith CKG_ORACLE_DSN set, every ckg query / ckg inject (and the pi plugin's transparent
injection) runs the neighborhood match via GRAPH_TABLE ... MATCH inside Oracle and only
Personalized PageRank in Python. ckg oracle-status shows the retrieval mode at a glance.
4. Inject into an agent
ckg inject "fix the rate limiter bug"
# ---
# ## CKG Structure Map for `myapp`
#
# ### Anchor Files (lexical match)
# - `core/rate_limiter.py` — Module ...
#
# ### Dependency Reach (2-hop imports, calls, co-edits)
# - `core/throttle.py` — ...
# *(via rate_limiter.py, imports)*
# - `config/settings.py` — ...
# *(via rate_limiter.py, imports)*
# ...The output is a markdown blob ready to append to your agent's system prompt.
🔌 pi Plugin (detailed)
CKG for pi is a transparent background extension: you install it once and never think about it again.
What it does on every coding prompt:
- Detects the project root (
.git/pyproject.toml/package.json). - Loads the cached code graph (
.ckg/code_graph.json), building it once in the background if missing — the footer shows⚙ CKG building graph…while it runs. - Runs hybrid retrieval against your prompt — via Oracle PGQ when
CKG_ORACLE_DSNis set, in-memory otherwise. - Appends a compact structure map (anchor files + dependency reach) to the system prompt, behind
the
before_agent_startevent — footer shows✓ CKG map injected (n anchors).
Keyword-gated (only coding prompts), time-boxed (never blocks the loop), and cached per session — the agent sees the map, the user sees the HUD.
CLI discovery (in order): CKG_CLI env override → the npm package's bundled venv
(<pkg>/.venv/bin/ckg) → anything on PATH that answers ckg --help.
Tools the agent can call:
| Tool | Purpose |
|------|---------|
| ckg_status | CLI / project / cache / Oracle state |
| ckg_build | Parse the tree once (.ckg/code_graph.json) |
| ckg_load | Store the graph into Oracle PGQ |
| ckg_query | Ranked hybrid retrieval for a task |
| ckg_inject | Explicit structure map for a query |
| ckg_oracle_status | Oracle connectivity + stored graph stats |
/ckg shows the full status in the TUI. Disable transparent injection with CKG_INJECT=0 or
.ckg/pi.json ({"inject": false}) — the footer flips to ○ CKG off to confirm.
🟣 Claude Code Plugin (detailed)
CKG works as a transparent Claude Code plugin. Install the marketplace and Claude Code automatically injects structure maps on every prompt — no user action needed.
- Hook:
UserPromptSubmitrunshooks/before_prompt.py(8s timeout, best-effort) which appends the structure map viahookSpecificOutput.additionalContext. - Commands:
/ckg-status,/ckg-build,/ckg-load,/ckg-query,/ckg-inject,/ckg-oracle-status. - Skill:
skills/ckg/activates on coding keywords and instructs the agent to runckg build/injectsilently.
The user never sees CKG — they just make fewer tool calls.
🔍 Retrieval Algorithm
The hybrid retrieval pipeline runs in three steps:
Lexical anchors — Token overlap between the query and enriched node labels (docstrings, signatures, string literals). These are the entry points an agent would find anyway.
Graph reach — 2-hop neighborhood from each anchor via Oracle PGQ
MATCH(or in-memory BFS). These are the files a keyword search misses — the imports, callers, and co-edited siblings.Personalized PageRank — Structural ranking over the matched subgraph. Seeds at the lexical anchors, teleports to the graph neighborhood, surfaces the most structurally central files.
from ckg.retrieval import hybrid_retrieve
results = hybrid_retrieve(
"add rate limiting to the API gateway",
graph,
k_anchor=5, # max lexical seeds
hops=2, # graph reach depth
top_k=10, # results to return
)
# results["results"] → [{node_id, score, text}, ...]
# results["anchors"] → ["file:api/gateway.py", ...]
# results["method"] → "memory" or "pgq"⚙️ Configuration
# .ckg/config.yaml or configs/default.yaml
# Top-level package name
pkg_root: "myapp"
# Retrieval tuning
k_anchor: 5 # Max lexical seeds
hops: 2 # Graph reach depth
top_k: 10 # Results to return
# Oracle PGQ (optional)
domain: "default"
graph_name: "ckg_code_graph"
table_prefix: "MEMORY_GRAPH"Environment variables
| Variable | Default | Purpose |
|----------|---------|---------|
| CKG_ORACLE_DSN | — | Oracle DSN (host:port/service); unset → in-memory retrieval |
| CKG_ORACLE_USER / CKG_ORACLE_PASSWORD | — | Oracle credentials |
| CKG_ORACLE_DOMAIN | default | PGQ domain scope |
| CKG_ORACLE_GRAPH / CKG_ORACLE_TABLE_PREFIX | ckg_code_graph / MEMORY_GRAPH | PGQ object names |
| CKG_ORACLE_POOL_MIN / CKG_ORACLE_POOL_MAX | — | Connection pool sizing |
| CKG_CLI | — | Explicit path to the ckg CLI (bypasses discovery) |
| CKG_INJECT | 1 | 0 disables transparent injection (footer shows ○ CKG off) |
| CKG_AUTOBUILD | 1 | 0 disables background graph building |
| CKG_NONINTERACTIVE | — | Suppress prompts (CI/headless) |
🧩 Edge Types
CKG parses four edge types from your source tree and git history:
| Edge | Direction | Source | Meaning |
|------|:---------:|--------|---------|
| import | directed | AST import / from X import | File A depends on file B |
| call | directed | AST Call nodes | Function A calls function B |
| co_edit | undirected | git log --name-only | Files A and B changed together |
| contains | directed | AST top-level symbols | File contains a function/class |
🗄 Schema (Oracle PGQ)
When using Oracle PGQ as the graph backend, CKG creates these tables:
| Table | Purpose | Key Feature |
|--------|---------|-------------|
| MEMORY_GRAPH_NODES | Code graph vertices | Composite key: (id, domain) |
| MEMORY_GRAPH_EDGES | Typed dependency edges | Composite key: (src, dst, kind, domain) |
The property graph (ckg_code_graph) layers SQL/PGQ over both tables so
GRAPH_TABLE ... MATCH queries traverse dependencies entirely in the database.
📁 Layout
ckg/
src/ckg/
graph/
parser.py # AST-based import/call/co_edit parsing
builder.py # Enrichment, CodeGraph dataclass, structure map rendering
storage/
oracle_pgq.py # Oracle PGQ: CREATE PROPERTY GRAPH, MATCH, upsert
connection.py # CKG_ORACLE_* env config, pool, oracle-summary
retrieval/
hybrid.py # Lexical anchor → graph reach → PPR pipeline
pagerank.py # Personalized PageRank (pure NumPy)
claude/
plugin.py # Agent integration: detect, build, inject
prompts.py # System prompt templates
cli/
main.py # CLI: build, load, query, inject, oracle-status
pi/
extensions/ckg/ # pi plugin: injection, ckg_* tools, /ckg, HUD (hud.ts)
skills/
ckg/ # Claude Code / Codex skill definition
ckg-pi/ # pi-native skill (uses the ckg_* tools)
.claude-plugin/
plugin.json # Claude Code plugin manifest (UserPromptSubmit hook)
marketplace.json # Claude Code marketplace
hooks/
before_prompt.py # Claude Code UserPromptSubmit hook
commands/ # Claude Code /ckg-* slash commands
scripts/
postinstall.js # npm postinstall: bundles the Python venv
configs/
default.yaml # Default configuration
docs/ # Banner + HUD artwork
tests/ # Test suite (incl. live Oracle tests, CKG_ORACLE_LIVE=1)
package.json # npm / pi-package manifest
pyproject.toml
install.sh # One-command installer (pi + Claude Code + Codex)🧭 Sister Projects
- dl-ai-continual-learning — the 4-module course where CKG was developed and empirically verified. Module 3 teaches structure-aware retrieval from first principles.
- ironoraclaw — Oracle AI Database-powered Rust agent using the same PGQ graph patterns for memory persistence.
- picooraclaw — Go-based agent, same Oracle PGQ pattern.
- oraclaw — TypeScript + Python sidecar agent with Oracle memory.
🙏 Credits
- Oracle AI Database — the PGQ property graph engine that makes in-DB graph traversal possible
- Claude Code — the coding agent CKG integrates with transparently
- The graphify-verification experiment — 14 repos, 250+ headless agent runs, 1 thesis proven
License
MIT
