ORCH-073: SHA-in-main merge-verify + main regression guard #77

Merged
admin merged 7 commits from feature/ORCH-073-crit-main-orch-067-069 into main 2026-06-08 16:54:01 +03:00
Owner

Summary

CRIT: системный фикс эрозии main + восстановление кода ORCH-067/069 (G1 уже сделан restore-PR #76; здесь — устранение корня навсегда).

  • FR-1 verify_merged_to_main: подтверждение merge ТОЛЬКО по git merge-base --is-ancestor <validated_sha> origin/main (OR-ветка pr_already_merged удалена). Пустой SHA / git-ошибка → False, never-raise.
  • FR-2 pr_already_merged → idempotency-guard: засчитывает PR лишь при merged & head.ref==<branch> & base.ref=="main" (исключает авто docs-PR).
  • FR-3 merge_pr выбирает open code-PR по head==<branch> И base==main; merge только Gitea PR-API.
  • FR-5 новый check_main_regression в _handle_merge_verify (после SHA-в-main, до done): проверяет MAIN_REGRESSION_MARKERS в origin/main; count==0 → alert «main regressed» + HOLD (НЕ done, без отката), git-ошибка грепа → fail-open. Kill-switch ORCH_REGRESSION_GUARD_ENABLED; non-self → no-op.
  • FR-4 корневой .gitattributes: CHANGELOG.md merge=union.

Инварианты STAGE_TRANSITIONS/QG_CHECKS/deploy-status/merge-gate/image-freshness/схема БД/HTTP API — без изменений; non-self — no-op (INV-5); merge только PR-API без force-push (INV-2).

Test plan

  • tests/test_orch073_*.py (TC-01..18)
  • pytest tests/ -q → 941 passed; ruff clean on changed files (TC-19)
  • staging-прогон 2 задач с правкой CHANGELOG (AC-10) — стадия deploy-staging

Docs

CHANGELOG (Unreleased), .env.example; README + ADR обновлены архитектором.

Refs: ORCH-073

## Summary CRIT: системный фикс эрозии `main` + восстановление кода ORCH-067/069 (G1 уже сделан restore-PR #76; здесь — устранение корня навсегда). - **FR-1** `verify_merged_to_main`: подтверждение merge ТОЛЬКО по `git merge-base --is-ancestor <validated_sha> origin/main` (OR-ветка `pr_already_merged` удалена). Пустой SHA / git-ошибка → False, never-raise. - **FR-2** `pr_already_merged` → idempotency-guard: засчитывает PR лишь при `merged & head.ref==<branch> & base.ref=="main"` (исключает авто docs-PR). - **FR-3** `merge_pr` выбирает open code-PR по `head==<branch>` И `base==main`; merge только Gitea PR-API. - **FR-5** новый `check_main_regression` в `_handle_merge_verify` (после SHA-в-main, до `done`): проверяет `MAIN_REGRESSION_MARKERS` в `origin/main`; `count==0` → alert «main regressed» + HOLD (НЕ done, без отката), git-ошибка грепа → fail-open. Kill-switch `ORCH_REGRESSION_GUARD_ENABLED`; non-self → no-op. - **FR-4** корневой `.gitattributes`: `CHANGELOG.md merge=union`. Инварианты `STAGE_TRANSITIONS`/`QG_CHECKS`/deploy-status/merge-gate/image-freshness/схема БД/HTTP API — без изменений; non-self — no-op (INV-5); merge только PR-API без force-push (INV-2). ## Test plan - [x] tests/test_orch073_*.py (TC-01..18) - [x] `pytest tests/ -q` → 941 passed; ruff clean on changed files (TC-19) - [ ] staging-прогон 2 задач с правкой CHANGELOG (AC-10) — стадия deploy-staging ## Docs CHANGELOG (Unreleased), .env.example; README + ADR обновлены архитектором. Refs: ORCH-073
admin added 6 commits 2026-06-08 16:30:47 +03:00
Root-cause fix for main erosion (phantom merge): code of ORCH-067/069 reached
`done` while absent from origin/main (only their auto docs-PRs landed).

- FR-1: verify_merged_to_main confirms merge ONLY by `git merge-base
  --is-ancestor <validated_sha> origin/main`; the OR-branch pr_already_merged is
  removed (a merged PR no longer confirms). Empty SHA / git error -> False.
- FR-2: pr_already_merged demoted to merge_pr idempotency-guard; counts a PR only
  when merged & head.ref==<branch> & base.ref=="main" (explicit in-loop filter).
- FR-3: merge_pr selects the open code-PR by head==<branch> AND base==main.
- FR-5: new deterministic check_main_regression in _handle_merge_verify (after
  confirmed SHA-in-main, before done) verifies MAIN_REGRESSION_MARKERS still in
  origin/main; deterministic count==0 -> alert "main regressed" + HOLD (NOT done,
  no rollback); git error of the grep -> fail-open. Kill-switch
  ORCH_REGRESSION_GUARD_ENABLED; non-self -> no-op.
- FR-4: root .gitattributes `CHANGELOG.md merge=union` so Unreleased edits
  auto-merge on rebase without conflict (branch not rolled back).

Invariants unchanged (STAGE_TRANSITIONS, QG_CHECKS, deploy-status, merge-gate,
image-freshness, DB schema, external HTTP API); non-self repos no-op (INV-5);
never-raise (INV-1); merge only via Gitea PR-API (INV-2).

Docs: CHANGELOG, .env.example (README/ADR updated by architect). Tests:
tests/test_orch073_*.py (TC-01..18); existing merge-gate tests updated for the
new code-PR filter.

Refs: ORCH-073

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
tester(ET): auto-commit from tester run_id=384
All checks were successful
CI / test (push) Successful in 26s
CI / test (pull_request) Successful in 21s
1f0929838a
admin force-pushed feature/ORCH-073-crit-main-orch-067-069 from e3a818b5dc to 1f0929838a 2026-06-08 16:30:47 +03:00 Compare
admin merged commit 1c3ecb973e into main 2026-06-08 16:54:01 +03:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/orchestrator#77