Skip to content

Dependabot Pipeline

Marty McEnroe edited this page May 26, 2026 · 4 revisions

Dependabot Pipeline: Why It Lives Outside Cerberus

The dependabot review + merge flow has nothing to do with Cerberus, pr-sentinel, or the auto-reviewer GitHub App. Companion to Closing-the-Agent-Self-Authorization-Loop (agent PR governance). Last verified: 2026-05-24 — file:line evidence for every claim.


Why this page exists

Cerberus, pr-sentinel, and the auto-reviewer workflow exist for one specific job: break the agent self-authorization loop. When an agent under user credentials creates an issue, files a PR, and would otherwise approve + merge its own work, the App-identity approval and the branch-protection's "1 approving review" requirement together force a non-self reviewer. That is what Cerberus is for.

Dependabot is not in that loop. Dependabot is external automation that opens PRs from outside the user's identity. There is no self-authorization risk to fence. So dependabot PRs use a completely separate governance pathtools/dependabot_review.py invoked via the /dependabot skill, gated by author + local test result, approved + merged under the user's own credentials.


The two pipelines (side by side)

Aspect Agent PR (Cerberus pipeline) Dependabot PR (this pipeline)
Who creates the PR Agent acting under user gh credentials Dependabot bot
Self-authorization risk YES — agent could approve own work NO — dependabot has its own identity
Review identity GitHub App (AssemblyZero Reviewer, aka Cerberus) — separate from agent's user User (the operator running the skill)
What validates the PR pr-sentinel Cloudflare Worker → creates pr-sentinel / issue-reference Check Run tools/dependabot_review.py runs the local test suite in an audit worktree
Gating mechanism Required check + required approving review = branch-protection clean Author gate (dependabot[bot] only) + exit-code gate (pytest must pass)
What approves the merge auto-reviewer.yml workflow POSTs an APPROVE review using a Cerberus App token The user, via gh pr review --approve (executes from dependabot_review.py)
Whose Code Review profile stat accrues The Cerberus App (not the user) The user (intentional, per /dependabot skill rules § 102, #1091)
PR body requirement Closes #N (or No-Issue:) — pr-sentinel checks No-Issue: automated dependency update (...) injected by the tool before merge
Workflow firing on the PR .github/workflows/auto-reviewer.yml approves automatically once required checks pass The auto-reviewer workflow also fires but its result is irrelevant — the dependabot merge path uses dependabot_review.py, not the App-token approval
Failure mode Stuck on mergeable_state: blocked until pr-sentinel + Cerberus approval both land Test failure → tool defers with structured review comment; merge conflict → tool requests @dependabot rebase

The dependabot pipeline architecture

sequenceDiagram
    autonumber
    participant D as Dependabot Bot
    participant GH as GitHub
    participant PRS as pr-sentinel<br/>(CF Worker)
    participant AR as auto-reviewer.yml<br/>(reusable workflow)
    participant USER as Operator
    participant DR as /dependabot skill<br/>+ dependabot_review.py
    participant WT as Audit worktree

    D->>GH: open PR (e.g., dependabot/pip/foo)
    GH->>PRS: webhook: pull_request.opened
    PRS->>PRS: pr.user.login == "dependabot[bot]"<br/>(sentinel/src/webhook.js:78)
    PRS-->>GH: 200 "Skipped dependabot"<br/>(no Check Run created)
    Note over AR: auto-reviewer.yml fires but its result<br/>is irrelevant — dependabot_review.py<br/>is the only mover.
    GH->>AR: pull_request event fires caller workflow
    AR-->>GH: result ignored by the dependabot merge path
    Note over USER,WT: Separately, on the operator's schedule:
    USER->>DR: /dependabot (or scheduled task)
    DR->>GH: gh pr list --author "app/dependabot" --state open
    GH-->>DR: open dependabot PRs
    loop per PR
        DR->>DR: author gate:<br/>must be dependabot[bot]<br/>(dependabot_review.py:235-241)
        DR->>WT: create audit worktree from main
        DR->>WT: gh pr checkout --detach (no local branch)
        DR->>WT: poetry install --with dev<br/>poetry run pytest -q --tb=short
        alt pytest exit 0
            DR->>GH: PATCH PR body — inject "No-Issue: automated dependency update"
            DR->>GH: gh pr review --approve<br/>(user credentials)<br/>(dependabot_review.py:327-335)
            DR->>GH: poll mergeable_state (clean or unstable)
            DR->>GH: gh pr merge --squash
        else pytest non-zero
            DR->>GH: gh pr review --comment<br/>(structured failure report)
            DR->>GH: optional @dependabot rebase or recreate
        end
        DR->>WT: git restore .<br/>git worktree remove<br/>git branch -d dependabot-audit-<N>
    end
    DR-->>USER: summary: Merged [N], Deferred [N], Errored [N]
Loading

Key observations from the diagram:

  1. pr-sentinel correctly skips dependabot at the webhook level. The CF Worker code (sentinel/src/webhook.js:78) explicitly early-returns on pr.user.login === "dependabot[bot]". No Check Run is ever created for dependabot PRs.
  2. auto-reviewer.yml fires on dependabot PRs but its result doesn't matter — the dependabot merge path is independent and runs via dependabot_review.py using the operator's gh credentials.
  3. The No-Issue: injection into the PR body is belt-and-suspenders — pr-sentinel already skips dependabot, but if it DID re-evaluate for any reason, the injected exemption would pass.
  4. Zero persistent disk artifacts on any exit path (per /dependabot skill cleanup contract + #1116). Worktree + audit branch removed via try/finally regardless of outcome.

The dependabot skill (/dependabot)

Location: C:\Users\mcwiz\.claude\skills\dependabot.md

A thin wrapper that:

  1. Checks if there are any open dependabot PRs (gh pr list --author "app/dependabot")
  2. Invokes tools/dependabot_review.py from the AssemblyZero root (not a worktree)
  3. Streams output, relays the summary (merged / deferred / errored counts)

The skill itself contains no decision logic. All logic is in dependabot_review.py. The skill enforces three rules:

  • Never modify the Python tool from the skill — skill is a wrapper, not a logic layer.
  • Never approve/merge dependabot PRs outside this tool — author gate + exit-code gate guarantees bypassed otherwise.
  • The tool uses the invoking user's gh credentials for pr review --approve — intentional, so the PullRequestReview event attributes to the user and the Code Review profile stat accrues (per #1091).

Arguments:

  • --dry-run — list PRs that would be processed, take no action
  • --fleet — process across ALL user-owned Poetry repos, not just AssemblyZero (#1091)
  • --help — show help and exit

The dependabot tool (tools/dependabot_review.py)

Location: C:\Users\mcwiz\Projects\AssemblyZero\tools\dependabot_review.py (987 lines)

Gates the tool enforces

  1. Author gate (lines 235-241): PR author must be dependabot[bot] or app/dependabot. Anything else → refused, counted as "errored." This is the structural guarantee that the tool can only touch dependabot PRs.
  2. Test gate (lines 276-305): in an audit worktree, poetry install --with dev then poetry run pytest -q --tb=short. Exit 0 → proceed to merge. Non-zero → defer with a structured comment.

Merge sequence (on pytest green)

  1. Inject No-Issue: automated dependency update (N packages, ...) into PR body (lines 312-324). Belt-and-suspenders against pr-sentinel re-evaluation.
  2. Wait 5 seconds for any pr-sentinel re-evaluation (line 641).
  3. gh pr review --approve under the invoking user's credentials (lines 327-335). The review event attributes to the user, not to Cerberus.
  4. Poll mergeable_state until clean or unstable (lines 338-365). The unstable acceptance is per #971 — pr-sentinel legacy checks sometimes fail benignly even when required checks pass.
  5. gh pr merge --squash (lines 368-385).

Deferred-PR path (on pytest red)

  1. gh pr review --comment (via review_comment_on_pr) with a structured failure report (attributable review, accrues Code Review credit per #1091).
  2. If branch is stale: @dependabot rebase. (Takes precedence over #3 below — stale-branch check fires first via if/elif.)
  3. Else if a multi-package PR: @dependabot recreate (forces dependabot to re-open as per-package PRs which can then be retried individually).

Cleanup contract (every exit path)

Lines 487-552 — zero persistent disk artifacts after ANY exit (success, defer, error, exception):

  • git restore . before worktree removal (discards auto-modified files; lesson from #1155)
  • git worktree remove <path> (poetry venv evicted first to release Windows file locks per #944)
  • git branch -d dependabot-audit-<N> (safe-delete only; lowercase -d per banned-commands rule)
  • On cleanup failure: prints CLEANUP FAILURE to stderr with the exit code; does NOT flip the PR processing result
  • gh pr checkout --detach is used during audit so no local dependabot/<group>/<branch> ref is left behind (#1107)

The dependabot status tool (tools/dependabot_morning_status.py)

Companion tool. Dashboard for scheduled overnight runs:

  1. Reads the scheduled-task log file (default: C:/Users/mcwiz/Projects/dependabot-fleet.log)
  2. Checks the log tail for completion markers (| OK | vs | EXIT vs | ERROR | — note EXIT has a trailing space rather than a closing pipe)
  3. Lists fleet-wide open dependabot PRs via gh search prs --author app/dependabot
  4. Reports the user's Code Review profile stat (unique PRs reviewed all-time)
  5. Shows PRs closed on a specified date (default: today)

No mutation; pure status display. Operator uses this to triage overnight queue results.


Failure modes the tool surfaces

These are the kinds of failures that dependabot_review.py itself surfaces and handles:

Mode Symptom Fix
Test failure poetry run pytest returns non-zero Tool defers PR with structured comment. Operator either: fixes the underlying compatibility issue; or rejects the dep version. Tool may post @dependabot rebase (if branch is stale) — else if it's a multi-package PR, @dependabot recreate (forces dependabot to re-open as per-package PRs).
Stale branch Detected (a) as sub-diagnosis after test-failure (dependabot_review.py:625), or (b) when mergeable_state returns dirty after green tests (:663-666) — there is no pre-test stale check Tool posts @dependabot rebase and defers. Next run will pick it up.
Multi-package PR with one bad package Tests fail because of one package among N Tool posts @dependabot recreate; dependabot re-opens as per-package PRs; next run processes them individually.
Audit worktree cleanup failure Windows file lock on poetry venv prevents git worktree remove Tool evicts the venv first (per #944) then attempts the worktree remove (single attempt; no retry loop). Failure prints CLEANUP FAILURE to stderr but does NOT flip the PR's outcome. Manual cleanup via git worktree prune may be needed if cleanup repeatedly fails.
Stuck wedge Same dep version keeps failing tests run after run The dep itself is genuinely incompatible. Either pin to an older known-good version (override dependabot's update) or accept the upgrade and fix the breakage in code. Not a tool bug.

When you'd use this pipeline

Situation Action
Open dependabot PRs piled up /dependabot (or /dependabot --fleet to sweep all user repos)
Want to see what's queued without processing /dependabot --dry-run
Check overnight scheduled-run result poetry run python tools/dependabot_morning_status.py
Add a fleet-wide dep version pin Edit each repo's pyproject (out of scope of this tool)
Disable dependabot for a specific repo Disable Dependabot security/version updates in repo settings (out of scope)

When this pipeline does NOT apply

Situation Why not
Agent PR is stuck on mergeable_state: blocked That's the Cerberus pipeline, not dependabot. See Closing-the-Agent-Self-Authorization-Loop.
pr-sentinel marked PR as action_required That's a real PR-body validation issue. See docs/runbooks/0935-pr-stuck-recovery.md. Dependabot PRs are skipped by sentinel — this won't apply.
A dependabot PR has been open for months Likely there's a long-standing test failure. Run /dependabot to see why it's deferred, or gh pr view <N> --comments to read the failure reports the tool has been posting.

References

Component Path / URL Notes
/dependabot skill C:\Users\mcwiz\.claude\skills\dependabot.md Thin wrapper around the Python tool
Dependabot review tool AssemblyZero/tools/dependabot_review.py 987 lines, author + test gates, zero-artifact cleanup
Dependabot status dashboard AssemblyZero/tools/dependabot_morning_status.py Overnight-run triage
pr-sentinel webhook skip sentinel/src/webhook.js:78-79 The early-return on dependabot[bot] (check on :78, return on :79)
Runbook AssemblyZero/docs/runbooks/0911-dependabot-pr-audit.md (v2.3) Operational procedure for the skill

AssemblyZero Wiki

Home


Start Here

You are... Go to
Engineering Leader Why AssemblyZero?
AI Strategy / Ops AI Strategy & Operations
Technical Architect Technical Architecture
Security & Compliance Secret Guard Architecture
Practitioner Quick Start

What's New


Metrics


For Leaders


Architecture


Core Workflows


Security & Governance


Cost & Platform Engineering


Reliability


Intelligence Layer


Core Solutions


Observability & Operations


Safety & Guardrails


Orchestration


Getting Started


Reference


Reflections


Chronicles

Clone this wiki locally