diff --git a/.bot/config.yaml b/.bot/config.yaml index a3a1c099..83ebd975 100644 --- a/.bot/config.yaml +++ b/.bot/config.yaml @@ -23,16 +23,14 @@ bot_login_prefix: peco-engineer-bot # <-- your engineer-bot App's login pr # safe_path denylist (relative to repo root). .git + the secret-scanner allowlist # at minimum. NOTE (security): csharp/src is NOT denied — the agent must edit the -# code it fixes. But .github + .bot ARE denied as defense-in-depth: a bug fix -# never needs to write the bot's own CI/workflows or config/prompts, and both the -# author and follow-up system prompts already forbid it. Enforcing it in-sandbox -# means a prompt-injected issue/review body cannot induce such edits at all, -# rather than relying solely on a reviewer spotting them. The human PR-review gate -# remains the backstop — reviewers should still scrutinize any .bot/.github diffs. +# code it fixes. `.bot` stays denied as defense-in-depth (the agent should never +# rewrite its own config/prompts). `.github` is INTENTIONALLY allowed (maintainer +# decision): the engineer-bot may need to fix its own CI/workflow wiring (e.g. a +# missing engine flag), and the human PR-review gate is the backstop — reviewers +# must scrutinize any `.github` diffs, since workflows carry secrets/tokens. denied_subpaths: - .git - .gitleaksignore - - .github - .bot # csharp/hiveserver2 is a SEPARATE repo (git submodule -> adbc-drivers/hiveserver2). # Edits there cannot be committed to a parent-repo PR, so deny them. The author diff --git a/.github/workflows/engineer-bot-followup.yml b/.github/workflows/engineer-bot-followup.yml index 0e01933a..ec26c11a 100644 --- a/.github/workflows/engineer-bot-followup.yml +++ b/.github/workflows/engineer-bot-followup.yml @@ -241,4 +241,9 @@ jobs: MODEL_ENDPOINT: https://${{ secrets.DATABRICKS_HOST }}/serving-endpoints/databricks-claude-opus-4-8/invocations REPO_RULES_FILES: csharp/CLAUDE.md,rust/CLAUDE.md # adbc keeps conventions per-language (no root CLAUDE.md) DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }} - run: python -m databricks_bot_engine.engineer_bot.run --phase followup --bot .bot + # --system-prompt is REQUIRED for the followup phase (engine #89 removed the + # .bot/ prompt-name fallback). Point at the engineer-followup system prompt + # that already exists in .bot/prompts/ (mirrors databricks-jdbc's onboarding). + run: >- + python -m databricks_bot_engine.engineer_bot.run --phase followup --bot .bot + --system-prompt .bot/prompts/engineer-followup/system.md diff --git a/.github/workflows/engineer-bot.yaml b/.github/workflows/engineer-bot.yaml index 7543b467..7a7bab5b 100644 --- a/.github/workflows/engineer-bot.yaml +++ b/.github/workflows/engineer-bot.yaml @@ -246,20 +246,10 @@ jobs: OUT_OF_SCOPE: ${{ steps.author.outputs.out_of_scope }} run: python -m databricks_bot_engine.engineer_bot.publish - - name: Label the fix PR for review - # publish applies `engineer-bot` (engineer opt-in) but the reviewer gates - # strictly on `review-bot`, so add that label here too — otherwise the fix - # PR would never be reviewed and the loop wouldn't close. Keeps the labels - # single-purpose (engineer-bot ⇒ engineer, review-bot ⇒ reviewer); the fix - # PR simply opts into both. The `labeled` event fires reviewer-bot.yml. - if: steps.author.outputs.outcome == 'success' && steps.publish.outputs.coverage_pr_url != '' - env: - GH_TOKEN: ${{ steps.token.outputs.token }} - # Bind the engine-produced URL to an env var rather than interpolating - # ${{ }} into the run-script, mirroring the "Comment outcome" step — the - # runner shell never parses it as command syntax (defense-in-depth). - COVERAGE_PR_URL: ${{ steps.publish.outputs.coverage_pr_url }} - run: gh pr edit "$COVERAGE_PR_URL" --add-label review-bot + # (Removed "Label the fix PR for review": the reviewer now auto-runs on every + # non-draft, non-fork PR — no `review-bot` label needed — so the fix PR is + # reviewed without an explicit label-add. publish still applies `engineer-bot` + # for the engineer follow-up opt-in.) - name: Comment outcome on the issue if: always() diff --git a/.github/workflows/reviewer-bot-followup.yml b/.github/workflows/reviewer-bot-followup.yml index 700b63df..537c4aa5 100644 --- a/.github/workflows/reviewer-bot-followup.yml +++ b/.github/workflows/reviewer-bot-followup.yml @@ -55,12 +55,14 @@ concurrency: jobs: followup: # SECURITY: skip fork PRs — keep model/LLM secrets out of untrusted code's reach. - # Same `review-bot` label gate as reviewer-bot.yml — the follow-up only acts on - # PRs the reviewer was allowed to review. + # Like reviewer-bot.yml, there is NO label gate (dropped for consistency with the + # other consumer repos). Unlike the initial reviewer, the follow-up deliberately + # does NOT require draft == false: it must keep responding to existing review + # threads even after a PR is converted to draft. So it runs on any OPEN, non-fork + # PR (draft or not). if: >- github.event.pull_request.head.repo.fork == false && github.event.pull_request.state == 'open' - && contains(github.event.pull_request.labels.*.name, 'review-bot') runs-on: [self-hosted, Linux, X64, peco-driver] timeout-minutes: 15 steps: diff --git a/.github/workflows/reviewer-bot.yml b/.github/workflows/reviewer-bot.yml index 7f278291..b35307c1 100644 --- a/.github/workflows/reviewer-bot.yml +++ b/.github/workflows/reviewer-bot.yml @@ -32,12 +32,7 @@ name: Reviewer Bot on: pull_request: - # `labeled` is included so adding `review-bot` to an already-open PR triggers - # a review immediately, not just on the next push. (The `if:` gate below only - # honors `review-bot`; applying `engineer-bot` alone fires this event but the - # job is skipped. Engineer-bot fix PRs are reviewed because engineer-bot.yaml - # separately adds the `review-bot` label after publish.) - types: [opened, synchronize, reopened, ready_for_review, labeled] + types: [opened, synchronize, reopened, ready_for_review] permissions: contents: read @@ -51,18 +46,14 @@ concurrency: jobs: review: - # Non-fork, non-draft, `review-bot`-labeled PRs only: - # - fork PRs must never see the LLM/engine secrets; drafts aren't ready. - # - label gate: review ONLY PRs carrying `review-bot`. `review-bot` guards the - # reviewer; `engineer-bot` guards the engineer — strictly separate, never - # mixed. A maintainer opts a PR in with `review-bot`; the bug-fix bot's own - # fix PRs get `review-bot` applied by engineer-bot.yaml after publish, so - # they're reviewed and the loop still closes. Without the label the reviewer - # stays silent, so it doesn't comment on every PR in the repo. + # Non-fork, non-draft PRs — auto-review, matching the other consumer repos + # (databricks-sql-python/go/nodejs/kernel), which review every non-draft, + # non-fork PR without an opt-in label. fork == false keeps the LLM/engine + # secrets off untrusted code; drafts aren't ready. (Previously also required a + # `review-bot` label; dropped for fleet consistency.) if: >- github.event.pull_request.draft == false && github.event.pull_request.head.repo.fork == false - && contains(github.event.pull_request.labels.*.name, 'review-bot') # ACTIVATION BLOCKER: before taking this workflow out of DRAFT, switch this to # the protected `peco-driver` self-hosted runner (or adopt OIDC + a scoped, # short-lived model credential distinct from the CI DATABRICKS_TOKEN). As long