refactor(curator): point review prompt at existing tools

The LLM review prompt mentioned bespoke `archive_skill` and `pin_skill`
tools that are not registered as model tools. Swap the prompt to rely
on the real surface:

  - skill_manage action=patch  — for patching and consolidation
  - terminal                   — to `mv` skill dirs into .archive/

Also drop `pin` from the model's decision list — pinning is a user
opt-out for `hermes curator pin <skill>`, not something the model
should do autonomously.

Decision list is now: keep / patch / consolidate / archive.

Tests updated: prompt-invariant test now asserts the existing tools
are referenced and that bespoke tool names do NOT appear. New test
prevents `pin` from being re-added as a model decision.
This commit is contained in:
Teknium
2026-04-26 06:13:09 -07:00
parent 9dd59cb637
commit f40ccece11
2 changed files with 56 additions and 19 deletions

View File

@@ -261,28 +261,33 @@ def apply_automatic_transitions(now: Optional[datetime] = None) -> Dict[str, int
CURATOR_REVIEW_PROMPT = (
"You are running as Hermes' background skill CURATOR.\n\n"
"Your job is to maintain the collection of AGENT-CREATED skills. Review "
"each one and decide what to do, using skill_manage and the curator tools.\n\n"
"each candidate below and decide what to do.\n\n"
"Rules — all load-bearing, do not violate:\n"
"1. You MUST NOT touch bundled or hub-installed skills. The candidate list "
"below is already filtered to agent-created skills only.\n"
"2. You MUST NOT delete any skill. Archive (move to .archive/) is the "
"maximum action. Archives are recoverable; deletion is not.\n"
"3. You MUST NOT touch pinned skills. If a skill is pinned, skip it.\n"
"4. Prefer GENERALIZING overlapping skills by patching the better one and "
"archiving the duplicate, rather than leaving two narrow skills in the "
"2. You MUST NOT delete any skill. Archiving (moving the skill's directory "
"into ~/.hermes/skills/.archive/) is the maximum action. Archives are "
"recoverable; deletion is not.\n"
"3. You MUST NOT touch skills shown as pinned=yes. Skip them.\n"
"4. Prefer GENERALIZING overlapping skills by patching the stronger one "
"and archiving the weaker, rather than leaving two narrow skills in the "
"collection.\n\n"
"For each candidate decide one of:\n"
" keep leave as-is (most common default)\n"
" patch — fix stale commands, wrong paths, environment-specific "
"claims that are no longer true. Use skill_manage action=patch.\n"
" consolidate — when two skills overlap, patch the stronger one to "
"absorb the weaker, then archive the weaker via the 'archive_skill' tool.\n"
" archive — if the skill is genuinely obsolete and the sidecar shows "
"it has not been used recently. Use the 'archive_skill' tool.\n"
" pin if the skill is rare but important (low use_count but "
"high value). Use the 'pin_skill' tool.\n\n"
"Start by calling skills_list and then skill_view on any skill you want to "
"consider patching or consolidating. Be conservative — if in doubt, keep. "
"Your toolset:\n"
" - skills_list, skill_viewread the current landscape\n"
" - skill_manage action=patch — fix stale commands, wrong paths, or "
"merge two overlapping skills by broadening the stronger one\n"
" - terminal — move a skill directory into the archive, "
"e.g. mv ~/.hermes/skills/<skill-dir> ~/.hermes/skills/.archive/\n\n"
"For each candidate, decide one of:\n"
" keep — leave as-is (most common default; don't over-curate)\n"
" patchskill_manage action=patch to fix stale commands, wrong "
"paths, or env-specific claims that are no longer true\n"
" consolidate — two skills overlap: patch the stronger one to absorb "
"the weaker (skill_manage), then mv the weaker directory to .archive/\n"
" archive — the skill is genuinely obsolete and has not been used "
"recently: mv its directory to ~/.hermes/skills/.archive/\n\n"
"Start by calling skills_list and skill_view on anything you consider "
"patching or consolidating. Be conservative — if in doubt, keep. "
"When you are done, write a one-sentence summary of what you changed."
)

View File

@@ -359,5 +359,37 @@ def test_curator_review_prompt_has_invariants():
assert "delete" in CURATOR_REVIEW_PROMPT.lower()
assert "pinned" in CURATOR_REVIEW_PROMPT.lower()
# Must mention the decisions the reviewer can make
for verb in ("keep", "patch", "archive", "pin"):
for verb in ("keep", "patch", "archive", "consolidate"):
assert verb in CURATOR_REVIEW_PROMPT.lower()
def test_curator_review_prompt_points_at_existing_tools_only():
"""The review prompt must rely on existing tools (skill_manage + terminal)
and must NOT reference bespoke curator tools that are not registered
model tools."""
from agent.curator import CURATOR_REVIEW_PROMPT
assert "skill_manage" in CURATOR_REVIEW_PROMPT
assert "skills_list" in CURATOR_REVIEW_PROMPT
assert "skill_view" in CURATOR_REVIEW_PROMPT
assert "terminal" in CURATOR_REVIEW_PROMPT.lower()
# These would be nice but aren't actually registered as tools — the
# curator uses skill_manage + terminal mv instead.
assert "archive_skill" not in CURATOR_REVIEW_PROMPT
assert "pin_skill" not in CURATOR_REVIEW_PROMPT
def test_curator_does_not_instruct_model_to_pin():
"""Pinning is a user opt-out, not a model decision. The prompt should
not tell the reviewer to pin skills autonomously."""
from agent.curator import CURATOR_REVIEW_PROMPT
# "pinned" appears in the invariant ("skip pinned skills"), but "pin"
# as a decision verb should not.
lines = CURATOR_REVIEW_PROMPT.split("\n")
decision_block = "\n".join(
l for l in lines
if l.strip().startswith(("keep", "patch", "archive", "consolidate", "pin "))
)
# No standalone "pin" action line
assert not any(l.strip().startswith("pin ") for l in lines), (
f"Found a pin action line in:\n{decision_block}"
)