# audit-force-merge — emit `incident.force_merge` to runner stdout when
# a PR is merged with required-status-checks not green. Vector picks
# the JSON line off docker_logs and ships to Loki on
# molecule-canonical-obs (per `reference_obs_stack_phase1`); query as:
#
#   {host="operator"} |= "event_type" |= "incident.force_merge" | json
#
# Closes the §SOP-6 audit gap (the doc says force-merges write to
# `structure_events`, but that table lives in the platform DB, not
# Gitea-side; Loki is the practical equivalent for Gitea Actions
# events). When the credential / observability stack converges later,
# this can sync into structure_events from Loki via a backfill job —
# the structured JSON shape is forward-compatible.
#
# Logic in `.gitea/scripts/audit-force-merge.sh` per the same script-
# extract pattern as sop-tier-check.

name: audit-force-merge

# pull_request_target loads from the base branch — same security model
# as sop-tier-check. Without this, an attacker could rewrite the
# workflow on a PR and skip the audit emission for their own
# force-merge. See `.gitea/workflows/sop-tier-check.yml` for the full
# rationale.
on:
  pull_request_target:
    types: [closed]

jobs:
  audit:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
    # Skip when PR is closed without merge — saves a runner.
    if: github.event.pull_request.merged == true
    steps:
      - name: Check out base branch (for the script)
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd  # v6.0.2
        with:
          ref: ${{ github.event.pull_request.base.sha }}
      - name: Detect force-merge + emit audit event
        env:
          # Same org-level secret the sop-tier-check workflow uses.
          GITEA_TOKEN: ${{ secrets.SOP_TIER_CHECK_TOKEN || secrets.GITHUB_TOKEN }}
          GITEA_HOST: git.moleculesai.app
          REPO: ${{ github.repository }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
          # Required-status-check contexts to evaluate at merge time.
          # Newline-separated. Mirror this against branch protection
          # (settings → branches → protected branch → required checks).
          # Declared here rather than fetched from /branch_protections
          # because that endpoint requires admin write — sop-tier-bot is
          # read-only by design (least-privilege).
          REQUIRED_CHECKS: |
            CI / all-required (pull_request)
            sop-checklist / all-items-acked (pull_request)
        run: bash .gitea/scripts/audit-force-merge.sh
