diff --git a/.github/workflows/ai-testgen.yml b/.github/workflows/ai-testgen.yml
index 6b8709f..95b6614 100644
--- a/.github/workflows/ai-testgen.yml
+++ b/.github/workflows/ai-testgen.yml
@@ -16,6 +16,12 @@ on:
pull_request:
workflow_dispatch:
+# Least privilege (CodeQL actions/missing-workflow-permissions, 2026-10-21): the jobs
+# here only read the repository; artefact upload and the Actions cache use the
+# runtime token, not GITHUB_TOKEN, so read access to the contents is all it needs.
+permissions:
+ contents: read
+
jobs:
harness:
runs-on: ubuntu-latest
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9119613..2ff7c87 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,6 +11,12 @@ concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
+# Least privilege (CodeQL actions/missing-workflow-permissions, 2026-10-21): the jobs
+# here only read the repository; artefact upload and the Actions cache use the
+# runtime token, not GITHUB_TOKEN, so read access to the contents is all it needs.
+permissions:
+ contents: read
+
jobs:
test:
runs-on: ubuntu-latest
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 59de445..2432299 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -13,6 +13,12 @@ on:
- cron: '0 2 * * *' # nightly, 02:00 UTC
workflow_dispatch:
+# Least privilege (CodeQL actions/missing-workflow-permissions, 2026-10-21): the jobs
+# here only read the repository; artefact upload and the Actions cache use the
+# runtime token, not GITHUB_TOKEN, so read access to the contents is all it needs.
+permissions:
+ contents: read
+
jobs:
e2e:
runs-on: ubuntu-latest
diff --git a/.github/workflows/legacy-ci.yml b/.github/workflows/legacy-ci.yml
index 84d5d97..3b58a96 100644
--- a/.github/workflows/legacy-ci.yml
+++ b/.github/workflows/legacy-ci.yml
@@ -11,6 +11,12 @@ on:
pull_request:
workflow_dispatch:
+# Least privilege (CodeQL actions/missing-workflow-permissions, 2026-10-21): the jobs
+# here only read the repository; artefact upload and the Actions cache use the
+# runtime token, not GITHUB_TOKEN, so read access to the contents is all it needs.
+permissions:
+ contents: read
+
jobs:
legacy-build:
runs-on: ubuntu-latest
diff --git a/.github/workflows/modern-ci.yml b/.github/workflows/modern-ci.yml
index 949b099..4cdfc89 100644
--- a/.github/workflows/modern-ci.yml
+++ b/.github/workflows/modern-ci.yml
@@ -11,6 +11,12 @@ on:
pull_request:
workflow_dispatch:
+# Least privilege (CodeQL actions/missing-workflow-permissions, 2026-10-21): the jobs
+# here only read the repository; artefact upload and the Actions cache use the
+# runtime token, not GITHUB_TOKEN, so read access to the contents is all it needs.
+permissions:
+ contents: read
+
jobs:
modern-build:
runs-on: ubuntu-latest
diff --git a/.github/workflows/playbook.yml b/.github/workflows/playbook.yml
index 155abf0..87a814d 100644
--- a/.github/workflows/playbook.yml
+++ b/.github/workflows/playbook.yml
@@ -22,6 +22,12 @@ on:
- '.github/workflows/playbook.yml'
workflow_dispatch:
+# Least privilege (CodeQL actions/missing-workflow-permissions, 2026-10-21): the jobs
+# here only read the repository; artefact upload and the Actions cache use the
+# runtime token, not GITHUB_TOKEN, so read access to the contents is all it needs.
+permissions:
+ contents: read
+
jobs:
playbook-pdf:
runs-on: ubuntu-latest
diff --git a/ai-testgen/testbed/modern/pom.xml b/ai-testgen/testbed/modern/pom.xml
index 9471025..1dc7114 100644
--- a/ai-testgen/testbed/modern/pom.xml
+++ b/ai-testgen/testbed/modern/pom.xml
@@ -73,7 +73,7 @@
org.postgresql
postgresql
- 42.7.12
+ 42.7.14
0.80
+
+ 11.0.25
+ 3.1.7
@@ -65,7 +74,8 @@
fixed in 42.7.12. Not theoretical: PostgreSQL 18 authenticates with SCRAM, so
this is the mechanism the modern stand actually uses. Held at the minimum fixed
version rather than the newest (42.7.13) so this is a security fix and nothing
- else — Dependabot owns routine drift.
+ else — Dependabot owns routine drift. 2026-10-21: 42.7.14 (Dependabot #101),
+ testbed pom moved in the same commit.
Declared as a literal here AND in ai-testgen/testbed/modern/pom.xml rather than
as a property: PomDriftGuardTest compares DECLARED coordinates, and a property
override does not travel through the testbed's imported BOM the way it travels
@@ -74,7 +84,7 @@
org.postgresql
postgresql
- 42.7.12
+ 42.7.14