From ce3fcd15d9747ad48e60a7002ed0f2fed7404fa9 Mon Sep 17 00:00:00 2001 From: Michael Suchacz <203725896+ibetitsmike@users.noreply.github.com> Date: Fri, 11 Sep 2026 18:20:07 +0000 Subject: [PATCH] ci: accept resolved Codex advisories on the review summary board Codex keeps resolved security advisories listed on its summary board and only adds the Resolved marker once a later review completes, so a completed board with the "Security findings" section failed the Codex Comments gate forever. Whitelist the section header, the advisory count line and bullets that link a review thread on this PR and end with Codex's Resolved marker; bare bullets, unknown sections and non-thread links keep blocking. --- scripts/check_codex_comments_test.py | 9 +++++++++ scripts/lib/codex_comments.jq | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/scripts/check_codex_comments_test.py b/scripts/check_codex_comments_test.py index acb98798ba..f6804e7f81 100644 --- a/scripts/check_codex_comments_test.py +++ b/scripts/check_codex_comments_test.py @@ -169,11 +169,20 @@ def test_summary_completion_requires_metadata_and_every_review_row(self): .replace('"status":"running"', '"status":"completed"') .replace("🔄 **Running** since", "✅ **Completed**") ) + # Codex keeps resolved advisories on the board; only its own Resolved marker, + # not a bare bullet, an unknown section, or a non-thread link, is informational. + resolved_findings = completed_findings.replace( + ") · **Medium**", ") · **Medium** · **Resolved**" + ) for body, expected in ( (completed.replace('"status":"completed"', '"status":"running"'), 1), (completed.replace("✅ **Completed**", "🔄 **Running** since", 1), 1), (completed_pr_opened, 0), (completed_findings, 1), + (resolved_findings, 0), + (resolved_findings.replace("#### Advisory findings", "#### Blocking findings"), 1), + (resolved_findings.replace("#discussion_r3960253571", "#issuecomment-1"), 1), + (resolved_findings.replace("· **Resolved**", "· **Resolved** see below"), 1), ): for cached in (False, True): with self.subTest(body=body, cached=cached): diff --git a/scripts/lib/codex_comments.jq b/scripts/lib/codex_comments.jq index e26403e38b..e28b3c225e 100644 --- a/scripts/lib/codex_comments.jq +++ b/scripts/lib/codex_comments.jq @@ -45,6 +45,13 @@ def codex_comment_is_informational($bot): + "[^[:alnum:]|]*\\*\\*Completed\\*\\*" + "( [0-9TZ:.+-]+)? " + "\\| `[0-9a-f]+` \\| (Manual request|New commits|Draft marked ready|PR opened) \\|$") + # Security advisories stay listed after their review threads are resolved, and + # Codex adds the Resolved marker only when a later review completes. A bullet + # without it is a live finding and keeps blocking; other sections stay unknown. + or . == "### Security findings" + or test("^#### Advisory findings \\([0-9]+\\)$") + or test("^- [^[:alnum:]|\\[]*\\[[^\\]]+\\]\\(https://github\\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+/pull/[0-9]+#discussion_r[0-9]+\\)" + + " · \\*\\*[A-Za-z]+\\*\\* · \\*\\*Resolved\\*\\*$") )) ) catch false) // false else