restore(main): долить фантомные ORCH-022/059/066/068 (4 потерянных PR) #71
Reference in New Issue
Block a user
Delete Branch "integ/restore-main-2026-06-08"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Восстановление целостности main после фантомного merge.
Все 4 фичи сосуществуют. pytest 832 passed. Верифицировано вручную (8/8 маркеров, целостность, нет тихих потерь). См. ORCH-71 (root-fix фантома) + docs/history/LESSONS_2026-06-08_phantom-merge.md
Split the overloaded `Approved` Plane status: it served BOTH as the human BRD gate on `analysis` AND as the silent Phase B prod-deploy trigger on `deploy` (ORCH-036), so a routine approve could launch a self-hosting prod restart. ORCH-059 introduces a dedicated logical status `confirm_deploy` ("Confirm Deploy") that triggers ONLY Phase B on `deploy`; `Approved` stays purely a pipeline gate. - plane_sync: map "Confirm Deploy" -> "confirm_deploy" in _PLANE_NAME_TO_KEY; intentionally absent from _DEFAULT_STATES => fail-closed (no UUID -> .get yields None, no KeyError, no blind deploy). - webhooks/plane: handle_issue_updated routes "Confirm Deploy" (fail-closed .get) to new handle_confirm_deploy (guarded to stage=="deploy") -> _try_advance_stage(confirm_deploy=True). - stage_engine: advance_stage gains keyword-only confirm_deploy=False; Phase B block returns early for deploy+finished_agent is None but only initiates the deploy when confirm_deploy=True; a plain Approved is a deterministic no-op (returns before check_deploy_status -> no false БАГ-8 rollback). - Phase A CTA now asks the operator for "Confirm Deploy", not "Approved". Contracts unchanged: STAGE_TRANSITIONS, QG_CHECKS, check_deploy_status, hook exit codes, Phases A/C, merge-gate, DB schema. Conditional like ORCH-35/36 (self-hosting only). Docs updated (CLAUDE.md, architecture/README.md, CHANGELOG). Refs: ORCH-059 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>Reconciler F-2 spammed Telegram "<wi> разблокирована" every ~120s for a fully-synchronized Done task (incident ET-002, 191+ msgs/night) after the ORCH-066 Plane status model merge. Two stacked defects (defense in depth): - D1 (selection): actionable states were told apart by bare UUID, so a Done issue aliased onto the approved UUID entered the approved branch. Now terminal states are excluded by Plane state GROUP (completed/cancelled), a project-independent discriminator robust to UUID aliasing; per-issue check with a logical-key fallback when the group is unavailable. get_project_states caches {uuid -> group} from the same /states/ fetch; new sibling accessor get_project_state_groups. - D2 (notification): _note_unblock fired unconditionally after _dispatch. Now it only fires on a confirmed state change (stage before/after _dispatch; task-appears for the start case) — handlers' contracts untouched. - TR-3: in-memory dedup guard {issue_id -> last unblocked state} as a backstop. - TR-4: _STATES_CACHE lived for the whole process lifetime, so a new Plane status was invisible without a restart. Added TTL ORCH_PLANE_STATES_TTL_S (default 300s; 0 = previous lifetime cache) reusing reload_project_states(); a failed refresh serves the stale-but-correct set, not enduro defaults. STAGE_TRANSITIONS / QG_CHECKS / DB schema / handle_* contracts / F-1 / F-3 unchanged; never-raise preserved; self-hosting tick never restarts prod. Observability: skipped_terminal_total / deduped_total in /queue reconcile block. Tests: tests/test_reconciler_plane.py (TC-01..TC-10), tests/test_plane_states_cache.py (TC-11/TC-12). Refs: ORCH-068 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>