Skip to content

Make bundled skill descriptions router-precise (stop false-positive skill loading) - #48780

Draft
John-Lussier wants to merge 1 commit into
NousResearch:mainfrom
John-Lussier:fix/skill-description-router-precision
Draft

Make bundled skill descriptions router-precise (stop false-positive skill loading)#48780
John-Lussier wants to merge 1 commit into
NousResearch:mainfrom
John-Lussier:fix/skill-description-router-precision

Conversation

@John-Lussier

Copy link
Copy Markdown
Contributor

Make bundled skill descriptions router-precise (stop false‑positive skill loading)

TL;DR

A skill's description is the only signal the router sees at Level 0 (skills_list() returns {name, description, category}). Today many bundled descriptions are written as human taglines ("TDD: tests before code", "Delegate coding to OpenAI Codex CLI") optimized for a catalog listing — not as routing predicates. The result is false‑positive loading: the model pulls a skill because the words matched, not because the task did.

This PR rewrites 15 bundled descriptions (and one When to Use block) to behave as routing logic: state the precise trigger, then exclude the look‑alikes. No behavior, code, or skill body logic changes beyond TDD's "When to Use" wording.

The bug, concretely

A kernel/optimization goal prompt — dense with the words test, gate, verify, PASS, prove, correctness (those are an external benchmark harness and acceptance gates, with zero unit‑testing intent) — caused the test-driven-development skill to load. The prompt contained no literal TDD trigger ("red‑green", "tests before code" — zero occurrences). The skill loaded purely on keyword density against a greedy description plus a When to Use: **Always** block.

That is not a one‑off. It is the predictable behavior of a description that advertises itself as universally applicable.

Root cause: descriptions are routing predicates, not marketing copy

The progressive‑disclosure design is good — but it puts 100% of the routing burden on one sentence. A description therefore has two jobs, and most only do the first:

  1. Tell a human what the skill is (every current description does this).
  2. Tell the router when NOT to fire (almost none do this).

Job 2 is the one that prevents misfires, and it is exactly what catalog‑style taglines omit.

Three anti‑patterns this PR fixes

1. Greedy / "Always" triggers. Descriptions that claim broad applicability ("tests before code", "validate an idea", "find bugs") match generic task vocabulary (test / gate / verify / prove / experiment / validate / optimize / debug / build) that appears in countless unrelated prompts.

2. Bare‑proper‑noun collisions. "Delegate coding to Codex CLI" fires whenever the token "Codex" appears — including when Codex is named as a collaborator or workspace owner, not as a tool you want to invoke. Same for Claude, OpenCode, "Hermes Agent" (the runtime), MCP, etc. Any multi‑agent workspace mentions these names constantly.

3. Umbrella/index magnets. (Mostly in user‑space skills, but called out here for the authoring guide.) Descriptions that enumerate many tools out‑compete the specific sibling skill that should actually win.

The fix pattern, applied uniformly: <precise trigger> + "Not for … / Do NOT load when …" <named look‑alikes>.


The 15 changes, documented

Pattern 1 — greedy / generic‑vocabulary triggers

test-driven-development — the skill that triggered the investigation.

  • before: "TDD: enforce RED-GREEN-REFACTOR, tests before code." + When to Use → **Always**: New features, Bug fixes, Refactoring, Behavior changes
  • after: scoped to "writing/changing source code that has (or should have) a test suite" and explicitly "do NOT match on test/gate/verify/PASS/prove/correctness when they refer to external checkers, submission modes, or acceptance gates." The body When to Use block drops the unconditional Always and adds a "Do NOT load for …" section (research/optimization loops; prompts where 'test'/'gate' mean an external checker).
  • why: "Always" is an open invitation to misfire on any code‑adjacent prompt. The negative clause is what actually stops the keyword false‑positive.

spike

  • before: "Throwaway experiments to validate an idea before build."
  • after: "Time-boxed throwaway CODE spike to answer one specific technical feasibility question before building a feature. Not for research/optimization loops, benchmark or kernel tuning, or any context where experiment/validate/prove refers to offline gates or external checkers rather than throwaway exploratory code."
  • why: "experiments to validate an idea" matches every research/optimization loop on Earth. Anchored to throwaway code + excluded the offline‑gate meaning.

systematic-debugging

  • before: "4-phase root cause debugging: understand bugs before fixing."
  • after: scoped to "a specific, reproducible software defect or incorrect behavior … Load only when chasing a concrete failure, not for performance/optimization or research loops, or green‑field design where nothing is broken yet."
  • why: "understand bugs before fixing" fires on any prompt containing "fix" or "bug". Bound it to a reproducible defect.

requesting-code-review

  • before: "Pre-commit review: security scan, quality gates, auto-fix."
  • after: "Review a concrete code diff you are about to commit … Load only to review changed source files, not when gate/verify/quality refer to CI, benchmark, or acceptance gates or a research loop's offline checker."
  • why: "quality gates" collides with the pervasive "gate" vocabulary of CI/benchmark pipelines.

simplify-code

  • before: "Parallel 3-agent cleanup of recent code changes."
  • after: "Load only when the user explicitly asks to simplify or clean up their own recent code diff (says simplify, /simplify, clean up my changes) … Not for general code review, bug hunting, or any prompt that merely mentions agents or code."
  • why: vague on when; "agents" + "code" are collision magnets. Made the trigger an explicit user request.

research-paper-writing

  • before: "Write ML papers for NeurIPS/ICML/ICLR: design→submit."
  • after: "End-to-end authoring of a formal academic ML paper for a venue (NeurIPS/ICML/ICLR/ACL): experiment design, LaTeX, figures, citations, submission. Not for internal research notes, deep-read write-ups, digests, or leaderboard/benchmark submissions."
  • why: "design→submit" + "research" pulled it into any research‑flavored or "submit" prompt. Bound to a formal venue paper.

dogfood

  • before: "Exploratory QA of web apps: find bugs, evidence, reports."
  • after: "Use to manually exercise a running web app in a real browser to hunt UI/UX and functional bugs, capturing console errors and screenshots into a QA report. Not for unit/integration test writing or code review."
  • why: "QA / find bugs / testing" collided with plain "test my code". Anchored to a running web app in a browser.

Pattern 2 — bare‑proper‑noun collisions

codex, claude-code, opencode (the coding‑agent delegators)

  • before (pattern): "Delegate coding to <X> CLI (features, PRs)."
  • after (pattern): "Use when you want to actively hand a coding task to the <X> CLI tool … Do NOT load merely because <X> is mentioned as a collaborator, agent, or workspace owner."
  • why: these fire on the name alone. In any multi‑agent setup the names Codex/Claude/OpenCode appear constantly as participants, not as invocation targets. The negative clause distinguishes "use the tool" from "the tool was named."

hermes-agent

  • before: "Configure, extend, or contribute to Hermes Agent."
  • after: "Load when working on the Hermes Agent framework itself: editing its config (hermes.toml, profiles, providers), extending its source, or contributing code to the repo. Not when Hermes Agent is merely mentioned as the runtime executing some other task."
  • why: "Hermes Agent" is the runtime's own name — it appears in virtually every session. Scoped to working on the framework.

Pattern 3 — under‑specified, sibling‑overlapping, or malformed

claude-design

  • before: Design one-off HTML artifacts (landing, deck, prototype). (also: unquoted scalar)
  • after: "Hand-code a from-scratch single-file HTML/CSS design artifact … when no brand or token system is dictated. Not for known-brand looks (use popular-web-designs) or design-token spec files (use design-md)."
  • why: "design … HTML … prototype" is a magnet that out‑competes its concrete siblings. Added explicit hand‑offs to popular-web-designs / design-md.

obsidian

  • before: Read, search, create, and edit notes in the Obsidian vault. (unquoted)
  • after: "Obsidian vault file operations … Not for generic note-taking or to-do apps that do not name Obsidian."
  • why: led with generic "notes" verbs; now anchors on the Obsidian vault.

kanban-orchestrator, kanban-worker

  • before: long prose descriptions that contained embedded " double‑quotes inside an unquoted YAML scalar (a latent parser hazard) and led with generic "orchestrator / routing work / decomposition" / "pitfalls, examples, edge cases".
  • after: clean one‑line quoted scalars, anchored to "running as a Hermes Kanban orchestrator/worker", with Not for generic task planning / multi-agent design / general troubleshooting.
  • why: fixes both an over‑trigger (generic orchestration/troubleshooting vocab) and a real YAML correctness smell.

What this PR deliberately does NOT do

  • No code, no behavior, no body logic changes — except TDD's When to Use block, which reinforced the misfire.
  • No new frontmatter fields. Everything here works with the existing description field and current router.
  • No touching of correctly‑scoped skills. ~95 other bundled descriptions were reviewed and left alone because they are already tool/domain‑bound (e.g. apple-reminders, himalaya, arxiv, openhue). Tightening good descriptions would only add noise.

Opinionated recommendations beyond this PR

  1. Document the contract in the skill‑authoring guide: a description is a routing predicate. Require (a) a concrete trigger and (b) at least one negative boundary for any skill whose domain words overlap generic task vocabulary or a proper noun. I'd add a short "writing router‑safe descriptions" section with the three anti‑patterns above.
  2. Consider a first‑class do_not_load_when / not_for field surfaced at Level 0 alongside description. Negative scoping is doing the heavy lifting here; making it a structured field (instead of a sentence convention) would make it consistent and lintable.
  3. Add a lightweight description linter to CI: flag Always/any, bare‑proper‑noun‑only descriptions, embedded " in unquoted scalars, and descriptions with no negative boundary in collision‑prone categories.
  4. Revisit umbrella vs. granular duplication. Several umbrella/index skills fully overlap their leaf skills and act as router magnets; either make umbrellas explicitly defer ("prefer the concrete sibling") or retire them. (Most live in user‑space, so out of scope for this PR, but the pattern is worth a stance upstream.)

Validation

  • All 15 changed descriptions are single‑line, balanced double‑quoted YAML scalars with no embedded ".
  • A frontmatter sweep over all bundled SKILL.md files reports no malformed frontmatter and no broken description scalars after the change.

🤖 Generated with Claude Code

@alt-glitch alt-glitch added type/docs Documentation improvements P3 Low — cosmetic, nice to have tool/skills Skills system (list, view, manage) labels Jun 19, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #32361 (tightens skill descriptions for prompt budget). Different goal/mechanism — that PR trims descriptions for token economy; this one rewrites 15 bundled descriptions as routing predicates (precise trigger + negative "Not for ..." boundaries) to stop false-positive skill loading. Docs/content-only, no code or behavior changes.

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

Verdict: Approved

Clean targeted fix. The router description update is well-scoped (single file, 23 additions) and directly addresses false-positive skill loading by making bundled skill descriptions more precise. No security, performance, or code quality concerns.


Reviewed by Hermes Agent

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for isolating a real routing-quality concern. The current skill index does use descriptions (agent/prompt_builder.py:1392), but this patch needs a re-scope before it can deliver the claimed boundary behavior.

Problems

  • Every replacement description exceeds the hard 60-character skill standard (AGENTS.md:882-900). The actual system-prompt path truncates descriptions to 57 characters plus ... (agent/skill_utils.py:771-779), so the proposed "Not for" clauses do not reach the Level-0 index.
  • Two changed files no longer exist on main: skills/devops/kanban-orchestrator/SKILL.md and skills/devops/kanban-worker/SKILL.md. They were removed when their guidance was folded into injected KANBAN_GUIDANCE by 84e1d31e5.

Suggested changes

  • Recast the remaining descriptions as router-focused, single-sentence descriptions of 60 characters or fewer; keep the strongest trigger in that budget.
  • Remove the obsolete Kanban file edits and reassess any desired change against current KANBAN_GUIDANCE.

This is an automated hermes-sweeper review.

@@ -1,6 +1,6 @@
---
name: test-driven-development
description: "TDD: enforce RED-GREEN-REFACTOR, tests before code."
description: "Use ONLY when writing or changing application/library source code that has (or should have) a unit/integration test suite: enforce RED-GREEN-REFACTOR, write a failing test before the code. Do NOT load for research/optimization loops, performance/benchmark tuning, data/ML experiments, prototypes, or config — and do NOT match on the words test/tests/gate/verify/verified/PASS/prove/correctness when they refer to external checkers, submission modes, or acceptance gates rather than a code-level test suite."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description exceeds the hard 60-character skill limit (AGENTS.md:882-900). More importantly, the system-prompt index truncates descriptions after 57 characters (agent/skill_utils.py:771-779), so the negative routing boundary later in this sentence will not be visible there. Please reduce this to one router-focused sentence within 60 characters.

@teknium1 teknium1 added the sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit label Jul 14, 2026
Rewrite the 13 bundled skill descriptions to fit the hard 60-character
project standard (AGENTS.md). Keep the strongest trigger in the first
~57 characters so the Level-0 index sees the router predicate, not the
negative boundary. Remove the obsolete Kanban-orchestrator and
Kanban-worker edits; those files no longer exist on main and their
guidance lives in injected KANBAN_GUIDANCE.

Also tighten TDD's When to Use block so it explicitly lists the
external-checker false-positive class that caused the original misfire.
@John-Lussier
John-Lussier force-pushed the fix/skill-description-router-precision branch from d122881 to b8ae879 Compare July 17, 2026 00:01
@John-Lussier

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and addressed the review feedback in b8ae87904:

  • Rewrote all 13 non-Kanban skill descriptions to fit the hard 60-character project standard (trigger in the first ~57 chars so the Level-0 index actually sees the predicate).
  • Dropped the skills/devops/kanban-orchestrator/SKILL.md and skills/devops/kanban-worker/SKILL.md edits; those files no longer exist on main and their guidance is injected as KANBAN_GUIDANCE.
  • Kept the expanded TDD "When to Use" block, including the explicit external-checker false-positive class that caused the original misfire.

git diff --check passes. Existing skill discovery tests should exercise these descriptions; happy to add a length-capped regression if you want one.

teknium1 added a commit that referenced this pull request Jul 24, 2026
… budget

Every SKILL.md description over 60 chars was silently truncated to
57 chars + '...' in the system-prompt skill index
(extract_skill_description, agent/skill_utils.py), destroying the
routing signal for 69 of 179 skills — some descriptions ran to
1,005 chars.

Rewrites follow the authoring standard: <=60 chars, one sentence,
ends with a period, trigger front-loaded, no marketing words, no
skill-name repetition. Excess detail already lives in each skill's
body.

Includes the touchdesigner-mcp trim from PR #32361 (credit:
@JeliTron) and aligns with the router-precision direction of PR
#48780 (@John-Lussier). Docs catalogs + per-skill pages regenerated
via website/scripts/generate-skill-docs.py.

Co-authored-by: JeliTron <287797501+JeliTron@users.noreply.github.com>
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
… budget

Every SKILL.md description over 60 chars was silently truncated to
57 chars + '...' in the system-prompt skill index
(extract_skill_description, agent/skill_utils.py), destroying the
routing signal for 69 of 179 skills — some descriptions ran to
1,005 chars.

Rewrites follow the authoring standard: <=60 chars, one sentence,
ends with a period, trigger front-loaded, no marketing words, no
skill-name repetition. Excess detail already lives in each skill's
body.

Includes the touchdesigner-mcp trim from PR NousResearch#32361 (credit:
@JeliTron) and aligns with the router-precision direction of PR
NousResearch#48780 (@John-Lussier). Docs catalogs + per-skill pages regenerated
via website/scripts/generate-skill-docs.py.

Co-authored-by: JeliTron <287797501+JeliTron@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low — cosmetic, nice to have sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit tool/skills Skills system (list, view, manage) type/docs Documentation improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants