✨ feat(workflow): enforce auditable agent rules
This commit is contained in:
@@ -400,6 +400,81 @@ no_backup = true
|
||||
self.assertIn("`.agents/tsl/index.md`", after)
|
||||
self.assertIn("`.agents/markdown/index.md`", after)
|
||||
|
||||
def test_resync_refreshes_the_rules_block_and_keeps_project_additions(self):
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
project_root = Path(tmp_dir) / "project"
|
||||
project_root.mkdir()
|
||||
playbook_root = MODE_ROOTS["snapshot"]
|
||||
config = write_config(project_root, "snapshot", playbook_root)
|
||||
|
||||
seed = run_playbook(SCRIPT, config, project_root)
|
||||
self.assertEqual(
|
||||
seed.returncode, 0, msg=f"{seed.stdout}{seed.stderr}"
|
||||
)
|
||||
|
||||
rules_md = project_root / "AGENT_RULES.md"
|
||||
seeded = rules_md.read_text(encoding="utf-8")
|
||||
self.assertIn("<!-- playbook:rules:start -->", seeded)
|
||||
self.assertIn("<!-- playbook:rules:end -->", seeded)
|
||||
|
||||
# A project appendix outside the block, and drift inside it.
|
||||
appendix = "\n## 项目补充\n\n保留这段项目自己的说明。\n"
|
||||
drifted = seeded.replace("## 任务入口", "## 任务入口(本地改过)") + appendix
|
||||
rules_md.write_text(drifted, encoding="utf-8", newline="\n")
|
||||
|
||||
resync = run_playbook(SCRIPT, config, project_root)
|
||||
self.assertEqual(
|
||||
resync.returncode, 0, msg=f"{resync.stdout}{resync.stderr}"
|
||||
)
|
||||
|
||||
after = rules_md.read_text(encoding="utf-8")
|
||||
self.assertIn(
|
||||
"保留这段项目自己的说明。",
|
||||
after,
|
||||
msg="content outside the block belongs to the project",
|
||||
)
|
||||
self.assertIn(
|
||||
"## 任务入口\n",
|
||||
after,
|
||||
msg="the process itself is playbook-owned and must be refreshed",
|
||||
)
|
||||
self.assertNotIn("## 任务入口(本地改过)", after)
|
||||
self.assertEqual(after.count("<!-- playbook:rules:start -->"), 1)
|
||||
|
||||
legacy = project_root / "legacy" / "AGENT_RULES.md"
|
||||
legacy.parent.mkdir()
|
||||
legacy.write_text(
|
||||
"# AGENT_RULES\n\n没有 marker 的旧文件。\n",
|
||||
encoding="utf-8",
|
||||
newline="\n",
|
||||
)
|
||||
legacy_config = project_root / "playbook-legacy.toml"
|
||||
legacy_config.write_text(
|
||||
f"""
|
||||
[playbook]
|
||||
project_root = "legacy"
|
||||
playbook_root = "{playbook_root.as_posix()}"
|
||||
install_mode = "snapshot"
|
||||
|
||||
[sync_rules]
|
||||
date = "2026-01-01"
|
||||
no_backup = true
|
||||
""".lstrip(),
|
||||
encoding="utf-8",
|
||||
newline="\n",
|
||||
)
|
||||
legacy_run = run_playbook(SCRIPT, legacy_config, project_root)
|
||||
self.assertEqual(
|
||||
legacy_run.returncode,
|
||||
0,
|
||||
msg=f"{legacy_run.stdout}{legacy_run.stderr}",
|
||||
)
|
||||
self.assertEqual(
|
||||
legacy.read_text(encoding="utf-8"),
|
||||
"# AGENT_RULES\n\n没有 marker 的旧文件。\n",
|
||||
msg="a file predating the markers must not be rewritten silently",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user