Skip to content

About

Jev-powered skill router for Claude Code — one Noul per skill, sharded in parallel, typed probabilities code can act on

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

jev-skill-router

Per-turn skill routing for Claude Code. A Jev-powered router that scores every skill against every prompt, turning the model's hidden "should I use this skill?" judgment call into probabilities that code can act on.

Demo · Install · What it guarantees · What the experiment found · Who it's for · How it works · Everyday use · Configuration · Results · Docs

The recorded demo: one prompt, run as a plain coding agent and with jev-skill-router

Open the recorded demo → Real Jev runs over a real 51-skill catalog, replayed in the browser. No key needed.

Install

Note

Requires Claude Code, Node 20.12+ on your PATH, and a TypeSafe API key.

To install, run:

claude /plugin marketplace add abgregs/jev-skill-router
claude /plugin install jev-skill-router@abgregs

In the Claude Code desktop app or an already open Claude Code session, run:

/plugin marketplace add abgregs/jev-skill-router
/plugin install jev-skill-router@abgregs

Enter your TypeSafe key when Claude Code asks; it's kept in your system's credential store. From then on, every prompt is routed before the model sees it.

Tip

Cost: one Noul per routed skill per prompt (51 skills = 51 Nouls). Excluded skills are never judged and cost nothing. The router is not a cost or latency saver: in a paired multi-turn A/B on opus it loaded more skill text and spent more time and money than stock selection. What it buys is coverage and control (see Results).

CLI install, the key lookup order, uninstalling, and local development: install guide.

What it is

A working Claude Code plugin, and an experiment in using a judgment model as the control plane for skill selection. The plugin routes every prompt. The experiment asks what changes when that decision is made by scored judgments instead of by the model in the session. The findings are as much the point as the tool.

What it guarantees

  • The decision doesn't depend on the session model. The same prompt and catalog produced the same invoke list on fable, sonnet, opus, and haiku. In our runs, identical requests returned scores that differed by about 0.01, so a skill sitting on a cut can flicker: the decision is reproducible to that floor, not deterministic. What the model then does with the verdict still varies by model.
  • Every decision is visible. Every skill is scored on every turn. In a session you see one line per routed turn: what was invoked, what was suggested, how many skills were judged, and how long it took. The scores themselves come from the CLI: jev-skill-router route prints every skill's probability for any prompt, so a skill that should have fired can be shown its number. Set log in .skillrouter.json and every turn's scores are written to a session log as well (recording scores).
  • Every description is read, at any catalog size. Claude Code's skill listing has a budget, a fraction of the context window set by one dial. Past it the listing keeps every name but drops descriptions, least-used first, so for those skills the model is choosing from a name alone, and nothing tells you which ones (Claude Code skills docs). The router judges every routed skill's full description in parallel: 51 skills in 121–270ms, 1,064 in about half a second. Spend is one Noul per skill per prompt, so it grows with the catalog.
  • Control is per prompt, in code. Thresholds, an invoke band and a suggest band, exclude, alwaysAllow, and a gate that holds the model to the verdict, in place of per-skill switches set once.

What the experiment found

Recorded runs grade the judge alone; development runs put a session model in the loop (the tiers).

  • Frontier models skip workflow skills. In a paired multi-turn A/B on opus, the router's only hit advantage, 18/18 to 14/18, was git-commit and git-create-pr; opus did the commit with raw git in two of three sessions. Task skills it found on its own. Development run.
  • Descriptions are the routing surface, and hierarchies fall out of them. The same orchestrator scored 0.09 on a narrow build and 0.97 on a holistic review (finding 0001). Recorded runs.
  • Invoke and suggest are different speech acts. Models load a commanded list and consult a suggested one (finding 0003). Development.
  • Single-turn evals miss the failure that matters. Topic switches mid-session broke the judge until its input was reframed, and only a multi-turn bench caught it (finding 0004). Development.
  • The verdict is a snapshot, so the gate asks before it denies. A task reveals needs the prompt never named, and a hard gate turned judge misses into session losses by refusing the model's own correct reach. The gate now asks Jev about any off-list call and allows at 0.5: a discovered PDF load passed at 0.96, an unrelated Swift skill was kept out at 0.03 (finding 0005). Development.
  • Claude Code's skill listing is a lossy dial. By default the listing is budgeted at 1% of the context window; past that, descriptions are dropped least-invoked first, which removes the text selection depends on, and which skills lose it depends on your history. The router reads every description every turn (finding 0006). Documented behavior, contrasted with recorded runs.
  • The router matters most where the model is weakest. On the same prompt, haiku loaded no skill unrouted and the right one when routed, while three stronger models found it either way (cross-model probes). One run per model. Development.
  • It is not a cost or latency saver. About 0.3s and one Noul per skill per turn, and the model loads and does more with the skills it is handed (bench results). Development.
  • Judgment-model lessons. Nouls over a Choice for multi-select and lossless sharding, the noise floor, context rot from unrelated state, and a two-sided question for "go" turns (how routing works).

Who it's for

  • Skill authors: see how a skill scores against real prompts and where it collides with its siblings (route, doctor).
  • Large-catalog maintainers: proof every skill was judged on its full description every turn, with no listing budget to tune or to truncate silently, and any skill's score for any prompt on demand.
  • Teams with process mandates: workflow skills that standing instructions require fire instead of being skipped.
  • People building or evaluating tool selection: the methodology findings above.
  • Developers curious about Jev: a worked control-plane pattern in a real harness.

Trade-offs. It adds cost and latency rather than removing them. Overlapping catalogs co-invoke, which the doctor exists to clean up. The gate fails open and is not a security boundary, and enforcement ended up advisory: each time the gate denied hard it cost more than it saved, so it now advises, logs, and asks at the edge (finding 0005). It runs only in Claude Code. And a frontier model on a small catalog already finds its task skills without help.

How it works

Before the model sees your prompt, Jev scores every skill against it. Plain-code thresholds turn those scores into a verdict that is added to the model's context, and a gate holds the model to it.

  • What Jev reads: your prompt, with up to ~8,000 characters of conversation as background, against each skill's name and description. Not CLAUDE.md, open files, or tool output. A bare "go" is judged against the plan it approves.
  • Two bands: skills at 0.85 or above are invoked (up to 6); skills from 0.80 to 0.85 are suggested by name for the model to use if a need shows up.
  • The gate: holds the model to the turn's list, with two ways through for a skill that isn't on it: a skill the model already loaded names it in its SKILL.md, or Jev judges the call useful for the work when the model makes it. It fails open: a relevance filter, not a lock.
  • Fast at any size: every skill is judged in parallel. Recorded runs: 51 skills in 121–270ms, 1,064 in about half a second.

Details: how routing works · Claude Code hooks.

Everyday use

I want to… Do this
Make sure a skill runs this turn Slash-invoke it: /git-commit.
Keep a skill callable every turn (e.g. one your CLAUDE.md requires) Add it to alwaysAllow.
Never route a skill Add it to exclude. It's never judged and costs nothing.
Get fewer or more skills per prompt Raise or lower threshold (0.85), or change maxSelected (6).
Find duplicate or overlapping skills Run the catalog doctor.
See what the router would pick jev-skill-router route "<prompt>" (CLI).

Important

Asking for a skill in words ("use the git-commit skill") doesn't guarantee it runs. It can raise the skill's score, but only a slash command or alwaysAllow gets it past the gate without a judgment.

Configuration

Routing works with no config file. To tune it, write .skillrouter.json in the folder you start Claude Code from, or ~/.skillrouter.json for every project.

{
  "threshold": 0.85,
  "exclude": ["debrief"],
  "alwaysAllow": ["git-commit", "anthropic-skills:pdf"]
}
Key Default Purpose
threshold 0.85 Invoke bar. Set 0.9 for precision.
suggestFloor 0.8 Bottom of the suggest band.
maxSelected 6 Most skills invoked per prompt.
exclude [] Skills removed from routing.
alwaysAllow [] Skills the gate always lets through.

Warning

The first file found wins and files don't merge: a project .skillrouter.json replaces your home file, lists included.

All keys, file precedence, and the config command: configuration.

Results

Important

These are the only routing-quality numbers the repo claims: 44 recorded runs on the released router, captured 2026-10-01 on a real 51-skill catalog, judged on the same inputs the plugin sends.

Check Result
Needed skills invoked (11 tasks) 13 / 13
User-only skill left alone 1 / 1
Off-catalog asks with no stand-in invoked 5 / 5
Prompts needing no skill with nothing invoked 27 / 27
  • The top-scoring skill landed at 0.97–0.99 on every task; on the off-catalog asks, the best wrong candidate topped out between 0.29 and 0.61.
  • Small, single-turn, and labeled by us: evidence, not a benchmark.
  • Not a cost or latency saver. A paired multi-turn A/B on the released bundles (opus, three six-turn sessions per arm, every turn run to completion) found the router hit 18/18 expected skills to stock's 14/18, with the gap entirely the workflow skills the model skips on its own, and neither arm loading a skill needlessly. It also loaded 12k–40k more bytes of SKILL.md per session and cost $0.05–$0.45 and 11–72s more. Development tier, not a claim: bench results.

Full breakdown and caveats: results.

Documentation

Section Pages
Guide Install · Configuration · Claude Code hooks · CLI · Catalog doctor
Architecture How routing works · Repo layout
Evaluation Results · Running evals
Findings All findings

Findings

# Finding Evidence
0001 Skill hierarchies are read from descriptions alone; skills sharing the ask co-invoke. Recorded runs
0002 Co-invoking overlapping skills improved output. Development
0003 Models follow invoke wholesale, to a degree that varies by model, and consult suggest when needed. Development
0004 Weight the current request over the transcript; bench multi-turn. Development
0005 The verdict is a snapshot; the gate asks Jev before denying an off-list call. Development
0006 Claude Code's skill listing is budgeted and trimmed by history; the router reads every description. Claude Code docs, recorded runs

Development

Run it from a clone
git clone https://github.com/abgregs/jev-skill-router
cd jev-skill-router
npm install && npm link    # puts jev-skill-router on your PATH

npm run inspect     # pure-code smoke test (mock judge, no key)
npm run typecheck
npm run demo        # recorded web demo, no key

More scripts: CLI · running evals · repo layout.

License

MIT

About

Jev-powered skill router for Claude Code — one Noul per skill, sharded in parallel, typed probabilities code can act on

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages