From 451bcf754cf4a5a41fa38a1d37018d628681f5ad Mon Sep 17 00:00:00 2001 From: Oz Date: Tue, 8 Sep 2026 21:28:45 +0000 Subject: [PATCH 1/2] fix(docs): follow-up fixes for agent-docs-review non-blocking gate PR #688 merged with three unaddressed review findings. This fixes them: - publish_review_signal.py: recognize the request_changes (underscore) verdict spelling alongside 'request changes', matching verify_review_signal.py's _BLOCKING_VERDICTS and preventing an 'unsupported review verdict' crash for a valid signal spelling. - review-docs-pr/SKILL.md: the manual publishing snippet now maps every verdict (Approve, Approve with nits, Request changes) to a non-blocking COMMENT review, matching the automated publisher and the PR's stated goal that the independent agent's review never blocks merge. - ci.yml: invoke test_stale_review_requests.py in the doc_quality_policy test step so its regression coverage actually runs in CI. Adds regression tests for the request_changes spelling and updates test_publishing_snippet.py to expect COMMENT for a request-changes verdict. Ref: #688, QUALITY-2048 --- .../doc_quality_policy/publish_review_signal.py | 1 + .../test_publish_review_signal.py | 16 ++++++++++++++++ .agents/skills/review-docs-pr/SKILL.md | 15 ++++++++------- .../review-docs-pr/test_publishing_snippet.py | 2 +- .github/workflows/ci.yml | 1 + 5 files changed, 27 insertions(+), 8 deletions(-) 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..53ed425e8 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` review. The independent agent's + review never blocks merge; only a human reviewer or the engineering-review + gate can request changes. 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..aa9c687d4 100644 --- a/.agents/skills/review-docs-pr/test_publishing_snippet.py +++ b/.agents/skills/review-docs-pr/test_publishing_snippet.py @@ -122,7 +122,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 From fc4f2d0a1e774b6a8f49c28cb3059d35f938349c Mon Sep 17 00:00:00 2001 From: Rachael Rose Renk <91027132+rachaelrenk@users.noreply.github.com> Date: Tue, 8 Sep 2026 16:10:04 -0600 Subject: [PATCH 2/2] fix(docs): clarify agent review enforcement Co-Authored-By: Warp --- .agents/skills/review-docs-pr/SKILL.md | 6 +++--- .agents/skills/review-docs-pr/test_publishing_snippet.py | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.agents/skills/review-docs-pr/SKILL.md b/.agents/skills/review-docs-pr/SKILL.md index 53ed425e8..faa30e928 100644 --- a/.agents/skills/review-docs-pr/SKILL.md +++ b/.agents/skills/review-docs-pr/SKILL.md @@ -205,9 +205,9 @@ short-lived token after the cloud agent returns. REVIEWER_LOGIN=$(gh api user --jq .login) ``` Every verdict — `Approve`, `Approve with nits`, and `Request changes` — - publishes as a non-blocking `COMMENT` review. The independent agent's - review never blocks merge; only a human reviewer or the engineering-review - gate can 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 diff --git a/.agents/skills/review-docs-pr/test_publishing_snippet.py b/.agents/skills/review-docs-pr/test_publishing_snippet.py index aa9c687d4..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."}],