diff --git a/.agents/skills/doc_quality_policy/publish_review_signal.py b/.agents/skills/doc_quality_policy/publish_review_signal.py index 56a3dd073..53e33e57e 100644 --- a/.agents/skills/doc_quality_policy/publish_review_signal.py +++ b/.agents/skills/doc_quality_policy/publish_review_signal.py @@ -20,6 +20,7 @@ "approve with nits": "COMMENT", "approve_with_nits": "COMMENT", "request changes": "COMMENT", + "request_changes": "COMMENT", } diff --git a/.agents/skills/doc_quality_policy/test_publish_review_signal.py b/.agents/skills/doc_quality_policy/test_publish_review_signal.py index 1c879ee27..f58100a65 100644 --- a/.agents/skills/doc_quality_policy/test_publish_review_signal.py +++ b/.agents/skills/doc_quality_policy/test_publish_review_signal.py @@ -74,6 +74,22 @@ def test_request_changes_maps_to_non_blocking_github_comment(self): self.assertEqual(payload["event"], "COMMENT") self.assertIn("canonical subagent terminology", payload["body"]) + def test_request_changes_underscore_spelling_maps_to_non_blocking_comment(self): + payload = prs.build_review_payload( + _signal( + "request_changes", + important=1, + blocking_findings=[ + "`src/content/docs/example.mdx:42` — Use the canonical subagent " + "terminology. Requested change: replace `children` with `subagents`." + ], + ), + "1", + "sha1", + "github-actions[bot]", + ) + self.assertEqual(payload["event"], "COMMENT") + def test_rejects_blocking_verdict_without_actionable_findings(self): with self.assertRaisesRegex(ValueError, "blocking_findings"): prs.build_review_payload( diff --git a/.agents/skills/review-docs-pr/SKILL.md b/.agents/skills/review-docs-pr/SKILL.md index bab12cff7..faa30e928 100644 --- a/.agents/skills/review-docs-pr/SKILL.md +++ b/.agents/skills/review-docs-pr/SKILL.md @@ -200,13 +200,14 @@ the review yourself. Emit the signal with `reviewer_login` set to `github-actions[bot]`; the GitHub Actions runner publishes the review with its short-lived token after the cloud agent returns. -1. Determine the authenticated reviewer and map the verdict: +1. Determine the authenticated reviewer: ```bash REVIEWER_LOGIN=$(gh api user --jq .login) ``` - Use `APPROVE` for `Approve` and `Approve with nits`; nits do not block - merge, so an approval supersedes any earlier change request from the same - reviewer. Use `REQUEST_CHANGES` only for `Request changes`. + Every verdict — `Approve`, `Approve with nits`, and `Request changes` — + publishes as a non-blocking `COMMENT` GitHub review event. The required + `Agent docs review` status check still fails on critical or important + findings. Engineering review requests remain advisory. 2. Write the signal JSON object to `/tmp/review-signal.json`, set its `reviewer_login` to `$REVIEWER_LOGIN`, and render that same object as the `[SIGNAL:pr-review]` line in the final response. Then construct the @@ -223,9 +224,9 @@ short-lived token after the cloud agent returns. review = json.loads(Path("review.json").read_text()) signal = json.loads(Path("/tmp/review-signal.json").read_text()) event = { - "Approve": "APPROVE", - "Approve with nits": "APPROVE", - "Request changes": "REQUEST_CHANGES", + "Approve": "COMMENT", + "Approve with nits": "COMMENT", + "Request changes": "COMMENT", }[os.environ["VERDICT"]] findings = [] for comment in review["comments"]: diff --git a/.agents/skills/review-docs-pr/test_publishing_snippet.py b/.agents/skills/review-docs-pr/test_publishing_snippet.py index 48e32a5d2..5da62fc4d 100644 --- a/.agents/skills/review-docs-pr/test_publishing_snippet.py +++ b/.agents/skills/review-docs-pr/test_publishing_snippet.py @@ -114,6 +114,12 @@ def test_hidden_signal_remains_parseable(self): self.assertEqual(problems, []) self.assertEqual(parsed["verdict"], signal["verdict"]) + def test_policy_distinguishes_comment_event_from_required_check(self): + text = SKILL.read_text(encoding="utf-8") + self.assertIn("non-blocking `COMMENT` GitHub review event", text) + self.assertIn("`Agent docs review` status check still fails", text) + self.assertIn("Engineering review requests remain advisory.", text) + def test_findings_and_verdict_are_still_rendered(self): payload, _ = self._run( comments=[{"path": "a.md", "line": 3, "body": "Fix this typo."}], @@ -122,7 +128,7 @@ def test_findings_and_verdict_are_still_rendered(self): self.assertIn("## Findings", payload["body"]) self.assertIn("`a.md:3` — Fix this typo.", payload["body"]) self.assertIn("## Verdict\nRequest changes", payload["body"]) - self.assertEqual(payload["event"], "REQUEST_CHANGES") + self.assertEqual(payload["event"], "COMMENT") if __name__ == "__main__": diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6bed93bbf..6a00fe72e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,6 +63,7 @@ jobs: python3 .agents/skills/doc_quality_policy/test_check_compression_contract.py python3 .agents/skills/doc_quality_policy/test_verify_review_signal.py python3 .agents/skills/doc_quality_policy/test_publish_review_signal.py + python3 .agents/skills/doc_quality_policy/test_stale_review_requests.py python3 .agents/skills/doc_quality_policy/test_agent_docs_review_workflow.py python3 .agents/skills/doc_quality_policy/test_manifest.py