* fix: preserve PR number in recovery and dedupe validation utilities
Bugbot #2908822306: Use parsePrFromUrl utility to correctly extract
PR number from URL instead of defaulting to 0. Applied to both
recovery/actions.ts and session-manager.ts for consistency.
Bugbot #2908822310: Extract safeJsonParse and validateStatus to
shared utils/validation.ts to eliminate duplication between
recovery/validator.ts and session-manager.ts.
Clean rebuild from origin/main with only recovery-specific changes.
* fix: add PR number fallback and remove unused import
Bugbot #2908822306: Add fallback regex to extract PR number from URL
ending when full GitHub URL pattern doesn't match (e.g., non-GitHub URLs).
Bugbot #2908822310: Remove unused SessionStatus import from session-manager.ts
(now imported from utils/validation.ts).
Tests: 406 passed, typecheck clean.
* fix(core): harden recovery action selection and escalation
* fix(core): preserve recovered agent summary metadata
* fix(core): reuse canonical PR type in URL parser
Avoid shadowing the core PRInfo type in the recovery URL parser while keeping the non-GitHub trailing-number fallback covered by tests.
* fix(core): align recovery metadata and session reconstruction
Persist restored timestamps under the canonical metadata key, share
session reconstruction logic between recovery and session loading, and
log the real escalation reason when recovery aborts on retry limits.
* fix(core): keep dry-run escalation reasons accurate
Use the assessment's actual escalation reason in dry-run results so preview output matches real execution behavior for partial-session escalations.
* fix(core): dedupe recovery scanning and honor custom log path
Reuse metadata listing rules in scanner to avoid duplicated session ID filters,
and preserve user-supplied recovery logPath in recovery manager APIs.
* fix(core): align dry-run recovery behavior with real actions
Compute recovery escalation decisions before dry-run returns and route
single-session dry runs through executeAction so action-specific fields
(reason/manual-intervention) are preserved.
* fix(core): derive dry-run recovery report from action execution
Run dry-run recovery classification through executeAction so report actions
match real execution logic, including max-attempt escalation decisions.