SKILL.md header pointed at same-dir README.md but the pack had no such file (CHANGELOG was supplied by #217, README was not). This track adds the README only: purpose, chapter map, appendix provenance entry point, seeding behaviour, and known boundaries. It states no rule, changes no SKILL.md semantics, and does not duplicate the CHANGELOG/script explanations -- overlapping parts are pointers, with an explicit division-of-labour section. Deletion retention is written only as the tombstone-design placeholder, deferring to the skill_seed implementation, because no tombstone implementation has landed. Test pins that every file SKILL.md cites as same-directory exists (CHANGELOG, README).
89 lines
3.8 KiB
Python
89 lines
3.8 KiB
Python
"""Same-directory references of the software-engineering skill.
|
|
|
|
Background: SKILL.md's header points at two same-directory files --
|
|
``CHANGELOG.md`` ("see CHANGELOG") and ``README.md`` (install path).
|
|
CHANGELOG was supplied by the appendix-provenance track; README was
|
|
still missing, so the header's install-path pointer dangled. This file
|
|
pins the repair, and nothing else:
|
|
|
|
- every file SKILL.md cites with the qualifier "same directory"
|
|
(``同目录 `X.md` ``) exists in the skill directory -- today exactly
|
|
CHANGELOG.md and README.md, so a future dangling same-directory
|
|
reference fails here instead of shipping silently;
|
|
- README covers the topics it is supposed to cover (package layout,
|
|
appendix provenance entry point, seeding behaviour, and the
|
|
tombstone-design placeholder for deletion retention) without
|
|
becoming a second copy of the appendix or of CHANGELOG: it must
|
|
not contain appendix chapter headings, and it must not invent a
|
|
tombstone marker filename.
|
|
|
|
Scope guard: this test never edits SKILL.md. In particular it does
|
|
NOT assert on the templates/artifacts/ names mentioned in the SKILL
|
|
body (PRD outline, intake questions, acceptance checklist): those are
|
|
not same-directory references, they are not in this pack, and their
|
|
status is README's stated known boundary, not a dangling header
|
|
reference to pin here.
|
|
"""
|
|
|
|
import re
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
SKILL_DIR = REPO_ROOT / "cloud" / "skills" / "software-engineering"
|
|
SKILL_FILE = SKILL_DIR / "SKILL.md"
|
|
README_FILE = SKILL_DIR / "README.md"
|
|
|
|
# ``同目录 `X.md` `` -- the header's same-directory citations only.
|
|
SAME_DIR_REF_RE = re.compile(r"同目录\s*`([^`]+\.md)`")
|
|
|
|
|
|
class SkillReadmeRefsTestCase(unittest.TestCase):
|
|
def test_same_dir_refs_all_exist(self):
|
|
skill_text = SKILL_FILE.read_text(encoding="utf-8")
|
|
refs = set(SAME_DIR_REF_RE.findall(skill_text))
|
|
self.assertEqual(
|
|
refs, {"CHANGELOG.md", "README.md"},
|
|
"SKILL.md 的同目录引用应恰为 CHANGELOG 与 README,实际:%s"
|
|
% sorted(refs))
|
|
for name in sorted(refs):
|
|
self.assertTrue(
|
|
(SKILL_DIR / name).is_file(),
|
|
"SKILL.md 引用的同目录文件缺失:%s" % name)
|
|
|
|
def test_readme_covers_required_topics(self):
|
|
self.assertTrue(README_FILE.is_file(), "README.md 缺失")
|
|
text = README_FILE.read_text(encoding="utf-8")
|
|
for fragment in (
|
|
"templates/roles/",
|
|
"check_appendix.py",
|
|
"CHANGELOG.md",
|
|
"skill_seed",
|
|
"只复制各技能的 `SKILL.md` 一个文件",
|
|
# Deletion retention is NOT implemented: README must
|
|
# say so via the tombstone-design placeholder, and
|
|
# defer to the skill_seed implementation, verbatim.
|
|
"删除保留机制见 tombstone 设计",
|
|
"行为以 skill_seed 实现为准",
|
|
"分工",
|
|
):
|
|
self.assertIn(fragment, text, "README.md 应提及:%s" % fragment)
|
|
|
|
def test_readme_does_not_duplicate_appendix(self):
|
|
text = README_FILE.read_text(encoding="utf-8")
|
|
self.assertIsNone(
|
|
re.search(r"^## 附录角色:", text, flags=re.M),
|
|
"README 不应复制附录章节标题,否则会成为第二份会漂移的附录")
|
|
|
|
def test_readme_invents_no_tombstone_marker(self):
|
|
text = README_FILE.read_text(encoding="utf-8")
|
|
self.assertIn("tombstone", text, "README 应提及 tombstone 设计占位")
|
|
self.assertIsNone(
|
|
re.search(r"tombstone\.[a-z]+", text),
|
|
"tombstone 未落地为实现,README 不得编造标记文件名")
|
|
self.assertNotIn(".tombstone", text)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|