graph
This Claude Code skill provides interactive analysis of knowledge graph structure by routing natural language questions to specialized graph operations and interpreting results using domain-specific vocabulary. Users trigger it with commands like "/graph health" or "/graph triangles" to receive findings about network density, orphaned notes, synthesis opportunities, and actionable next steps based on configured thresholds and note descriptions.
git clone --depth 1 https://github.com/agenticnotetaking/arscontexta /tmp/graph && cp -r /tmp/graph/skill-sources/graph ~/.claude/skills/graphSKILL.md
## Runtime Configuration (Step 0 — before any processing)
Read these files to configure domain-specific behavior:
1. **`ops/derivation-manifest.md`** — vocabulary mapping, platform hints
- Use `vocabulary.notes` for the notes folder name
- Use `vocabulary.note` / `vocabulary.note_plural` for note type references
- Use `vocabulary.topic_map` / `vocabulary.topic_map_plural` for MOC references
- Use `vocabulary.cmd_reflect` for connection-finding command name
- Use `vocabulary.cmd_reweave` for backward-pass command name
2. **`ops/config.yaml`** — for graph thresholds (MOC size limits, orphan thresholds)
If no derivation file exists, use universal terms (notes, MOCs, etc.).
---
## EXECUTE NOW
**Target: $ARGUMENTS**
Parse the operation from arguments:
- If arguments match a known operation: route to that operation
- If arguments are a natural language question: map to the closest operation (see Interactive Mode)
- If no arguments: enter interactive mode
**START NOW.** Route to the appropriate operation.
---
## Philosophy
**The graph IS the knowledge. This skill makes it visible.**
Individual {vocabulary.note_plural} are valuable, but their connections create compound value. /graph reveals the structural properties of those connections — where the graph is dense, where it is sparse, where it is fragile, and where synthesis opportunities hide.
Every operation produces two things: **findings** (what the analysis reveals) and **actions** (what to do about it). Never dump raw data. Always interpret results with {vocabulary.note} descriptions and domain context. Always suggest specific next steps.
---
## Operations
### /graph health
Full graph health report: density, orphans, dangling links, coverage.
**Step 1: Collect raw metrics**
```bash
# Count total notes (excluding MOCs)
NOTES_DIR="{vocabulary.notes}"
TOTAL=$(ls -1 "$NOTES_DIR"/*.md 2>/dev/null | wc -l | tr -d ' ')
MOC_COUNT=$(grep -rl '^type: moc' "$NOTES_DIR"/*.md 2>/dev/null | wc -l | tr -d ' ')
NOTE_COUNT=$((TOTAL - MOC_COUNT))
# Count all wiki links
LINK_COUNT=$(grep -ohP '\[\[[^\]]+\]\]' "$NOTES_DIR"/*.md 2>/dev/null | wc -l | tr -d ' ')
# Calculate link density
# Density = actual_links / possible_links
# possible_links = N * (N - 1) for directed graph
echo "Density: $LINK_COUNT / ($NOTE_COUNT * ($NOTE_COUNT - 1))"
# Find orphan notes (zero incoming links)
for f in "$NOTES_DIR"/*.md; do
NAME=$(basename "$f" .md)
INCOMING=$(grep -rl "\[\[$NAME\]\]" "$NOTES_DIR"/ 2>/dev/null | grep -v "$f" | wc -l | tr -d ' ')
[[ "$INCOMING" -eq 0 ]] && echo "ORPHAN: $NAME"
done
# Find dangling links (links to non-existent files)
grep -ohP '\[\[([^\]]+)\]\]' "$NOTES_DIR"/*.md 2>/dev/null | sort -u | while read -r link; do
NAME=$(echo "$link" | sed 's/\[\[//;s/\]\]//')
[[ ! -f "$NOTES_DIR/$NAME.md" ]] && echo "DANGLING: $NAME"
done
# MOC coverage: % of notes appearing in at least one MOC's Core Ideas
COVERED=0
for f in "$NOTES_DIR"/*.md; do
NAME=$(basename "$f" .md)
# Skip MOCs themselves
grep -q '^type: moc' "$f" 2>/dev/null && continue
# Check if any MOC links to this note
if grep -rl '^type: moc' "$NOTES_DIR"/*.md 2>/dev/null | xargs grep -l "\[\[$NAME\]\]" >/dev/null 2>&1; then
COVERED=$((COVERED + 1))
fi
done
echo "Coverage: $COVERED / $NOTE_COUNT"
```
If graph helper scripts exist in `ops/scripts/graph/`, use them instead of inline analysis:
- `ops/scripts/graph/link-density.sh` for density metrics
- `ops/scripts/graph/orphan-notes.sh` for orphan detection
- `ops/scripts/graph/dangling-links.sh` for dangling link detection
**Step 2: Interpret and present**
```
--=={ graph health }==--
{vocabulary.note_plural}: [N] (plus [M] {vocabulary.topic_map_plural})
Connections: [N] (avg [X] per {vocabulary.note})
Graph density: [0.XX]
{vocabulary.topic_map} coverage: [N]% of {vocabulary.note_plural} appear in at least one {vocabulary.topic_map}
Orphans ([N]):
- [[orphan name]] — [description from YAML]
→ Suggestion: Run /{vocabulary.cmd_reflect} to find connections
Dangling Links ([N]):
- [[missing name]] — referenced from [[source note]]
→ Suggestion: Create the {vocabulary.note} or remove the link
{vocabulary.topic_map} Sizes:
- [[moc name]]: [N] {vocabulary.note_plural} [OK | WARN: approaching split threshold | WARN: consider merging]
Overall: [HEALTHY | NEEDS ATTENTION | FRAGMENTED]
```
**Density benchmarks:**
| Density | Interpretation |
|---------|---------------|
| < 0.02 | Sparse — {vocabulary.note_plural} exist but connections are thin |
| 0.02-0.06 | Healthy — growing network with meaningful connections |
| 0.06-0.15 | Dense — well-connected, watch for over-linking |
| > 0.15 | Very dense — verify connections are genuine, not noise |
### /graph triangles
Find synthesis opportunities — open triadic closures where A links to B and A links to C, but B does not link to C.
**Step 1: Build adjacency data**
```bash
# For each note, extract outgoing wiki links
for f in "$NOTES_DIR"/*.md; do
NAME=$(basename "$f" .md)
LINKS=$(grep -oP '\[\[([^\]]+)\]\]' "$f" 2>/dev/null | sed 's/\[\[//;s/\]\]//' | sort -u)
echo "FROM:$NAME"
echo "$LINKS" | while read -r target; do
[[ -n "$target" ]] && echo " TO:$target"
done
done
```
If `ops/scripts/graph/find-triangles.sh` exists, use it directly.
**Step 2: Find open triangles**
For each note A with outgoing links to B and C:
1. Check if B links to C (in either direction)
2. Check if C links to B (in either direction)
3. If neither link exists: this is an open triangle (synthesis opportunity)
**Step 3: Evaluate and rank**
For each open triangle:
1. Read descriptions of BOTH unlinked {vocabulary.note_plural}
2. Assess: is there a genuine conceptual relationship that the common parent suggests?
3. Rank by potential value: how surprising and useful would the connection be?
**Step 4: Present top findings**
```
--=={ graph triangles }==--
Found [N] synthesis opportunities — pairs of {vocabulProactive methodology guidance agent. Monitors note creation and provides real-time quality advice. Suggests connections, flags quality issues, recommends MOC updates. Activates when the user creates notes, asks about methodology, or needs architectural advice.
Research a topic and grow your knowledge graph. Uses Exa deep researcher, web search, or basic search to investigate topics, files results with full provenance, and chains to processing pipeline. Triggers on "/learn", "/learn [topic]", "research this", "find out about".
Surface the most valuable next action by combining task stack, queue state, inbox pressure, health, and goals. Recommends one specific action with rationale. Triggers on "/next", "what should I do", "what's next".
End-to-end source processing -- seed, reduce, process all claims through reflect/reweave/verify, archive. The full pipeline in one command. Triggers on "/pipeline", "/pipeline [file]", "process this end to end", "full pipeline".
Queue processing with fresh context per phase. Processes N tasks from the queue, spawning isolated subagents to prevent context contamination. Supports serial, parallel, batch filter, and dry run modes. Triggers on "/ralph", "/ralph N", "process queue", "run pipeline tasks".
Extract structured knowledge from source material. Comprehensive extraction is the default — every insight that serves the domain gets extracted. For domain-relevant sources, skip rate must be below 10%. Zero extraction from a domain-relevant source is a BUG. Triggers on "/reduce", "/reduce [file]", "extract insights", "mine this", "process this".
Plan vault restructuring from config changes. Compares config.yaml against derivation.md, identifies dimension shifts, shows restructuring plan, executes on approval. Triggers on "/refactor", "restructure vault".
Find connections between notes and update MOCs. Requires semantic judgment to identify genuine relationships. Use after /reduce creates notes, when exploring connections, or when a topic needs synthesis. Triggers on "/reflect", "/reflect [note]", "find connections", "update MOCs", "connect these notes".