feat(curator): hint at hermes curator pin in the rename block (#23212)

Surfaces the pin command at the moment users care about it: when a
consolidation just landed against their skill library and they're
looking at the umbrella name in the curator output. Previously `hermes
curator pin` existed but had no discovery surface — users only learned
it existed by reading docs or stumbling onto `hermes curator --help`.

The hint:

    archived 3 skill(s):
      • docx-extraction → document-tools
      • pdf-extraction → document-tools
      • old-stale — pruned (stale)
    full report: hermes curator status
    keep an umbrella stable: hermes curator pin document-tools

Gated on having at least one consolidation that produced an umbrella.
Pruned-only runs (nothing surviving to pin) skip the hint. When
multiple umbrellas were produced, picks alphabetically first as a
concrete example rather than listing them all.

3 new tests in tests/agent/test_curator_classification.py covering:
consolidation produces hint with real umbrella name, pruned-only run
omits it, multi-umbrella picks one example.
This commit is contained in:
Teknium 2026-05-10 06:44:53 -07:00 committed by GitHub
parent 50f9fee988
commit 7312f7f849
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 118 additions and 1 deletions

View file

@ -899,9 +899,12 @@ def _build_rename_summary(
flaky-thing pruned (stale)
old-utility spreadsheet-ops
full report: hermes curator status
keep an umbrella stable: hermes curator pin document-tools
Cap is 10 entries so a 50-skill consolidation doesn't blow up
agent.log; the full list is always in REPORT.md.
agent.log; the full list is always in REPORT.md. The pin hint only
appears when at least one consolidation produced an umbrella worth
pinning (pruned-only runs skip it).
"""
after_by_name = {r.get("name"): r for r in after_report if isinstance(r, dict)}
after_names = set(after_by_name.keys())
@ -950,6 +953,17 @@ def _build_rename_summary(
if total > SHOW:
lines.append(f" … and {total - SHOW} more")
lines.append("full report: hermes curator status")
# Pin hint — only surface it when there's actually a destination skill
# worth pinning. The umbrella skills that absorbed content are the natural
# candidates: pinning one tells future curator runs to leave it alone.
# Pruned-only runs don't get this hint (nothing surviving to pin).
if consolidated:
umbrellas = sorted({e.get("into") for e in consolidated if e.get("into")})
if umbrellas:
example = umbrellas[0]
lines.append(
f"keep an umbrella stable: hermes curator pin {example}"
)
return "\n".join(lines)