fix(reconciler): skip escalated / Blocked / Needs-Input tasks in F-1 (ORCH-060) #60

Merged
admin merged 7 commits from feature/ORCH-060-reconciler-escalated-max-retri into main 2026-06-07 15:01:11 +03:00
Owner

Summary

  • Guard 1 (escalated, no network, first): F-1 skips a task once developer_retry_count(task_id) >= MAX_DEVELOPER_RETRIES. Promotes stage_engine._developer_retry_count to public developer_retry_count (single source of truth; private alias kept); limit read from the constant, never a literal 3. Closes the ET-013 infinite-bounce loop (green CI + reviewer REQUEST_CHANGES at the cap re-unblocked every tick).
  • Guard 2 (explicit human Plane gate, Variant A, no DB migration): new never-raise plane_sync.fetch_issue_state + Reconciler._is_blocked_or_needs_input; issue in Plane Blocked / Needs Input -> skip. Any error / None / unresolved project -> conservative skip. New sub-flag ORCH_RECONCILE_SKIP_BLOCKED_ENABLED mutes only the networked Guard 2 (Guard 1 always active).
  • Guards added in _reconcile_gate_task AFTER the existing analysis/no-gate/active-job/grace guards and BEFORE the gate pre-evaluation; silent skip (no advance, no unblocked_total, no notifications).
  • F-2 unchanged: Blocked/Needs Input are outside {in_progress, approved, rejected} -> never replayed (regression test).
  • Invariants preserved: DB schema, STAGE_TRANSITIONS, QG_CHECKS, never-raise per unit of work, analysis carve-out, kill-switches.
  • Docs (golden source) updated in-PR: docs/architecture/README.md, README.md + .env.example (new flag), CHANGELOG.md. ADR: docs/work-items/ORCH-060/06-adr/ADR-001-reconciler-skip-escalated.md.

Test plan

  • pytest tests/test_reconciler.py -q - 27 passed (15 ORCH-053 regression + 12 new TC-01..TC-11)
  • pytest tests/ -q - 644 passed, 0 regressions
  • AC-1/2/4 escalated skipped; AC-3 happy-path advances; AC-5/6 Blocked/Needs Input skipped
  • AC-7/8 no spam, gate not evaluated on escalated; AC-9 F-2 no replay; AC-10 never-raise; AC-11 limit from constant

Generated with Claude Code

## Summary - **Guard 1 (escalated, no network, first):** F-1 skips a task once `developer_retry_count(task_id) >= MAX_DEVELOPER_RETRIES`. Promotes `stage_engine._developer_retry_count` to public `developer_retry_count` (single source of truth; private alias kept); limit read from the constant, never a literal `3`. Closes the ET-013 infinite-bounce loop (green CI + reviewer REQUEST_CHANGES at the cap re-unblocked every tick). - **Guard 2 (explicit human Plane gate, Variant A, no DB migration):** new never-raise `plane_sync.fetch_issue_state` + `Reconciler._is_blocked_or_needs_input`; issue in Plane Blocked / Needs Input -> skip. Any error / None / unresolved project -> conservative skip. New sub-flag `ORCH_RECONCILE_SKIP_BLOCKED_ENABLED` mutes only the networked Guard 2 (Guard 1 always active). - Guards added in `_reconcile_gate_task` AFTER the existing analysis/no-gate/active-job/grace guards and BEFORE the gate pre-evaluation; silent skip (no advance, no `unblocked_total`, no notifications). - F-2 unchanged: Blocked/Needs Input are outside `{in_progress, approved, rejected}` -> never replayed (regression test). - Invariants preserved: DB schema, `STAGE_TRANSITIONS`, `QG_CHECKS`, never-raise per unit of work, `analysis` carve-out, kill-switches. - Docs (golden source) updated in-PR: `docs/architecture/README.md`, `README.md` + `.env.example` (new flag), `CHANGELOG.md`. ADR: `docs/work-items/ORCH-060/06-adr/ADR-001-reconciler-skip-escalated.md`. ## Test plan - [x] `pytest tests/test_reconciler.py -q` - 27 passed (15 ORCH-053 regression + 12 new TC-01..TC-11) - [x] `pytest tests/ -q` - 644 passed, 0 regressions - [x] AC-1/2/4 escalated skipped; AC-3 happy-path advances; AC-5/6 Blocked/Needs Input skipped - [x] AC-7/8 no spam, gate not evaluated on escalated; AC-9 F-2 no replay; AC-10 never-raise; AC-11 limit from constant Generated with Claude Code
admin added 4 commits 2026-06-07 14:50:49 +03:00
docs: init ORCH-060 business request
All checks were successful
CI / test (push) Successful in 17s
d6e0df3550
analyst(ET): auto-commit from analyst run_id=288
All checks were successful
CI / test (push) Successful in 17s
365c67f45d
architect(ET): auto-commit from architect run_id=289
All checks were successful
CI / test (push) Successful in 16s
efe437a4aa
fix(reconciler): skip escalated / Blocked / Needs-Input tasks in F-1
All checks were successful
CI / test (push) Successful in 16s
CI / test (pull_request) Successful in 16s
4db8276f98
Reconciler F-1 could not tell "stuck by a lost webhook" from "escalated:
max developer retries reached, waiting for a human". With CI green and a
reviewer that kept sending REQUEST_CHANGES up to the cap, every tick
re-unblocked development -> review -> rollback -> re-unblock (incident
ET-013, infinite bounce: wasted agent runs, Telegram spam, parasitic load
on the shared self-hosting instance).

Add two pre-gate guards in Reconciler._reconcile_gate_task (after the
existing analysis/no-gate/active-job/grace guards, before the gate
pre-evaluation), each an early silent return (no advance, no unblocked_total
increment, no notifications):
- Guard 1 (escalated, deterministic, no network, checked first):
  developer_retry_count(task_id) >= MAX_DEVELOPER_RETRIES. Promote
  stage_engine._developer_retry_count to public developer_retry_count
  (single source of truth; private alias kept). Limit from the constant,
  not a literal 3.
- Guard 2 (explicit human Plane gate, Variant A, no DB migration): new
  never-raise plane_sync.fetch_issue_state + Reconciler._is_blocked_or_needs_input;
  any error/None/unresolved project -> conservative skip. New sub-flag
  ORCH_RECONCILE_SKIP_BLOCKED_ENABLED mutes only the networked Guard 2.

F-2 unchanged: Blocked/Needs Input are outside {in_progress, approved,
rejected} so they are never replayed (regression test added). DB schema,
STAGE_TRANSITIONS, QG_CHECKS, never-raise, analysis carve-out and
kill-switches untouched.

Refs: ORCH-060

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
admin added 1 commit 2026-06-07 14:53:36 +03:00
reviewer(ET): auto-commit from reviewer run_id=291
All checks were successful
CI / test (push) Successful in 16s
CI / test (pull_request) Successful in 22s
55e5e968ae
admin added 1 commit 2026-06-07 14:55:01 +03:00
tester(ET): auto-commit from tester run_id=292
All checks were successful
CI / test (push) Successful in 17s
CI / test (pull_request) Successful in 16s
829b914ff7
admin added 1 commit 2026-06-07 14:59:01 +03:00
deployer(ET): auto-commit from deployer run_id=293
All checks were successful
CI / test (push) Successful in 17s
CI / test (pull_request) Successful in 16s
210aef6954
admin merged commit d4c6cc0f61 into main 2026-06-07 15:01:11 +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#60