How to Configure Custom Routing Rules in routing.json for New Skill Types

To register a new skill type, add a route entry to skills/config/routing.json specifying the label, skill path, and keyword matching rules, then insert the route ID into the priority array to control selection precedence.

The reverse-skill repository uses a declarative routing system where the skills/config/routing.json file serves as the single source of truth for all skill dispatching logic. This JSON configuration defines which skill handles each user query through regex-based keyword matching and a priority-ordered resolution mechanism. Unlike code-based routing systems, no script modifications are required—simply updating this configuration file automatically propagates changes across all routing components.

Understanding the routing.json Structure

The routing.json file contains two top-level sections that work together to determine skill selection:

  • routes — A mapping of route identifiers (e.g., R1, R2, R41) to route definitions containing the skill metadata and matching rules
  • priority — An ordered array of route identifiers where earlier positions receive higher precedence when multiple routes match

Each route entry in routes follows this schema:

Field Type Description
label string Human-readable description of the skill purpose
skill string Relative path to the skill's markdown documentation file
keywords array Matching rules that determine when this route applies
priority (implied) integer Derived from position in the global priority array

Keyword Matching Rules

The keywords array contains objects that define query matching through regular expressions. The routing engine evaluates these rules to score each route's relevance.

Available Matching Operators

  • must — Required regex pattern that must appear in the query for this keyword object to match
  • exclude (optional) — Disqualifying regex; if this pattern appears, the keyword object fails to match regardless of must
  • mustAll (optional) — Array of additional regex patterns that must all match alongside must

Multiple keyword objects in the keywords array are evaluated independently—any matching keyword object contributes to the route's score.

Step-by-Step: Adding a New Skill Route

Step 1: Create Your Skill File

Before configuring routing, ensure your skill documentation exists at skills/<your-skill>/SKILL.md. The skill field in your route will reference this path relative to skills/.

Step 2: Define the Route Entry

Add a new unique route identifier to the routes object following the established pattern in routing.json. Route IDs use the format R followed by a number (e.g., R41, R42).

Example route for an IoT reverse engineering skill:

"R41": {
  "label": "IoT / Embedded reverse",
  "skill": "iot-reverse/SKILL.md",
  "keywords": [
    {
      "must": "iot|embedded|firmware|device|microcontroller|arm|mcu|esp32|esp8266",
      "note": "All IoT-related queries should match this route"
    }
  ]
}

Step 3: Set Priority Position

Insert your new route ID into the priority array at the desired precedence level. Routes earlier in the array win ties when multiple routes achieve equal match scores.

"priority": [
  "R4", "R1", "R2", "R3", "R30", "R31", "R33", "R5", "R9", "R21",
  "R22", "R6", "R7", "R8", "R34", "R28", "R17", "R16", "R18", "R24",
  "R37", "R23", "R35", "R25", "R36", "R29", "R38", "R32", "R26", "R27",
  "R10", "R11", "R12", "R13", "R14", "R15", "R19", "R40", "R20", "R39",
  "R0", "R41"
]

Placing R41 at the end gives it lowest priority; move it earlier to override more generic routes.

Advanced Routing Patterns

Combined Requirements with mustAll

For skills requiring multiple distinct concepts, use mustAll to ensure all patterns appear:

"R42": {
  "label": "JTAG Firmware Extraction",
  "skill": "jtag-firmware/SKILL.md",
  "keywords": [
    {
      "must": "jtag",
      "mustAll": ["firmware", "extract|dump"],
      "note": "Ensures the query explicitly mentions JTAG and firmware extraction"
    }
  ]
}

This route only matches when the query contains "jtag" AND "firmware" AND either "extract" or "dump".

Negative Exclusion Patterns

Prevent false positives by excluding ambiguous terms:

"R43": {
  "label": "Cloud Function Reverse",
  "skill": "cloud-function/SKILL.md",
  "keywords": [
    {
      "must": "lambda|function|cloud",
      "exclude": "aws|gcp|azure",
      "note": "Only match custom-written cloud functions, not managed services"
    }
  ]
}

The exclude pattern prevents matching generic cloud provider queries.

Validation and Testing

Three PowerShell scripts automatically consume routing.json and verify its integrity:

  • skills/scripts/verify-routing-coherence.ps1 — Validates that routing.json matches generated documentation
  • skills/scripts/test-routing.ps1 — Executes 162 test cases to ensure new routes don't break existing logic
  • skills/scripts/master-route.ps1 — The production routing engine that reads this configuration

Run these scripts after any routing.json modification to catch syntax errors or priority conflicts before deployment.


# Run full routing test suite

.\skills\scripts\test-routing.ps1

# Verify documentation coherence

.\skills\scripts\verify-routing-coherence.ps1

Summary

  • skills/config/routing.json is the single configuration file controlling all skill routing
  • Route entries require a unique ID, label, skill path, and keyword matching rules
  • Keyword rules support must, exclude, and mustAll regex operators for precise matching
  • Priority array determines selection precedence—position earlier for higher priority
  • No code changes needed—the configuration automatically propagates to validation and runtime scripts

Frequently Asked Questions

What happens if two routes match the same query with equal scores?

The routing engine consults the priority array and selects whichever matching route appears first. This deterministic tie-breaking ensures consistent behavior without requiring arbitrary tie-breaker logic in code.

Can I use case-insensitive matching in my regex patterns?

Yes—all regex evaluation in the routing engine is case-insensitive by default, so patterns like iot|embedded match "IoT", "IOT", "iot", and mixed-case variants without requiring explicit case flags.

How do I test my new route without running the full test suite?

Create a minimal test case in skills/scripts/test-routing.ps1 or execute the routing logic directly against your query string using master-route.ps1 with diagnostic output enabled. The test framework will automatically pick up new routes from routing.json for evaluation.

Is there a limit to how many keyword objects a route can have?

No explicit limit exists in the schema, though practical considerations suggest keeping routes focused. Multiple keyword objects within a route are ORed together—any matching keyword contributes to the score—allowing you to cover synonymous concepts without excessive regex complexity in a single pattern.

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 →