feat(playbook): version durable scratch workflow state

This commit is contained in:
csh
2026-08-14 17:11:54 +08:00
parent 9487dbddf1
commit 8f1056130d
8 changed files with 237 additions and 17 deletions
+54 -10
View File
@@ -277,17 +277,20 @@ class TemplateContractsTests(unittest.TestCase):
for legacy in LEGACY_FLOW_TERMS:
self.assertNotIn(legacy, rules)
def test_agent_rules_states_whether_scratch_is_version_controlled(self):
rules = rules_text()
responsibilities = section(rules, "## 文档职责", "## 稳定知识维护")
def test_gitignore_template_tracks_scratch_and_ignores_only_runtime(self):
template = (TEMPLATES / "gitignore.template").read_text(encoding="utf-8")
self.assertIn("AGENT_RULES.local.md", responsibilities)
self.assertIn(
"纳入版本控制",
responsibilities,
msg="the review contract reads spec sources out of .scratch/, so "
"whether it is tracked has to be an explicit project decision",
)
for durable_rule in ("!/.scratch/", "!/.scratch/**"):
self.assertIn(durable_rule, template)
for runtime_rule in (
"/.scratch/*.lock",
"/.scratch/worktrees/",
"/.scratch/**/*.tmp",
):
self.assertIn(runtime_rule, template)
rules = rules_text()
self.assertNotIn("是否纳入版本控制由项目决定", rules)
def test_agent_rules_routes_each_current_matt_on_ramp_to_its_destination(self):
rules = rules_text()
@@ -315,6 +318,47 @@ class TemplateContractsTests(unittest.TestCase):
"the skill's own phase order",
)
def test_agent_rules_commits_planning_baseline_before_claim(self):
rules = rules_text()
main_chain = section(rules, "## 正式工程主链", "## On-ramps 与 detours")
ordered_steps = (
"-> to-spec",
"-> to-tickets",
"-> main_loop.py enqueue",
"-> 提交 planning baseline",
"-> main_loop.py claim",
)
positions = [main_chain.index(step) for step in ordered_steps]
self.assertEqual(positions, sorted(positions))
for durable_input in (
"`.scratch/<feature>/spec.md`",
"`.scratch/<feature>/issues/*.md`",
"`.scratch/queue.md`",
):
self.assertIn(durable_input, main_chain)
self.assertIn("任何 `claim` 之前", main_chain)
self.assertIn("不隐式提交", main_chain)
def test_agent_rules_commits_final_workflow_state_after_integration(self):
rules = rules_text()
main_chain = section(rules, "## 正式工程主链", "## On-ramps 与 detours")
integration = section(rules, "### Feature 顺序集成", "## Git 与证据门禁")
self.assertLess(
main_chain.index("-> main_loop.py integrate"),
main_chain.index("-> 提交 final workflow state"),
)
for durable_path in (
"`.scratch/<feature>/`",
"`.scratch/queue.md`",
"`.scratch/<feature>/.main-loop.json`",
):
self.assertIn(durable_path, integration)
self.assertIn("不得用\n`git add .scratch`", integration)
self.assertIn("不得 amend 或 squash", integration)
self.assertIn("`MAIN_INTEGRATION_COMMIT`", integration)
def test_agent_rules_defines_a_local_ticket_execution_adapter(self):
rules = rules_text()
main_flow = section(rules, "## 正式工程主链", "## On-ramps 与 detours")