From a0c367c0582ffb7051c6fa8cc3170e6c37eeed43 Mon Sep 17 00:00:00 2001 From: xr843 Date: Sat, 11 Apr 2026 09:18:59 +0800 Subject: [PATCH] fix(lint): exempt meta-skills from lineage/source checks The compare-masters skill is an aggregate meta-skill that borrows from other masters and has no single lineage, dates, sources, or own corpus directories. Treating it as a regular master made --strict CI fail on all branches since 2026-04-08. Introduce a kind field (default master) and skip the lineage/dates/ sources/citation_format and references/sources directory checks when kind == meta-skill. compare/SKILL.md gains kind: meta-skill. Required fields (name, description) and version/license are still enforced for all skills. Co-Authored-By: Claude Opus 4.6 (1M context) --- prebuilt/compare/SKILL.md | 1 + scripts/validate.py | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/prebuilt/compare/SKILL.md b/prebuilt/compare/SKILL.md index 13b1d57..1799fd5 100644 --- a/prebuilt/compare/SKILL.md +++ b/prebuilt/compare/SKILL.md @@ -3,6 +3,7 @@ name: compare-masters description: Use when user asks to compare masters, compare schools, compare perspectives, 对比, 各宗怎么看, 不同宗派, 禅净之争, 性相之辩, 空有之争, or wants multiple masters to answer the same question. Triggers include "对比"、"比较"、"各宗"、"不同宗派怎么看"、"禅宗和净土"、"天台和华严"、"唯识和中观"、"空有之争"、"性相之辩"、"各位祖师"、"多个角度"、"compare"、"comparison" — invoke whenever user's question implicitly or explicitly seeks multi-tradition perspectives on a Buddhist topic. version: 0.3.0 license: MIT +kind: meta-skill verified_by: xr843 verified_at: 2026-04-06 --- diff --git a/scripts/validate.py b/scripts/validate.py index 3664ed7..c4f1c26 100644 --- a/scripts/validate.py +++ b/scripts/validate.py @@ -24,6 +24,8 @@ PREBUILT_DIR = Path(__file__).resolve().parent.parent / "prebuilt" REQUIRED_FIELDS = {"name", "description"} RECOMMENDED_FIELDS = {"version", "license", "lineage", "dates", "sources", "citation_format"} +# Fields not applicable to meta-skills (aggregate/comparison skills with no single lineage) +META_SKILL_EXCLUDED = {"lineage", "dates", "sources", "citation_format"} MAX_DESCRIPTION_CHARS = 500 MAX_SKILL_LINES = 500 @@ -104,7 +106,10 @@ def lint_master(master_dir: Path, strict: bool = False) -> list[str]: issues.append(f"[ERROR] {name}: missing required field '{field}'") # --- Recommended fields --- + kind = fm.get("kind", "master") for field in RECOMMENDED_FIELDS: + if kind == "meta-skill" and field in META_SKILL_EXCLUDED: + continue if field not in fm: issues.append(f"[WARN] {name}: missing recommended field '{field}'") @@ -126,21 +131,23 @@ def lint_master(master_dir: Path, strict: bool = False) -> list[str]: issues.append(f"[WARN] {name}: sources[{i}] missing 'title' or 'cbeta_id'") # --- Directory structure checks --- - refs_dir = master_dir / "references" - sources_dir = master_dir / "sources" + # Meta-skills (e.g. compare-masters) borrow from other masters and have no own corpus + if kind != "meta-skill": + refs_dir = master_dir / "references" + sources_dir = master_dir / "sources" - if not refs_dir.exists(): - issues.append(f"[WARN] {name}: missing references/ directory") - else: - if not (refs_dir / "voice.md").exists(): - issues.append(f"[WARN] {name}: missing references/voice.md") - if not (refs_dir / "teaching.md").exists(): - issues.append(f"[WARN] {name}: missing references/teaching.md") + if not refs_dir.exists(): + issues.append(f"[WARN] {name}: missing references/ directory") + else: + if not (refs_dir / "voice.md").exists(): + issues.append(f"[WARN] {name}: missing references/voice.md") + if not (refs_dir / "teaching.md").exists(): + issues.append(f"[WARN] {name}: missing references/teaching.md") - if not sources_dir.exists(): - issues.append(f"[WARN] {name}: missing sources/ directory") - elif not list(sources_dir.glob("*.md")): - issues.append(f"[WARN] {name}: sources/ directory is empty") + if not sources_dir.exists(): + issues.append(f"[WARN] {name}: missing sources/ directory") + elif not list(sources_dir.glob("*.md")): + issues.append(f"[WARN] {name}: sources/ directory is empty") # --- Check for tests --- tests_dir = master_dir / "tests"