auto-merge.yml interpolated ${{ github.event.workflow_run.head_branch }} straight into a run script that holds a contents:write token. A fork pull request controls that branch name, so it could run commands with write access (CodeQL actions/code-injection/critical). It now arrives as an environment variable.
ci.yml, code-quality.yml and deploy.yml get permissions: contents: read; none of them writes through GITHUB_TOKEN.
The auto-merge job fires when CI finishes, but Code Quality, Security and
CodeQL can still be running then. Once main requires those checks, a direct
merge at that moment is refused and nothing would retry it. Try the merge,
and if the branch rules do not allow it yet, hand it to GitHub auto-merge.