From 6a038a47b0c9d7089754040465878baf332f5940 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Wed, 19 Aug 2026 10:12:12 -0700 Subject: [PATCH 1/4] Label Audit Commands as Bash --- AUDIT.md | 6 +++--- scripts/tests/test_release_guards.py | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/AUDIT.md b/AUDIT.md index 96977dc1..fac1abe3 100644 --- a/AUDIT.md +++ b/AUDIT.md @@ -95,7 +95,7 @@ Run [`WORKFLOW.md`][workflow]'s methodology against the repo's **own** Actions: - **General settings** - diff the live repository settings against [`repo-config/settings.json`][repo-config-settings], and confirm the two state-dependent settings: `has_discussions` follows visibility (public on / private off) and `default_branch` is `main`. - ```sh + ```bash live=$(gh api "repos//" --jq '{has_wiki,has_projects,allow_merge_commit,allow_squash_merge,allow_rebase_merge,allow_auto_merge,allow_update_branch,delete_branch_on_merge}') diff <(jq -S . repo-config/settings.json) <(jq -S . <<<"$live") \ && echo "settings: in sync" || echo "settings: DRIFT" @@ -103,7 +103,7 @@ Run [`WORKFLOW.md`][workflow]'s methodology against the repo's **own** Actions: - **Rulesets** - diff each live ruleset against the committed expected payload with a normalized comparison (sort the order-insensitive `rules[]` on each rule's whole content before diffing, so a reordered but equivalent ruleset does not read as drift). The compared subset is `name`, `target`, `enforcement`, `conditions` and `rules`, and `bypass_actors` sits deliberately outside it, which is the same subset and the same sort key [`spec/audit.py`][audit-runner] uses. Who may bypass a ruleset is a per-repository human decision taken in the UI, no payload declares one, and [`repo-config/configure.sh`][repo-config] treats it that way in both modes, writing the live list back unchanged on `apply` and reporting it without asserting on `check`. Comparing it here would contradict that and report a ruleset finding against every repository that has any bypass actor, which is the field's normal state rather than a deviation: - ```sh + ```bash # bypass_actors stays outside the projection, since no payload declares one and jq cannot sort the null that leaves. # Rules sort on each rule's whole content, matching the key normalize_ruleset in audit.py sorts by. # Sorting on .type alone leaves two rules of one type in input order, so a reordered pair would read as drift. @@ -135,7 +135,7 @@ Run [`WORKFLOW.md`][workflow]'s methodology against the repo's **own** Actions: - **Dependabot ecosystem coverage** - for each ecosystem the repo's tree implies, `.github/dependabot.yml` must declare it: `github-actions` when `.github/workflows/` is present (its workflows reference actions, and otherwise those versions go stale and a stood-up merge-bot has no action-update PRs to auto-merge), and `devcontainers` when a `.devcontainer` is present. The mechanical check (`spec/audit.py`) asserts each implied ecosystem's **presence**. A tree-implied ecosystem declared nowhere is a **drift finding** (the file exists, so its absence would instead be a file-presence letter). Then confirm **by inspection** that each declared ecosystem **dual-targets `main` + `develop`** per the [Branching Model][governance-branching-model], since the regex below cannot pair an ecosystem with its `target-branch`. Language ecosystems (`nuget`/`uv`/`npm`) are directory-scoped and audited by inspection too. - ```sh + ```bash # Anchor to the line start (optional list dash) so a commented-out '# package-ecosystem:' is not counted. dependabot_content=$(gh api "repos///contents/.github/dependabot.yml?ref=" --jq '.content') || exit 1 dependabot_yaml=$(base64 -d <<<"$dependabot_content") || exit 1 diff --git a/scripts/tests/test_release_guards.py b/scripts/tests/test_release_guards.py index 134eb06b..6b6d4322 100644 --- a/scripts/tests/test_release_guards.py +++ b/scripts/tests/test_release_guards.py @@ -59,6 +59,11 @@ def test_audit_probes_fail_before_local_path_checks(self) -> None: audit, ) + def test_audit_bash_blocks_are_not_labeled_as_posix_shell(self) -> None: + audit_lines = (REPO / "AUDIT.md").read_text(encoding="utf-8").splitlines() + + self.assertNotIn("```sh", (line.strip() for line in audit_lines)) + if __name__ == "__main__": unittest.main() From b7febbd30006415904506e2aa111586c17128f06 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Wed, 19 Aug 2026 10:19:33 -0700 Subject: [PATCH 2/4] Improve Audit Fence Test Diagnostics --- scripts/tests/test_release_guards.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/tests/test_release_guards.py b/scripts/tests/test_release_guards.py index 6b6d4322..4751a858 100644 --- a/scripts/tests/test_release_guards.py +++ b/scripts/tests/test_release_guards.py @@ -61,8 +61,9 @@ def test_audit_probes_fail_before_local_path_checks(self) -> None: def test_audit_bash_blocks_are_not_labeled_as_posix_shell(self) -> None: audit_lines = (REPO / "AUDIT.md").read_text(encoding="utf-8").splitlines() + mislabeled = [line for line in audit_lines if line.strip() == "```sh"] - self.assertNotIn("```sh", (line.strip() for line in audit_lines)) + self.assertEqual([], mislabeled) if __name__ == "__main__": From d31bd90a42454661cbcc3f1b2f79c49250c2d672 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Wed, 19 Aug 2026 10:28:31 -0700 Subject: [PATCH 3/4] Improve Audit Fence Failure Details --- scripts/tests/test_release_guards.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/tests/test_release_guards.py b/scripts/tests/test_release_guards.py index 4751a858..c3a66faa 100644 --- a/scripts/tests/test_release_guards.py +++ b/scripts/tests/test_release_guards.py @@ -61,7 +61,11 @@ def test_audit_probes_fail_before_local_path_checks(self) -> None: def test_audit_bash_blocks_are_not_labeled_as_posix_shell(self) -> None: audit_lines = (REPO / "AUDIT.md").read_text(encoding="utf-8").splitlines() - mislabeled = [line for line in audit_lines if line.strip() == "```sh"] + mislabeled = [ + (number, line) + for number, line in enumerate(audit_lines, start=1) + if line.strip() == "```sh" or line.strip().startswith("```sh ") + ] self.assertEqual([], mislabeled) From 6f72b239ba1f2fa44898f698811c78bbed8edbb8 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Wed, 19 Aug 2026 10:33:49 -0700 Subject: [PATCH 4/4] Detect Mislabeled Bash Audit Blocks --- scripts/tests/test_release_guards.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/scripts/tests/test_release_guards.py b/scripts/tests/test_release_guards.py index c3a66faa..b6e19fe0 100644 --- a/scripts/tests/test_release_guards.py +++ b/scripts/tests/test_release_guards.py @@ -61,11 +61,26 @@ def test_audit_probes_fail_before_local_path_checks(self) -> None: def test_audit_bash_blocks_are_not_labeled_as_posix_shell(self) -> None: audit_lines = (REPO / "AUDIT.md").read_text(encoding="utf-8").splitlines() - mislabeled = [ - (number, line) - for number, line in enumerate(audit_lines, start=1) - if line.strip() == "```sh" or line.strip().startswith("```sh ") - ] + bash_only = ("<(", "<<<", "$'", "[[") + mislabeled = [] + fence_label = "" + fence_start = 0 + fence_lines: list[str] = [] + + for number, line in enumerate(audit_lines, start=1): + stripped = line.strip() + if not fence_label and stripped.startswith("```"): + fence_label = stripped.removeprefix("```").split(maxsplit=1)[0] + fence_start = number + elif fence_label and stripped == "```": + if fence_label in {"sh", "shell"} and any( + token in "\n".join(fence_lines) for token in bash_only + ): + mislabeled.append((fence_start, fence_label)) + fence_label = "" + fence_lines = [] + elif fence_label: + fence_lines.append(line) self.assertEqual([], mislabeled)