From 17c060c0cf30dcc0ac7963d57ee26c37c8a6a55b Mon Sep 17 00:00:00 2001 From: Sudhanshu Sali Date: Mon, 6 Jul 2026 14:25:15 -0400 Subject: [PATCH 1/3] Standardize bot identity to shadow (match deequ) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the bot's user-facing identity from deequ-bot to shadow so all three migrated repos (deequ, python-deequ, dqdl) are uniform. The migration PR kept the legacy deequ-bot name to avoid touching auto-approve.yml; this aligns it with the shared engine's home project. bot.name, the auto-approve clean marker, the workflows[] trigger entry, and the caller workflow name all move in lockstep — changing any one alone breaks the marker match and silently disables auto-approve. - .shadow.yml: bot.name deequ-bot -> shadow - auto-approve.yml: CLEAN_MARKER + workflows[] entry -> shadow / Shadow - issue-bot.yml: workflow name PyDeequ Bot -> Shadow (prompt_sm_prefix stays pydeequ-bot — that is the Secrets Manager namespace, not the bot identity.) --- .github/workflows/auto-approve.yml | 4 ++-- .github/workflows/issue-bot.yml | 2 +- .shadow.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml index f24c211..99f5f6b 100644 --- a/.github/workflows/auto-approve.yml +++ b/.github/workflows/auto-approve.yml @@ -2,7 +2,7 @@ name: Auto-Approve Clean PRs on: workflow_run: - workflows: [".github/workflows/base.yml", "PyDeequ Bot"] + workflows: [".github/workflows/base.yml", "Shadow"] types: [completed] permissions: @@ -72,7 +72,7 @@ jobs: owner, repo, pull_number: prNumber }); - const CLEAN_MARKER = ''; + const CLEAN_MARKER = ''; const latestBot = reviews .filter(r => r.user.login === 'github-actions[bot]') diff --git a/.github/workflows/issue-bot.yml b/.github/workflows/issue-bot.yml index dd20644..3f160c4 100644 --- a/.github/workflows/issue-bot.yml +++ b/.github/workflows/issue-bot.yml @@ -1,4 +1,4 @@ -name: PyDeequ Bot # load-bearing: auto-approve.yml keys on this exact name +name: Shadow # load-bearing: auto-approve.yml keys on this exact name # To upgrade the engine, bump the SHA in BOTH `uses:` and `shadow_ref` below # (GitHub forbids expressions in `uses:`, so they can't share a variable). diff --git a/.shadow.yml b/.shadow.yml index 3f09bbb..2fe03d4 100644 --- a/.shadow.yml +++ b/.shadow.yml @@ -7,7 +7,7 @@ codebase: language: python bot: - name: deequ-bot # not pydeequ-bot: must render the marker auto-approve.yml greps for + name: shadow # renders the marker auto-approve.yml greps for attribution: "Reviewed by Shadow · github.com/sudsali/shadow" escalate_label: needs-human max_replies: 2 From 525b457a6903f1658731a2d83df5fc844ef38f9f Mon Sep 17 00:00:00 2001 From: Sudhanshu Sali Date: Mon, 6 Jul 2026 14:39:04 -0400 Subject: [PATCH 2/3] Doc hygiene: restore caller comment + clarify model-pin override - issue-bot.yml: re-add deequ's comment explaining BEDROCK_REPORTER/CRITIC_MODEL_ID are sourced from repo variables (empty falls back to engine defaults) - .shadow.yml: note the BEDROCK_MODEL_ID secret overrides models.investigator (live opus-4-8), so the yaml value is the fallback; critic has no secret so it runs the yaml value --- .github/workflows/issue-bot.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/issue-bot.yml b/.github/workflows/issue-bot.yml index 3f160c4..a91aa1f 100644 --- a/.github/workflows/issue-bot.yml +++ b/.github/workflows/issue-bot.yml @@ -54,6 +54,7 @@ jobs: KB_S3_BUCKET: ${{ secrets.KB_S3_BUCKET }} KB_S3_KEY: ${{ secrets.KB_S3_KEY }} BEDROCK_MODEL_ID: ${{ secrets.BEDROCK_MODEL_ID }} + # Repo variables (not secrets); empty falls back to engine defaults. BEDROCK_REPORTER_MODEL_ID: ${{ vars.BEDROCK_REPORTER_MODEL_ID }} BEDROCK_CRITIC_MODEL_ID: ${{ vars.BEDROCK_CRITIC_MODEL_ID }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} From f2db110373c2ac4408b8354ba7e312a2a8659ded Mon Sep 17 00:00:00 2001 From: Sudhanshu Sali Date: Mon, 6 Jul 2026 15:28:21 -0400 Subject: [PATCH 3/3] Harden auto-approve: never self-approve guardrail changes Add a check that skips auto-approval when a PR modifies .github/** or .shadow.yml. Without it, a PR that weakens the approval gate (or repoints the bot at a different engine) is approved by the very gate it edits. Paginates listFiles so a large PR cannot slip a guarded file past a 30-item page. --- .github/workflows/auto-approve.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml index 99f5f6b..9115d83 100644 --- a/.github/workflows/auto-approve.yml +++ b/.github/workflows/auto-approve.yml @@ -55,6 +55,21 @@ jobs: return; } + // Condition 0: never auto-approve a PR that changes the bot's own + // guardrails (workflows or engine config) — that lets a PR weaken + // the approval gate and be approved by the very gate it edits. + // Require a human for these. + const files = await github.paginate(github.rest.pulls.listFiles, { + owner, repo, pull_number: prNumber, per_page: 100 + }); + const guarded = files.find(f => + f.filename.startsWith('.github/') || f.filename === '.shadow.yml' + ); + if (guarded) { + core.info(`PR touches guarded path ${guarded.filename} — requires human review, skipping`); + return; + } + // Condition 1: CI must have passed for this SHA const {data: workflowRuns} = await github.rest.actions.listWorkflowRunsForRepo({ owner, repo, head_sha: sha, status: 'completed'