From 50d2927cb44a33aec653c7e36614048d3d722466 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 30 Aug 2026 20:50:03 -0500 Subject: [PATCH 1/2] chore: group Dependabot updates and slow the cadence to monthly Applies GitHub's "Tame Dependabot" guidance: group routine version bumps into one PR per ecosystem, move the schedule to monthly, and add a 7-day cooldown so a release has time to be found bad and yanked before it is proposed here. One deliberate departure from the article, which says to delete `open-pull-requests-limit`. Omitting that key does not mean unlimited -- the default is 5, and once five version-update PRs are open Dependabot raises no more. That is the silent withholding the article argues against, so the limit is instead set explicitly and set high (50 for cargo, 20 elsewhere), high enough not to bind. Grouping is what controls the noise. Cargo needs the extra headroom because Dependabot applies Cargo's semver rules, where a 0.y.z crate's y-bump is breaking: `0.8 -> 0.9` counts as a major, falls out of the group, and arrives as its own PR. Security updates are untouched. `applies-to` defaults to `version-updates`, so security PRs ignore the grouping, schedule, cooldown and limit, and keep arriving one per advisory, immediately. Major bumps are also left ungrouped: every group matches only `minor` and `patch`, so a major still gets its own PR and its own review. Ref: https://github.blog/security/supply-chain-security/tame-dependabot-group-your-updates-slow-the-cadence-keep-security-fast/ [AI-assisted - Claude] --- .github/dependabot.yml | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b80b701 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,105 @@ +version: 2 + +# Dependabot configuration. +# +# Shaped by GitHub's "Tame Dependabot: group your updates, slow the cadence, +# keep security fast" guidance: +# https://github.blog/security/supply-chain-security/tame-dependabot-group-your-updates-slow-the-cadence-keep-security-fast/ +# +# - GROUP routine churn, so a month of bumps arrives as ONE reviewable PR per +# ecosystem instead of thirty. Open PRs are not free: they rot into +# conflicts, and a wall of them trains reviewers to skim past the whole +# list, including the bumps that matter. +# - SLOW the cadence to monthly, so updates land on a rhythm you can plan +# around rather than "whenever anything upstream changes". +# - COOLDOWN of 7 days, so a release has been in the wild long enough for a +# bad one to be found and yanked before it is proposed here. Dependabot +# already applies 3 days by default; this raises it. Note the interaction +# with a monthly schedule: a release published just inside the window is +# skipped and waits for the NEXT monthly run, so the practical delay from +# publish to PR can approach five weeks, not seven days. +# +# ONE PLACE THIS DELIBERATELY DEPARTS FROM THE ARTICLE. +# +# The article says to delete `open-pull-requests-limit`. Do not. Omitting the +# key does not mean "unlimited" -- the documented default is FIVE, and once five +# version-update PRs are open Dependabot raises no more until some are closed. +# That is silent withholding, the exact failure the article is arguing against, +# so the limit is set EXPLICITLY and set high enough never to bind in practice. +# Grouping, not the limit, is what controls the noise. (Security PRs are exempt +# from the limit and do not count toward it.) +# +# TWO THINGS THIS DELIBERATELY DOES NOT DO. Both are one config key away, and +# both would be worse than the noise this file exists to reduce: +# +# 1. It does not group MAJOR bumps. Every group below matches only `minor` and +# `patch`, so a major arrives as its own PR with its own review. A major can +# change behaviour, and must never land buried in a large diff that reads as +# routine. +# +# Know how Dependabot classifies, because it differs by ecosystem. For CARGO +# it applies Cargo's own semver rules, where for a 0.y.z crate a bump in y is +# BREAKING: `0.8 -> 0.9` is treated as a MAJOR, falls out of the group, and +# arrives as its own PR. That is right for Rust, and it is why the cargo +# limit below is generous -- a repo with many 0.x dependencies produces a +# real queue of individual PRs alongside the single grouped one. For every +# other ecosystem here (npm, pip, docker, gradle, github-actions) Dependabot +# compares raw version segments instead, so an npm `0.8 -> 0.9` is classified +# `minor` and WILL be grouped, even though npm convention treats 0.x minors +# as breaking. The "majors are always reviewed alone" guarantee is therefore +# strong for cargo and weaker for the rest. +# +# 2. It does not touch SECURITY updates. `applies-to` defaults to +# `version-updates`, so Dependabot's security PRs ignore the grouping, the +# monthly schedule, the cooldown and the PR limit entirely, and keep arriving +# one per advisory, immediately. Do NOT "finish the job" by adding +# `applies-to: security-updates` -- slowing security fixes down is precisely +# the outcome this configuration avoids. + +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "monthly" + cooldown: + default-days: 7 + # Set explicitly: omitting this caps at 5 and silently withholds the rest. + open-pull-requests-limit: 50 + groups: + cargo-minor-and-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + cooldown: + default-days: 7 + # Set explicitly: omitting this caps at 5 and silently withholds the rest. + open-pull-requests-limit: 20 + groups: + github-actions-minor-and-patch: + patterns: + - "*" + update-types: + - "minor" + - "patch" + +# WARNING -- this workspace contains contract and/or delegate crates whose +# COMPILED WASM IS THE CONTRACT ADDRESS. A cargo workspace shares one Cargo.lock, +# so a grouped dependency bump merged here can silently re-key a deployed +# contract and strand existing user data. ANY wasm change moves the address: a +# direct bump, a transitive bump, or a rustc upgrade. +# +# This repo has NO migration or wasm-hash guard workflow, so nothing here will +# turn red when that happens. Before merging a cargo PR, rebuild and compare the +# contract key, and ship a migration if it moved. See the `freenet-app-migration` +# skill and `.claude/rules/` in the freenet tree. +# +# Dependabot does not create this hazard -- a hand-run `cargo update` does the +# same thing -- but it does deliver a steady stream of routine-LOOKING PRs, and +# that is exactly the context in which a re-key gets merged unnoticed. From 6dd8a40332949f507a038c9d2a0a448407922708 Mon Sep 17 00:00:00 2001 From: Ian Clarke Date: Sun, 30 Aug 2026 21:05:33 -0500 Subject: [PATCH 2/2] chore: label cargo Dependabot PRs that can re-key a contract A comment in dependabot.yml reaches whoever reads the config; it does not reach whoever reviews the monthly bump PR, which is where the decision is actually made. These workspaces reach a contract or delegate crate, so a grouped cargo bump can change compiled WASM and move a contract address. Tagging those PRs `contract-rekey-risk` puts the warning on the PR itself. The label exists in each repo, since Dependabot silently drops labels that do not. Note this does not fire every month: a bump only moves the address if it reaches a contract crate's dependency graph, and those crates are small (freenet-stdlib, ciborium, serde, ed25519-dalek, blake3). A group bumping only native deps leaves the WASM byte-identical. [AI-assisted - Claude] --- .github/dependabot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b80b701..98e4454 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -65,6 +65,11 @@ updates: default-days: 7 # Set explicitly: omitting this caps at 5 and silently withholds the rest. open-pull-requests-limit: 50 + # This workspace reaches a contract/delegate crate: a bump here can move a + # contract address. Labelled so that shows on the PR, not just in this file. + labels: + - "dependencies" + - "contract-rekey-risk" groups: cargo-minor-and-patch: patterns: