Querying the Ctx Skill Graph
Install the fast runtime graph (default path for almost everyone):
Bashctx-init --graph
Query it from Python:
Pythonimport json from pathlib import Path from networkx.readwrite import node_link_graph raw = json.loads( Path("~/.claude/skill-wiki/graphify-out/graph.json").expanduser().read_text() ) edges_key = "links" if "links" in raw else "edges" G = node_link_graph(raw, edges=edges_key) seed = "skill:fastapi-pro" neighbors = sorted( G.neighbors(seed), key=lambda n: G[seed][n]["weight"], reverse=True, )[:10]
Or browse it live: python -m ctx_monitor serve → http://127.0.0.1:8765/graph?slug=<slug>&type=<type>.
Use this decision tree — pick the smallest tool that answers the question.
Progress:
- Identify the need: install, query, explain, update, or compact
- Install:
ctx-init --graph(fast) or--graph-install-mode full(full wiki) - Query: dashboard route, Python
node_link_graph, or recommendation API - Explain: read edge metadata (
edge_reasons,score_components) before guessing why two nodes connect - Update one entity: queue worker + overlay pack, not a full rebuild
- Full rebuild: only for release artifact refresh, config change, or overlay compaction
1. Install
ctx-init --graphinstallsgraphify-out/*, the skill index, and harness pages only. Source checkouts prefer a verified local cache, else hydrate the manifest-declared release asset (graph/release-artifacts.json); pip installs fetch the matching GitHub release asset for the installed version.ctx-init --graph --graph-install-mode fullpulls the full wiki-pack (entity pages, concepts, converted micro-skills, harness pages, Obsidian vault).- Manual path:
python scripts/graph_release_manifest.py hydrate --manifest graph/release-artifacts.jsonthentar xzf graph/wiki-graph.tar.gz -C ~/.claude/skill-wiki/. The extracted tree is a valid Obsidian vault. - Installation is fail-closed on identity/overlay collisions, changed reserved bodies, symlinked ancestors, command args, or substituted executable paths. It never touches unrelated content; runtime-managed harness pages are refreshed in place.
2. Query
- Dashboard:
python -m ctx_monitor serve, then/graph?slug=<slug>&type=<type>(SVG neighborhood view) or/api/graph/<slug>.json?type=<type>&hops=1&limit=40(JSON). Passtypewhenever the slug is ambiguous (e.g.langgraph). - Python: load
graphify-out/graph.jsonwithnode_link_graph, auto-detecting theedges/linkskey (or just useresolve_graph.load_graph(), which handles this). - Recommendations: execution paths (
ctx.recommend_bundle,ctx.recommend_related, MCP tools, hook suggestions, repo-scan advisories) all funnel throughctx.core.resolve.recommendations.recommend_by_tags. Harness recommendations are a separate path (ctx-init --model-mode custom,harness_install, explicit adapter consent) — harnesses are never emitted from repo scans or Claude Code hook bundles by design. - If a graph is present but sparse/missing (old extracted wiki), the recommender falls back to the skill index JSON; if no graph at all, repo scans fall back to the legacy installed skill resolver.
3. Explain an edge or ranking
Read the edge's metadata before speculating:
semantic_sim,shared_tags,shared_tokens,shared_sources,direct_link— base signals, at least one required to create an edge.adamic_adar,type_affinity,usage_score,quality_score— boost-only signals; they re-rank existing edges but never create new ones.edge_reasons,score_components— human-readable breakdown of the blend.- Default floor is
graph.min_edge_weight = 0.03(calibrated as zero-edge-loss vs. the shipped graph; 0.05 would drop ~29.7% of edges).
4. Update one entity (normal path)
Bashpython -m ctx.core.wiki.wiki_queue_worker --wiki ~/.claude/skill-wiki --limit 1
This validates the queued page hash, updates the wiki index, best-effort ANN-attaches the entity into graphify-out/entity-overlays.jsonl if a vector index exists, mirrors into a wiki overlay pack (or tombstone for deletes), and queues a graph-store refresh. Do not run a full wiki_graphify rebuild just to add one skill.
Debug/manual attach:
Bashpython -m ctx.core.graph.incremental_attach calibrate --graph ~/.claude/skill-wiki/graphify-out/graph.json python -m ctx.core.graph.incremental_attach attach \ --index-dir ~/.claude/skill-wiki/.embedding-cache/graph/vector-index \ --overlay ~/.claude/skill-wiki/graphify-out/entity-overlays.jsonl \ --node-id skill:fastapi-review --type skill --label fastapi-review \ --text-file ~/.claude/skill-wiki/entities/skills/fastapi-review.md --dry-run
Shadow-gate before trusting a new ANN backend or threshold change:
Bashpython -m ctx.core.graph.incremental_shadow \ --index-dir ~/.claude/skill-wiki/.embedding-cache/graph/vector-index \ --graph ~/.claude/skill-wiki/graphify-out/graph.json \ --sample-size 100 --min-overlap 0.85
A failing gate means tune thresholds or fall back to a full rebuild — don't ship the new backend blind.
Missing vector index, no repack needed:
Bashpython -m ctx.core.wiki.wiki_graphify --wiki-dir ~/.claude/skill-wiki --incremental --graph-only --semantic-vector-index numpy-flat python -m ctx.core.wiki.wiki_queue_worker --wiki ~/.claude/skill-wiki
5. Full rebuild (only when necessary)
Trigger only for: release artifact refresh, global scoring config change, community recompute, or overlay compaction.
Bashpython -m ctx.core.wiki.wiki_graphify
The pre-commit hook deliberately does not rebuild/repack from ~/.claude/skill-wiki/ (may contain private entities) — it only refreshes README stats and warns on staged entity-source changes. Rebuild, validate, repack, and stage artifacts explicitly for releases.
6. Compaction (collapsing overlays into a new base)
Bashpython -m ctx.core.wiki.pack_compaction compact \ --wiki-path ~/.claude/skill-wiki --base-export-id <new-export-id> \ --staging-dir /tmp/ctx-pack-stage --json python -m ctx.core.wiki.pack_compaction validate \ --staged-graph-packs-dir /tmp/ctx-pack-stage/graph-packs \ --staged-wiki-packs-dir /tmp/ctx-pack-stage/wiki-packs \ --require-compaction-manifest --json python -m ctx.core.wiki.pack_compaction promote \ --wiki-path ~/.claude/skill-wiki \ --staged-graph-packs-dir /tmp/ctx-pack-stage/graph-packs \ --staged-wiki-packs-dir /tmp/ctx-pack-stage/wiki-packs --json
Promotion refreshes the SQLite dashboard/recommendation store by default (--graph-store-db <path> to target a non-default store, --no-graph-store-refresh to skip and rebuild separately via ctx.core.graph.graph_store build/validate). Never trust a pack whose manifest checksum isn't a lowercase 64-char SHA-256 hex digest.
Example 1 — "Why isn't my new skill showing up in recommendations?"
Input: Added entities/skills/fastapi-review.md, ran nothing else.
Output: Run python -m ctx.core.wiki.wiki_queue_worker --wiki ~/.claude/skill-wiki --limit 1 to hash-validate, index, and ANN-attach it. If no vector index exists yet, first rebuild one with wiki_graphify --incremental --graph-only --semantic-vector-index numpy-flat, then drain the queue.
Example 2 — "langgraph slug returns the wrong entity type in the dashboard"
Input: /graph?slug=langgraph
Output: Duplicate slug across types — pass type explicitly: /graph?slug=langgraph&type=agent (or skill/mcp).
Example 3 — "Two unrelated-looking skills are strongly linked"
Input: skill:fastapi-pro and skill:django-orm-patterns have high edge weight.
Output: Check edge metadata for shared_sources (same repo/homepage URL) or shared_tokens (e.g. both tokenize to patterns) rather than assuming semantic similarity is wrong.
Example 4 — "Need to add a custom local-model harness"
Input: Onboarding a new local model.
Output: Use ctx-init --model-mode custom ... or python -m harness_install, not the execution recommender — harness ranking uses a separate graph filter and higher match floor, and dashboard load/unload POSTs reject harnesses outright (they return the dry-run CLI command instead).
- Default to
ctx-init --graph, not--graph-install-mode full— most consumers only needgraphify-out/*and the skill index, not the entire wiki-pack. - Prefer the queue worker + overlay pack for single-entity changes; reserve full
wiki_graphifyrebuilds for release/config/community-level changes. - Always pass
typein dashboard/API calls when the slug could be ambiguous across skill/agent/MCP/harness. - When explaining "why does X relate to Y," cite the actual edge metadata fields, not intuition — boost-only signals (
adamic_adar,type_affinity,usage_score,quality_score) never create edges by themselves. - Treat harness flows as categorically separate from skill/agent/MCP execution recommendations — different graph filter, different match floor, different consent model.
- Verify pack manifest checksums are lowercase 64-char hex SHA-256 before trusting a pack.
- Use
incremental_shadowto gate any change to the ANN backend or similarity thresholds before it goes live.