Hermes plugin's mode filter silently drops rule bullets that start with a mode word (pre-#571 regex)
_filter_skill_body_for_mode in the Hermes plugin (__init__.py) is a Python
port of filterSkillBodyForMode in hooks/ponytail-instructions.js. Both trim
the shared skills/ponytail/SKILL.md body down to the active intensity, and
every host adapter is supposed to see the same filtered text for a given mode
(see docs/agent-portability.md).
#571 fixed a landmine in the JS filter: its worked-example detector matched
any bullet shaped - label: text and treated it as a mode-specific example
whenever the label happened to normalize to a mode name, silently dropping it
in every other mode. The fix required the worked-example bullet to be quoted
(- lite: "..."), since that's the only shape real examples take; an ordinary
rule bullet that happens to start with, say, "Full:" is prose and must survive
verbatim.
The Hermes/Python filter still has the pre-#571 regex and reproduces the exact bug:
import importlib.util
spec = importlib.util.spec_from_file_location('m', '__init__.py')
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
body = '## Rules\n- Full: real rule text about something unrelated to intensity.\n- Deletion over addition.'
print(m._filter_skill_body_for_mode(body, 'ultra'))
## Rules
- Deletion over addition.
The "Full:" rule silently disappears in ultra mode, with no error. Same
input through the JS filter keeps it. Any Hermes Agent user is exposed to
this the moment a rule bullet in SKILL.md happens to start with a mode word
— which is exactly the scenario #571 called out as a landmine for a future
edit, just on the adapter that didn't get the fix.
There's also a second, smaller divergence in the same function: Python's
str.splitlines() drops the body's trailing newline on rejoin, while the JS
filter's split(/\r?\n/) preserves it, so the two adapters don't even agree
on whitespace at the end of the injected context.
Both bugs live in the one function every Hermes-integrated agent calls before
every LLM turn (pre_llm_call -> build_injected_context ->
_filter_skill_body_for_mode), so they affect the actual instructions an
agent sees, not just test fixtures.
Source: DietrichGebert/ponytail