
Capability Graph Builder
Build queryable capability graphs from manifests using Codex for relationship inference between skills, resources, and capabilities.
Build queryable capability graphs from manifests using Codex for relationship inference between skills, resources, and capabilities.
Capability Graph Builder
Build queryable capability graphs from manifests using Codex for relationship inference
Purpose
Consumes capability manifests (generated by manifest-generator) and constructs a queryable graph structure representing all capabilities and their relationships. Uses OpenAI Codex to infer missing relationships and validate compatibility declarations.
When to Use
- After generating manifests for skills/MCPs/tools
- When building the orchestration system's knowledge base
- To discover capability relationships and dependencies
- To validate manifest consistency across resources
- To enable graph-based queries for orchestration planning
Key Capabilities
- Graph Construction: Builds nodes (capabilities) and edges (relationships) from manifests
- Relationship Inference: Uses Codex to discover implicit relationships from descriptions
- Consistency Validation: Validates bidirectional relationships (if A enables B, does B require A?)
- Path Finding: Supports queries like "what skills are needed to achieve X?"
- Subgraph Extraction: Finds all capabilities in a domain or with specific effects
Inputs
inputs:
manifest_dir: string # Directory containing manifest.yaml files (e.g., SKILLS/)
output_path: string # Where to write capability-graph.json
validate_consistency: boolean # Run Codex validation on relationships
infer_missing: boolean # Use Codex to infer missing compatibility fields
Process
Step 1: Scan and Load Manifests
#!/bin/bash
# Find all manifest.yaml files
MANIFESTS=$(find SKILLS MCP-SERVERS TOOLS COMPONENTS INTEGRATIONS -name 'manifest.yaml' 2>/dev/null)
# Load each manifest
echo "Loading manifests..."
for manifest in $MANIFESTS; do
echo " - $manifest"
done
Step 2: Build Initial Graph
// Pseudocode for graph construction
const graph = {
nodes: [],
edges: [],
domains: {},
effects: {}
}
for (const manifest of manifests) {
// Add node
graph.nodes.push({
id: manifest.name,
kind: manifest.kind,
description: manifest.description,
preconditions: manifest.preconditions,
effects: manifest.effects,
domains: manifest.domains,
cost: manifest.cost,
latency: manifest.latency,
risk_level: manifest.risk_level
})
// Add edges from compatibility
if (manifest.compatibility) {
if (manifest.compatibility.requires) {
for (const required of manifest.compatibility.requires) {
graph.edges.push({
from: required,
to: manifest.name,
type: 'requires'
})
}
}
if (manifest.compatibility.enables) {
for (const enabled of manifest.compatibility.enables) {
graph.edges.push({
from: manifest.name,
to: enabled,
type: 'enables'
})
}
}
if (manifest.compatibility.conflicts_with) {
for (const conflict of manifest.compatibility.conflicts_with) {
graph.edges.push({
from: manifest.name,
to: conflict,
type: 'conflicts_with'
})
}
}
if (manifest.compatibility.composes_with) {
for (const compose of manifest.compatibility.composes_with) {
graph.edges.push({
from: manifest.name,
to: compose,
type: 'composes_with'
})
}
}
}
// Index by domain
for (const domain of manifest.domains) {
if (!graph.domains[domain]) graph.domains[domain] = []
graph.domains[domain].push(manifest.name)
}
// Index by effect
for (const effect of manifest.effects) {
if (!graph.effects[effect]) graph.effects[effect] = []
graph.effects[effect].push(manifest.name)
}
}
Step 3: Infer Missing Relationships with Codex
# For each pair of capabilities, ask Codex about relationships
for capability_a in "${capabilities[@]}"; do
for capability_b in "${capabilities[@]}"; do
if [ "$capability_a" != "$capability_b" ]; then
# Get manifests
MANIFEST_A=$(cat "path/to/$capability_a/manifest.yaml")
MANIFEST_B=$(cat "path/to/$capability_b/manifest.yaml")
# Ask Codex
codex exec "
Analyze these two capabilities and determine their relationship:
CAPABILITY A:
$MANIFEST_A
CAPABILITY B:
$MANIFEST_B
Questions:
1. Does A require B to function?
2. Does A enable B (make B possible)?
3. Do A and B conflict (can't coexist)?
4. Do A and B compose well together?
5. Are there any implicit dependencies or relationships?
Output JSON:
{
\"requires\": boolean,
\"enables\": boolean,
\"conflicts_with\": boolean,
\"composes_with\": boolean,
\"reasoning\": \"explanation\"
}
" > /tmp/relationship-${capability_a}-${capability_b}.json
fi
done
done
Step 4: Validate Consistency
# Check bidirectional relationships
codex exec "
Analyze this capability graph for consistency issues:
GRAPH:
$(cat /tmp/capability-graph.json)
Check for:
1. Asymmetric relationships (A enables B but B doesn't require A)
2. Conflicting declarations (A enables B but B conflicts with A)
3. Missing transitive relationships (A requires B, B requires C, but A doesn't require C)
4. Circular dependencies (A requires B, B requires A)
Output JSON array of issues:
[
{
\"type\": \"asymmetric_enables\",
\"from\": \"capability-a\",
\"to\": \"capability-b\",
\"issue\": \"A enables B but B doesn't list A as required\",
\"severity\": \"warning\"
}
]
"
Step 5: Write Graph
# Write final graph with metadata
cat > META/capability-graph.json <<EOF
{
"version": "1.0.0",
"generated_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"node_count": ${node_count},
"edge_count": ${edge_count},
"graph": $(cat /tmp/capability-graph.json)
}
EOF
Graph Query API
The generated graph supports these queries:
Find Capabilities by Effect
// Find all capabilities that create vector indexes
const creators = graph.effects['creates_vector_index']
// => ['rag-implementer', 'pinecone-mcp', 'weaviate-mcp']
Find Capabilities by Domain
// Find all RAG-related capabilities
const ragCapabilities = graph.domains['rag']
// => ['rag-implementer', 'embedding-generator-mcp', 'vector-search-tool', ...]
Find Dependencies
// What does rag-implementer require?
const deps = findDependencies('rag-implementer')
// => ['openai-integration', 'pinecone-mcp']
function findDependencies(capabilityName) {
return graph.edges.filter(e => e.to === capabilityName && e.type === 'requires').map(e => e.from)
}
Find Enabled Capabilities
// What does having openai-integration enable?
const enabled = findEnabled('openai-integration')
// => ['rag-implementer', 'embedding-generator-mcp', 'gpt-vision-analyzer']
function findEnabled(capabilityName) {
return graph.edges.filter(e => e.from === capabilityName && e.type === 'enables').map(e => e.to)
}
Find Conflicts
// What conflicts with existing-vector-database?
const conflicts = findConflicts('existing-vector-database')
// => ['rag-implementer']
function findConflicts(capabilityName) {
return graph.edges
.filter(
e => (e.from === capabilityName || e.to === capabilityName) && e.type === 'conflicts_with'
)
.map(e => (e.from === capabilityName ? e.to : e.from))
}
Find Composition Partners
// What composes well with rag-implementer?
const partners = findCompositionPartners('rag-implementer')
// => ['pinecone-mcp', 'weaviate-mcp', 'semantic-search-tool']
function findCompositionPartners(capabilityName) {
return graph.edges
.filter(
e => (e.from === capabilityName || e.to === capabilityName) && e.type === 'composes_with'
)
.map(e => (e.from === capabilityName ? e.to : e.from))
}
Find Path to Goal
// What capabilities are needed to achieve "semantic_search"?
const path = findPathToEffect('semantic_search')
// => ['openai-integration', 'rag-implementer', 'vector-search-tool']
function findPathToEffect(effect) {
// BFS through requires/enables edges
const capabilities = graph.effects[effect] || []
const visited = new Set()
const path = []
for (const cap of capabilities) {
const deps = findAllDependencies(cap, visited)
path.push(...deps, cap)
}
return [...new Set(path)]
}
function findAllDependencies(capabilityName, visited = new Set()) {
if (visited.has(capabilityName)) return []
visited.add(capabilityName)
const directDeps = graph.edges
.filter(e => e.to === capabilityName && e.type === 'requires')
.map(e => e.from)
const allDeps = []
for (const dep of directDeps) {
allDeps.push(...findAllDependencies(dep, visited), dep)
}
return allDeps
}
Example Output
{
"version": "1.0.0",
"generated_at": "2025-10-28T12:00:00Z",
"node_count": 109,
"edge_count": 287,
"graph": {
"nodes": [
{
"id": "rag-implementer",
"kind": "skill",
"description": "Implement retrieval-augmented generation systems",
"preconditions": [
{ "check": "file_exists('package.json')", "required": true },
{ "check": "env_var_set('OPENAI_API_KEY')", "required": true }
],
"effects": ["creates_vector_index", "adds_embedding_pipeline", "configures_retrieval_api"],
"domains": ["rag", "ai", "search"],
"cost": "medium",
"latency": "slow",
"risk_level": "low"
},
{
"id": "pinecone-mcp",
"kind": "mcp",
"description": "Vector database operations for Pinecone",
"effects": ["creates_vector_index", "performs_similarity_search"],
"domains": ["rag", "vector-db"],
"cost": "low",
"latency": "fast",
"risk_level": "safe"
}
],
"edges": [
{
"from": "openai-integration",
"to": "rag-implementer",
"type": "requires"
},
{
"from": "rag-implementer",
"to": "pinecone-mcp",
"type": "composes_with"
},
{
"from": "rag-implementer",
"to": "semantic-search",
"type": "enables"
}
],
"domains": {
"rag": ["rag-implementer", "pinecone-mcp", "weaviate-mcp", "embedding-generator-mcp"],
"auth": ["frontend-builder", "api-designer", "security-engineer"],
"api": ["api-designer", "frontend-builder", "performance-optimizer"]
},
"effects": {
"creates_vector_index": ["rag-implementer", "pinecone-mcp", "weaviate-mcp"],
"adds_auth": ["frontend-builder", "api-designer"],
"configures_database": ["api-designer", "data-engineer"]
}
}
}
Integration
With manifest-generator
Consumes manifests generated by manifest-generator skill.
With orchestration-planner
Provides queryable graph for finding capabilities matching goal requirements.
With skill-validator
Graph structure helps validate that claimed relationships actually exist.
Success Metrics
- ✅ Graph includes all 109 capabilities
- ✅ All edges validated for bidirectional consistency
- ✅ Domain and effect indexes complete
- ✅ Path finding queries return correct results
- ✅ Graph can be serialized/deserialized efficiently
Related Skills
- manifest-generator: Generates manifests that feed this builder
- orchestration-planner: Uses graph for planning
- skill-validator: Validates graph consistency
You Might Also Like
Related Skills

coding-agent
Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.
openclaw
add-uint-support
Add unsigned integer (uint) type support to PyTorch operators by updating AT_DISPATCH macros. Use when adding support for uint16, uint32, uint64 types to operators, kernels, or when user mentions enabling unsigned types, barebones unsigned types, or uint support.
pytorch
at-dispatch-v2
Convert PyTorch AT_DISPATCH macros to AT_DISPATCH_V2 format in ATen C++ code. Use when porting AT_DISPATCH_ALL_TYPES_AND*, AT_DISPATCH_FLOATING_TYPES*, or other dispatch macros to the new v2 API. For ATen kernel files, CUDA kernels, and native operator implementations.
pytorch
skill-writer
Guide users through creating Agent Skills for Claude Code. Use when the user wants to create, write, author, or design a new Skill, or needs help with SKILL.md files, frontmatter, or skill structure.
pytorch
implementing-jsc-classes-cpp
Implements JavaScript classes in C++ using JavaScriptCore. Use when creating new JS classes with C++ bindings, prototypes, or constructors.
oven-sh
implementing-jsc-classes-zig
Creates JavaScript classes using Bun's Zig bindings generator (.classes.ts). Use when implementing new JS APIs in Zig with JSC integration.
oven-sh