# How the Keyword Matching System Works in reverse-skill Rules

> Explore how the keyword matching system works in reverse-skill rules. Discover how regex rules and a priority list efficiently route user requests to the correct SKILL.md file.

- Repository: [ZhaoXu/reverse-skill](https://github.com/zhaoxuya520/reverse-skill)
- Tags: internals
- Published: 2026-08-22

---

**The reverse-skill repository implements a data-driven routing engine that scores user requests against regex rules in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) to select the most appropriate SKILL.md file, using a priority list to break ties.**

The **keyword matching system** in *reverse-skill* serves as the central decision engine for routing security and reverse-engineering queries. By parsing natural language input against structured regular expressions, the system determines which specialized skill module—each defined by its own [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) file—should handle the request. All routing logic lives in the [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) file, which functions as a declarative rule engine processed by the master router scripts.

## Core Architecture of the Routing Engine

The routing engine operates on a **scoring-based classification** model. Each potential route (e.g., APK reverse, Mobile reverse, Pentest tools) contains one or more keyword rules. When a user submits a request, the system evaluates every rule against the input text and aggregates scores to identify the winning route.

### The routing.json Configuration File

The heart of the keyword matching system resides at **[`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json)**. This JSON file defines all available routes (R0 through R14 and beyond), each mapped to a specific skill directory. According to the repository source code, the configuration separates concerns between **rule definitions** (matching logic) and **execution priority** (tie-breaking logic).

### Rule Structure and Syntax

Every rule object within a route accepts one or more of the following fields:

- **`must`** – A regular expression that must be found in the input for the rule to match.
- **`exclude`** – A regular expression that must **not** be present; used to filter out false positives.
- **`mustAll`** – An array of regular expressions where **all** patterns must match simultaneously.
- **`note`** – Human-readable documentation explaining the rule’s intent.

In [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) at lines 16-18, the APK reverse route (R1) demonstrates a complex `must` pattern covering multiple attack vectors:

```json
{
  "must": "\\bapk\\b|smali|jadx|apktool|\\bandroid\\b|android.?reverse|安卓|反编译.?apk|apk.?加固|重打包|root.?detect|root.?检测|证书.?校验|certificate.?pinning|pinning.?绕过|签名.?校验",
  "note": "android 裸词/root 检测/证书校验/pinning 绕过 均为 APK 分析常见诉求"
}

```

## The Matching and Scoring Algorithm

The keyword matching system employs a **positive scoring model** combined with deterministic tie-breaking. Understanding this flow is essential for debugging routing decisions or extending the rule set.

### Scoring Logic and Candidate Points

When processing a request, the engine evaluates every rule across all routes. **Each matching rule contributes exactly one point** to its parent route’s candidate score. Routes can accumulate multiple points if several of their rules match the input simultaneously. The route with the highest aggregate score becomes the selected handler.

### Priority-Based Tie Breaking

If multiple routes achieve identical scores, the system consults the **`priority`** array defined at the bottom of [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) (lines 24-30). This array lists route IDs from most specific to most general. The route appearing earlier in the `priority` list wins the tie, ensuring that specialized skills (e.g., R1 for APK analysis) take precedence over generic ones (R0 for general reverse-engineering) when keyword overlap occurs.

### The Fallback Mechanism

If no rules match any route, the system defaults to route **`R0`** (General reverse-engineering), defined at lines 14-16 of [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json). This ensures the system always provides a relevant skill file rather than failing silently.

## Advanced Rule Composition

The keyword matching system supports boolean logic through field composition, allowing for precise control over routing decisions.

### Conjunctive Matching with mustAll

The `mustAll` field creates an **AND condition** across multiple regex patterns. All expressions in the array must match for the rule to score a point. At lines 24-27 of [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json), the Mobile reverse route (R2) uses `mustAll` to require both jailbreak terminology and mobile platform indicators:

```json
{
  "must": "jailbreak",
  "mustAll": ["ios|iphone|ipad|mobile|objection|ipa"],
  "note": "iOS jailbreak specific terms"
}

```

This ensures the route only matches when the user mentions jailbreaking **and** references iOS-specific contexts, preventing false matches against Android rooting discussions.

### Negative Matching with exclude

The `exclude` field implements **NOT logic**, removing points when certain terms appear. In the LLM/Agent security route (R14) at lines 12-14, the system excludes generic LLM discussions from security-focused routing:

```json
{
  "must": "llm",
  "exclude": "模型|提示词|jailbreak|红队.?ai|ai.?红队",
  "note": "Exclude generic LLM discussion, catch security-focused"
}

```

A match only registers if the `must` pattern is found **and** none of the `exclude` patterns appear in the input.

## From Configuration to Execution

The keyword matching system bridges static JSON configuration with dynamic skill invocation through the master router scripts.

### Execution Flow

1. **Input Reception**: The master router (`skills/scripts/master-route.ps1` or its `.sh` counterpart) receives the user query.
2. **JSON Parsing**: The script loads [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) into memory.
3. **Regex Evaluation**: Each rule’s `must`, `exclude`, and `mustAll` patterns are evaluated against the normalized input text.
4. **Score Calculation**: Points are tallied per route based on successful matches.
5. **Selection**: The highest-scoring route wins; ties are resolved using the `priority` array.
6. **Invocation**: The corresponding [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) file is loaded and executed.

### Documentation References

The repository includes human-readable specifications explaining this behavior:

- **[`RULES.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/RULES.md)** – Describes the scoring methodology and priority system.
- **[`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md)** – Maps the priority list to specific route IDs and explains tie-breaking semantics.

## Practical Routing Examples

The following scenarios demonstrate how the keyword matching system resolves real-world queries:

**Scenario 1: APK Analysis Request**
Input: *"I need to decompile an APK and bypass its certificate pinning"*
- **Matching Route**: R1 (APK reverse)
- **Reasoning**: The `must` regex matches "apk", "decompile", and "certificate pinning". No `exclude` patterns triggered. R1 scores 1 point and wins due to high specificity in the priority list.

**Scenario 2: iOS Jailbreak Request**
Input: *"How can I jailbreak an iPhone and dump its memory?"*
- **Matching Route**: R2 (Mobile reverse)
- **Reasoning**: The `must` pattern "jailbreak" matches, and the `mustAll` array confirms presence of "iphone". Both conditions satisfied, awarding R2 the point.

**Scenario 3: Network Pentest Request**
Input: *"I want to run a Nmap scan on a target network"*
- **Matching Route**: R11 (Pentest tools)
- **Reasoning**: The `must` regex includes "nmap". No higher-priority routes claim this keyword, so R11 receives the point and handles the request.

## Summary

- The **keyword matching system** in reverse-skill evaluates user input against regex rules defined in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json).
- Routes accumulate **one point per matching rule**, with the highest score winning the routing decision.
- **Tie-breaking** relies on the `priority` array, where earlier entries beat later ones.
- **Complex logic** supports conjunction (`mustAll`) and negation (`exclude`) for precise matching.
- The system **falls back to R0** (General reverse-engineering) when no keywords match.
- Execution is handled by **`skills/scripts/master-route.ps1`** (and its shell counterpart), which processes the JSON configuration and launches the appropriate [`SKILL.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/SKILL.md) file.

## Frequently Asked Questions

### How does reverse-skill handle ambiguous requests that match multiple rules?

When a request matches rules across multiple routes, each route receives one point per matching rule. The route with the highest point total wins. If two routes tie, the **`priority` list** in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) determines the winner, with routes listed earlier taking precedence. This ensures that specialized skills (like APK reverse) defeat general ones (like general reverse-engineering) when both match the same input.

### What happens if no keywords match the user's request?

If no rules in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) match the input, the system routes to the **default fallback route `R0`** (General reverse-engineering). This route is defined at lines 14-16 of the configuration file and serves as the catch-all handler, ensuring the system always returns a relevant skill module even for novel or vague queries.

### Can I add custom keywords to existing routes?

Yes. To extend an existing route, edit the `must` field in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) to include additional regex patterns. You can also add new rule objects to a route’s array. After modification, the master router scripts (`master-route.ps1` or the `.sh` equivalent) will automatically incorporate your changes on the next execution, as they read the JSON configuration at runtime.

### How does the mustAll field differ from having multiple separate rules?

The **`mustAll`** field requires **all** listed regex patterns to appear in the input simultaneously for a single rule to match, functioning as a logical AND. In contrast, placing multiple separate rule objects under a route creates a logical OR relationship—**any** of those rules can match to contribute a point. Use `mustAll` when a concept requires multiple distinct concepts to be present together (e.g., "jailbreak" AND "iOS"), and use multiple rules when different phrasings indicate the same intent (e.g., "apk" OR "android reverse").