docs: split LLM project workflow into task-specific modes (Closes #333)
Consolidate all four canonical workflow files and router SKILL.md: - review-merge-pr.md (from #334 canonical prompt) - reconcile-landed-pr.md (reconciliation gates + handoff schema) - create-issue.md (canonical issue-creation prompt) - work-issue.md (canonical author/coder prompt) SKILL.md is now a short router with mode isolation and universal rules. Adds final-report schemas for all modes and 13 doc-contract tests. Supersedes partial split work in PR #335; full #333 acceptance in one PR.
This commit is contained in:
@@ -3,43 +3,96 @@ from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
SKILL_DIR = REPO_ROOT / "skills" / "llm-project-workflow"
|
||||
SKILL = (SKILL_DIR / "SKILL.md").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_work_issue_workflow_file_exists():
|
||||
path = SKILL_DIR / "workflows" / "work-issue.md"
|
||||
text = path.read_text(encoding="utf-8")
|
||||
def test_skill_md_exists():
|
||||
assert SKILL_DIR.joinpath("SKILL.md").is_file()
|
||||
|
||||
|
||||
def test_all_workflow_files_exist():
|
||||
for name in (
|
||||
"review-merge-pr.md",
|
||||
"reconcile-landed-pr.md",
|
||||
"create-issue.md",
|
||||
"work-issue.md",
|
||||
):
|
||||
assert (SKILL_DIR / "workflows" / name).is_file(), name
|
||||
|
||||
|
||||
def test_skill_references_all_workflow_files():
|
||||
for name in (
|
||||
"workflows/review-merge-pr.md",
|
||||
"workflows/reconcile-landed-pr.md",
|
||||
"workflows/create-issue.md",
|
||||
"workflows/work-issue.md",
|
||||
):
|
||||
assert name in SKILL
|
||||
|
||||
|
||||
def test_skill_contains_mode_isolation_language():
|
||||
assert "## Mode isolation" in SKILL
|
||||
assert "review-merge-pr" in SKILL
|
||||
assert "reconcile-landed-pr" in SKILL
|
||||
assert "create-issue" in SKILL
|
||||
assert "work-issue" in SKILL
|
||||
assert "Do not mix modes" in SKILL or "do not mix modes" in SKILL.lower()
|
||||
|
||||
|
||||
def test_skill_is_router_not_monolithic_review_body():
|
||||
assert "This skill is a **router**" in SKILL or "router" in SKILL.lower()
|
||||
assert "## F. Review workflow" not in SKILL
|
||||
assert "gitea_mark_final_review_decision" not in SKILL
|
||||
assert "gitea_submit_pr_review" not in SKILL
|
||||
|
||||
|
||||
def test_review_merge_workflow_contract():
|
||||
text = (SKILL_DIR / "workflows" / "review-merge-pr.md").read_text(encoding="utf-8")
|
||||
assert "canonical: true" in text
|
||||
assert "work-issue" in text
|
||||
assert "## 0. Load the canonical workflow first" in text
|
||||
assert "## 29. Controller handoff schema" in text
|
||||
assert "## 30. Stop conditions summary" in text
|
||||
assert "ISSUE_ELIGIBILITY_UNVERIFIED" in text
|
||||
assert "OPEN_PR_EXISTS" in text
|
||||
assert "author/coder workflow" in text.lower()
|
||||
assert "## 26A. Terminal review mutation hard-stop" in text
|
||||
assert "## 11A. Skipped PRs are read-only" in text
|
||||
assert "## 35. Duplicate request-changes prevention" in text
|
||||
assert "ALREADY_LANDED_RECONCILE_REQUIRED" in text
|
||||
|
||||
|
||||
def test_work_issue_final_report_schema_exists():
|
||||
path = SKILL_DIR / "schemas" / "work-issue-final-report.md"
|
||||
text = path.read_text(encoding="utf-8")
|
||||
assert "Controller Handoff" in text
|
||||
assert "Issue inventory pagination proof:" in text
|
||||
assert "File edits by author:" in text
|
||||
assert "Workspace mutations" in text # documented as rejected
|
||||
def test_reconcile_landed_workflow_contract():
|
||||
text = (SKILL_DIR / "workflows" / "reconcile-landed-pr.md").read_text(encoding="utf-8")
|
||||
assert "canonical: true" in text
|
||||
assert "Do not review or merge normal PRs" in text
|
||||
assert "Already-landed proof" in text
|
||||
|
||||
|
||||
def test_skill_router_points_to_work_issue_workflow():
|
||||
skill = (SKILL_DIR / "SKILL.md").read_text(encoding="utf-8")
|
||||
assert "## Task mode router" in skill
|
||||
assert "workflows/work-issue.md" in skill
|
||||
assert "schemas/work-issue-final-report.md" in skill
|
||||
assert "Identify task mode before any mutation" in skill
|
||||
def test_create_issue_workflow_contract():
|
||||
text = (SKILL_DIR / "workflows" / "create-issue.md").read_text(encoding="utf-8")
|
||||
assert "canonical: true" in text
|
||||
assert "## 9. Duplicate search before mutation" in text
|
||||
|
||||
|
||||
def test_skill_still_declares_controller_handoff_contract():
|
||||
skill = (SKILL_DIR / "SKILL.md").read_text(encoding="utf-8")
|
||||
assert "## Controller Handoff" in skill
|
||||
assert "assess_controller_handoff" in skill
|
||||
assert "## Global LLM Worktree Rule" in skill
|
||||
def test_work_issue_workflow_contract():
|
||||
text = (SKILL_DIR / "workflows" / "work-issue.md").read_text(encoding="utf-8")
|
||||
assert "canonical: true" in text
|
||||
assert "Do not merge your own PR" in text
|
||||
assert "## 21. PR creation rules" in text
|
||||
|
||||
|
||||
def test_final_report_schemas_exist():
|
||||
for name in (
|
||||
"review-merge-final-report.md",
|
||||
"reconcile-landed-final-report.md",
|
||||
"create-issue-final-report.md",
|
||||
"work-issue-final-report.md",
|
||||
):
|
||||
assert (SKILL_DIR / "schemas" / name).is_file(), name
|
||||
|
||||
|
||||
def test_review_pr_template_references_workflow():
|
||||
text = (SKILL_DIR / "templates" / "review-pr.md").read_text(encoding="utf-8")
|
||||
assert "workflows/review-merge-pr.md" in text
|
||||
|
||||
|
||||
def test_merge_pr_template_references_workflow():
|
||||
text = (SKILL_DIR / "templates" / "merge-pr.md").read_text(encoding="utf-8")
|
||||
assert "workflows/review-merge-pr.md" in text
|
||||
|
||||
|
||||
def test_start_issue_template_references_work_issue_workflow():
|
||||
|
||||
Reference in New Issue
Block a user