Add repository-local tutorial agent skills (#218)

* Add repository-local tutorial agent skills

* Enforce tutorial writer safety boundaries

* Reduce trace verifier complexity

* Add cross-model tutorial writing review

* Refresh apt metadata in libbpf CI

* Split tutorial workflow and writing style skills

* Check complete tutorial source blocks

* Harden the tutorial writing workflow

* Refactor source block validation

* Close tutorial workflow isolation gaps

* Test the isolated writer trace verifier

* Keep complete-source synchronization byte exact

* Separate tutorial and Skill review gates

* Simplify the tutorial writing workflow

* Keep tutorial source and explanations together

* Keep public tutorial references self-contained

* Restore tutorial checker executable bits

* Refine tutorial writing workflow

* Prefer positive tutorial prose

* Add diagram guidance to tutorial skills

* Standardize tutorial source links

---------

Co-authored-by: LinuxDev9002 <i@littlefisher.me>
This commit is contained in:
云微
2026-07-19 14:56:27 -07:00
committed by GitHub
parent c054586a39
commit d055a0833f
16 changed files with 1344 additions and 1 deletions

View File

@@ -0,0 +1,174 @@
#!/usr/bin/env python3
"""Check exact source files embedded in standard Markdown code fences."""
from __future__ import annotations
import argparse
import collections
import pathlib
import re
import sys
FENCE_RE = re.compile(r"^(`{3,})([A-Za-z0-9_+.-]*)[ \t]*$")
LEGACY_MARKERS = ("<!-- BEGIN FULL SOURCE:", "<!-- END FULL SOURCE -->")
LANGUAGES = {
".c": "c",
".cc": "cpp",
".cpp": "cpp",
".go": "go",
".h": "c",
".py": "python",
".rs": "rust",
".sh": "bash",
}
def contained_path(root: pathlib.Path, value: str, label: str) -> pathlib.Path:
path = (root / value).resolve()
try:
path.relative_to(root)
except ValueError as error:
raise ValueError(f"{label} escapes repository root: {value}") from error
return path
def parse_fenced_blocks(readme: pathlib.Path) -> list[tuple[str, str]]:
text = readme.read_text(encoding="utf-8")
for marker in LEGACY_MARKERS:
if marker in text:
raise ValueError(
f"legacy complete-source HTML marker is not allowed in {readme.name}"
)
lines = text.splitlines(keepends=True)
blocks: list[tuple[str, str]] = []
index = 0
while index < len(lines):
opening = FENCE_RE.match(lines[index].rstrip("\r\n"))
if not opening:
index += 1
continue
fence, language = opening.groups()
end = index + 1
while end < len(lines) and lines[end].rstrip("\r\n") != fence:
end += 1
if end == len(lines):
raise ValueError(f"unclosed Markdown code fence in {readme.name}")
blocks.append((language, "".join(lines[index + 1 : end])))
index = end + 1
return blocks
def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--repo", required=True, help="absolute repository root")
parser.add_argument(
"--readme", action="append", required=True, help="repository-relative README"
)
parser.add_argument(
"--expected-source",
action="append",
required=True,
help="repository-relative complete core source; repeat for the full inventory",
)
parser.add_argument(
"--check", action="store_true", required=True, help="check exact fenced source"
)
return parser.parse_args()
def resolve_readmes(
root: pathlib.Path, values: list[str]
) -> list[tuple[str, pathlib.Path]]:
readmes: list[tuple[str, pathlib.Path]] = []
seen: set[pathlib.Path] = set()
for value in values:
readme = contained_path(root, value, "README path")
if not readme.is_file():
raise ValueError(f"README does not exist: {value}")
if readme in seen:
raise ValueError(f"duplicate README path: {value}")
readmes.append((value, readme))
seen.add(readme)
if len(readmes) != 2:
raise ValueError("pass exactly the English and Chinese README pair")
names = {path.name for _, path in readmes}
parents = {path.parent for _, path in readmes}
if names != {"README.md", "README.zh.md"} or len(parents) != 1:
raise ValueError("README paths must be README.md and README.zh.md from one lesson")
return readmes
def source_payload(
root: pathlib.Path, value: str, readme_paths: set[pathlib.Path]
) -> tuple[str, str]:
source = contained_path(root, value, "expected source path")
if not source.is_file():
raise ValueError(f"expected source file does not exist: {value}")
if source in readme_paths:
raise ValueError(f"expected source cannot be a tutorial README: {value}")
if source.suffix not in LANGUAGES:
raise ValueError(f"unsupported expected-source file type: {value}")
source_bytes = source.read_bytes()
if not source_bytes:
raise ValueError(f"complete source cannot be empty: {value}")
if not source_bytes.endswith(b"\n"):
raise ValueError(f"complete source must end with an LF byte: {value}")
source_text = source_bytes.decode("utf-8")
if "\r" in source_text:
raise ValueError(f"complete source must use LF line endings: {value}")
return LANGUAGES[source.suffix], source_text
def check_readme(
value: str,
readme: pathlib.Path,
expected: collections.Counter[tuple[str, str]],
labels: dict[tuple[str, str], list[str]],
) -> None:
actual = collections.Counter(parse_fenced_blocks(readme))
for payload, count in expected.items():
found = actual[payload]
names = ", ".join(labels[payload])
if found < count:
raise ValueError(f"missing exact fenced source in {value}: {names}")
if found > count:
raise ValueError(f"duplicate exact fenced source in {value}: {names}")
def main() -> int:
args = parse_arguments()
root = pathlib.Path(args.repo).resolve()
if not (root / ".git").exists():
print(f"not a Git worktree: {root}", file=sys.stderr)
return 2
try:
readmes = resolve_readmes(root, args.readme)
readme_paths = {path for _, path in readmes}
labels: dict[tuple[str, str], list[str]] = collections.defaultdict(list)
expected: collections.Counter[tuple[str, str]] = collections.Counter()
seen_values: set[str] = set()
for value in args.expected_source:
if value in seen_values:
raise ValueError(f"duplicate expected source: {value}")
payload = source_payload(root, value, readme_paths)
expected[payload] += 1
labels[payload].append(value)
seen_values.add(value)
for value, readme in readmes:
check_readme(value, readme, expected, labels)
print(f"checked {sum(expected.values())} fenced source blocks in {value}")
except (OSError, UnicodeError, ValueError) as error:
print(error, file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main())

View File

@@ -0,0 +1,182 @@
#!/usr/bin/env python3
"""Tests for marker-free tutorial source-block checks."""
from __future__ import annotations
import pathlib
import subprocess
import tempfile
import unittest
SCRIPT = pathlib.Path(__file__).with_name("sync-source-blocks.py")
class SourceBlocksTest(unittest.TestCase):
def setUp(self) -> None:
self.temporary = tempfile.TemporaryDirectory()
self.root = pathlib.Path(self.temporary.name)
(self.root / ".git").mkdir()
(self.root / "src/lesson").mkdir(parents=True)
(self.root / "src/lesson/tool.c").write_text(
"int main(void)\n{\n\treturn 0;\n}\n", encoding="utf-8"
)
(self.root / "src/lesson/contract.h").write_text(
"#define VALUE 1\n", encoding="utf-8"
)
def tearDown(self) -> None:
self.temporary.cleanup()
def write_readme(
self,
name: str,
payload: str | None = None,
language: str = "c",
fence: str = "```",
) -> pathlib.Path:
if payload is None:
payload = (self.root / "src/lesson/tool.c").read_text(encoding="utf-8")
path = self.root / name
path.write_text(
f"# Lesson\n\n{fence}{language}\n{payload}{fence}\n", encoding="utf-8"
)
return path
def write_pair(self, **kwargs: str) -> None:
self.write_readme("src/lesson/README.md", **kwargs)
self.write_readme("src/lesson/README.zh.md", **kwargs)
def run_script(
self,
*arguments: str,
expected: tuple[str, ...] = ("src/lesson/tool.c",),
) -> subprocess.CompletedProcess[str]:
expected_arguments = [
item for source in expected for item in ("--expected-source", source)
]
return subprocess.run(
[
"python3",
str(SCRIPT),
"--repo",
str(self.root),
*expected_arguments,
*arguments,
],
text=True,
capture_output=True,
check=False,
)
def check_pair(self, expected: tuple[str, ...] = ("src/lesson/tool.c",)):
return self.run_script(
"--readme",
"src/lesson/README.md",
"--readme",
"src/lesson/README.zh.md",
"--check",
expected=expected,
)
def test_accepts_exact_standard_markdown_fences(self) -> None:
self.write_pair()
result = self.check_pair()
self.assertEqual(0, result.returncode, result.stderr)
self.assertIn("checked 1 fenced source blocks", result.stdout)
def test_rejects_stale_source_block(self) -> None:
self.write_pair(payload="int stale;\n")
result = self.check_pair()
self.assertEqual(1, result.returncode)
self.assertIn("missing exact fenced source", result.stderr)
def test_rejects_duplicate_exact_source_block(self) -> None:
source = (self.root / "src/lesson/tool.c").read_text(encoding="utf-8")
payload = f"{source}```\n\n```c\n{source}"
self.write_pair(payload=payload)
result = self.check_pair()
self.assertEqual(1, result.returncode)
self.assertIn("duplicate exact fenced source", result.stderr)
def test_rejects_legacy_html_markers(self) -> None:
self.write_pair()
readme = self.root / "src/lesson/README.md"
readme.write_text(
readme.read_text(encoding="utf-8")
+ "<!-- END FULL SOURCE -->\n",
encoding="utf-8",
)
result = self.check_pair()
self.assertEqual(1, result.returncode)
self.assertIn("HTML marker is not allowed", result.stderr)
def test_rejects_source_outside_repository(self) -> None:
self.write_pair()
result = self.check_pair(expected=("../outside.c",))
self.assertEqual(1, result.returncode)
self.assertIn("escapes repository root", result.stderr)
def test_rejects_readme_as_source(self) -> None:
self.write_pair()
result = self.check_pair(expected=("src/lesson/README.md",))
self.assertEqual(1, result.returncode)
self.assertIn("expected source cannot be a tutorial README", result.stderr)
def test_rejects_incomplete_inventory(self) -> None:
self.write_pair()
result = self.check_pair(
expected=("src/lesson/tool.c", "src/lesson/contract.h")
)
self.assertEqual(1, result.returncode)
self.assertIn("src/lesson/contract.h", result.stderr)
def test_rejects_unsupported_source_type(self) -> None:
source = self.root / "src/lesson/source.txt"
source.write_text("text\n", encoding="utf-8")
self.write_pair(payload="text\n", language="text")
result = self.check_pair(expected=("src/lesson/source.txt",))
self.assertEqual(1, result.returncode)
self.assertIn("unsupported expected-source file type", result.stderr)
def test_accepts_longer_fence_for_source_with_backticks(self) -> None:
source = self.root / "src/lesson/tool.py"
payload = 'value = """\n```\n"""\n'
source.write_text(payload, encoding="utf-8")
self.write_pair(payload=payload, language="python", fence="````")
result = self.check_pair(expected=("src/lesson/tool.py",))
self.assertEqual(0, result.returncode, result.stderr)
def test_rejects_empty_source(self) -> None:
(self.root / "src/lesson/tool.c").write_bytes(b"")
self.write_pair(payload="")
result = self.check_pair()
self.assertEqual(1, result.returncode)
self.assertIn("complete source cannot be empty", result.stderr)
def test_rejects_source_without_final_lf(self) -> None:
(self.root / "src/lesson/tool.c").write_bytes(b"int value = 1;")
self.write_pair(payload="int value = 1;\n")
result = self.check_pair()
self.assertEqual(1, result.returncode)
self.assertIn("must end with an LF byte", result.stderr)
def test_requires_bilingual_pair(self) -> None:
self.write_readme("src/lesson/README.md")
result = self.run_script(
"--readme", "src/lesson/README.md", "--check"
)
self.assertEqual(1, result.returncode)
self.assertIn("exactly the English and Chinese README pair", result.stderr)
def test_rejects_unclosed_fence(self) -> None:
self.write_pair()
readme = self.root / "src/lesson/README.zh.md"
readme.write_text("# Lesson\n\n```c\nint value;\n", encoding="utf-8")
result = self.check_pair()
self.assertEqual(1, result.returncode)
self.assertIn("unclosed Markdown code fence", result.stderr)
if __name__ == "__main__":
unittest.main()