Use these terms consistently:
profile: one account-level configuration for a GitHub ownerrepository entry: one repository definition inside a profiletarget_id: one stable remediation target inside a repository entryremediation unit: one actionable work item derived from alerts and mapped onto onetarget_idremediation dedup key: the stable identity used for PR reuse, branch naming, and reporting
Each repository entry must declare one automation mode:
active: the agent may patch, open pull requests, and merge when all gates passmanual_only: the agent may scan and report, but must not mutate the repositoryignored: the agent must skip the repository entry and report the configured reason
active requires at least one real verification command for every enabled remediation target. If a repository entry cannot define real verification commands, it must remain manual_only.
report_only: read alerts and write local or public reports only; no branch creation, no pull request creation or update, no pushes, and no mergespull_request: commit verified fixes to dedicated remediation branches, push them, and create or update pull requests foractiverepositories after verification allows it; no direct default-branch pushes and no auto-mergeauto_merge: do everything allowed bypull_request, then merge only eligible Dependabot fixes and allowlisted deterministic code-scanning fixes after local verification passes, required GitHub checks are green, and branch protection allows the merge
manual_only repository entries remain read/report-only under every mutation mode. Secret-scanning cleanup PRs are never auto-merged by this scaffold. pull_request is not enough for auto-merge.
A real verification command must:
- exit non-zero on failure with no manual intervention
- exercise the dependency graph that the fix touches; install plus at least one test, type-check, or equivalent validation pass (a bare install is not sufficient)
- complete within a profile-configured timeout (default 15 minutes)
- require no interactive input
A target whose only available command is install without downstream verification must remain manual_only.
For allowlisted deterministic code scanning rules that operate on repository metadata such as GitHub Actions workflows, the rule contract may supply focused rule-specific verification in place of dependency-graph verification.
For secret_scanning, focused cleanup verification may be used when it proves that secret material was removed or replaced safely, but relevant mapped-target validation commands must still run when they exist.
The automation mode must be evaluated before any patching begins.
For Dependabot, the remediation unit is:
- one repository entry
- one base branch
- one
target_id
The normalized remediation key should include:
profile.owner/repo- alert class
- base branch
target_id
For code_scanning, the normalized remediation key must also include the normalized rule id or rule family so different allowlisted rules in the same target do not compete for one branch or PR.
For secret_scanning, the normalized remediation key must also include the GitHub alert number so distinct secret alerts in the same target stay isolated.
When one remediation unit needs finer distinction because the underlying alert set changed materially, the framework may append a normalized alert-set hash. The base remediation key must remain stable across runs.
An alert-set change is material only when a new advisory enters scope and is not satisfied by the currently selected fix, or when the smallest patched version allowed by policy changes. CVSS rescoring, advisory text edits, or other metadata-only updates do not create a new remediation unit.
Do not combine unrelated targets into one pull request.
Agent-managed branches follow the template security/{alert_class}/{target_id}/{remediation_key_short}. remediation_key_short is the first 12 characters of a stable hash over the full remediation dedup key. This keeps branch names readable while remaining stable and collision-resistant across runs.
For Dependabot, the scaffold uses adopt-first behavior.
- native Dependabot PR matching is candidate discovery only:
owner/repo + base_branch + manifest_path + package_ecosystem + head_branch_prefix, wherehead_branch_prefixcomes from the selected profile and defaults todependabot/in the public template - native PR candidates are re-evaluated structurally on every pass; PR body metadata is advisory only
- adoption requires current advisory-set equivalence
- adoption also requires confirmation that the PR still represents the smallest patched fix allowed by policy
- re-stamp PR body metadata on every pass as a best-effort breadcrumb for human readers
- verification of an adopted native PR runs against a local checkout of that PR head ref without pushing commits
- merge of an adopted native PR means a GitHub merge API call after the review gate passes, not a push to the Dependabot branch
- agent-managed PR matching is by remediation dedup key carried in branch naming and PR body metadata
- optional static labels may be added for categorization, but labels are not part of the remediation dedup contract
- if no usable native PR exists, open or update one deduplicated agent-managed PR
- do not create parallel PRs for the same remediation unit
Every processed remediation unit should end in exactly one outcome:
merged: remediation completed and mergedopened_pr: remediation was committed to a remediation branch, pushed, and represented by an opened or updated pull requestblocked: remediation exists or was attempted but cannot proceed under current policy or environmentskipped: intentionally not processed because of policy or unsupported scopefailed: execution error or unrecoverable tooling failure
Reason codes use a closed reason-code vocabulary and must be reported consistently:
supersededadvisory_withdrawndependency_removedunsupported_alert_classunsupported_ecosystemverification_unavailableverification_failedchecks_pendingchecks_redbranch_protection_blockmanifest_change_requiredno_patch_availableclone_missingrate_limitedenv_mismatchauth_insufficientregistry_auth_missinglock_contendedpolicy_blockedunsupported_rulecode_scanning_disabledsecret_scanning_disabledno_analysis_foundhistory_rewrite_required
The scaffold uses a two-pass merge model.
- remediation pass: discover alerts, adopt or open PRs, and apply the review gate using current status
- merge pass: re-evaluate existing PRs and merge only after checks are green
Within one locked profile run, the agent should exhaust eligible Dependabot work in active repository entries.
- repeat discovery, normalization, remediation, review, merge, and rediscovery until an iteration creates no new PR and performs no merge
- after every merge, re-query open
Dependabotalerts before deciding the run is complete - it is valid to end a run with
opened_prunits still waiting on required checks, but only after all other eligible units in scope were processed - after
Dependabotconvergence, the run may continue into the code-scanning and secret-scanning passes
After Dependabot work converges, a locked run may process eligible code scanning work in active repository entries.
- query open
code scanningalerts for each active repository entry - if GitHub reports that code scanning is disabled, record
skippedwith reasoncode_scanning_disabled - if GitHub reports that no analysis exists, record
skippedwith reasonno_analysis_found - only rule ids allowlisted in the selected profile's
defaults.code_scanning.allowlisted_rulesmay enter remediation - rules outside the allowlist are
skippedwith reasonunsupported_rule - merge decisions for allowlisted rules still flow through the review gate
After code_scanning work converges, a locked run may process eligible secret_scanning work in active repository entries.
- query open
secret_scanningalerts for each active repository entry that enables the alert class - if GitHub reports that secret scanning is disabled or unavailable, record
skippedwith reasonsecret_scanning_disabled - map each alert to the nearest enabled
target_idthat owns the affected path, using the root target for repository-level alerts - record one incident triage state per alert:
active,revoked,historical, orfalse_positive - deterministic cleanup may open or update a review-required pull request
- secret-scanning pull requests never auto-merge
- alerts that require history rewrite, external provider mutation, dismissal review, or non-deterministic edits should remain
blockedorskippedwith explicit follow-up actions
The current scaffold supports:
Dependabotremediation- a very small allowlist of deterministic
code_scanningremediation secret_scanningresponse with review-required cleanup PRs when deterministic cleanup is possible
The current scaffold still does not rotate credentials, dismiss alerts, rewrite history, or auto-merge secret_scanning pull requests.