Files
molecule-core/.gitea/workflows/lint-workflow-yaml.yml
T
hongmingandClaude Opus 5 ce726966d4
Block integration-tester contamination artifacts / Block staging-trigger / invalid manifest contamination (pull_request) Successful in 23s
Lint forbidden hand-written mcp__ tool-id literals / Scan for hand-written mcp__ tool-id literals (pull_request) Successful in 18s
lint-continue-on-error-tracking / lint-continue-on-error-tracking (pull_request) Successful in 25s
Lint forbidden tenant-env keys / Scan for repo-host token write into tenant workspace surface (pull_request) Successful in 22s
Lint forbidden tenant-env keys / Scan workspace_secrets writers for forbidden env keys (pull_request) Successful in 22s
Concierge Creates Workspace Hermetic / Concierge Creates Workspace Hermetic (pull_request) Successful in 36s
lint-phantom-gate / lint-phantom-gate (pull_request) Successful in 30s
lint-required-workflows-docker-host-pinned / Lint docker-host pin on docker-touching workflows (pull_request) Successful in 22s
Lint publish-runner timeout-minutes / Lint publish-runner timeout-minutes (pull_request) Successful in 29s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 37s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 1m23s
Lint schedule budget / Zero-cron ratchet (pull_request) Successful in 30s
lint-staging-tenant-cd-gate-chain / lint-staging-tenant-cd-gate-chain (pull_request) Successful in 32s
lint-setup-go-cache / lint-setup-go-cache (pull_request) Successful in 33s
lint-bp-context-emit-match / lint-bp-context-emit-match (pull_request) Successful in 1m41s
Lint workflow YAML (repository compatibility policy) / Lint workflow YAML for repository compatibility policy (pull_request) Successful in 32s
E2E API Smoke Test / detect-changes (pull_request) Successful in 1m46s
E2E Ephemeral CP Happy Path / detect (pull_request) Successful in 1m46s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 6s
Lint pre-flip continue-on-error / Verify continue-on-error flips have run-log proof (pull_request) Successful in 1m34s
sdk-pin-drift / SDK consumer pin vs molecule-ai-sdk main (pull_request) Successful in 37s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 25s
sdk-route-milestone-contract-drift / SDK route + milestone derive-gates (pull_request) Successful in 30s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 2m21s
lint-required-context-exists-in-bp / lint-required-context-exists-in-bp (pull_request) Successful in 1m42s
CI / Python Lint & Test (pull_request) Successful in 2m22s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (stub) (pull_request) Successful in 58s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 2m23s
ci-required-drift / drift (pull_request) Successful in 2m41s
lint-no-coe-on-required / lint-no-coe-on-required (pull_request) Successful in 2m23s
lint-context-set-shrink / lint-context-set-shrink (pull_request) Successful in 2m51s
Ops Scripts Tests / Ops scripts (unittest) (pull_request) Successful in 1m8s
pin-provenance-guard / Pin provenance (pull_request) Successful in 1m35s
E2E Chat / E2E Chat (pull_request) Successful in 3m28s
Local Provision Lifecycle E2E / Local Provision Lifecycle E2E (real image + MiniMax LLM, advisory) (pull_request) Successful in 1m12s
template-delivery-e2e / detect-changes (pull_request) Successful in 2m40s
template-delivery-e2e / Template-asset delivery (fresh seo-agent — config+prompts via asset channel, seo-all via plugin reconcile) (pull_request) Successful in 3s
lint-env-coupling-dismissal / lint-env-coupling-dismissal (pull_request) Successful in 4m42s
CI / Detect changes (pull_request) Successful in 5m30s
CI / Canvas (Next.js) (pull_request) Successful in 5m51s
CI / Canvas Deploy Status (pull_request) Successful in 1s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 6m43s
CI / Platform (Go) (pull_request) Successful in 6m49s
CI / all-required (pull_request) Successful in 30s
E2E Ephemeral CP Happy Path / E2E Ephemeral CP Happy Path (pull_request) Successful in 25m21s
gitea-merge-queue / queue (pull_request_review) Successful in 3m17s
chore: delete uninstalled status-reaper
status-reaper is LATENT, not active, and its only effect is to manufacture
a green required status. Remove it.

WHY

* It cannot currently run. Its workflow `on:` block is `workflow_dispatch:`
  only -- no `schedule:`. (Verified by PyYAML parse, not grep: a synthetic
  mutant with the cron restored parses as ['schedule','workflow_dispatch']
  while the real file parses as ['workflow_dispatch']. Note that grepping
  for `schedule:` is misleading here -- several workflows carry the string
  inside comments.) Its schedule had been moved to
  /etc/cron.d/molecule-core-status-reaper on the Hetzner operator host,
  which was DECOMMISSIONED; that cron stanza survives only under
  operator-config/archive/, whose README says archived material "is not
  current operating guidance, is not installed, and must never be invoked
  by a Gitea workflow". On the live k3s head there is no status-reaper
  CronJob, no /etc/cron.d entry and no systemd unit, and the
  /usr/local/bin/molecule-core-cron-bot.sh the comment points at does not
  exist. The 5-minute compensation cadence it documents has not been
  running. Repo-wide there are zero active `schedule:` triggers, enforced
  by lint_schedule_budget.py's zero-cron ratchet.

* Its ONLY write manufactures green. Across all four api() call sites,
  three are GET and exactly one is
  POST /repos/{o}/{r}/statuses/{sha} with a hardcoded state: "success".
  It does this with a CI_STATUS_TOKEN PAT rather than the Actions token,
  and main branch protection is status_check_contexts: ["*"], so every
  posted context must be green to merge. An uninstalled tool whose sole
  effect is turning a red required context green, still dispatchable by
  any maintainer, is a loaded gun in a drawer.

* Nothing depends on its compensation. Because it has not been running,
  nothing currently relies on it, so removal cannot regress a green that
  something needs.

* Its evidence set was incomplete by construction. It reads the combined
  endpoint /commits/{sha}/status with no limit, and that endpoint silently
  truncates its `statuses` array at 30 (measured on main: default 30,
  page=2 returns 17 more, limit=100 returns 47). So the
  `successful_contexts` set it reasoned about could never see the full
  picture.

WHAT CHANGED

Deleted (all four confirmed tracked before removal, so this is not a
no-op on a nonexistent path):
  .gitea/workflows/status-reaper.yml
  .gitea/scripts/status-reaper.py
  .gitea/scripts/tests/test_status_reaper_api.py
  tests/test_status_reaper.py

No dedicated fixture directory exists (the tests build workflows in
tmp_path), and nothing imports the script as a module -- its own tests
loaded it by path via importlib. umbrella-reaper is a separate tool and
is untouched.

Eight files keep comment-only references as design/incident history;
each is annotated in place noting the tool was removed here.

NO WAIVER IS ADDED, DELIBERATELY

lint_context_set_shrink.py CHECK B exists to catch exactly this shape --
a deleted workflow whose lane silently disappears. It does not fire here,
and that was tested rather than assumed: status-reaper.yml has
fires_on_pull_request=False, so it derives no lane. Deriving the whole
tree before and after the deletion gives 46 lanes -> 46 lanes, zero lost
(positive control: deleting ci.yml loses 7). A waiver matching nothing is
a hard ERROR in that gate, so adding one "just in case" would itself red
this PR.

VERIFICATION

lint-workflow-yaml.py: 76 workflows checked, no violations.
lint_schedule_budget.py: zero-cron ratchet OK across 76 workflows.
No workflow, cron, systemd unit or CronJob can still invoke the script;
the only remaining `status-reaper` hits are prose.

Test suites, before on origin/main vs after on this branch:
  .gitea/scripts/tests  38 failed / 1592 passed -> 38 failed / 1569 passed
  tests/                 3 failed /  318 passed ->  3 failed /  269 passed
The failure SETS are byte-identical in both directions -- no new
failures. The pre-existing failures are Windows/docker environment
artifacts in this checkout and are unrelated to status-reaper; they are
not addressed here. The passed-count drops are exactly the 23 + 49 tests
that only tested the deleted script.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 07:29:25 -07:00

101 lines
4.7 KiB
YAML

name: Lint workflow YAML (repository compatibility policy)
# Tier-2 hard-gate lint (RFC internal#219 §1, charter §SOP-N rule (m)).
# Enforces repository workflow-policy shapes before they reach `main`. Rules 1
# and 2 originated under the former Gitea 1.22.6 fleet; the current server
# supports additional syntax, but policy adoption requires an explicit
# fleet/status migration rather than an incidental workflow edit.
#
# 1. workflow_dispatch.inputs — feedback_gitea_workflow_dispatch_inputs_unsupported
# (2026-05-11 PyPI freeze 24h)
# 2. on: workflow_run — not yet adopted by the status/reaper topology
# 3. name: containing "/" — breaks status-context tokenization
# 4. cross-file name collision — status-reaper rev1 fail-loud class
# (status-reaper itself was REMOVED in
# chore/delete-uninstalled-status-reaper; the
# rule it motivated still stands)
# 5. cross-repo uses: org/r/p@r — feedback_gitea_cross_repo_uses_blocked
# (DEFAULT_ACTIONS_URL=github → 404)
# 6. (WARN) api.github.com refs — feedback_act_runner_github_server_url
# without workflow-level GITHUB_SERVER_URL
#
# Empirical history this hardens against:
# - status-reaper rev1 caught rule-4 (name-collision) class
# - sop-checklist DOA'd on rule-2 (workflow_run partial)
# - #319 bootstrap-paradox (chained-defect class, related)
# - internal#329 dispatcher race (adjacent)
# - 2026-05-11 publish-runtime: rule-1, 24h PyPI freeze
#
# Triggers:
# - pull_request: pre-merge gate — block hostile shapes before they land
# - push: post-merge regression detection — catch direct-to-main edits
#
# Per RFC internal#219 §1 contract: continue-on-error: true during the
# surface-broken-shapes phase. Follow-up PR flips off after surfaced
# defects are triaged. The push-trigger ensures we catch regressions
# even if the pull_request gate is bypassed by branch-protection drift.
concurrency:
# Auto-cancel a superseded run: a newer commit/event supersedes the old
# one instead of leaving it queued forever (root fix for waiting-run pileup).
# PR events group by PR number; push events group by ref.
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
on:
pull_request:
paths:
- '.gitea/workflows/**'
- '.gitea/scripts/lint-workflow-yaml.py'
- 'tests/test_lint_workflow_yaml.py'
- 'tests/test_current_state_ci_docs.py'
push:
branches: [main, staging]
paths:
- '.gitea/workflows/**'
- '.gitea/scripts/lint-workflow-yaml.py'
- 'tests/test_lint_workflow_yaml.py'
- 'tests/test_current_state_ci_docs.py'
# Belt-and-suspenders against runner default
# (feedback_act_runner_github_server_url).
env:
GITHUB_SERVER_URL: https://git.moleculesai.app
jobs:
# bp-required: pending #4392
lint:
# The live wildcard branch protection already gates every posted status.
# #4392 tracks teaching Tier 2g that `*` covers this renamed context so the
# directive can become `bp-required: yes` without a redundant literal.
name: Lint workflow YAML for repository compatibility policy
runs-on: ubuntu-latest
# UNMASKED 2026-07-14 (was `continue-on-error: true`, the RFC #219 §1
# "Phase 3" mask). The old comment promised a follow-up flip "after the 4
# existing-on-main rule-2 (workflow_run) violations are migrated" — those
# migrations landed long ago; the mask outlived its reason and left this
# hard-gate lint unable to fail. It is now a real gate.
#
# Proven green before un-masking — the lint AND its unit tests, run locally
# against this tree:
# $ python3 .gitea/scripts/lint-workflow-yaml.py
# ::notice::lint-workflow-yaml: 84 workflow file(s) checked, no fatal
# repository-policy violations. (0 heuristic warning(s) emitted.) -> exit 0
# $ python3 -m pytest tests/test_lint_workflow_yaml.py -q -> all pass
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.11'
- name: Install PyYAML
run: pip install --quiet 'PyYAML>=6.0'
- name: Lint .gitea/workflows/*.yml
run: python3 .gitea/scripts/lint-workflow-yaml.py
- name: Run lint-workflow-yaml unit tests
run: |
pip install --quiet pytest
python3 -m pytest tests/test_lint_workflow_yaml.py tests/test_current_state_ci_docs.py -v