From a5ac4e003a33aa58b2da9f5a6d34f70a0b618a60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 16 Oct 2026 17:46:57 +0000 Subject: [PATCH 1/2] fix(deps): bump github/codeql-action/init from 4.38.2 to 4.38.3 Bumps [github/codeql-action/init](https://github.com/github/codeql-action) from 4.38.2 to 4.38.3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2...24c54180a607b1449ed407dd24f251e4e9147c8d) --- updated-dependencies: - dependency-name: github/codeql-action/init dependency-version: 4.38.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/rg-security.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/rg-security.yml b/.github/workflows/rg-security.yml index 692ee35..b5f9af1 100644 --- a/.github/workflows/rg-security.yml +++ b/.github/workflows/rg-security.yml @@ -39,7 +39,7 @@ jobs: timeout-minutes: 20 steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 - - uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4 + - uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4 with: languages: ${{ inputs.codeql-languages }} - uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4 From ed8b96c0b3dd5b12677fad9126e256ec483996f5 Mon Sep 17 00:00:00 2001 From: daedalus-omt <268206840+daedalus-omt@users.noreply.github.com> Date: Mon, 19 Oct 2026 22:04:38 +0000 Subject: [PATCH 2/2] fix(ci): recover strict CodeQL v4.38.3 lockstep contract Continue canonical PR271 without rewriting its Dependabot source commit. Recover the sealed prior Daedalus/OpenAI implementation byte-for-byte; update analyze/upload with init and retain exact ordered pins, singleton Set and subaction identity checks plus strict rejection controls. Recovered-Implementation-Session: agent:daedalus:daedalus-fleet268-269-20261016 Recovered-Implementation-Model: openai/gpt-6-astra (native session metadata) Continuation-Provider: OpenAI Continuation-Model: openai/gpt-6.1-sol Continuation-Configured-Effort: high; not provider-attested --- .github/workflows/rg-security.yml | 4 +- test/security-workflow.test.ts | 76 ++++++++++++++++++++++--------- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/.github/workflows/rg-security.yml b/.github/workflows/rg-security.yml index b5f9af1..a7e24ff 100644 --- a/.github/workflows/rg-security.yml +++ b/.github/workflows/rg-security.yml @@ -42,7 +42,7 @@ jobs: - uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4 with: languages: ${{ inputs.codeql-languages }} - - uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4 + - uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4 - uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 if: inputs.enable-dependency-review && github.event_name == 'pull_request' with: @@ -55,7 +55,7 @@ jobs: --lockfile=${{ inputs.lockfile }} --format=sarif --output=osv-results.sarif - - uses: github/codeql-action/upload-sarif@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4 + - uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4 if: always() && hashFiles('osv-results.sarif') != '' with: sarif_file: osv-results.sarif diff --git a/test/security-workflow.test.ts b/test/security-workflow.test.ts index 219ce80..8dbb707 100644 --- a/test/security-workflow.test.ts +++ b/test/security-workflow.test.ts @@ -5,7 +5,61 @@ import { describe, expect, test } from "vitest"; const shellSafePublicRunner = ["self-hosted", "linux", "shell-only", "public"]; +type WorkflowStep = { uses?: string }; + +function expectCodeqlPins(rgSecuritySteps: WorkflowStep[]) { + const codeqlActionVersions = rgSecuritySteps + .map((step) => step.uses) + .filter((uses): uses is string => uses?.startsWith("github/codeql-action/") ?? false) + .map((uses) => uses.split("@")[1]); + expect(codeqlActionVersions).toEqual([ + "24c54180a607b1449ed407dd24f251e4e9147c8d", + "24c54180a607b1449ed407dd24f251e4e9147c8d", + "24c54180a607b1449ed407dd24f251e4e9147c8d" + ]); + + const codeqlSteps = rgSecuritySteps.filter((step): step is { uses: string } => + step.uses?.startsWith("github/codeql-action/") ?? false + ); + const codeqlVersions = codeqlSteps.map((step) => step.uses.split("@")[1]); + expect(codeqlVersions).toHaveLength(3); + expect(new Set(codeqlVersions)).toEqual( + new Set([ + "24c54180a607b1449ed407dd24f251e4e9147c8d" + ]) + ); + expect(codeqlSteps.map((step) => step.uses?.split("@")[0])).toEqual([ + "github/codeql-action/init", + "github/codeql-action/analyze", + "github/codeql-action/upload-sarif" + ]); +} + describe("security and reusable workflows", () => { + test.each(["wrong", "missing", "mixed", "tag", "duplicate"])( + "rejects %s CodeQL subaction pins", + (mutation) => { + const workflow = YAML.parse( + fs.readFileSync(path.resolve(".github/workflows/rg-security.yml"), "utf8") + ); + const steps = (workflow.jobs.security.steps as WorkflowStep[]).filter( + (step) => step.uses?.startsWith("github/codeql-action/") + ); + if (mutation === "wrong") { + for (const step of steps) step.uses = step.uses!.replace(/@.*/, "@" + "0".repeat(40)); + } else if (mutation === "missing") { + steps.splice(1, 1); + } else if (mutation === "mixed") { + steps[1].uses = steps[1].uses!.replace(/@.*/, "@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2"); + } else if (mutation === "tag") { + for (const step of steps) step.uses = step.uses!.replace(/@.*/, "@v4.38.3"); + } else { + steps[1].uses = steps[0].uses; + } + expect(() => expectCodeqlPins(steps)).toThrow(); + } + ); + test("keeps security scans on GitHub-hosted runners with Security tab upload", () => { const workflow = YAML.parse( fs.readFileSync(path.resolve(".github/workflows/security.yml"), "utf8") @@ -73,27 +127,7 @@ describe("security and reusable workflows", () => { for (const job of Object.values(rgSecurity.jobs)) { expect(job["runs-on"]).toBe("ubuntu-24.04"); } - const rgSecuritySteps = rgSecurity.jobs.security.steps as Array<{ uses?: string }>; - const codeqlActionVersions = rgSecuritySteps - .map((step) => step.uses) - .filter((uses): uses is string => uses?.startsWith("github/codeql-action/") ?? false) - .map((uses) => uses.split("@")[1]); - expect(codeqlActionVersions).toEqual([ - "2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2", - "2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2", - "2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2" - ]); - - const codeqlSteps = rgSecurity.jobs.security.steps.filter((step: { uses?: string }) => - step.uses?.startsWith("github/codeql-action/") - ); - const codeqlVersions = codeqlSteps.map((step: { uses: string }) => step.uses.split("@")[1]); - expect(codeqlVersions).toHaveLength(3); - expect(new Set(codeqlVersions)).toEqual( - new Set([ - "2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2" - ]) - ); + expectCodeqlPins(rgSecurity.jobs.security.steps as WorkflowStep[]); const rgRelease = YAML.parse( fs.readFileSync(path.resolve(".github/workflows/rg-release.yml"), "utf8")