# How Routing Decisions Are Made in reverse-skill: A 3-Step Keyword Matching System

> Discover how reverse-skill makes routing decisions. Learn the 3-step keyword matching system that normalizes hints, scores routes, and selects the best skill module for efficient reverse engineering.

- Repository: [ZhaoXu/reverse-skill](https://github.com/zhaoxuya520/reverse-skill)
- Tags: how-to-guide
- Published: 2026-08-29

---

**The reverse-skill framework determines which skill module to invoke by normalizing natural-language hints, scoring routes against keyword patterns in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), and selecting the highest-priority match from the ordered priority list, falling back to the general reverse-engineering skill (R0) when no keywords match.**

Routing decisions in the reverse-skill project are governed by a deterministic, data-driven engine that treats [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) as the single source of truth. When you provide a natural-language hint—such as "unpack an APK" or "analyze a malicious PDF"—the system parses this input through a standardized scoring algorithm to select the most appropriate skill workflow. This architecture ensures consistent behavior across Windows, Linux, macOS, and Kali environments without hardcoding logic into the platform-specific wrappers.

## The Three-Step Routing Algorithm

The routing engine implemented in `skills/scripts/master-route.ps1` and [`skills/scripts/master-route.sh`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/master-route.sh) follows a strict three-phase process to resolve every hint to a specific [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) file.

### Step 1: Input Normalisation

First, the raw user hint undergoes normalization to strip extraneous language and isolate technical keywords. This preprocessing removes conversational filler such as "I need to" or "please help me," ensuring the matching algorithm focuses exclusively on domain-specific terms like "APK," "certificate pinning," or "payload extraction."

### Step 2: Keyword Matching and Scoring

The normalized input is evaluated against every route defined in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json). Each route entry contains structured keyword rules:

- **must**: Required regex patterns that must match to contribute to the score
- **exclude**: Patterns that immediately disqualify the route if detected in the hint
- **mustAll**: Flags indicating whether all listed terms must appear simultaneously
- **note**: Contextual documentation for route maintainers

The scoring logic increments the route’s score for every `must` pattern found in the hint. If an `exclude` pattern matches, the route receives a zero score and is discarded from consideration. This granular filtering allows precise targeting—for example, distinguishing between generic Android analysis and specific APK unpacking scenarios.

### Step 3: Priority-Based Selection

After scoring, the engine consults the `priority` array in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json). Routes are not merely ranked by score; they are ordered by their position in this explicit priority list. The system selects the **PRIMARY** route by identifying the highest-scoring route that appears earliest in the priority hierarchy.

If no route accumulates any points—meaning no keywords matched—the engine executes a fallback to `fallbackId` `R0`, which maps to the general reverse-engineering skill defined in the JSON’s `meta` block.

## Configuration Structure and Data Flow

All routing decisions derive from [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json). This central configuration defines:

- The complete route inventory with unique string identifiers
- Keyword rule objects containing inclusion and exclusion criteria
- The ordered `priority` array that breaks scoring ties by precedence
- The `meta.fallbackId` pointer (defaulting to `R0`) for unmatched inputs

Each route’s `skill` field contains a relative filesystem path to its workflow documentation—for instance, [`apk-reverse/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/apk-reverse/SKILL.md) for Android package analysis or [`pdf-analysis/SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/pdf-analysis/SKILL.md) for document forensics. The [`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md) document provides the formal contract explaining this priority mechanism and fallback behavior, while [`skills/routing.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/routing.md) maintains a human-readable matrix for quick disambiguation.

## Executing Routing Decisions Across Platforms

While the configuration remains platform-agnostic, the repository provides optimized wrappers that implement identical logic for different operating systems.

On Windows, invoke the PowerShell wrapper:

```powershell

# Executes the master-route script with a user-provided hint.

# The script reads routing.json, matches keywords, and prints the chosen SKILL file.

powershell -NoProfile -ExecutionPolicy Bypass -File skills/scripts/master-route.ps1 -Hint "I need to unpack an APK and bypass its certificate pinning"

```

On Linux, macOS, or Kali, use the Bash equivalent:

```bash

# Equivalent Bash wrapper that invokes the same routing logic.

bash skills/scripts/master-route.sh --hint "Extract a hidden payload from a malicious PDF"

```

Both scripts accept the hint parameter, parse [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) using their respective JSON libraries, apply the scoring algorithm, and output the absolute path to the selected [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) file for downstream consumption.

## Internal Routing Logic

Conceptually, the router executes the following pseudocode algorithm as implemented in the cross-platform scripts:

```python
def route(hint):
    candidates = {}
    for route_id, data in routing_json["routes"].items():
        score = 0
        for kw in data["keywords"]:
            if re.search(kw["must"], hint, re.I):
                if "exclude" in kw and re.search(kw["exclude"], hint, re.I):
                    continue          # discard this route

                score += 1
        if score:
            candidates[route_id] = score

    # Apply priority order

    for rid in routing_json["priority"]:
        if rid in candidates:
            return routing_json["routes"][rid]["skill"]
    return routing_json["routes"][routing_json["meta"]["fallbackId"]]["skill"]

```

This implementation guarantees deterministic behavior: the first route in the priority list with a non-zero score wins, ensuring predictable skill selection even when multiple routes match partially.

## Maintaining Routing Coherence

To prevent configuration drift between the machine-readable JSON and human documentation, the repository includes `skills/scripts/verify-routing-coherence.ps1`. This verification script parses both [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) and [`skills/routing.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/routing.md), validating that the priority order and route identifiers remain synchronized across both sources. CI/CD pipelines should execute this check to ensure that documentation accurately reflects the active routing logic.

```powershell

# Checks that the markdown matrix matches the JSON definitions.

powershell -NoProfile -ExecutionPolicy Bypass -File skills/scripts/verify-routing-coherence.ps1

```

## Summary

- **Single Source of Truth**: All routing decisions originate from [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), eliminating logic duplication across platform-specific scripts.
- **Keyword Scoring System**: Routes accumulate points for matching `must` patterns and are disqualified by `exclude` patterns, enabling precise hint interpretation.
- **Priority-Ordered Resolution**: Ties are broken by the explicit `priority` array in the JSON, not by score magnitude alone.
- **Guaranteed Fallback**: Unmatched hints automatically route to `fallbackId` `R0`, ensuring the system always returns a valid skill path even for ambiguous inputs.
- **Integrity Verification**: The `verify-routing-coherence.ps1` script ensures documentation parity with configuration changes.

## Frequently Asked Questions

### What happens if my hint doesn't match any keywords in the routing table?

If the scoring algorithm assigns zero points to all available routes—meaning no `must` patterns matched your normalized input—the engine defaults to the route specified in `meta.fallbackId` (typically `R0`). This fallback route points to the general reverse-engineering skill, ensuring the system always provides a viable workflow rather than failing.

### How do I add support for a new reverse-engineering domain?

To introduce a new skill route, you must edit [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) to append a unique route identifier with its associated `must` and `exclude` keyword patterns, insert the identifier into the `priority` array at your desired precedence level, and create the corresponding [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) file referenced in the route’s `skill` field. Finally, update [`skills/routing.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/routing.md) to reflect the new entry and run `verify-routing-coherence.ps1` to validate consistency.

### Can I prevent certain keywords from triggering a specific route?

Yes. Each keyword object in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) supports an optional `exclude` field containing regex patterns. If the input hint matches any pattern listed in `exclude`, that keyword match is discarded and the route receives no points for that term, effectively preventing the route from being selected for those specific contexts.

### How does the system handle multiple routes with identical scores?

When two or more routes achieve the same score, the `priority` array in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) acts as the tiebreaker. The router iterates through the priority list in order and selects the first route identifier that exists in the candidate set. This explicit ordering allows maintainers to fine-tune precedence without adjusting complex scoring weights.