From 6437ba18182e26fbe3a9e2ff0f6b8b09edfec160 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 3 Sep 2026 12:01:57 +0900 Subject: [PATCH 01/10] fix(ci): skip docs-only changes for Tests, OpenSSF Evidence Coverage, Pinned HTTPS Coverage, Retention Audit Coverage, Scan path context coverage Org-wide audit flagged these workflows as lacking paths-ignore, triggering full CI on every docs-only push/PR and contributing to org-wide Actions queue congestion. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/openssf-evidence-coverage.yml | 6 ++++++ .github/workflows/pinned-https-coverage.yml | 6 ++++++ .github/workflows/retention-audit-coverage.yml | 6 ++++++ .github/workflows/scan-path-context-coverage.yml | 6 ++++++ .github/workflows/tests.yml | 6 ++++++ 5 files changed, 30 insertions(+) diff --git a/.github/workflows/openssf-evidence-coverage.yml b/.github/workflows/openssf-evidence-coverage.yml index 782d7720..c5e9d0dc 100644 --- a/.github/workflows/openssf-evidence-coverage.yml +++ b/.github/workflows/openssf-evidence-coverage.yml @@ -3,8 +3,14 @@ name: OpenSSF Evidence Coverage on: pull_request: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" push: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" permissions: contents: read diff --git a/.github/workflows/pinned-https-coverage.yml b/.github/workflows/pinned-https-coverage.yml index 6149a566..91e19f0f 100644 --- a/.github/workflows/pinned-https-coverage.yml +++ b/.github/workflows/pinned-https-coverage.yml @@ -3,8 +3,14 @@ name: Pinned HTTPS Coverage on: pull_request: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" push: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" permissions: contents: read diff --git a/.github/workflows/retention-audit-coverage.yml b/.github/workflows/retention-audit-coverage.yml index 3c4d0f71..f2bc5b68 100644 --- a/.github/workflows/retention-audit-coverage.yml +++ b/.github/workflows/retention-audit-coverage.yml @@ -3,8 +3,14 @@ name: Retention Audit Coverage on: pull_request: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" push: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" permissions: contents: read diff --git a/.github/workflows/scan-path-context-coverage.yml b/.github/workflows/scan-path-context-coverage.yml index 4cee4b8c..aa3148f9 100644 --- a/.github/workflows/scan-path-context-coverage.yml +++ b/.github/workflows/scan-path-context-coverage.yml @@ -3,8 +3,14 @@ name: Scan path context coverage on: push: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" pull_request: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" permissions: contents: read diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8ce929df..7594811a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,8 +3,14 @@ name: Tests on: push: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" pull_request: branches: [develop, main] + paths-ignore: + - "docs/**" + - "*.md" permissions: contents: read From 22c303e0475c8c65d85460fe97693d9aa9dc0262 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 3 Sep 2026 13:14:38 +0900 Subject: [PATCH 02/10] fix(ci): ignore Markdown documentation at any depth --- .../workflows/openssf-evidence-coverage.yml | 4 ++-- .github/workflows/pinned-https-coverage.yml | 4 ++-- .../workflows/retention-audit-coverage.yml | 4 ++-- .../workflows/scan-path-context-coverage.yml | 4 ++-- .github/workflows/tests.yml | 4 ++-- tests/test_docs_only_workflow_filters.py | 23 +++++++++++++++++++ 6 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 tests/test_docs_only_workflow_filters.py diff --git a/.github/workflows/openssf-evidence-coverage.yml b/.github/workflows/openssf-evidence-coverage.yml index c5e9d0dc..4d43c764 100644 --- a/.github/workflows/openssf-evidence-coverage.yml +++ b/.github/workflows/openssf-evidence-coverage.yml @@ -5,12 +5,12 @@ on: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" push: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" permissions: contents: read diff --git a/.github/workflows/pinned-https-coverage.yml b/.github/workflows/pinned-https-coverage.yml index 91e19f0f..f8618d61 100644 --- a/.github/workflows/pinned-https-coverage.yml +++ b/.github/workflows/pinned-https-coverage.yml @@ -5,12 +5,12 @@ on: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" push: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" permissions: contents: read diff --git a/.github/workflows/retention-audit-coverage.yml b/.github/workflows/retention-audit-coverage.yml index f2bc5b68..b4fe4652 100644 --- a/.github/workflows/retention-audit-coverage.yml +++ b/.github/workflows/retention-audit-coverage.yml @@ -5,12 +5,12 @@ on: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" push: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" permissions: contents: read diff --git a/.github/workflows/scan-path-context-coverage.yml b/.github/workflows/scan-path-context-coverage.yml index aa3148f9..307d4e75 100644 --- a/.github/workflows/scan-path-context-coverage.yml +++ b/.github/workflows/scan-path-context-coverage.yml @@ -5,12 +5,12 @@ on: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" pull_request: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" permissions: contents: read diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7594811a..839a34ec 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,12 +5,12 @@ on: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" pull_request: branches: [develop, main] paths-ignore: - "docs/**" - - "*.md" + - "**.md" permissions: contents: read diff --git a/tests/test_docs_only_workflow_filters.py b/tests/test_docs_only_workflow_filters.py new file mode 100644 index 00000000..1c87313e --- /dev/null +++ b/tests/test_docs_only_workflow_filters.py @@ -0,0 +1,23 @@ +"""Contracts for docs-only workflow path filtering.""" + +from pathlib import Path + +import pytest + + +WORKFLOWS = ( + ".github/workflows/tests.yml", + ".github/workflows/openssf-evidence-coverage.yml", + ".github/workflows/pinned-https-coverage.yml", + ".github/workflows/retention-audit-coverage.yml", + ".github/workflows/scan-path-context-coverage.yml", +) + + +@pytest.mark.parametrize("workflow_path", WORKFLOWS) +def test_docs_only_filters_ignore_markdown_at_any_depth(workflow_path: str) -> None: + """Optimized workflows skip Markdown anywhere, not only at repository root.""" + workflow = Path(workflow_path).read_text(encoding="utf-8") + + assert workflow.count(' - "**.md"') == 2 + assert ' - "*.md"' not in workflow From 38e0537f600eb8108ceac674b7ff52099756f267 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 3 Sep 2026 13:46:32 +0900 Subject: [PATCH 03/10] test(ci): keep contract-sensitive docs under validation --- tests/test_docs_only_workflow_filters.py | 29 ++++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/tests/test_docs_only_workflow_filters.py b/tests/test_docs_only_workflow_filters.py index 1c87313e..3ead2023 100644 --- a/tests/test_docs_only_workflow_filters.py +++ b/tests/test_docs_only_workflow_filters.py @@ -1,4 +1,4 @@ -"""Contracts for docs-only workflow path filtering.""" +"""Contracts preventing documentation-backed behavior from bypassing CI.""" from pathlib import Path @@ -14,10 +14,29 @@ ) +def _event_block(workflow: str, event: str) -> str: + """Return one peer event block from the workflow's top-level ``on`` mapping.""" + lines = workflow.splitlines() + marker = f" {event}:" + try: + start = lines.index(marker) + except ValueError as exc: + raise AssertionError(f"missing workflow event: {event}") from exc + + block: list[str] = [] + for line in lines[start + 1 :]: + if line.startswith(" ") and not line.startswith(" "): + break + block.append(line) + return "\n".join(block) + + @pytest.mark.parametrize("workflow_path", WORKFLOWS) -def test_docs_only_filters_ignore_markdown_at_any_depth(workflow_path: str) -> None: - """Optimized workflows skip Markdown anywhere, not only at repository root.""" +def test_contract_sensitive_workflows_do_not_skip_documentation( + workflow_path: str, +) -> None: + """Docs and policy Markdown remain covered until a dedicated contract lane exists.""" workflow = Path(workflow_path).read_text(encoding="utf-8") - assert workflow.count(' - "**.md"') == 2 - assert ' - "*.md"' not in workflow + for event in ("push", "pull_request"): + assert "paths-ignore:" not in _event_block(workflow, event) From 6b66f93391872405332d17436ce1bba500d6c63c Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 3 Sep 2026 13:47:21 +0900 Subject: [PATCH 04/10] fix(ci): keep documentation contracts in full tests --- .github/workflows/tests.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 839a34ec..8ce929df 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,14 +3,8 @@ name: Tests on: push: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" pull_request: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" permissions: contents: read From 65af96ec0e05c1466edfdfad91dcd1d1db688373 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 3 Sep 2026 13:47:45 +0900 Subject: [PATCH 05/10] fix(ci): keep OpenSSF document contracts covered --- .github/workflows/openssf-evidence-coverage.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/openssf-evidence-coverage.yml b/.github/workflows/openssf-evidence-coverage.yml index 4d43c764..782d7720 100644 --- a/.github/workflows/openssf-evidence-coverage.yml +++ b/.github/workflows/openssf-evidence-coverage.yml @@ -3,14 +3,8 @@ name: OpenSSF Evidence Coverage on: pull_request: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" push: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" permissions: contents: read From d53f6534cec7b99ca2ab5890e31b2a1ee96febe7 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 3 Sep 2026 13:48:11 +0900 Subject: [PATCH 06/10] fix(ci): keep pinned-HTTPS document contracts covered --- .github/workflows/pinned-https-coverage.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/pinned-https-coverage.yml b/.github/workflows/pinned-https-coverage.yml index f8618d61..6149a566 100644 --- a/.github/workflows/pinned-https-coverage.yml +++ b/.github/workflows/pinned-https-coverage.yml @@ -3,14 +3,8 @@ name: Pinned HTTPS Coverage on: pull_request: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" push: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" permissions: contents: read From a0072fb49e10731d7f573902b08a52cd1bb18e58 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 3 Sep 2026 13:48:50 +0900 Subject: [PATCH 07/10] fix(ci): keep retention document contracts covered --- .github/workflows/retention-audit-coverage.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/retention-audit-coverage.yml b/.github/workflows/retention-audit-coverage.yml index b4fe4652..3c4d0f71 100644 --- a/.github/workflows/retention-audit-coverage.yml +++ b/.github/workflows/retention-audit-coverage.yml @@ -3,14 +3,8 @@ name: Retention Audit Coverage on: pull_request: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" push: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" permissions: contents: read From e159c7b2a3269d918727e41a92898d1df95eee01 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 3 Sep 2026 13:49:19 +0900 Subject: [PATCH 08/10] fix(ci): keep scan-path document contracts covered --- .github/workflows/scan-path-context-coverage.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/scan-path-context-coverage.yml b/.github/workflows/scan-path-context-coverage.yml index 307d4e75..4cee4b8c 100644 --- a/.github/workflows/scan-path-context-coverage.yml +++ b/.github/workflows/scan-path-context-coverage.yml @@ -3,14 +3,8 @@ name: Scan path context coverage on: push: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" pull_request: branches: [develop, main] - paths-ignore: - - "docs/**" - - "**.md" permissions: contents: read From f1172f0b5cbeb8ce0f7f7ef8c38a468353b45f62 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 8 Sep 2026 12:12:25 +0900 Subject: [PATCH 09/10] test(ci): require checks on stacked pull requests --- tests/test_docs_only_workflow_filters.py | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/tests/test_docs_only_workflow_filters.py b/tests/test_docs_only_workflow_filters.py index 3ead2023..893bda77 100644 --- a/tests/test_docs_only_workflow_filters.py +++ b/tests/test_docs_only_workflow_filters.py @@ -1,11 +1,11 @@ -"""Contracts preventing documentation-backed behavior from bypassing CI.""" +"""Contracts preventing CI admission gaps for documentation and stacked pull requests.""" from pathlib import Path import pytest -WORKFLOWS = ( +CONTRACT_SENSITIVE_WORKFLOWS = ( ".github/workflows/tests.yml", ".github/workflows/openssf-evidence-coverage.yml", ".github/workflows/pinned-https-coverage.yml", @@ -13,6 +13,17 @@ ".github/workflows/scan-path-context-coverage.yml", ) +STACKED_PR_WORKFLOWS = ( + ".github/workflows/tests.yml", + ".github/workflows/security-process.yml", + ".github/workflows/openssf-evidence-coverage.yml", + ".github/workflows/pinned-https-coverage.yml", + ".github/workflows/retention-audit-coverage.yml", + ".github/workflows/scan-path-context-coverage.yml", + ".github/workflows/controlplane-schema-coverage.yml", + ".github/workflows/commercial-readiness-agent-coverage.yml", +) + def _event_block(workflow: str, event: str) -> str: """Return one peer event block from the workflow's top-level ``on`` mapping.""" @@ -31,7 +42,7 @@ def _event_block(workflow: str, event: str) -> str: return "\n".join(block) -@pytest.mark.parametrize("workflow_path", WORKFLOWS) +@pytest.mark.parametrize("workflow_path", CONTRACT_SENSITIVE_WORKFLOWS) def test_contract_sensitive_workflows_do_not_skip_documentation( workflow_path: str, ) -> None: @@ -40,3 +51,11 @@ def test_contract_sensitive_workflows_do_not_skip_documentation( for event in ("push", "pull_request"): assert "paths-ignore:" not in _event_block(workflow, event) + + +@pytest.mark.parametrize("workflow_path", STACKED_PR_WORKFLOWS) +def test_pull_request_checks_admit_stacked_bases(workflow_path: str) -> None: + """PR checks must materialize when a reviewable stack targets another feature branch.""" + workflow = Path(workflow_path).read_text(encoding="utf-8") + + assert "branches:" not in _event_block(workflow, "pull_request") From cf5e3557109cfb947d1a487cc0f9503242ca30e5 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 8 Sep 2026 12:15:16 +0900 Subject: [PATCH 10/10] fix(ci): admit stacked pull-request bases --- .github/workflows/commercial-readiness-agent-coverage.yml | 1 - .github/workflows/controlplane-schema-coverage.yml | 1 - .github/workflows/openssf-evidence-coverage.yml | 1 - .github/workflows/pinned-https-coverage.yml | 1 - .github/workflows/retention-audit-coverage.yml | 1 - .github/workflows/scan-path-context-coverage.yml | 1 - .github/workflows/security-process.yml | 1 - .github/workflows/tests.yml | 1 - 8 files changed, 8 deletions(-) diff --git a/.github/workflows/commercial-readiness-agent-coverage.yml b/.github/workflows/commercial-readiness-agent-coverage.yml index ff362412..680875e7 100644 --- a/.github/workflows/commercial-readiness-agent-coverage.yml +++ b/.github/workflows/commercial-readiness-agent-coverage.yml @@ -20,7 +20,6 @@ on: - ".github/workflows/commercial-readiness-loop.yml" - ".github/workflows/commercial-readiness-agent-coverage.yml" pull_request: - branches: [develop, main] paths: - "scripts/ci/commercial_readiness_loop.py" - "scripts/ci/commercial_readiness_reconcile.py" diff --git a/.github/workflows/controlplane-schema-coverage.yml b/.github/workflows/controlplane-schema-coverage.yml index 9059283f..22d3c15b 100644 --- a/.github/workflows/controlplane-schema-coverage.yml +++ b/.github/workflows/controlplane-schema-coverage.yml @@ -11,7 +11,6 @@ on: - "CHANGELOG.d/871-retention-schema-migration.md" - ".github/workflows/controlplane-schema-coverage.yml" pull_request: - branches: [develop, main] paths: - "appguardrail_core/controlplane_schema.py" - "appguardrail_core/__init__.py" diff --git a/.github/workflows/openssf-evidence-coverage.yml b/.github/workflows/openssf-evidence-coverage.yml index 782d7720..cc0de91c 100644 --- a/.github/workflows/openssf-evidence-coverage.yml +++ b/.github/workflows/openssf-evidence-coverage.yml @@ -2,7 +2,6 @@ name: OpenSSF Evidence Coverage on: pull_request: - branches: [develop, main] push: branches: [develop, main] diff --git a/.github/workflows/pinned-https-coverage.yml b/.github/workflows/pinned-https-coverage.yml index 6149a566..0003cc7f 100644 --- a/.github/workflows/pinned-https-coverage.yml +++ b/.github/workflows/pinned-https-coverage.yml @@ -2,7 +2,6 @@ name: Pinned HTTPS Coverage on: pull_request: - branches: [develop, main] push: branches: [develop, main] diff --git a/.github/workflows/retention-audit-coverage.yml b/.github/workflows/retention-audit-coverage.yml index 3c4d0f71..78619fcf 100644 --- a/.github/workflows/retention-audit-coverage.yml +++ b/.github/workflows/retention-audit-coverage.yml @@ -2,7 +2,6 @@ name: Retention Audit Coverage on: pull_request: - branches: [develop, main] push: branches: [develop, main] diff --git a/.github/workflows/scan-path-context-coverage.yml b/.github/workflows/scan-path-context-coverage.yml index 4cee4b8c..08e63bcd 100644 --- a/.github/workflows/scan-path-context-coverage.yml +++ b/.github/workflows/scan-path-context-coverage.yml @@ -4,7 +4,6 @@ on: push: branches: [develop, main] pull_request: - branches: [develop, main] permissions: contents: read diff --git a/.github/workflows/security-process.yml b/.github/workflows/security-process.yml index 46716c39..95dee869 100644 --- a/.github/workflows/security-process.yml +++ b/.github/workflows/security-process.yml @@ -4,7 +4,6 @@ on: push: branches: [develop, main, master] pull_request: - branches: [develop, main, master] schedule: - cron: "31 4 * * 1" workflow_dispatch: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8ce929df..eaeea17c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,7 +4,6 @@ on: push: branches: [develop, main] pull_request: - branches: [develop, main] permissions: contents: read