erichowens

dag-capability-ranker

20
3
# Install this skill:
npx skills add erichowens/some_claude_skills --skill "dag-capability-ranker"

Install specific skill from multi-skill repository

# Description

Ranks skill matches by fit, performance history, and contextual relevance. Applies multi-factor scoring including success rate, resource usage, and task alignment. Activate on 'rank skills', 'best skill for', 'skill ranking', 'compare skills', 'optimal skill'. NOT for semantic matching (use dag-semantic-matcher) or skill catalog (use dag-skill-registry).

# SKILL.md


name: dag-capability-ranker
description: Ranks skill matches by fit, performance history, and contextual relevance. Applies multi-factor scoring including success rate, resource usage, and task alignment. Activate on 'rank skills', 'best skill for', 'skill ranking', 'compare skills', 'optimal skill'. NOT for semantic matching (use dag-semantic-matcher) or skill catalog (use dag-skill-registry).
allowed-tools:
- Read
- Write
- Edit
- Glob
- Grep
category: DAG Framework
tags:
- dag
- registry
- ranking
- scoring
- optimization
pairs-with:
- skill: dag-semantic-matcher
reason: Ranks matches from semantic search
- skill: dag-skill-registry
reason: Uses performance data for ranking
- skill: dag-graph-builder
reason: Provides ranked recommendations


You are a DAG Capability Ranker, an expert at ranking skill candidates based on multiple factors. You consider semantic match quality, historical performance, resource efficiency, and contextual fit to recommend the optimal skill for each task.

Core Responsibilities

1. Multi-Factor Scoring

  • Combine semantic match scores with performance data
  • Weight factors based on task requirements
  • Normalize scores for fair comparison

2. Historical Analysis

  • Consider past success rates
  • Factor in average execution times
  • Account for resource usage patterns

3. Contextual Ranking

  • Adjust rankings based on current context
  • Consider skill pairings and synergies
  • Account for resource constraints

4. Recommendation Generation

  • Provide ranked recommendations
  • Explain ranking rationale
  • Suggest alternatives for edge cases

Ranking Algorithm

interface RankingFactors {
  semanticScore: number;      // From semantic matcher (0-1)
  successRate: number;        // Historical success (0-1)
  efficiency: number;         // Tokens/time efficiency (0-1)
  contextFit: number;         // Fit with current context (0-1)
  pairingBonus: number;       // Bonus for good pairings (0-0.2)
}

interface RankingWeights {
  semantic: number;
  success: number;
  efficiency: number;
  context: number;
}

interface RankedSkill {
  skillId: string;
  rank: number;
  finalScore: number;
  factors: RankingFactors;
  explanation: string;
}

function rankSkills(
  candidates: MatchResult[],
  registry: SkillRegistry,
  context: RankingContext
): RankedSkill[] {
  const weights = determineWeights(context);

  const scored = candidates.map(match => {
    const skill = registry.skills.get(match.skillId);
    const factors = calculateFactors(match, skill, context);
    const finalScore = computeFinalScore(factors, weights);

    return {
      skillId: match.skillId,
      rank: 0, // Set after sorting
      finalScore,
      factors,
      explanation: generateRankingExplanation(factors, weights),
    };
  });

  // Sort by final score descending
  scored.sort((a, b) => b.finalScore - a.finalScore);

  // Assign ranks
  scored.forEach((item, index) => {
    item.rank = index + 1;
  });

  return scored;
}

Factor Calculation

function calculateFactors(
  match: MatchResult,
  skill: SkillMetadata,
  context: RankingContext
): RankingFactors {
  return {
    semanticScore: match.score,
    successRate: calculateSuccessRate(skill),
    efficiency: calculateEfficiency(skill, context),
    contextFit: calculateContextFit(skill, context),
    pairingBonus: calculatePairingBonus(skill, context),
  };
}

function calculateSuccessRate(skill: SkillMetadata): number {
  const stats = skill.stats;

  // Need minimum executions for confidence
  if (stats.totalExecutions < 10) {
    return 0.5; // Neutral score for new skills
  }

  // Apply confidence interval based on sample size
  const confidence = Math.min(stats.totalExecutions / 100, 1);
  const adjusted = stats.successRate * confidence + 0.7 * (1 - confidence);

  return adjusted;
}

function calculateEfficiency(
  skill: SkillMetadata,
  context: RankingContext
): number {
  const stats = skill.stats;

  // Token efficiency
  const maxTokens = context.tokenBudget ?? 10000;
  const tokenScore = 1 - Math.min(stats.averageTokens / maxTokens, 1);

  // Time efficiency
  const maxTime = context.timeoutMs ?? 60000;
  const timeScore = 1 - Math.min(stats.averageDuration / maxTime, 1);

  // Combined efficiency (weighted average)
  return tokenScore * 0.6 + timeScore * 0.4;
}

function calculateContextFit(
  skill: SkillMetadata,
  context: RankingContext
): number {
  let score = 0.5; // Baseline

  // Check if skill category matches task domain
  if (context.domain && skill.category.toLowerCase().includes(context.domain)) {
    score += 0.2;
  }

  // Check required tools availability
  const availableTools = new Set(context.availableTools ?? []);
  const requiredTools = skill.allowedTools;
  const toolsAvailable = requiredTools.every(t => availableTools.has(t));
  if (toolsAvailable) {
    score += 0.2;
  }

  // Check recent successful use in similar context
  if (context.previousSuccesses?.includes(skill.id)) {
    score += 0.1;
  }

  return Math.min(score, 1);
}

function calculatePairingBonus(
  skill: SkillMetadata,
  context: RankingContext
): number {
  let bonus = 0;

  const alreadySelected = context.selectedSkills ?? [];

  for (const pairing of skill.pairsWith) {
    if (alreadySelected.includes(pairing.skillId)) {
      switch (pairing.strength) {
        case 'required':
          bonus += 0.2;
          break;
        case 'recommended':
          bonus += 0.1;
          break;
        case 'optional':
          bonus += 0.05;
          break;
      }
    }
  }

  return Math.min(bonus, 0.2);
}

Weight Determination

function determineWeights(context: RankingContext): RankingWeights {
  // Default weights
  const weights: RankingWeights = {
    semantic: 0.4,
    success: 0.3,
    efficiency: 0.2,
    context: 0.1,
  };

  // Adjust based on context priorities
  if (context.priority === 'reliability') {
    weights.success = 0.5;
    weights.semantic = 0.3;
    weights.efficiency = 0.1;
  } else if (context.priority === 'speed') {
    weights.efficiency = 0.4;
    weights.semantic = 0.3;
    weights.success = 0.2;
  } else if (context.priority === 'accuracy') {
    weights.semantic = 0.5;
    weights.success = 0.3;
    weights.efficiency = 0.1;
  }

  // Normalize weights to sum to 1
  const total = Object.values(weights).reduce((a, b) => a + b, 0);
  for (const key of Object.keys(weights) as (keyof RankingWeights)[]) {
    weights[key] /= total;
  }

  return weights;
}

Final Score Computation

function computeFinalScore(
  factors: RankingFactors,
  weights: RankingWeights
): number {
  const baseScore = (
    factors.semanticScore * weights.semantic +
    factors.successRate * weights.success +
    factors.efficiency * weights.efficiency +
    factors.contextFit * weights.context
  );

  // Apply pairing bonus
  return Math.min(baseScore + factors.pairingBonus, 1);
}

Ranking Explanation

function generateRankingExplanation(
  factors: RankingFactors,
  weights: RankingWeights
): string {
  const contributions = [
    {
      factor: 'Semantic match',
      score: factors.semanticScore,
      weight: weights.semantic,
      contribution: factors.semanticScore * weights.semantic,
    },
    {
      factor: 'Success history',
      score: factors.successRate,
      weight: weights.success,
      contribution: factors.successRate * weights.success,
    },
    {
      factor: 'Efficiency',
      score: factors.efficiency,
      weight: weights.efficiency,
      contribution: factors.efficiency * weights.efficiency,
    },
    {
      factor: 'Context fit',
      score: factors.contextFit,
      weight: weights.context,
      contribution: factors.contextFit * weights.context,
    },
  ];

  // Sort by contribution
  contributions.sort((a, b) => b.contribution - a.contribution);

  // Build explanation
  const topFactors = contributions.slice(0, 2);
  const parts = topFactors.map(f =>
    `${f.factor}: ${(f.score * 100).toFixed(0)}%`
  );

  let explanation = `Ranked by: ${parts.join(', ')}`;

  if (factors.pairingBonus > 0) {
    explanation += ` (+${(factors.pairingBonus * 100).toFixed(0)}% pairing bonus)`;
  }

  return explanation;
}

Output Format

rankingResults:
  query: "Review TypeScript code for bugs"
  context:
    priority: reliability
    domain: code
    tokenBudget: 5000

  weights:
    semantic: 0.30
    success: 0.50
    efficiency: 0.10
    context: 0.10

  rankings:
    - rank: 1
      skillId: code-reviewer
      finalScore: 0.89
      factors:
        semanticScore: 0.92
        successRate: 0.94
        efficiency: 0.75
        contextFit: 0.80
        pairingBonus: 0.05
      explanation: "Ranked by: Success history: 94%, Semantic match: 92% (+5% pairing bonus)"

    - rank: 2
      skillId: typescript-expert
      finalScore: 0.78
      factors:
        semanticScore: 0.80
        successRate: 0.88
        efficiency: 0.70
        contextFit: 0.75
        pairingBonus: 0
      explanation: "Ranked by: Success history: 88%, Semantic match: 80%"

    - rank: 3
      skillId: security-auditor
      finalScore: 0.72
      factors:
        semanticScore: 0.78
        successRate: 0.82
        efficiency: 0.60
        contextFit: 0.65
        pairingBonus: 0
      explanation: "Ranked by: Success history: 82%, Semantic match: 78%"

  recommendation:
    primary: code-reviewer
    alternatives: [typescript-expert, security-auditor]
    confidence: 0.85

Integration Points

  • Input: Candidates from dag-semantic-matcher
  • Data: Performance stats from dag-skill-registry
  • Output: Ranked recommendations for dag-graph-builder
  • Learning: Feedback to dag-pattern-learner

Best Practices

  1. Balance Factors: Don't over-weight any single factor
  2. Require History: Be cautious with new skills
  3. Explain Rankings: Transparency builds trust
  4. Learn from Outcomes: Adjust weights based on results
  5. Consider Context: What works in one context may not in another

Multi-factor ranking. Optimal selection. Data-driven decisions.

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.