fix: #412/#413/#414 runtime stability and PR governance preflight #415
@@ -50,11 +50,13 @@ def validate_pr_body_text(text: str, *, check_governance: bool = True) -> list[s
|
|||||||
if not LIST_ITEM_PATTERN.search(text):
|
if not LIST_ITEM_PATTERN.search(text):
|
||||||
errors.append("body is missing markdown list items")
|
errors.append("body is missing markdown list items")
|
||||||
if check_governance:
|
if check_governance:
|
||||||
if not REQ_ID_PATTERN.search(text):
|
# Check governance IDs against code-stripped text so IDs hidden in code
|
||||||
|
# blocks or inline code are not counted (prevents spoof via code fences).
|
||||||
|
if not REQ_ID_PATTERN.search(searchable):
|
||||||
errors.append("body is missing REQ-ID traceability (e.g. REQ-OPS-001)")
|
errors.append("body is missing REQ-ID traceability (e.g. REQ-OPS-001)")
|
||||||
if not TASK_ID_PATTERN.search(text):
|
if not TASK_ID_PATTERN.search(searchable):
|
||||||
errors.append("body is missing TASK-ID traceability (e.g. TASK-OPS-001)")
|
errors.append("body is missing TASK-ID traceability (e.g. TASK-OPS-001)")
|
||||||
if not TEST_ID_PATTERN.search(text):
|
if not TEST_ID_PATTERN.search(searchable):
|
||||||
errors.append("body is missing TEST-ID traceability (e.g. TEST-OPS-001)")
|
errors.append("body is missing TEST-ID traceability (e.g. TEST-OPS-001)")
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,26 @@ def test_validate_pr_body_text_skips_governance_when_disabled() -> None:
|
|||||||
assert not any("REQ-ID" in err or "TASK-ID" in err or "TEST-ID" in err for err in errors)
|
assert not any("REQ-ID" in err or "TASK-ID" in err or "TEST-ID" in err for err in errors)
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_pr_body_text_rejects_governance_ids_in_code_block_only() -> None:
|
||||||
|
"""Regression for review comment: IDs inside code fences must not count."""
|
||||||
|
module = _load_module()
|
||||||
|
text = "\n".join(
|
||||||
|
[
|
||||||
|
"## Summary",
|
||||||
|
"- no governance IDs in narrative text",
|
||||||
|
"```text",
|
||||||
|
"REQ-FAKE-999",
|
||||||
|
"TASK-FAKE-999",
|
||||||
|
"TEST-FAKE-999",
|
||||||
|
"```",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
errors = module.validate_pr_body_text(text)
|
||||||
|
assert any("REQ-ID" in err for err in errors)
|
||||||
|
assert any("TASK-ID" in err for err in errors)
|
||||||
|
assert any("TEST-ID" in err for err in errors)
|
||||||
|
|
||||||
|
|
||||||
def test_fetch_pr_body_reads_body_from_tea_api(monkeypatch) -> None:
|
def test_fetch_pr_body_reads_body_from_tea_api(monkeypatch) -> None:
|
||||||
module = _load_module()
|
module = _load_module()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user