Capability Graph Builder

Build queryable capability graphs from manifests using Codex for relationship inference between skills, resources, and capabilities.

$ Installer

git clone https://github.com/daffy0208/ai-dev-standards /tmp/ai-dev-standards && cp -r /tmp/ai-dev-standards/skills/capability-graph-builder ~/.claude/skills/ai-dev-standards

// tip: Run this command in your terminal to install the skill


name: Capability Graph Builder description: Build queryable capability graphs from manifests using Codex for relationship inference between skills, resources, and capabilities. version: 1.0.0 category: ai-native tags:

  • graph
  • codex
  • orchestration

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