fix(learning-graph): skip force-install swap leftovers via shared exclusions

build_skill_nodes used a private skip list without .hermes-dist, so a locked backup left by a force install showed up as a second skill. Use EXCLUDED_SKILL_DIRS on paths relative to each root.
This commit is contained in:
unsupportedpastels authored and Mark S. committed 2026-11-02 19:08:46 -05:00
1 parent 3e0985d017
commit e676645209
2 files changed
+14 -2

No files matched your search

+2 -2
View File
@@ -17,9 +17,9 @@ from datetime import datetime, timezone, UTC
from pathlib import Path
from typing import Any, Optional
from agent.skill_utils import EXCLUDED_SKILL_DIRS
from hermes_constants import get_hermes_home
_SKIP_PARTS = {".archive", ".hub", ".locks", "node_modules", ".git"}
_USAGE_TS_KEYS = ("last_activity_at", "last_used_at", "last_viewed_at", "last_patched_at", "created_at")
@@ -92,7 +92,7 @@ def build_skill_nodes(skill_roots: list[tuple[str, Path]]) -> dict[str, SkillNod
is_external_skill_path = None # type: ignore[assignment]
for source, root in skill_roots:
for skill_md in root.rglob("SKILL.md") if root.exists() else ():
if _SKIP_PARTS.intersection(skill_md.parts):
if EXCLUDED_SKILL_DIRS.intersection(skill_md.relative_to(root).parts):
continue
try:
text = skill_md.read_text(encoding="utf-8-sig")[:4000]
+12
View File
@@ -81,6 +81,18 @@ def test_full_payload_shape_and_edge_integrity(tmp_path):
assert all("timestamp" in n for n in graph["nodes"])
def test_build_skill_nodes_skips_profile_install_swap_leftover(tmp_path):
"""A locked old tree a force install left in ``.hermes-dist`` is not a second copy."""
from agent.skill_utils import DIST_SWAP_DIR
skills = tmp_path / "skills"
for skill_dir, body in ((skills / "demo", "new"), (skills / DIST_SWAP_DIR / "demo.old-1", "old")):
skill_dir.mkdir(parents=True)
(skill_dir / "SKILL.md").write_text(f"---\nname: demo-{body}\n---\n", encoding="utf-8")
assert set(learning_graph.build_skill_nodes([("profile", skills)])) == {"demo-new"}
def test_foreground_created_skill_is_in_journey_before_first_use(tmp_path):
"""A skill created in the foreground (/learn, skill_manage) shows in the journey with zero
uses, while an unmarked never-used local skill (hand-written) stays out."""