-
Notifications
You must be signed in to change notification settings - Fork 2
Dependabot Pipeline
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.
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 path — tools/dependabot_review.py invoked via the /dependabot skill, gated by author + local test result, approved + merged under the user's own credentials.
| 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
|
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]
Key observations from the diagram:
- pr-sentinel correctly skips dependabot at the webhook level. The CF Worker code (
sentinel/src/webhook.js:78) explicitly early-returns onpr.user.login === "dependabot[bot]". No Check Run is ever created for dependabot PRs. - auto-reviewer.yml fires on dependabot PRs but its result doesn't matter — the dependabot merge path is independent and runs via
dependabot_review.pyusing the operator'sghcredentials. - 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. - Zero persistent disk artifacts on any exit path (per
/dependabotskill cleanup contract + #1116). Worktree + audit branch removed via try/finally regardless of outcome.
Location: C:\Users\mcwiz\.claude\skills\dependabot.md
A thin wrapper that:
- Checks if there are any open dependabot PRs (
gh pr list --author "app/dependabot") - Invokes
tools/dependabot_review.pyfrom the AssemblyZero root (not a worktree) - 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
ghcredentials forpr review --approve— intentional, so thePullRequestReviewevent 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
Location: C:\Users\mcwiz\Projects\AssemblyZero\tools\dependabot_review.py (987 lines)
-
Author gate (lines 235-241): PR author must be
dependabot[bot]orapp/dependabot. Anything else → refused, counted as "errored." This is the structural guarantee that the tool can only touch dependabot PRs. -
Test gate (lines 276-305): in an audit worktree,
poetry install --with devthenpoetry run pytest -q --tb=short. Exit 0 → proceed to merge. Non-zero → defer with a structured comment.
- Inject
No-Issue: automated dependency update (N packages, ...)into PR body (lines 312-324). Belt-and-suspenders against pr-sentinel re-evaluation. - Wait 5 seconds for any pr-sentinel re-evaluation (line 641).
-
gh pr review --approveunder the invoking user's credentials (lines 327-335). The review event attributes to the user, not to Cerberus. - Poll
mergeable_stateuntilcleanorunstable(lines 338-365). Theunstableacceptance is per #971 — pr-sentinel legacy checks sometimes fail benignly even when required checks pass. -
gh pr merge --squash(lines 368-385).
-
gh pr review --comment(viareview_comment_on_pr) with a structured failure report (attributable review, accrues Code Review credit per #1091). - If branch is stale:
@dependabot rebase. (Takes precedence over #3 below — stale-branch check fires first viaif/elif.) - Else if a multi-package PR:
@dependabot recreate(forces dependabot to re-open as per-package PRs which can then be retried individually).
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-dper banned-commands rule) - On cleanup failure: prints
CLEANUP FAILUREto stderr with the exit code; does NOT flip the PR processing result -
gh pr checkout --detachis used during audit so no localdependabot/<group>/<branch>ref is left behind (#1107)
Companion tool. Dashboard for scheduled overnight runs:
- Reads the scheduled-task log file (default:
C:/Users/mcwiz/Projects/dependabot-fleet.log) - Checks the log tail for completion markers (
| OK |vs| EXITvs| ERROR |— noteEXIThas a trailing space rather than a closing pipe) - Lists fleet-wide open dependabot PRs via
gh search prs --author app/dependabot - Reports the user's Code Review profile stat (unique PRs reviewed all-time)
- Shows PRs closed on a specified date (default: today)
No mutation; pure status display. Operator uses this to triage overnight queue results.
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. |
| 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) |
| 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. |
| 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 |
| 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 |
- Q2 2026 Velocity — 398 issues closed, 321 PRs merged; the orchestrator goes end-to-end
- March 2026 Velocity — 206 issues in 21 days
- Why AssemblyZero?
- AI Strategy & Operations
- Security & Compliance
- OWASP LLM & Agentic Top 10 — AssemblyZero's own agentic risk map
- Dramatis Personae
- Multi-Agent Orchestration
- RAG and Beyond — ⚠ retired 2026-07-06 (ADR-0223); LLD grounding is now Tiphys
- Gemini Verification
- Governance Gates
- How AssemblyZero Learns
- LangGraph Evolution
- The Pipeline (Idea → Tested Code)
- Requirements Workflow
- Implementation Workflow
- The Scout
- Worktree Isolation
- OWASP LLM & Agentic Top 10 — risk map for the system itself
- Secret Guard Architecture
- Fleet Security Audit
- Agent Instruction Hierarchy
- Closing the Agent Self-Authorization Loop — separating identity for AI-safe PR governance
- Dependabot Pipeline — adjacent, intentionally separate
- Branch Protection at Scale
- Hex (Codebase) — ⚠ RAG layer retired (ADR-0223)
- Ponder Stibbons
- History Monks
- Concept Field Guide
- State of Activation — what's live, dormant, historical, or metaphor
- Audits Catalog
- Tools Reference