tag conventions

This commit is contained in:
John Lancaster
2026-06-21 22:52:26 -05:00
parent e93462ec3b
commit 35d7fa1718
2 changed files with 135 additions and 0 deletions
+1
View File
@@ -9,6 +9,7 @@ x-personal-mcp:
- uv
- uvicorn
- docker
- architecture
capabilities:
- resource://skills/fastapi-uv-docker/document
---
@@ -0,0 +1,134 @@
from __future__ import annotations
import pytest
from personal_mcp.registry.load import load_docs_registry
pytestmark = pytest.mark.unit
REGISTRY = load_docs_registry(
package_anchor="personal_mcp",
docs_root="../../docs",
)
# Convention: every skill should include tags for the core libraries/frameworks
# it relies on so search_patterns query terms map to discoverable skills.
REQUIRED_LIBRARY_TAGS_BY_SKILL = {
"copilot-customization": {"copilot", "vscode", "mcp"},
"fastapi-async-sqlalchemy-modernization": {"fastapi", "sqlalchemy", "asyncio"},
"fastapi-uv-docker": {"fastapi", "uv", "uvicorn", "docker"},
"mcp-details": {"mcp", "fastmcp"},
"new-skill": {"mcp", "fastmcp"},
"nicegui": {"nicegui", "fastapi"},
"nicegui-ui-customization": {"nicegui", "fastapi"},
"pytest-scaffolding": {"pytest", "testing", "fastapi", "asyncio", "anyio"},
"python-logging-dictconfig": {"python", "logging"},
"python-typing": {"python", "typing"},
"ruff-linting-formating": {"ruff", "python"},
"vscode-configuration": {"vscode", "debugpy", "fastapi", "python"},
"zensical-docs": {"zensical", "mkdocs", "mkdocs-material", "mkdocstrings"},
}
LIBRARY_OR_PLATFORM_TAGS = {
"anyio",
"asyncio",
"copilot",
"debugpy",
"docker",
"fastapi",
"fastmcp",
"logging",
"mcp",
"mkdocs",
"mkdocs-material",
"mkdocstrings",
"nicegui",
"pytest",
"python",
"ruff",
"sqlalchemy",
"typing",
"uv",
"uvicorn",
"vscode",
"zensical",
}
DOMAIN_FACET_TAGS = {
"agent-skills",
"architecture",
"authoring",
"bootstrap",
"ci",
"custom-agents",
"customization",
"deterministic",
"discovery",
"docs",
"documentation",
"formatting",
"frontend",
"hooks",
"information-architecture",
"instructions",
"launch-json",
"linting",
"modernization",
"observability",
"personal-mcp",
"prompts",
"references",
"scaffolding",
"skills",
"source-docs",
"static-analysis",
"tasks-json",
"testing",
"type-hints",
"ui",
}
TAG_CONVENTION_PARAMETERS = tuple(
pytest.param(skill_id, required_tags, id=skill_id)
for skill_id, required_tags in sorted(REQUIRED_LIBRARY_TAGS_BY_SKILL.items())
)
SKILL_IDS = tuple(pytest.param(skill_id, id=skill_id) for skill_id in sorted(REGISTRY.skills_by_id))
class TestSkillTagConventions:
"""Covers tag taxonomy conventions for skill discoverability."""
class TestRequiredLibraryTags:
"""Covers required per-skill library and framework tags."""
@pytest.mark.parametrize(("skill_id", "required_tags"), TAG_CONVENTION_PARAMETERS)
def test_includes_required_library_and_framework_tags(
self,
skill_id: str,
required_tags: set[str],
) -> None:
"""Ensures each skill includes its required library/framework tags."""
skill = REGISTRY.skills_by_id[skill_id]
skill_tags = set(skill.tags)
assert required_tags.issubset(skill_tags)
class TestTagTaxonomyShape:
"""Covers baseline tag-shape guarantees across all skills."""
@pytest.mark.parametrize("skill_id", SKILL_IDS)
def test_includes_library_or_platform_tag(self, skill_id: str) -> None:
"""Ensures each skill includes at least one library/platform tag."""
skill = REGISTRY.skills_by_id[skill_id]
skill_tags = set(skill.tags)
assert skill_tags & LIBRARY_OR_PLATFORM_TAGS
@pytest.mark.parametrize("skill_id", SKILL_IDS)
def test_includes_domain_facet_tag(self, skill_id: str) -> None:
"""Ensures each skill includes at least one domain facet tag."""
skill = REGISTRY.skills_by_id[skill_id]
skill_tags = set(skill.tags)
assert skill_tags & DOMAIN_FACET_TAGS