fix(reconciler): stop F-2 livelock spam on synced terminal tasks + cache TTL #70
Closed
admin
wants to merge 0 commits from
feature/ORCH-068-bug-reconciler-livelock-unbloc into main
pull from: feature/ORCH-068-bug-reconciler-livelock-unbloc
merge into: admin:main
admin:main
admin:feature/ORCH-104-eae59ef5
admin:feature/ORCH-105-
admin:feature/ORCH-106-fix-onboard-project-py-add-col
admin:feature/ORCH-011-
admin:feature/ORCH-103-orch-10b-bundled-bootstrap
admin:feature/ORCH-102-orch-10a-lite-watchdog
admin:feature/ORCH-101-orch-10-common-smoke
admin:feature/ORCH-009-turnkey-plane
admin:docs/ORCH-009-staging-log
admin:feature/ORCH-098-fnd
admin:feature/ORCH-100-fnd-f1b-sidecar-watchdog
admin:feature/ORCH-019-
admin:feature/ORCH-057-bug-follow-up-orch-040-normali
admin:feature/ORCH-099-fnd-f1a-metrics-agent-liveness
admin:feature/ORCH-027-code-coverage
admin:docs/ORCH-057-staging-log
admin:feature/ORCH-095-bug-html-1-render-task-tracker
admin:feature/ORCH-094-bug-done-deploy-plane-awaiting
admin:feature/ORCH-093-bug-merge-gitea-405-5xx-hold-p
admin:feature/ORCH-091-bug-to-analyse-stage-deploy-st
admin:feature/ORCH-090-stop-plane
admin:chore/ORCH-090-staging-log
admin:feature/ORCH-062-infra-prune-docker-build-cache
admin:feature/ORCH-063-infra-mva154-85
admin:feature/ORCH-092-6-escalation
admin:feature/ORCH-079-orch-52f-readme-reviewer
admin:feature/ORCH-078-orch-52e-orch-nnn
admin:feature/ORCH-077-orch-52d-6-anthropic
admin:feature/ORCH-076-orch-52c-handoff-frontmatter-w
admin:feature/ORCH-075-orch-52b-docs-templates-adr-na
admin:feature/ORCH-089-autoapprove-brd-autodeploy
admin:feature/ORCH-088-orch-88-10-20
admin:feature/ORCH-087-orch-87-to-analyse-bump
admin:feature/ORCH-086-orch-86-reconciler-telegram-et
admin:feature/ORCH-080-orch-52g-telegram-link-preview
admin:feature/ORCH-082-orch-81-pr-merge-verify-hold
admin:docs/ORCH-082-staging-log
admin:feature/ORCH-081-orch-52h-env-config
admin:docs/ORCH-081-staging-log
admin:feature/ORCH-074-orch-52a-frontmatter-routing-e
admin:feature/ORCH-026-b-a
admin:feature/ORCH-073-crit-main-orch-067-069
admin:feature/ORCH-069-qg-0-title-orch-qg0-title-max-
admin:restore/orch-6769-2026-06-08
admin:feature/ORCH-067-telegram-tracker-bump-plane
admin:docs/ORCH-069-staging-log
admin:feature/ORCH-071-crit-bug-merge-main
admin:integ/restore-main-2026-06-08
admin:feature/ORCH-066-plane
admin:feature/ORCH-059-approve-confirm-deploy-approve
admin:feature/ORCH-022-security-secret-scanning
admin:feature/ORCH-065-bug-zombie-jobs-merge-lease-ru
admin:feature/ORCH-021-post-deploy-rollback
admin:feature/ORCH-061-bug-deploy-staging-development
admin:docs/ORCH-061-staging-log
admin:feature/ORCH-060-reconciler-escalated-max-retri
admin:deployer/ORCH-058-staging-verdict-v3
admin:deployer/ORCH-058-staging-verdict
admin:feature/ORCH-058-self-deploy-retag-staging
admin:feature/ORCH-036-orch-36-deploy-b
admin:feature/ORCH-053-sweeper-webhook-stuck-task
admin:deploy-log/ORCH-053-20260606T210404
admin:feature/ORCH-043-merge-gate-auto-rebase-re-test
admin:feature/ORCH-040-root-git
admin:feature/ORCH-042-telegram-live-tracker-bump
admin:feature/ORCH-044-preflight-auth-effort
admin:staging-log/ORCH-044-20260606T084247
admin:docs/lessons-orch-048
admin:deploy-log/ORCH-048-20260606T071157
admin:feature/ORCH-048-staging-b6-check-reads-registr
admin:staging-log/ORCH-048-20260606T053413
admin:feature/ORCH-046-stage-engine-pass-reviewer-tes
admin:staging-log/ORCH-046-20260606T044841
admin:docs/lessons-2026-06-05
admin:feature/ORCH-047-check-tests-passed-gate-must-r
admin:feature/ORCH-045-ci-poll-retry
admin:docs/lessons-orch-017
admin:feature/ORCH-017-brd-plane-telegram
admin:feat/ORCH-41-agent-models
admin:fix/ORCH-39-webhook-tests
admin:feature/ORCH-016-plane
admin:feature/ORCH-10-per-project-states
admin:docs/ORCH-9-canon
admin:feature/ORCH-35-staging-gate
admin:feature/ORCH-34-deploy-hook
admin:feature/ORCH-33-staging-testsuite
admin:feature/ORCH-31-staging-infra
admin:fix/isolate-webhook-tests-from-plane
admin:ci/add-gitea-workflow
admin:docs/product-vision
admin:fix/tests-machine-verdict
admin:fix/deploy-gate-log-path
admin:fix/tracker-edit-not-modified
admin:feat/telegram-live-tracker
admin:fix/observability-and-merge-gate
admin:fix/deploy-verdict-gate
admin:fix/ci-fail-retry-developer
admin:fix/drop-local-tests-qg
admin:fix/qg-pytest-no-make
admin:fix/approved-advances-stage
admin:fix/gitea-public-url
admin:fix/taskmd-description
admin:fix/status-only-verdict
admin:fix/pipeline-start-bugs
admin:feature/pipeline-ux
admin:feature/plane-per-agent-author
admin:feature/ORCH-M6-plane-sequence
admin:feature/ORCH-cleanup-L1L2L3
admin:feature/ORCH-5-webhook-dedup
admin:feature/ORCH-4-stage-engine
admin:feature/ORCH-7-hardening
admin:feature/ORCH-1-job-queue
admin:feature/ORCH-6-multirepo
admin:feature/ORCH-2-worktree
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "feature/ORCH-068-bug-reconciler-livelock-unbloc"
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?
Summary
Fixes the reconciler F-2 livelock that spammed Telegram
<wi> разблокирована (потерян webhook)every ~120s for a fully-synchronized Done task (incident ET-002, 191+ messages/night) after the ORCH-066 Plane status-model merge. Two stacked defects fixed independently (defense in depth) + a secondary states-cache bug.Done/Cancelled) are excluded from the actionable set by Plane state group (completed/cancelled) — project-independent, robust to UUID aliasing after status renames. Per-issue check + logical-key fallback.get_project_statescaches{uuid → group}from the same/states/fetch; new accessorget_project_state_groups._note_unblockfires only on a confirmed state change (stage before/after_dispatch; task-appears for the start case). No-op dispatch → silence.handle_*contracts untouched.{issue_id → last unblocked state}as a backstop._STATES_CACHETTLORCH_PLANE_STATES_TTL_S(default 300s;0→ previous lifetime cache) self-heals a status added to Plane after start without a restart (reusesreload_project_states()); a failed refresh serves the stale-but-correct set, not enduro defaults.Invariants preserved:
STAGE_TRANSITIONS/QG_CHECKS/DB schema/handle_*/F-1/F-3 unchanged; never-raise per unit of work; 0 jobs/0 tokens for synced tasks; self-hosting tick never restarts prod. Observability:skipped_terminal_total/deduped_totalin the/queuereconcile block.ADR:
docs/work-items/ORCH-068/06-adr/ADR-001-reconciler-terminal-exclusion-and-cache-ttl.mdTest plan
pytest tests/ -qgreen (764 passed)tests/test_reconciler_plane.py(terminal exclusion incl. UUID aliasing on enduro+orchestrator, no-op silence, dedup, legit-unblock regression, never-raise, kill-switches)tests/test_plane_states_cache.py(TTL self-heal, ttl=0 back-compat, fallback preserved)🤖 Generated with Claude Code
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>53bc54c212to6bbd530caaSuperseded by #71 (restore-main 2026-06-08): ORCH-068 code restored to main after phantom-merge.
Pull request closed