Both were updating `github-actions` daily, so both proposed the same bumps.
actions/setup-python v7 arrived twice within an hour: Renovate as #5575, Dependabot
as #5576.
Renovate is the one to keep. It pins actions to digests via
`helpers:pinGitHubActionDigests`, so master carries
`actions/setup-python@5fda3b9... # v7`, while Dependabot proposes a bare `@v7` and
would undo that pinning. Renovate's bumps also merge on a branch once CI has run
them, whereas Dependabot's sit outside every automerge rule here and need a human
for each one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
Its `paths` filter listed `i18n/**` but not the workflow file, so a change to the
workflow - an action bump, say - triggered nothing. Those bumps automerge on a
branch, so they were merging with nothing having run them.
The Molecule workflow already lists itself for this reason. `update-translations.yml`
cannot do the same: it only runs on pushes to master, and it holds `contents: write`
and `pull-requests: write` to open translation PRs, so running it from a dependency
branch would be worse than not exercising it. Its bumps stay unexercised on purpose,
and a broken one shows up as a failed translations run rather than as anything users
see.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
It read "The API key is intentionally not required. Some OpenAI-compatible APIs
do not require a key", while validate_config.yml fails when the key is empty and
the provider is enabled. Enabling the provider against a keyless endpoint stopped
with "You need to define a required configuration setting".
baibot is the authority here, and it agrees with the validation rather than the
comment: `openai::Config` takes `api_key: String`, whereas the provider whose key
really is optional is a different one, `openai_compat`, with
`api_key: Option<String>`. So the comment described a real baibot feature, just
not this provider's.
The validation stays as it is; the comment now says what the code does, and
points at the provider the keyless case belongs to.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
The image tag prefixed `ig-` when `..._meta_mode` was `instagram`, but this role
does not accept that mode any more: `..._database_suffix` and
`..._bridge_username_prefix` map only `facebook`, `facebook-tor` and `messenger`,
so `instagram` raises an undefined-key error long before the tag is rendered.
Instagram has been a separate bridge since v26.07 and is handled by
matrix-bridge-mautrix-meta-instagram, which hardcodes the prefix. Left over from
before that split.
The comment stays, reworded: both bridges still share a container image
repository, so an `ig-` prefix on a tag here would mean this role had pulled the
other bridge's image - which is what the Molecule scenario asserts against.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
Eight scenarios in, the same few things keep deciding whether a scenario is
worth having, and none of them were obvious beforehand:
- Falsify every assertion, not just enough to see red. One control asserted that
a component emitted no DEBUG records from a module and passed just as happily
with that module set to `debug`, because it emits none on a first run either
way. Green for the wrong reason, and only breaking it deliberately showed that.
- `ActiveState == active` with `NRestarts == 0` can both hold while a component
is completely broken, when it catches its errors and retries rather than
exiting. Two of the eight behave that way.
- Startup lines are the oldest in the journal, so tailing loses them. Grep, and
strip ANSI first.
- Parse rendered configuration and assert on structure, so a value under the
wrong key cannot pass.
- `molecule converge` on a running instance does not restart the container, so a
falsification can pass for that reason alone.
Also documents that a role's scenario obliges it to join the automerge list, and
that prek enforces the two staying in step.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
The annotation read `depName=depName=ghcr.io/...`, so Renovate looked up a
package literally named `depName=ghcr.io/the-draupnir-project/draupnir` and found
nothing. Both Draupnir roles have been invisible to Renovate since v3.0.0 landed
in April, and the dependency dashboard has been reporting it as a repository
problem the whole time:
Failed to look up docker package
depName=ghcr.io/the-draupnir-project/draupnir: no-result
Checked every other annotation under roles/custom/ for the same shape; these two
were the only ones.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
A component bump touches that role's defaults/main.yml, which is on the Molecule
workflow's path filter, so the change-detection job runs that role's scenario.
The bump therefore only merges once the new version has actually been started on
the configuration the role renders. That is a real gate, and a stronger one than
a human reading a version number in a diff.
Patch only. A minor carries behaviour changes that no static rule can judge - the
MASH fleet tried a minor-automerge preset across 21 stateless roles and reverted
all of them, because reading a given release's notes is what decides it, and that
is a job for a human or an agent rather than a config file.
Branch push rather than a PR, as with the other automerge rules here.
The list has to stay in step with the roles that actually have a scenario, so
bin/check-molecule-automerge-list.py enforces it from prek. The direction that
matters is a role keeping automerge after losing its scenario: bumps would then
merge with nothing exercising them. It reports the harmless direction too, since
a role gaining a scenario without being listed is usually an oversight.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT
Anything under molecule-shared/ - the helper container images, Postgres, and the
Python pins - is on the Molecule workflow's path filter, and a change to a shared
file makes the detect job run every scenario rather than a subset. So an update
there is already gated on the whole suite passing on its own branch, which is a
stronger check than a human reading the diff.
Branch push rather than a PR, matching how the housekeeping updates in this file
already work: nothing to review and no email on success, and a failure still
surfaces as a PR.
This is also how a new Postgres major reaches us. The bump to the pin runs every
scenario against it before it can merge, so if a component does not cope with the
new major we find out from a failed Renovate branch rather than from a user.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SEH3vxYSQ5SV4N5z61eyGT