master-skill 0.10.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.cursor-plugin/plugin.json +1 -1
  4. package/GEMINI.md +1 -1
  5. package/README.md +84 -336
  6. package/README_EN.md +108 -321
  7. package/bin/cli.mjs +249 -9
  8. package/gemini-extension.json +1 -1
  9. package/hooks/session-start +68 -74
  10. package/hooks/session_start.py +152 -0
  11. package/package.json +6 -2
  12. package/prebuilt/{compare → compare-masters}/SKILL.md +21 -2
  13. package/prebuilt/master-ajahn-chah/meta.json +6 -0
  14. package/prebuilt/master-ajahn-chah/tests/fidelity.jsonl +6 -6
  15. package/prebuilt/master-atisha/tests/fidelity.jsonl +4 -4
  16. package/prebuilt/master-curriculum/SKILL.md +1 -1
  17. package/prebuilt/master-curriculum/references/tiantai.md +1 -1
  18. package/prebuilt/master-debate/SKILL.md +15 -3
  19. package/prebuilt/master-fazang/tests/fidelity.jsonl +2 -2
  20. package/prebuilt/master-help/SKILL.md +94 -0
  21. package/prebuilt/master-help/tests/fidelity.jsonl +10 -0
  22. package/prebuilt/master-huineng/tests/fidelity.jsonl +4 -4
  23. package/prebuilt/master-kumarajiva/meta.json +14 -3
  24. package/prebuilt/master-kumarajiva/tests/fidelity.jsonl +3 -3
  25. package/prebuilt/master-mahasi-sayadaw/tests/fidelity.jsonl +4 -4
  26. package/prebuilt/master-milarepa/tests/fidelity.jsonl +3 -3
  27. package/prebuilt/master-nagarjuna/meta.json +19 -4
  28. package/prebuilt/master-nagarjuna/tests/fidelity.jsonl +6 -6
  29. package/prebuilt/master-ouyi/meta.json +5 -0
  30. package/prebuilt/master-ouyi/references/teaching.md +3 -3
  31. package/prebuilt/master-ouyi/tests/fidelity.jsonl +3 -3
  32. package/prebuilt/master-tsongkhapa/meta.json +32 -5
  33. package/prebuilt/master-tsongkhapa/tests/fidelity.jsonl +2 -2
  34. package/prebuilt/master-xuanzang/tests/fidelity.jsonl +3 -3
  35. package/prebuilt/master-xuyun/tests/fidelity.jsonl +6 -6
  36. package/prebuilt/master-zhiyi/meta.json +2 -2
  37. package/prebuilt/master-zhiyi/tests/fidelity.jsonl +2 -2
  38. package/references/teaching-modes.md +8 -1
  39. package/routing.json +209 -0
  40. package/scripts/check-audit-ignores.py +105 -0
  41. package/scripts/check-eval-sdk-surface.py +142 -0
  42. package/scripts/check-gate-liveness.py +421 -0
  43. package/scripts/reaudit-report.py +163 -0
  44. package/scripts/regrade-report.py +157 -0
  45. package/scripts/smoke-eval-sdk.py +174 -0
  46. package/scripts/test-fidelity.py +992 -89
  47. package/scripts/validate-citation-references.py +150 -0
  48. package/scripts/validate-citation-templates.py +176 -0
  49. package/scripts/validate-fidelity.py +6 -1
  50. package/scripts/validate-fixture-terms.py +127 -0
  51. package/scripts/validate-routing.py +254 -0
  52. package/scripts/validate.py +63 -36
  53. package/scripts/verify-adjudication.py +316 -0
  54. package/scripts/verify_citations.py +739 -39
  55. package/skill-catalog.json +83 -20
  56. package/tools/cross_reference.py +44 -10
  57. package/tools/fojin-known-absent.json +14 -0
  58. package/tools/fojin_bridge.py +138 -8
  59. package/tools/rag_query.py +45 -2
  60. package/tools/skill_writer.py +50 -7
  61. package/tools/verify_sources.py +240 -15
  62. package/hooks/tests/test_run_hook.sh +0 -114
  63. package/hooks/tests/test_run_hook_cmd.sh +0 -94
  64. package/hooks/tests/test_session_start.sh +0 -149
  65. package/scripts/tests/test_check_manifest_versions.py +0 -217
  66. package/scripts/tests/test_debate_protocol.py +0 -159
  67. package/scripts/tests/test_injection_hardening.py +0 -174
  68. package/scripts/tests/test_select_fidelity_smoke.py +0 -142
  69. package/scripts/tests/test_validate_citation_contract.py +0 -408
  70. package/scripts/tests/test_validate_cross_critique.py +0 -149
  71. package/scripts/tests/test_validate_curriculum_sources.py +0 -144
  72. package/scripts/tests/test_validate_fidelity.py +0 -59
  73. package/scripts/tests/test_validate_lore_triggers_content.py +0 -372
  74. package/scripts/tests/test_validate_persona_fidelity.py +0 -317
  75. package/scripts/tests/test_validate_promptfoo_configs.py +0 -386
  76. package/scripts/tests/test_validate_workflow.py +0 -265
  77. /package/prebuilt/{compare → compare-masters}/tests/fidelity.jsonl +0 -0
@@ -1,149 +0,0 @@
1
- """Tests for validate-cross-critique.py."""
2
- from __future__ import annotations
3
-
4
- import json
5
- from pathlib import Path
6
-
7
- import importlib.util
8
- import sys
9
-
10
- import pytest
11
-
12
-
13
- def _load_module():
14
- spec_path = Path(__file__).resolve().parents[1] / "validate-cross-critique.py"
15
- spec = importlib.util.spec_from_file_location("vcc", spec_path)
16
- mod = importlib.util.module_from_spec(spec)
17
- sys.modules["vcc"] = mod
18
- spec.loader.exec_module(mod)
19
- return mod
20
-
21
-
22
- def _write_master(prebuilt: Path, slug: str, sources: list[dict], cross_critique=None):
23
- d = prebuilt / f"master-{slug}"
24
- d.mkdir(parents=True, exist_ok=True)
25
- data = {"slug": slug, "sources": sources}
26
- if cross_critique is not None:
27
- data["cross_critique"] = cross_critique
28
- (d / "meta.json").write_text(json.dumps(data), encoding="utf-8")
29
-
30
-
31
- @pytest.fixture
32
- def fake_tree(tmp_path):
33
- prebuilt = tmp_path / "prebuilt"
34
- # build enough masters to satisfy required_pairs in tests that need them
35
- for slug in [
36
- "huineng", "yinguang", "kumarajiva", "xuanzang", "zhiyi",
37
- "tsongkhapa", "ajahn-chah", "mahasi-sayadaw", "atisha", "ouyi",
38
- ]:
39
- _write_master(prebuilt, slug, [{"type": "cbeta", "id": "T00n0001", "title": "demo"}])
40
- return prebuilt
41
-
42
-
43
- def test_empty_cross_critique_is_ok(fake_tree):
44
- vcc = _load_module()
45
- # No master has cross_critique; structural check passes,
46
- # but required_pairs check still fails (no coverage).
47
- errors = vcc.validate(fake_tree, check_coverage=False)
48
- assert errors == []
49
-
50
-
51
- def test_well_formed_entry_passes(fake_tree):
52
- vcc = _load_module()
53
- _write_master(fake_tree, "huineng",
54
- [{"type": "cbeta", "id": "T48n2008", "title": "坛经"}],
55
- cross_critique=[
56
- {"target_master": "yinguang", "position": "对净土:本性弥陀唯心净土,何曾离自心。", "citation": "T48n2008"},
57
- ])
58
- errors = vcc.validate(fake_tree, check_coverage=False)
59
- # Only the huineng→yinguang structural check should pass.
60
- huineng_errors = [e for e in errors if "huineng" in e]
61
- assert huineng_errors == []
62
-
63
-
64
- def test_missing_required_field(fake_tree):
65
- vcc = _load_module()
66
- _write_master(fake_tree, "huineng",
67
- [{"type": "cbeta", "id": "T48n2008", "title": "坛经"}],
68
- cross_critique=[{"target_master": "yinguang"}]) # no position, no citation
69
- errors = vcc.validate(fake_tree, check_coverage=False)
70
- assert any("position" in e for e in errors)
71
- assert any("citation" in e for e in errors)
72
-
73
-
74
- def test_cannot_target_self(fake_tree):
75
- vcc = _load_module()
76
- _write_master(fake_tree, "huineng",
77
- [{"type": "cbeta", "id": "T48n2008", "title": "坛经"}],
78
- cross_critique=[{"target_master": "huineng", "position": "x" * 50, "citation": "T48n2008"}])
79
- errors = vcc.validate(fake_tree, check_coverage=False)
80
- assert any("self" in e.lower() for e in errors)
81
-
82
-
83
- def test_cannot_target_meta_skill(fake_tree):
84
- vcc = _load_module()
85
- _write_master(fake_tree, "huineng",
86
- [{"type": "cbeta", "id": "T48n2008", "title": "坛经"}],
87
- cross_critique=[{"target_master": "curriculum", "position": "x" * 50, "citation": "T48n2008"}])
88
- errors = vcc.validate(fake_tree, check_coverage=False)
89
- assert any("meta-skill" in e or "curriculum" in e for e in errors)
90
-
91
-
92
- def test_unknown_target_master(fake_tree):
93
- vcc = _load_module()
94
- _write_master(fake_tree, "huineng",
95
- [{"type": "cbeta", "id": "T48n2008", "title": "坛经"}],
96
- cross_critique=[{"target_master": "ghost", "position": "x" * 50, "citation": "T48n2008"}])
97
- errors = vcc.validate(fake_tree, check_coverage=False)
98
- assert any("ghost" in e for e in errors)
99
-
100
-
101
- def test_citation_not_in_own_sources(fake_tree):
102
- vcc = _load_module()
103
- _write_master(fake_tree, "huineng",
104
- [{"type": "cbeta", "id": "T48n2008", "title": "坛经"}],
105
- cross_critique=[{"target_master": "yinguang", "position": "x" * 50, "citation": "T99n9999"}])
106
- errors = vcc.validate(fake_tree, check_coverage=False)
107
- assert any("T99n9999" in e for e in errors)
108
-
109
-
110
- def test_position_length_bounds(fake_tree):
111
- vcc = _load_module()
112
- _write_master(fake_tree, "huineng",
113
- [{"type": "cbeta", "id": "T48n2008", "title": "坛经"}],
114
- cross_critique=[
115
- {"target_master": "yinguang", "position": "短", "citation": "T48n2008"}, # < 10
116
- {"target_master": "zhiyi", "position": "x" * 400, "citation": "T48n2008"}, # > 300
117
- ])
118
- errors = vcc.validate(fake_tree, check_coverage=False)
119
- assert any("length" in e for e in errors)
120
-
121
-
122
- def test_coverage_fails_when_pairs_missing(fake_tree):
123
- vcc = _load_module()
124
- errors = vcc.validate(fake_tree, check_coverage=True)
125
- # Should report all 16 missing critique entries.
126
- missing_errors = [e for e in errors if "missing critique" in e]
127
- assert len(missing_errors) == 16
128
-
129
-
130
- def test_coverage_succeeds_with_full_pairs(fake_tree):
131
- vcc = _load_module()
132
- pairs = [
133
- ("huineng", "yinguang"), ("yinguang", "huineng"),
134
- ("kumarajiva", "xuanzang"), ("xuanzang", "kumarajiva"),
135
- ("huineng", "zhiyi"), ("zhiyi", "huineng"),
136
- ("tsongkhapa", "huineng"), ("huineng", "tsongkhapa"),
137
- ("ajahn-chah", "mahasi-sayadaw"), ("mahasi-sayadaw", "ajahn-chah"),
138
- ("atisha", "huineng"), ("huineng", "atisha"),
139
- ("ouyi", "yinguang"), ("yinguang", "ouyi"),
140
- ("ouyi", "tsongkhapa"), ("tsongkhapa", "ouyi"),
141
- ]
142
- by_slug: dict[str, list[dict]] = {}
143
- for src, tgt in pairs:
144
- by_slug.setdefault(src, []).append(
145
- {"target_master": tgt, "position": "x" * 50, "citation": "T00n0001"})
146
- for slug, cc in by_slug.items():
147
- _write_master(fake_tree, slug, [{"type": "cbeta", "id": "T00n0001", "title": "demo"}], cc)
148
- errors = vcc.validate(fake_tree, check_coverage=True)
149
- assert errors == []
@@ -1,144 +0,0 @@
1
- """Tests for validate-curriculum-sources.py.
2
-
3
- Verifies that citations (CBETA T-numbers, X-numbers, Toh, compiled-teaching ids)
4
- and /master-<slug> references in curriculum reference files cross-check against
5
- the actual prebuilt master metadata.
6
- """
7
- from __future__ import annotations
8
-
9
- import json
10
- from pathlib import Path
11
-
12
- import pytest
13
-
14
- import importlib.util
15
- import sys
16
-
17
-
18
- def _load_module():
19
- spec_path = Path(__file__).resolve().parents[1] / "validate-curriculum-sources.py"
20
- spec = importlib.util.spec_from_file_location("vcs", spec_path)
21
- mod = importlib.util.module_from_spec(spec)
22
- sys.modules["vcs"] = mod
23
- spec.loader.exec_module(mod)
24
- return mod
25
-
26
-
27
- @pytest.fixture
28
- def fake_prebuilt(tmp_path):
29
- """Fake prebuilt tree with two masters and a curriculum dir."""
30
- prebuilt = tmp_path / "prebuilt"
31
- # Master A: cbeta source
32
- (prebuilt / "master-aaa").mkdir(parents=True)
33
- (prebuilt / "master-aaa" / "meta.json").write_text(json.dumps({
34
- "slug": "aaa",
35
- "sources": [{"type": "cbeta", "id": "T48n2008", "title": "demo"}],
36
- }), encoding="utf-8")
37
- # Master B: compiled_teaching source + Toh
38
- (prebuilt / "master-bbb").mkdir(parents=True)
39
- (prebuilt / "master-bbb" / "meta.json").write_text(json.dumps({
40
- "slug": "bbb",
41
- "sources": [
42
- {"type": "compiled_teaching", "id": "AjahnChah:FoodForTheHeart", "title": "demo"},
43
- {"type": "84000", "id": "Toh 21", "title": "demo"},
44
- ],
45
- }), encoding="utf-8")
46
- (prebuilt / "master-curriculum" / "references").mkdir(parents=True)
47
- return prebuilt
48
-
49
-
50
- def test_extract_citations_finds_T_numbers():
51
- vcs = _load_module()
52
- text = "See 《坛经》【T48n2008】 for details."
53
- assert "T48n2008" in vcs.extract_citations(text)
54
-
55
-
56
- def test_extract_citations_finds_Toh():
57
- vcs = _load_module()
58
- text = "藏文藏经 Toh 21 心经..."
59
- assert "Toh 21" in vcs.extract_citations(text)
60
-
61
-
62
- def test_extract_citations_finds_compiled_teaching():
63
- vcs = _load_module()
64
- text = "见 AjahnChah:FoodForTheHeart ..."
65
- assert "AjahnChah:FoodForTheHeart" in vcs.extract_citations(text)
66
-
67
-
68
- def test_extract_master_slugs():
69
- vcs = _load_module()
70
- text = "推荐 master:/master-aaa ;交叉 /master-bbb 。"
71
- assert vcs.extract_master_slugs(text) == {"aaa", "bbb"}
72
-
73
-
74
- def test_collect_known_citations(fake_prebuilt):
75
- vcs = _load_module()
76
- known = vcs.collect_known_citations(fake_prebuilt)
77
- assert "T48n2008" in known
78
- assert "AjahnChah:FoodForTheHeart" in known
79
- assert "Toh 21" in known
80
-
81
-
82
- def test_validate_pass(fake_prebuilt):
83
- vcs = _load_module()
84
- ref = fake_prebuilt / "master-curriculum" / "references" / "ok.md"
85
- ref.write_text(
86
- "## Path\n- 主用经《坛经》【T48n2008】\n- master:/master-aaa\n- 藏:Toh 21\n",
87
- encoding="utf-8",
88
- )
89
- errors = vcs.validate(fake_prebuilt)
90
- assert errors == []
91
-
92
-
93
- def test_validate_fails_on_fabricated_citation(fake_prebuilt):
94
- vcs = _load_module()
95
- ref = fake_prebuilt / "master-curriculum" / "references" / "bad.md"
96
- ref.write_text("【T99n9999】 fake\n", encoding="utf-8")
97
- errors = vcs.validate(fake_prebuilt)
98
- assert any("T99n9999" in e for e in errors)
99
-
100
-
101
- def test_validate_fails_on_unknown_master_slug(fake_prebuilt):
102
- vcs = _load_module()
103
- ref = fake_prebuilt / "master-curriculum" / "references" / "bad.md"
104
- ref.write_text("/master-ghost\n", encoding="utf-8")
105
- errors = vcs.validate(fake_prebuilt)
106
- assert any("ghost" in e for e in errors)
107
-
108
-
109
- def test_validate_ignores_meta_skill_slugs(fake_prebuilt):
110
- """/master-curriculum and /master-debate are meta-skills suppressed via
111
- META_SKILL_SLUGS. /compare-masters never matches _SLUG (no /master- prefix),
112
- so it is naturally ignored. None of these may raise validate errors."""
113
- vcs = _load_module()
114
- ref = fake_prebuilt / "master-curriculum" / "references" / "ok.md"
115
- ref.write_text(
116
- "延伸 → /compare-masters · /master-debate · /master-curriculum\n",
117
- encoding="utf-8",
118
- )
119
- errors = vcs.validate(fake_prebuilt)
120
- assert errors == []
121
-
122
-
123
- def test_validate_returns_error_when_refs_dir_missing(tmp_path):
124
- vcs = _load_module()
125
- prebuilt = tmp_path / "prebuilt"
126
- prebuilt.mkdir()
127
- # curriculum/references missing
128
- errors = vcs.validate(prebuilt)
129
- assert len(errors) == 1
130
- assert "references dir not found" in errors[0]
131
-
132
-
133
- def test_extract_citations_finds_hyphenated_compiled_teaching():
134
- vcs = _load_module()
135
- text = "PTS:DN-Comm 注释 / BDRC:Pha-chos-Bu-chos"
136
- cits = vcs.extract_citations(text)
137
- assert "PTS:DN-Comm" in cits
138
- assert "BDRC:Pha-chos-Bu-chos" in cits
139
-
140
-
141
- def test_extract_citations_finds_Toh_with_colon():
142
- vcs = _load_module()
143
- text = "见 Toh:3948"
144
- assert "Toh:3948" in vcs.extract_citations(text)
@@ -1,59 +0,0 @@
1
- import json
2
- import importlib.util
3
- from pathlib import Path
4
-
5
- MODULE_PATH = Path(__file__).resolve().parents[1] / "validate-fidelity.py"
6
- SPEC = importlib.util.spec_from_file_location("validate_fidelity", MODULE_PATH)
7
- validate_fidelity = importlib.util.module_from_spec(SPEC)
8
- SPEC.loader.exec_module(validate_fidelity)
9
-
10
-
11
- def _write_fixture(tmp_path: Path, master_name: str, cases: list[dict]) -> Path:
12
- master_dir = tmp_path / master_name
13
- tests_dir = master_dir / "tests"
14
- tests_dir.mkdir(parents=True)
15
- payload = "\n".join(json.dumps(case, ensure_ascii=False) for case in cases) + "\n"
16
- (tests_dir / "fidelity.jsonl").write_text(payload, encoding="utf-8")
17
- return master_dir
18
-
19
-
20
- def test_compare_requires_framework_output_sections(tmp_path):
21
- master_dir = _write_fixture(
22
- tmp_path,
23
- "compare",
24
- [
25
- {
26
- "q": "禅和净怎么比较?",
27
- "must_select_masters": ["huineng", "yinguang"],
28
- "must_have_sections": ["分歧雷达"],
29
- }
30
- for _ in range(5)
31
- ],
32
- )
33
-
34
- errors = validate_fidelity.validate_master(master_dir)
35
-
36
- assert any("共同点" in error for error in errors)
37
- assert any("引用来源" in error for error in errors)
38
-
39
-
40
- def test_compare_accepts_required_framework_output_sections(tmp_path):
41
- case = {
42
- "q": "禅和净怎么比较?",
43
- "must_select_masters": ["huineng", "yinguang"],
44
- "must_have_sections": sorted(validate_fidelity.COMPARE_REQUIRED_SECTIONS),
45
- }
46
- cases = [case.copy() for _ in range(5)]
47
- cases.append(
48
- {
49
- "q": "哪个更好?",
50
- "test_type": "boundary",
51
- "boundary": "sectarian_judgment",
52
- "must_not_contain": ["更好"],
53
- }
54
- )
55
- master_dir = _write_fixture(tmp_path, "compare", cases)
56
-
57
- errors = validate_fidelity.validate_master(master_dir)
58
-
59
- assert errors == []