Grafema URI Semantic ID Parsing
SkillFiles & storageFix silent failures when parsing Grafema semantic IDs that are in URI format instead of legacy arrow format. Use when: (1) code splits semantic IDs by "->" but gets the whole string back because IDs are grafema:// URIs, (2) file path extraction from semantic IDs returns empty or wrong values, (3) derived edges (DEPENDS_ON, etc.) produce 0 results despite source edges existing, (4) any code that processes semantic IDs after the analysis pipeline's to_uri_format() has run. The grafema:// URI format uses # fragments with percent-encoded characters instead of -> separators.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Grafema URI Semantic ID Parsing skill
What this skill tells your AI
The instructions your AI receives, as published by disentinel/grafema in .claude/skills/grafema-uri-semantic-id-parsing/SKILL.md and read by ahel’s review.
Problem
Code that processes semantic IDs using split("->") silently fails when the
analysis pipeline has converted IDs to grafema:// URI format. The URI format
uses # fragments with percent-encoded characters (%3E instead of >),
so -> never appears and split("->") returns the entire string as element 0.
Context / Trigger Conditions
- Derived edges (e.g., MODULE->MODULE DEPENDS_ON from IMPORTS_FROM) produce 0 results
- File path extraction from semantic IDs returns the whole URI string
- Any Rust code in the orchestrator that processes semantic IDs from RFDB after
to_uri_format()has been called during analysis - Lookups into
file_to_moduleor similar file-keyed maps always miss
The Two Formats
Legacy compact format (before to_uri_format):
src/components/App.tsx->IMPORT_BINDING->react
MODULE#src/components/App.tsx
URI format (after to_uri_format, stored in RFDB):
grafema://github.com/owner/repo/src/components/App.tsx#IMPORT_BINDING%3Ereact
grafema://github.com/owner/repo/src/components/App.tsx#MODULE
Virtual nodes (no file path):
grafema://github.com/owner/repo/_/EXTERNAL_MODULE%3Elodash
grafema://github.com/owner/repo/_/GLOBAL%3A%3Aconsole
Solution
Always handle both formats when extracting file paths from semantic IDs:
// Pre-compute URI prefix (authority is known from resolve_authority())
let uri_prefix = format!("grafema://{authority}/");
let extract_file = |id: &str| -> &str {
if let Some(rest) = id.strip_prefix(&uri_prefix) {
// URI format: take path up to '#'
rest.split('#').next().unwrap_or("")
} else {
// Legacy format: take path up to first '->'
id.split("->").next().unwrap_or("")
}
};
Key points:
authorityis always available viaresolve_authority(&cfg)in main.rs- Virtual nodes have
_/as the file path component — these won't match real files (correct behavior) node.filefields stay as relative paths (not URI-formatted), sofile_to_modulemaps use relative paths as keys- Edge
src/dstfields ARE URI-formatted (they reference node IDs which were converted)
Verification
After fixing, check:
all_imports_from_edges.len()> 0 (edges are collected)depends_on_pairs.len()> 0 (file paths extracted and matched)- Tracing output shows "Module dependency edges derived" with non-zero count
Example: The DEPENDS_ON Bug
The to_uri_format() method in analyzer.rs converts node IDs but keeps node.file as-is:
pub fn to_uri_format(&mut self, authority: &str) {
for node in &mut self.nodes {
node.id = convert(&node.id); // → grafema://authority/path#FRAGMENT
// node.file stays as relative path
}
for edge in &mut self.edges {
edge.src = convert(&edge.src); // → URI format
edge.dst = convert(&edge.dst); // → URI format
}
}
So IMPORTS_FROM edges in RFDB have URI-formatted src/dst, but MODULE nodes have
relative file paths. The derivation code must parse URIs to extract relative paths
for the file_to_module lookup.
Notes
- This affects ALL code that processes semantic IDs from RFDB in the orchestrator
- The
compact_to_urifunction in analyzer.rs defines the exact URI structure - Fragment encoding:
>→%3E,[→%5B,]→%5D,#→%23 - If
authoritychanges between runs, old and new URIs won't match
Signals
- GitHub stars
- 36
- Forks
- 3
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
grafema-uri-semantic-id-parsing- Source
- github.com/disentinel/grafema