Skip to content

feat(reliability): wire FailurePatternDetector into workflow failure handling (#10628) - #10631

Merged
mrveiss merged 2 commits into
Dev_new_guifrom
issue-10628
Jun 28, 2026
Merged

mrveiss merged 2 commits into
Dev_new_guifrom
issue-10628

Conversation

@mrveiss

@mrveiss mrveiss commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Thinking Path

The codebase audit (umbrella #10603, #10602) found FailurePatternDetector fully built with a Redis-backed singleton (get_pattern_detector()) but zero production callers on either side — nothing wrote patterns and nothing read them, so the learned-failure machinery was dead. Re-verified on the current base before implementing. This wires the full loop (write + read consumer) rather than a one-sided wire that would leave orphan data.

What Changed

  • WorkflowRunner._handle_workflow_execution_failure (enhanced_orchestration/workflow_runner.py) now calls a new guarded helper _record_failure_pattern(plan, error) that:
    • READ — detect_pattern(causal_chain, error_type) to check if this failure mode (causal_chain = "workflow:{strategy}:{error_type}") has recurred.
    • WRITE — learn_pattern(...) to record/increment the pattern in Redis.
    • CONSUMER — annotates the returned failure dict with known_failure_pattern: {pattern_id, occurrences, resolution_success_rate} when the pattern has recurred, so the learned data is actually surfaced to callers/logs.
  • Fire-and-forget: any detector/Redis error is swallowed (logger.debug) so workflow failure handling is never disrupted.

No code deleted; no _v2; detector reused as-is.

Verification

  • tests/enhanced_orchestration/test_failure_pattern_wiring.py — 3 passing:
    • recurring failure → learn_pattern called + known_failure_pattern annotation returned
    • first-time failure → no annotation, but still learned (write happens)
    • detector raising (e.g. Redis down) → swallowed, returns None, never propagates
  • flake8 --max-line-length=120 clean; black/isort clean; py_compile clean.

Part of #10602 / umbrella #10603. Closes #10628.

Model Used

Claude Opus 4.8 (1M context)

…handling (#10628)

The FailurePatternDetector was fully built but had zero production callers on
either side — nothing wrote patterns and nothing read them. Wire the full loop:

- WorkflowRunner._handle_workflow_execution_failure now calls a guarded helper
  _record_failure_pattern(plan, error) that:
  - detect_pattern(causal_chain, error_type) — READ: is this a known recurring
    failure? (causal_chain = "workflow:{strategy}:{error_type}")
  - learn_pattern(...) — WRITE: record/increment the pattern in Redis.
  - annotates the returned failure dict with `known_failure_pattern`
    {pattern_id, occurrences, resolution_success_rate} when it has recurred,
    so the learned data is actually consumed by callers/logs.
- Fire-and-forget: any detector/Redis error is swallowed so failure handling
  is never disrupted.

Tests: tests/enhanced_orchestration/test_failure_pattern_wiring.py — recurring
failure flagged, first-time returns no annotation, detector error never breaks
the failure path (3 passing).

Part of #10602 / umbrella #10603.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No hardcoded values detected that have SSOT config equivalents!

… (review #10631)

Address code review:
- Record the pattern once at the top level (_depth == 0) instead of on every
  fallback recursion, so occurrence_count isn't inflated by fallback depth.
  Extracted the GOAP-replan/fallback logic into _attempt_failure_recovery; the
  known_failure_pattern annotation now rides whatever failure result is
  ultimately returned (covers GOAP-replan-failure + fallback-exhausted paths).
- Correct the docstring: the detector call is awaited inline (guarded), not
  fire-and-forget; note the detector's sync Redis client is tracked separately.

Tests: +3 (records once at top level + annotates failure; no record/annotate on
recursion; success recovery not annotated) — 6 total, passing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant