Installs into .claude/skills of the current project.
Are you the author of Batch Dependabot Resolver?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/moonladderstudios-batch-dependabot-resolver)
---
name: batch-dependabot-resolver
description: Discover open Dependabot version-bump PRs and enqueue one `pr-resolver` workflow for each.
metadata:
sideEffect:
kind: enqueue_children
owner: agent
outcomeArtifact: artifacts/batch_dependabot_resolver_result.json
terminalContractId: batch_dependabot_resolver_fanout.v1
terminalSchemaVersion: moonmind.batch-dependabot-resolver-result.v1
required-capabilities:
- gh
inputSchema:
type: object
properties:
repo:
type: string
title: Repository
description: >-
Target repository in owner/repo form; inferred from task context when omitted.
x-moonmind-context-default: repository
state:
type: string
title: Pull request state
enum: [open, closed, merged, all]
default: open
mergeMethod:
type: string
title: Merge method
enum: [squash, merge, rebase]
default: squash
maxIterations:
type: integer
title: Resolver iteration limit
minimum: 1
default: 5
maxAttempts:
type: integer
title: Queue attempt limit
minimum: 1
default: 3
priority:
type: integer
title: Queue priority
default: 0
packageManagers:
type: array
title: Package managers
items:
type: string
default: []
titleRegex:
type: string
title: Version-bump title regex
default: '^(?!.* from .* from )(?!.* to .* to )(?:Bump|[A-Za-z][A-Za-z0-9_-]*\(deps(?:-dev)?\): bump) .+ from \S+ to \S+(?: in /.+)?$'
includeSecurityUpdates:
type: boolean
title: Include security updates
default: true
maxPrs:
type: integer
title: Maximum PRs per run
minimum: 1
dryRun:
type: boolean
title: Dry run
default: false
runtimeMode:
type: string
title: Child runtime override
runtimeModel:
type: string
title: Child model override
runtimeEffort:
type: string
title: Child effort override
runtimeProviderProfile:
type: string
title: Child provider profile override
uiSchema:
titleRegex:
widget: textarea
---
# Batch Dependabot Resolver Skill
## Purpose
Discover open Dependabot dependency-version PRs in a target repository and enqueue
one `pr-resolver` workflow per matching PR, so Dependabot bumps can be resolved
automatically on a daily or weekly recurring schedule. This is a narrower,
more restrictive by default discovery/filter layer over `batch-pr-resolver`: it reuses the
same child `pr-resolver` payload shape, fork and cross-repository protections, runtime
inheritance, and `/api/executions` submission path, and adds Dependabot-specific
matching, a cross-run-stable idempotency key, a dry-run mode, an optional `maxPrs`
cap, and a Dependabot-specific summary artifact.
This parent batch skill does not publish repository changes itself. It records
child workflow queueing evidence in `artifacts/batch_dependabot_resolver_result.json`;
each queued `pr-resolver` child owns its repository publishing outcome.
## Inputs (skill args)
- `repo` (string, required): Target repository in `owner/repo` form. Falls back to
parent task context, `git remote origin`, then env, like `batch-pr-resolver`.
- `state` (string, optional): PR state filter for discovery. Default `open`. Other
states print a warning.
- `mergeMethod` (string, optional): Merge method passed to `pr-resolver`. Default `squash`.
- `maxIterations` (number, optional): `pr-resolver` loop cap. Default `5`.
- `maxAttempts` (number, optional): Queue job `maxAttempts` for each created task. Default `3`.
- `priority` (number, optional): Queue job priority. Default `0`.
- `packageManagers` (list, optional): Allowlist of package managers, e.g. `pip`, `npm`,
`github-actions`. Matched against the Dependabot branch ecosystem segment with alias
normalization (`npm`↔`npm_and_yarn`, `github-actions`↔`github_actions`). Omit to allow all.
- `titleRegex` (string, optional): Override for the version-bump title matcher.
Default `^(?!.* from .* from )(?!.* to .* to )(?:Bump|[A-Za-z][A-Za-z0-9_-]*\(deps(?:-dev)?\): bump) .+ from \S+ to \S+(?: in /.+)?$`
(matches both Dependabot's legacy `Bump anthropic from 0.105.2 to 0.107.1`
titles and conventional-commit titles whose type is scoped to `deps` or `deps-dev`,
such as `Build(deps): bump anthropic from 0.105.2 to 0.107.1`, including
subdirectory suffixes like `in /frontend`, while rejecting grouped or edited titles
that contain multiple `from ... to ...` update segments).
- `includeSecurityUpdates` (boolean, optional): Default `true`. When `false`, PRs labeled
`security` are skipped.
- `maxPrs` (number, optional): Hard cap on the number of resolver workflows queued per run.
- `dryRun` (boolean, optional): Default `false`. When `true`, compute and report the resolver
workflows that would be submitted without creating any.
- `runtimeMode` / `runtimeModel` / `runtimeEffort` / `runtimeProviderProfile` (string, optional):
Inherited like `batch-pr-resolver` when omitted.
## Workflow
1. Resolve helpers exclusively from the run's immutable active bundle.
```bash
BATCH_DEPENDABOT_RESOLVER_SKILL_DIR="${BATCH_DEPENDABOT_RESOLVER_SKILL_DIR:-${MOONMIND_ACTIVE_SKILLS_DIR:+$MOONMIND_ACTIVE_SKILLS_DIR/batch-dependabot-resolver}}"
test -n "$BATCH_DEPENDABOT_RESOLVER_SKILL_DIR" && test -f "$BATCH_DEPENDABOT_RESOLVER_SKILL_DIR/SKILL.md"
```
Inside MoonMind, `MOONMIND_ACTIVE_SKILLS_DIR` is always set and the helper
below resolves from it; a checked-in `.agents/skills` directory must never
shadow the selected snapshot. When no skill-specific override is present, the
helper resolves to
`${MOONMIND_ACTIVE_SKILLS_DIR:-.agents/skills}/batch-dependabot-resolver/bin/batch_dependabot_resolver.py`.
Outside MoonMind, set
`BATCH_DEPENDABOT_RESOLVER_SKILL_DIR` to the directory containing this
`SKILL.md` (no MoonMind-only environment variables required). A missing
selected helper is a materialization/packaging error: stop as blocked instead
of substituting stale repository code.
2. Run the helper script from the resolved Skill directory:
```bash
python3 "$BATCH_DEPENDABOT_RESOLVER_SKILL_DIR/bin/batch_dependabot_resolver.py" \
--repo <owner/repo> \
--merge-method squash \
--max-iterations 5 \
--package-managers pip,npm,github-actions \
--max-prs 25 \
--runtime-mode <runtime_mode> \
--runtime-model <model> \
--runtime-effort <effort> \
--runtime-provider-profile <profile_id>
```
Add `--dry-run` to validate a schedule without creating resolver workflows.
Always forward the parent task's explicit runtime selection fields when present so the
queued `pr-resolver` tasks reuse the same runtime/model/effort/provider profile.
3. The skill discovers open PRs via
`gh pr list --json number,title,author,headRefName,headRefOid,headRepository,headRepositoryOwner,isCrossRepository,labels`.
4. A PR is **matched** only when ALL of:
- it is open and not a fork/cross-repository PR (same head-locality check as `batch-pr-resolver`),
- the author is `dependabot[bot]` (also accepts `app/dependabot`),
- the head branch starts with `dependabot/`,
- the title matches `titleRegex`,
- it passes the optional `packageManagers` allowlist,
- (when `includeSecurityUpdates=false`) it is not a `security`-labeled PR,
- it has a head SHA available for the idempotency key.
Every non-matching PR is recorded as skipped with a reason: `fork-pr`,
`not-dependabot-author`, `non-dependabot-branch`, `title-mismatch`,
`package-manager-filtered`, `security-update-excluded`, `missing-head-sha`, or `max-prs-cap`.
5. For each matched PR, submit a `pr-resolver` task with the canonical `batch-pr-resolver`
payload (`repository`, `task.inputs = { repo, pr, branch, mergeMethod, maxIterations }`,
`task.git.startingBranch/branch`, `task.skill.name = pr-resolver`,
`task.publish.mode = auto`, inherited runtime) and a stable idempotency key:
`batch-dependabot-resolver:{repo}:pr:{number}:head:{headSha}`. Submit via
`POST /api/executions`, require the canonical `workflowId`, and verify it via
`GET /api/executions/{workflowId}` before counting the child as queued
(`MOONMIND_URL` must point at the MoonMind API). When MoonMind supplies
`MOONMIND_EXECUTION_FANOUT_BEARER_TOKEN_FILE` (preferred) or
`MOONMIND_EXECUTION_FANOUT_BEARER_TOKEN`, read/forward the execution-scoped
bearer and mark both calls as fan-out v1. A configured capability file that
is missing or empty fails closed.
6. Write a summary artifact `batch_dependabot_resolver_result.json` (under the managed
session artifact spool when available, otherwise the configured `--artifacts-dir`) listing
discovered PRs, matched count, queued / would-queue resolver workflows, skipped PRs with
reasons, runtime-inheritance mode, and submission errors. A deliberate zero-match run also
writes `skill_outcome.json` with `status: "no_op"`. When the default title contract rejects
a Dependabot title that still has the shape of a single version bump (`bump ... from ... to
...`), the helper records title-contract drift and fails instead of silently reporting a
successful no-op.
7. Print a short summary to stdout (`matched`, `queued`, `would_queue`, `skipped`, `errors`).
## Idempotency
The idempotency key is `batch-dependabot-resolver:{repo}:pr:{number}:head:{headSha}` (capped at
128 chars with a sha256 fallback). The same Dependabot PR at the same commit only ever gets one
resolver across separate scheduled runs; if Dependabot rebases or updates the PR (new head SHA),
a fresh resolver is allowed.
## Recurring schedule (daily / weekly)
Target this skill from a `queue_task` recurring schedule rather than `pr-resolver` directly.
Example `POST /api/recurring-workflows` body:
```json
{
"name": "Daily Dependabot resolver (MoonLadderStudios/MoonMind)",
"description": "Resolve open Dependabot version-bump PRs every morning.",
"enabled": true,
"scheduleType": "cron",
"cron": "0 7 * * *",
"timezone": "UTC",
"scopeType": "personal",
"target": {
"kind": "queue_task",
"job": {
"type": "task",
"priority": 0,
"maxAttempts": 3,
"payload": {
"repository": "MoonLadderStudios/MoonMind",
"requiredCapabilities": ["gh"],
"task": {
"title": "batch-dependabot-resolver",
"instructions": "Discover open Dependabot version-bump PRs and enqueue one pr-resolver workflow for each.",
"skill": { "name": "batch-dependabot-resolver", "version": "1.0" },
"inputs": {
"repo": "MoonLadderStudios/MoonMind",
"mergeMethod": "squash",
"maxIterations": 5,
"packageManagers": ["pip", "npm", "github-actions"],
"dryRun": false
},
"publish": { "mode": "auto" }
}
}
}
}
}
```
Use `"cron": "0 7 * * *"` for daily 07:00 UTC or `"cron": "0 7 * * 1"` for weekly (Mondays).
MoonMind delegates cron/time handling to Temporal Schedules. Set `"dryRun": true` in `inputs`
to validate a schedule without creating resolver workflows.
## Security constraints
- Reject missing `repo` unless it can be inferred from task context / `git remote origin` / env.
- Use `state=open` by default to avoid dispatching against non-open PRs.
- Skip fork and cross-repository PRs (cannot reliably check out fork head refs in queued jobs).
- Match conservatively: author AND branch AND title must all indicate a Dependabot version bump. Establish bot identity from the GitHub account login only; display names never confer trust.
- Require `MOONMIND_URL` to reach the MoonMind API; the legacy direct-DB queue fallback is unsupported.
- Never queue a PR without a head SHA (no stable idempotency key) — skip it instead.