How the Reverse-Skill Routing Algorithm Prioritizes Keywords and Resolves Conflicts Between Multiple Matching Rules

The reverse-skill routing algorithm prioritizes keywords by scoring regex matches and resolves conflicts between multiple matching rules by selecting the highest-scoring route, breaking ties via the order defined in the priority array, and falling back to R0 when no matches occur.

The zhaoxuya520/reverse-skill repository implements a deterministic routing system driven by a single JSON configuration. Understanding how this routing algorithm prioritizes keywords and resolves conflicts between multiple matching rules is essential for customizing the skill selector or debugging unexpected route selections in skills/config/routing.json.

Keyword Matching and Scoring Logic

Each route (R1 through R40) defines a list of keyword objects. When a user query arrives, the algorithm evaluates every route against three pattern types to calculate a cumulative score.

The must Pattern

Every must regex that matches the user query adds a hit to that route’s candidate set【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/zhaoxuya520/reverse-skill/main/skills/config/routing.json#L6-L7】. The total number of successful hits becomes the score for that route. A higher score indicates greater relevance to the query.

Exclusion and mustAll Modifiers

Two optional modifiers refine the matching logic:

  • exclude: If this pattern matches the query, the hit is removed from the route’s score, even if must matched.
  • mustAll: Requires every sub-pattern in the set to be present in the query. If any sub-pattern fails, the hit is discarded.

These modifiers ensure that partial matches or unwanted keyword collisions do not inflate a route’s score.

Priority-Based Conflict Resolution

When multiple routes achieve positive scores, the algorithm uses a two-tier resolution strategy: score first, priority second.

Handling Ties with the Priority Array

After scoring completes, the algorithm walks the priority array from top to bottom【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/zhaoxuya520/reverse-skill/main/skills/config/routing.json#L10-L14】. The route with the highest score is selected. If several routes share the same highest score, the one appearing earlier in the priority list wins (the "first-winner" rule).

This deterministic ordering prevents ambiguous routing and allows explicit control over which skills take precedence when queries match multiple patterns.

Real-World Conflict Example

Consider a query containing both "apk" and "js reverse":

  • R1 (APK reverse) receives a hit from the apk keyword【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/zhaoxuya520/reverse-skill/main/skills/config/routing.json#L14-L18】, achieving a score of 1.
  • R3 (JS/frontend reverse) receives a hit from the js reverse keyword【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/zhaoxuya520/reverse-skill/main/skills/config/routing.json#L30-L34】, also achieving a score of 1.

Because the scores tie, the priority list (defined as R4, R1, R2, R3...) decides the winner. The algorithm selects R1 because it appears earlier than R3 in the array【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/zhaoxuya520/reverse-skill/main/skills/config/routing.json#L11-L13】.

Fallback Mechanism

If no route receives any hit (score = 0), the algorithm does not return a null result. Instead, it falls back to the route identified by fallbackId (R0)【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/zhaoxuya520/reverse-skill/main/skills/config/routing.json#L5-L6】, ensuring a graceful default behavior when queries match no defined keywords.

Implementation in PowerShell

The matching logic resides in skills/scripts/master-route.ps1, which loads routing.json and executes the scoring algorithm. The skills/scripts/verify-routing-coherence.ps1 script validates that the priority list and route definitions remain synchronized during configuration changes.

A simplified version of the scoring logic follows:


# Load routing table

$routing = Get-Content routing.json | ConvertFrom-Json

# 1️⃣ Score each route

foreach ($id in $routing.routes.Keys) {
    $route = $routing.routes[$id]
    $score = 0
    foreach ($kw in $route.keywords) {
        if ($query -match $kw.must) {
            if ($kw.exclude -and $query -match $kw.exclude) { continue }
            if ($kw.mustAll) {
                $allMatch = $true
                foreach ($sub in $kw.mustAll) { 
                    if (-not ($query -match $sub)) { $allMatch = $false } 
                }
                if (-not $allMatch) { continue }
            }
            $score++
        }
    }
    $route.score = $score
}

# 2️⃣ Choose the best route

$best = $null
$maxScore = -1
foreach ($id in $routing.priority) {
    $route = $routing.routes[$id]
    if ($route.score -gt $maxScore) {
        $best = $route
        $maxScore = $route.score
    } elseif ($route.score -eq $maxScore -and $best -eq $null) {
        # first in priority wins on tie

        $best = $route
    }
}

# 3️⃣ Fallback if nothing matched

if ($maxScore -le 0) { 
    $best = $routing.routes[$routing.fallbackId] 
}

# Result

$best.skill   # e.g. "apk-reverse/SKILL.md"

Summary

  • Scoring: Routes accumulate points based on must regex matches, modified by exclude and mustAll patterns defined in skills/config/routing.json.
  • Conflict Resolution: Highest score wins; ties are broken by order in the priority array (earlier wins).
  • Fallback: Route R0 (defined by fallbackId) handles queries with zero matches.
  • Validation: verify-routing-coherence.ps1 ensures the priority list and route definitions stay in sync.

Frequently Asked Questions

What happens when two routes have identical scores?

The algorithm selects the route that appears earlier in the priority array. This "first-winner" rule ensures deterministic routing when multiple rules match equally well, as implemented in master-route.ps1.

How does the exclude pattern work in the routing JSON?

If a query matches both a must pattern and its corresponding exclude pattern, the hit is discarded and does not contribute to the route’s score. This prevents false positives when keywords appear in unintended contexts.

What is the purpose of verify-routing-coherence.ps1?

This script validates that the priority array and route definitions in routing.json remain synchronized. It catches configuration errors where a route ID might be missing from the priority list or vice versa before runtime.

Can I assign different weights to different keywords?

No. According to the source code in master-route.ps1, each successful match (after applying modifiers) contributes exactly one point to the route’s score. To prioritize certain keywords, you must place their containing routes earlier in the priority array rather than assigning numerical weights.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →