# How to Migrate from an Older Routing Version to the Latest routing.json Schema in reverse-skill

> Easily migrate to the latest routing.json schema in reverse-skill. Learn to add meta blocks, convert keywords, set priority, and validate your changes with PowerShell scripts.

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

---

**Migrating to the latest routing.json schema in the reverse-skill repository requires adding a top-level `meta` block with `fallbackId`, converting legacy string-based keywords into structured objects, populating a `priority` array that defines route precedence, and validating the changes using the PowerShell scripts located in `skills/scripts/`.**

The `reverse-skill` project maintains a single source of truth for task routing at [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json). Legacy configurations that predate `schemaVersion: "1.0"` use a flat structure with simple keyword strings, while the current schema introduces a comprehensive `meta` section, structured keyword objects, and explicit priority ordering that the routing engine and CI pipeline depend on.

## Identify Legacy Schema Characteristics

Before upgrading, confirm you are working with an outdated schema. Legacy routing.json files typically exhibit these traits:

- **No `meta` block** at the root level.
- **`schemaVersion` is missing** or set to an older value like `"0.1"`.
- **Keywords are flat strings** inside an array (e.g., `"keywords": ["apk", "decompile"]`).
- **No `priority` array**, meaning the resolution order was implicit or hard-coded in scripts.

The current version (`schemaVersion: "1.0"`) wraps routes in a `routes` object and requires every keyword to be an object with fields like `must`, `exclude`, `mustAll`, or `note`.

## Update the Top-Level Structure

Begin the migration by restructuring the root of your JSON file to match the current specification.

### Add the schemaVersion and meta Block

Insert the following mandatory top-level keys above your route definitions:

```json
{
  "schemaVersion": "1.0",
  "meta": {
    "description": "reverse-skill task routing (single source of truth).",
    "fallbackId": "R0",
    "scoring": "exact-keyword-match-3pts, partial-match-1pt",
    "maintainers": [
      "skills/MASTER-ROUTING.md 中的优先级表与此文件 priority 字段一一对应",
      "skills/scripts/verify-routing-coherence.ps1 会校验二者一致性"
    ]
  },
  "routes": { },
  "priority": [ ]
}

```

The `meta` block serves multiple purposes: it documents the fallback route ID used when no match is found, defines the scoring algorithm for the routing engine, and links to the coherence verification script that CI runs automatically.

### Define the fallbackId

Ensure your `fallbackId` points to a valid route ID within your `routes` object. This ID is returned by `skills/scripts/master-route.ps1` when a user hint does not match any defined keywords, preventing null-pointer errors in downstream automation.

## Transform Individual Route Definitions

Once the skeleton is updated, migrate the content of each route from the legacy format to the current object-based structure.

### Convert String Keywords to Structured Objects

Legacy configurations store keywords as simple strings. You must convert each entry into an object where the search term resides in the `must` field. For example, migrate this legacy snippet:

```json
"R1": {
  "label": "APK Decompilation",
  "skill": "skills/apk-decompile",
  "keywords": ["apk", "decompile", "android package"]
}

```

To the current schema:

```json
"R1": {
  "label": "APK Decompilation",
  "skill": "skills/apk-decompile",
  "keywords": [
    { "must": "apk" },
    { "must": "decompile" },
    { "must": "android package" }
  ]
}

```

If your legacy configuration included exclusion logic (e.g., ignoring hints with "ios"), translate those into the `exclude` field:

```json
{ "must": "apk", "exclude": "ios", "note": "exclude iOS mentions" }

```

### Populate the priority Array

The `priority` array dictates precedence when multiple routes match a hint with equal scores. Populate it with all route IDs (`R1`, `R2`, etc.) in descending order of importance:

```json
"priority": ["R2", "R1", "R3", "R0"]

```

This order must align with the logic described in [`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md). The `verify-routing-coherence.ps1` script cross-references this array against the `routes` object to ensure every ID is accounted for and that the sequence matches the project's documented priority table.

## Validate Migration with Built-In Scripts

After editing [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), run the repository's validation toolchain to confirm schema compliance and functional correctness.

First, verify that PowerShell can parse the JSON without syntax errors:

```powershell
Get-Content .\skills\config\routing.json | ConvertFrom-Json | Out-Null

```

Next, test that the routing engine resolves hints correctly using `master-route.ps1`:

```powershell
.\skills\scripts\master-route.ps1 -Hint "apk decompile"

```

A successful migration should return the expected route ID (e.g., `R1`).

Then, check structural coherence between the `priority` array and the `routes` definitions:

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

```

This script validates that every route ID appears in the `priority` list and that all referenced `skill` paths exist on disk.

Finally, execute the full regression suite to ensure no routing logic regressed:

```powershell
.\skills\scripts\test-routing.ps1

```

This script runs 162 test cases; all should pass before you commit the migrated configuration.

## Summary

- **Legacy schemas** lack the `meta` block, use flat keyword strings, and omit the `priority` array.
- **Current schemas** require `schemaVersion: "1.0"`, a `meta` object with `fallbackId`, structured keyword objects with `must`/`exclude` fields, and a populated `priority` list.
- **Migration steps**: update the JSON skeleton, convert keyword strings to objects, define route precedence, and validate using `master-route.ps1`, `verify-routing-coherence.ps1`, and `test-routing.ps1`.
- **Source files**: [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) (configuration), [`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md) (logic documentation), and `skills/scripts/*.ps1` (validation tools).

## Frequently Asked Questions

### What is the current schema version for routing.json in reverse-skill?

The current version is `1.0`, specified in the `schemaVersion` field at the root of [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json). This version introduces the `meta` configuration block and structured keyword objects that were absent in earlier iterations.

### How do I convert old keyword arrays to the new format?

Transform each string in the legacy `keywords` array into an object with a `must` key containing the original string. If you previously had exclusion criteria, add an `exclude` key to the same object. For example, `"android"` becomes `{ "must": "android" }`.

### Why is the priority array required in the latest schema?

The `priority` array serves as the tie-breaker when multiple routes match a hint with identical scores. It ensures deterministic routing behavior and is strictly validated by `skills/scripts/verify-routing-coherence.ps1` to guarantee alignment with the project's documented precedence rules.

### Which PowerShell script validates routing coherence?

Use `skills/scripts/verify-routing-coherence.ps1` to check that every route ID in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) appears in the `priority` array and that all referenced skill directories exist. This script prevents mismatches between the configuration file and the actual filesystem structure.