a9bc5e39d5
Lint shellcheck (arm64 pilot) / shellcheck-arm64 (pilot) (pull_request) Waiting to run
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CI / Detect changes (pull_request) Successful in 16s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 15s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
E2E Chat / detect-changes (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 8s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 7s
CI / Platform (Go) (pull_request) Successful in 4m30s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 4s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 3s
Lint no tenant GITEA or GITHUB token write / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 4s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 1m37s
CI / Canvas (Next.js) (pull_request) Successful in 5m49s
lint-mask-pr-atomicity / lint-mask-pr-atomicity (pull_request) Successful in 1m32s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 6s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m11s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 10s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m19s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 5s
qa-review / approved (pull_request) Failing after 5s
gate-check-v3 / gate-check (pull_request) Successful in 5s
sop-checklist / na-declarations (pull_request) N/A: (none)
sop-checklist / all-items-acked (pull_request) Successful in 3s
sop-checklist / review-refire (pull_request) Has been skipped
security-review / approved (pull_request) Failing after 4s
sop-tier-check / tier-check (pull_request) Successful in 3s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m3s
Lint workflow YAML (Gitea-1.22.6-hostile shapes) / Lint workflow YAML for Gitea-1.22.6-hostile shapes (pull_request) Successful in 1m20s
CI / Python Lint & Test (pull_request) Successful in 6m53s
CI / all-required (pull_request) Successful in 6m58s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 2s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 3s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 2s
E2E Chat / E2E Chat (pull_request) Failing after 6m12s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 9m31s
audit-force-merge / audit (pull_request) Successful in 6s
118 lines
5.5 KiB
YAML
118 lines
5.5 KiB
YAML
# status-reaper — Option B (compensating-status POST) for Gitea 1.22.6's
|
|
# hardcoded `(push)` suffix on default-branch commit statuses.
|
|
#
|
|
# Tracking: molecule-core#? (this PR), internal#327 (sibling publish-runtime-bot),
|
|
# internal#328 (sibling mc-drift-bot), internal#80 (upstream RFC). Sister
|
|
# bots already deployed under the same per-persona-identity contract
|
|
# (`feedback_per_agent_gitea_identity_default`).
|
|
#
|
|
# Root cause:
|
|
# Gitea 1.22.6 emits commit-status context as
|
|
# `<workflow_name> / <job_name> (push)`
|
|
# for ANY workflow run on the default branch's HEAD commit, REGARDLESS
|
|
# of the trigger event. Schedule- and workflow_dispatch-triggered runs
|
|
# on `main` therefore appear as `(push)` failures on the latest main
|
|
# commit, painting main red via a fake-push status. Verified on runs
|
|
# 14525 + 14526 via Phase 1 evidence (3 sub-agents). No upstream fix
|
|
# in 1.23-1.26.1 (sibling a6f20db1 research).
|
|
#
|
|
# Why a cron-driven reaper, not workflow_run:
|
|
# Gitea 1.22.6 does NOT support `on: workflow_run` (verified via
|
|
# modules/actions/workflows.go enumeration; sister a6f20db1). The
|
|
# only event-shaped option that fires is cron. 5min is chosen to
|
|
# sit BETWEEN ci-required-drift (`:17` hourly) and main-red-watchdog
|
|
# (`:05` hourly) so the reaper sweeps red before the watchdog files
|
|
# a `[main-red]` issue (would-be false-positive).
|
|
#
|
|
# What the reaper does each tick:
|
|
# 1. Parse `.gitea/workflows/*.yml`, classify each by whether `on:`
|
|
# contains a `push:` trigger (see script for workflow_id resolution
|
|
# including `name:` collision and `/`-in-name fail-loud lints).
|
|
# 2. GET combined status for main HEAD.
|
|
# 3. For each `failure` status whose context ends ` (push)`:
|
|
# - if workflow has push trigger: PRESERVE (real defect signal).
|
|
# - if workflow has no push trigger: POST a compensating
|
|
# `state=success` with the same context and a description that
|
|
# documents the workaround.
|
|
#
|
|
# What it does NOT do:
|
|
# - Mutate non-`(push)`-suffix statuses (e.g. `(pull_request)` from
|
|
# branch_protections required-checks — verified safe 2026-05-11).
|
|
# - Auto-revert. Same reasoning as main-red-watchdog.
|
|
# - Cancel runs. The runs themselves stay visible in Actions UI; the
|
|
# fix is at the commit-status surface only.
|
|
#
|
|
# Removal path: drop this workflow when Gitea ≥ 1.24 ships with a
|
|
# real fix for the hardcoded-suffix bug. Audit issue (filed post-merge)
|
|
# tracks the deletion as a follow-up sweep.
|
|
|
|
name: status-reaper
|
|
|
|
# IMPORTANT — Gitea 1.22.6 parser quirk per
|
|
# `feedback_gitea_workflow_dispatch_inputs_unsupported`: do NOT add an
|
|
# `inputs:` block here. Gitea 1.22.6 rejects the whole workflow as
|
|
# "unknown on type" when `workflow_dispatch.inputs.X` is present.
|
|
on:
|
|
# Schedule moved to operator-config:
|
|
# /etc/cron.d/molecule-core-status-reaper ->
|
|
# /usr/local/bin/molecule-core-cron-bot.sh status-reaper
|
|
#
|
|
# This keeps the 5-minute compensation cadence but stops a maintenance
|
|
# bot from consuming Gitea Actions runner slots during PR merge waves.
|
|
workflow_dispatch:
|
|
|
|
# Compensating-status POST needs write on repo statuses; no other
|
|
# write surface is touched. checkout still needs `contents: read`.
|
|
permissions:
|
|
contents: read
|
|
|
|
# NOTE: NO `concurrency:` block is intentional.
|
|
# Gitea 1.22.6 doesn't honor `cancel-in-progress: false`: queued ticks
|
|
# of the same group get cancelled-with-started=0 instead of waiting
|
|
# (DB-verified 2026-05-12, runs 16053/16085 of status-reaper.yml).
|
|
# The reaper's POST /statuses/{sha} is idempotent — Gitea de-dups by
|
|
# context — so concurrent ticks are safe; accept them rather than
|
|
# serialise via the broken mechanism.
|
|
|
|
jobs:
|
|
reap:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 8
|
|
steps:
|
|
- name: Check out repo at default-branch HEAD
|
|
# BASE checkout per `feedback_pull_request_target_workflow_from_base`.
|
|
# The script reads .gitea/workflows/*.yml from the working tree to
|
|
# classify trigger sets; we must read main's CURRENT state, not
|
|
# the SHA a stale schedule fired against.
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
ref: ${{ github.event.repository.default_branch }}
|
|
|
|
- name: Set up Python (PyYAML for workflow `on:` parse)
|
|
# Pinned to 3.12 to match sibling watchdog / ci-required-drift.
|
|
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
|
with:
|
|
python-version: '3.12'
|
|
|
|
- name: Install PyYAML
|
|
# PyYAML is needed because shell-grep on `on:` misses list/string
|
|
# forms and nested `push: { paths: ... }`. Same install pattern
|
|
# as ci-required-drift.yml (sub-2s install, no wheel cache).
|
|
run: python -m pip install --quiet 'PyYAML==6.0.2'
|
|
|
|
- name: Compensate operational push-suffix failures on main
|
|
env:
|
|
# claude-status-reaper persona token; provisioned by sibling
|
|
# aefaac1b 2026-05-11. Owns write:repository scope to POST
|
|
# /statuses/{sha} but NOTHING ELSE
|
|
# (`feedback_per_agent_gitea_identity_default`).
|
|
GITEA_TOKEN: ${{ secrets.STATUS_REAPER_TOKEN }}
|
|
GITEA_HOST: git.moleculesai.app
|
|
REPO: ${{ github.repository }}
|
|
WATCH_BRANCH: ${{ github.event.repository.default_branch }}
|
|
WORKFLOWS_DIR: .gitea/workflows
|
|
STATUS_REAPER_API_RETRIES: "4"
|
|
STATUS_REAPER_API_TIMEOUT_SEC: "20"
|
|
STATUS_REAPER_API_RETRY_SLEEP_SEC: "2"
|
|
run: python3 .gitea/scripts/status-reaper.py
|