将角色与 Skill 从 .claude 迁入 .agent,移除 Claude CLI 运行时并接入固定 Opus 角色 profile、完整 schema、预算 deadline、raw 与回执证据链。 同步拆分 Skill 职责、复利 lesson、Gate 回放、Dashboard 人审入口、数据库登记和机械门禁;候选设计正文不包含在本提交中。
48 lines
1.9 KiB
Python
48 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""20 项研究机制覆盖矩阵的机械卫生门。"""
|
|
from __future__ import annotations
|
|
|
|
import pathlib
|
|
import unittest
|
|
|
|
import yaml
|
|
|
|
ROOT = pathlib.Path(__file__).resolve().parents[1]
|
|
MATRIX = ROOT / "research/20-project-skill-coverage.yaml"
|
|
|
|
|
|
class FrameworkCoverageTest(unittest.TestCase):
|
|
def test_matrix_has_skill_owners_and_real_implementation_paths(self):
|
|
data = yaml.safe_load(MATRIX.read_text(encoding="utf-8"))
|
|
self.assertEqual(data["schema_version"], "humanization-research-skill-coverage-v1")
|
|
capabilities = data["capabilities"]
|
|
self.assertGreaterEqual(len(capabilities), 12)
|
|
capability_ids = {item["id"] for item in capabilities}
|
|
projects = data["projects"]
|
|
self.assertEqual(len(projects), 20)
|
|
self.assertEqual(len({item["id"] for item in projects}), 20)
|
|
for project in projects:
|
|
self.assertTrue(project["mapped_capabilities"], project["id"])
|
|
self.assertTrue(set(project["mapped_capabilities"]) <= capability_ids, project["id"])
|
|
owners = {item["owner_skill"] for item in capabilities}
|
|
self.assertEqual(
|
|
owners,
|
|
{
|
|
"establish-voice-baseline",
|
|
"prevent-ai-flavor",
|
|
"diagnose-ai-flavor",
|
|
"revise-ai-flavor",
|
|
"capture-ai-flavor-cases",
|
|
"promote-ai-flavor-rule",
|
|
},
|
|
)
|
|
for item in capabilities:
|
|
implementation_ref = item["implementation"]
|
|
implementation = ROOT.parent / implementation_ref if implementation_ref.startswith((".", "humanization/")) else ROOT / implementation_ref
|
|
self.assertTrue(implementation.exists(), f"{item['id']}: {implementation}")
|
|
self.assertIn(item["status"], {"implemented", "partial", "pending"})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|