+
    <jJ                       R t ^ RIHt ^ RIHtHt ]R:,          t ! R R]4      t ! R R]4      t	 ! R R]]
4      t ! R	 R
]4      t ! R R]4      t ! R R]4      t ! R R]
4      t ! R R]4      t ! R R]4      t ! R R]
4      t ! R R]4      t ! R R]
4      t ! R R]
4      t ! R R]
4      t ! R R ]4      t ! R! R"]4      t ! R# R$]4      t ! R% R&]4      t ! R' R(]4      t ! R) R*]4      t ! R+ R,]4      t ! R- R.]
4      t ! R/ R0]4      t  ! R1 R2]!4      t" ! R3 R4]4      t# ! R5 R6]4      t$ ! R7 R8]!4      t%. R;Ot&R9# )<uJ  recoil.lib.exceptions — Canonical exception types per Tenet 6.

Tenet 6 (Errors Must Be Visible) requires that the engine fails loudly by
default. This module is the single home for the engine's typed exception
families. Provider-local exception families (LipSyncError in
execution/providers/sync_so.py, AudioSynthesisError in elevenlabs.py,
EvalProviderError in gemini_vision.py) remain in their provider modules —
those are localized to one transport / one upstream API and do not benefit
from consolidation.

The types here are the engine-wide canonical errors. Importers across
recoil/lib, recoil/core, recoil/pipeline, recoil/execution, recoil/workspace
all bind to these names.

Provenance:
    - RecoilError, SchemaValidationError, SidecarFieldError,
      CrossConfigDriftError: introduced as Phase A.1 temp at
      recoil/lib/_phase_a_exceptions.py; canonicalized here in Phase E.4.
    - CostMissingError: introduced as Phase C temp at
      recoil/pipeline/core/cost.py; canonicalized here in Phase E.5.
    - UnknownFailureEscalation: introduced as Phase C temp at
      recoil/pipeline/core/failure_mode.py; canonicalized here in Phase E.5.
    - PayloadHintsValidationError: introduced as Phase C temp at
      recoil/execution/providers/payload_hints.py; canonicalized here in
      Phase E.5.
    - RetryExhaustedError, SanctionedFallbackError, RefDimensionUnknownError:
      introduced new in Phase E.2.
    - SidecarCorruptError, VerdictCorruptError, WorkspaceStateCorruptError
      (+ subclasses CastingFragmentCorruptError, EditorialConfigCorruptError,
      RecommendationsCorruptError, PromptCompilerOverridesCorruptError):
      introduced new in Phase E.2 from Phase E.1 inventory's corruption-family
      cluster (8 of top-30 sites).
    - ConfigParseError, PromptValidatorConfigError, KeyframeContextLookupError,
      MediaProbeError, ExecutionStoreUnavailableError, VerdictAutofillError:
      introduced new in Phase E.2 from Phase E.1 inventory's lookup/config
      cluster.

CP-9 lock: production_loop.py is byte-untouched. Phase E does not import
these types from production_loop.
)annotations)LiteralOptionalc                      ] tR t^=tRtRtR# )RecoilErrorzBase for all Recoil typed exceptions.

Originated in Phase A.1's _phase_a_exceptions.py. Canonicalized here in
Phase E.2; the temp module re-exports for one cycle (Phase E.4 closes
the loop).
 N__name__
__module____qualname____firstlineno____doc____static_attributes__r       ڌ/Users/joeturnerlin/Code/recoil-sessions/Joes-MacBook-Pro/adhoc--claude--atlas-redesign--20260625T050330Z-1fd50d09/recoil/core/exceptions.pyr   r   =   s     	r   r   c                      ] tR t^KtRtRtR# )SchemaValidationErrorzRaised when a config file fails schema validation at load time.

Replaces the 'json.loads then .get(key, default)' pattern with fail-loud
validation per Tenet 6.
r   Nr   r   r   r   r   r   K       
 	r   r   c                      ] tR t^TtRtRtR# )SidecarFieldErroru   Raised when a sidecar write attempts an out-of-contract field.

Frozen-contract field set per data-contracts.md §1a. Inherits from
ValueError for API compatibility with existing callers.
r   Nr   r   r   r   r   r   T   r   r   r   c                      ] tR t^]tRtRtR# )CrossConfigDriftErrorzRaised when cross-config validation detects drift.

e.g. a model id in provider_strategy.json that doesn't exist in
model_profiles.json. Per Tenet 6.
r   Nr   r   r   r   r   r   ]   r   r   r   c                  >   a  ] tR t^jtRtRRRR/R V 3R llltRtV ;t# )	CostMissingErrora  Raised when a RunResult or record has no readable cost_usd.

Tenet 6: the default disposition for missing cost is to fail loud.
Callers that legitimately tolerate missing cost (display, aggregation)
use read_cost_from_result_safe() instead, which logs WARNING and
returns 0.0.
	result_idNsourceunknownc                    V ^8  d   QhRRRR/# )   r   Optional[str]r   strr   )formats   "r   __annotate__CostMissingError.__annotate__s   s        ! 	r   c               	T   < Wn         W n        R V: RV: R2p\        SV `  V4       R# )zCostMissingError: result_id=z source=z has no cost_usd. If this is a legitimate billing-zero case, the upstream writer must store cost_usd=0.0 explicitly. If missing is tolerable for this read site, use read_cost_from_result_safe() and accept the WARNING log.N)r   r   super__init__)selfr   r   msg	__class__s   &$$ r   r&   CostMissingError.__init__s   s=     #*9-xz JG H 	 	r   )r   r   r	   r
   r   r   r   r&   r   __classcell__r)   s   @r   r   r   j   s+     $(  	  r   r   c                  F   a  ] tR t^tRtRRRRRRRR/R V 3R llltR	tV ;t# )
UnknownFailureEscalationai  Raised by classify_failure() when an error cannot be classified.

Tenet 6 (Errors Must Be Visible): unknown error shapes ESCALATE rather
than silently defaulting to TRANSIENT (retry forever) or PERMANENT
(give up silently). The exception carries the full classification
context so the operator can grep for "UnknownFailureEscalation" in
logs and immediately see what input was unclassifiable.

Callers that legitimately need to handle unknown-as-data (e.g., an
aggregation pass over historical errors) opt in via
classify_failure(..., escalate_unknown=False); this returns
(FailureMode.UNKNOWN, 0.0) without raising.

error_textNgate_verdicthttp_statuscallerc               (    V ^8  d   QhRRRRRRRR/# )r   r0   r   r1   zOptional[object]r2   zOptional[int]r3   r   )r!   s   "r   r"   %UnknownFailureEscalation.__annotate__   s4       " '	
 # r   c          	     	|   < Wn         W n        W0n        W@n        R V: RV: RV: RV: R2	p\        SV `  V4       R# )zLUnknownFailureEscalation: classify_failure could not classify input. caller=z error_text=z http_status=z gate_verdict=zC. Add the missing pattern to pipeline.core.failure_mode and re-run.N)r0   r1   r2   r3   r%   r&   )r'   r0   r1   r2   r3   r(   r)   s   &$$$$ r   r&   !UnknownFailureEscalation.__init__   s\     %(&&&,Z|J> J&/7G H56 	 	r   )r3   r0   r1   r2   r+   r-   s   @r   r/   r/      s?     %) *.	
 &* !%  r   r/   c                      ] tR t^tRtRtR# )PayloadHintsValidationErroru   Raised when a PayloadHints subclass receives unknown keys.

Reserved for the follow-on sprint that flips extra="allow" → "forbid".
Not raised in Phase C.
r   Nr   r   r   r   r9   r9      s    r   r9   c                  >   a  ] tR t^tRtRRRR/R V 3R llltRtV ;t# )	RetryExhaustedErrorae  A retry helper exhausted its attempt budget without success.

Per Tenet 6: a retry exhausting all attempts must NOT return None or a
sentinel "give up" RunResult. It either raises this error (caller does
not bind to a `RunResult`) or returns a `RunResult` with explicit
`failure_mode = RETRY_EXHAUSTED` (caller does bind).

Phase E ships the raise variant.

last_errorN	operation c               $    V ^8  d   QhRRRRRR/# )r   attemptsintr<   zBaseException | Noner=   r    r   )r!   s   "r   r"    RetryExhaustedError.__annotate__   s*        )	
 r   c               	   < Wn         W n        W0n        R V R2pV'       d   V RV 2pV'       d   V RVP                  P                   RV 2p\
        SV `  V4       R# )zretry exhausted after z	 attemptsz for z; last error: : N)r@   r<   r=   r)   r	   r%   r&   )r'   r@   r<   r=   r(   r)   s   &$$$ r   r&   RetryExhaustedError.__init__   sh     !$"&xj	:Eyk*CE
(<(<(E(E'FbUCr   )r@   r<   r=   r+   r-   s   @r   r;   r;      s+     ,0	
   r   r;   c                      ] tR t^tRtRtR# )SanctionedFallbackErroru  Base class for errors raised from within sanctioned-fallback paths.

Most sanctioned fallbacks DO NOT raise — they log + return a substituted
value. This class is for the rare case where a fallback path itself
cannot complete (e.g., the fallback resolver also failed). Subclasses
in this module enumerate the specific cases.

Tenet 6 carve-out: a fallback firing is observable via
log.warning("FALLBACK_FIRED ..."); a fallback FAILING is observable
via this exception type.
r   Nr   r   r   r   rG   rG      s    
r   rG   c                  6   a  ] tR t^tRtRR V 3R llltRtV ;t# )RefDimensionUnknownErroru  A ref image's pixel dimensions could not be probed.

Replaces silent `return None` from `recoil/core/ref_resolver.py:113`
(and its alias re-export at `recoil/pipeline/lib/ref_resolver.py:71`).

Callers either propagate (preferred — the prompt builder's aspect-ratio
computation cannot proceed without dimensions) or catch and substitute
a documented default (rare; only call sites that explicitly choose to
skip the ref).
c                    V ^8  d   QhRRRR/# r   pathr    messager   )r!   s   "r   r"   %RefDimensionUnknownError.__annotate__         S 3 r   c                	d   < Wn         R V 2pV'       d   VRV 2,          p\        SV `	  V4       R# )zcould not probe dimensions for rD   NrL   r%   r&   r'   rL   rM   fullr)   s   &&& r   r&   !RefDimensionUnknownError.__init__   s4    	07b	N"Dr   rL   r>   r+   r-   s   @r   rI   rI      s    	  r   rI   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )MediaProbeErrori  zRaised when ffprobe / image probe / metadata extraction fails on a
media file (video / image / audio) and the caller cannot recover via
fallback.
c               $    V ^8  d   QhRRRRRR/# )r   rL   r    
probe_kindrM   r   )r!   s   "r   r"   MediaProbeError.__annotate__  s!      S c c r   c                	t   < Wn         W n        V R V 2pV'       d   VRV 2,          p\        SV `  V4       R# )z probe failed for rD   N)rL   rZ   r%   r&   )r'   rL   rZ   rM   rS   r)   s   &&&& r   r&   MediaProbeError.__init__  s>    	$/v6b	N"Dr   )rL   rZ   )mediar>   r+   r-   s   @r   rX   rX     s    
  r   rX   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )SidecarCorruptErrori  zRaised when a sidecar JSON file is unreadable or malformed.

Replaces silent ``except Exception: return None`` in
workspace/sidecar.py and reuse sites in workspace/server.py /
workspace/verdict.py.
c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"    SidecarCorruptError.__annotate__'  rO   r   c                	d   < Wn         R V 2pV'       d   VRV 2,          p\        SV `	  V4       R# )zcorrupt sidecar at rD   NrQ   rR   s   &&& r   r&   SidecarCorruptError.__init__'  4    	$TF+b	N"Dr   rU   rV   r+   r-   s   @r   r`   r`     s      r   r`   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )VerdictCorruptErrori/  zBRaised when a verdict YAML / JSON file is unreadable or malformed.c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"    VerdictCorruptError.__annotate__2  rO   r   c                	d   < Wn         R V 2pV'       d   VRV 2,          p\        SV `	  V4       R# )zcorrupt verdict at rD   NrQ   rR   s   &&& r   r&   VerdictCorruptError.__init__2  re   r   rU   rV   r+   r-   s   @r   rg   rg   /  s    L  r   rg   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )WorkspaceStateCorruptErrori:  zRaised when a workspace state JSON file (recommendations, casting
fragment, editorial config, etc.) is unreadable or malformed.

Common base for narrower subclasses below; usable directly when no
narrower class fits.
c               $    V ^8  d   QhRRRRRR/# )r   rL   r    kindWorkspaceStateKindrM   r   )r!   s   "r   r"   'WorkspaceStateCorruptError.__annotate__B  s(       ! 	r   c                	v   < Wn         W n        R V RV 2pV'       d   VRV 2,          p\        SV `  V4       R# )zcorrupt z at rD   N)rL   ro   r%   r&   )r'   rL   ro   rM   rS   r)   s   &&&& r   r&   #WorkspaceStateCorruptError.__init__B  sA     		$tD6*b	N"Dr   )ro   rL   )stater>   r+   r-   s   @r   rm   rm   :  s      r   rm   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )CastingFragmentCorruptErroriP  zCasting-fragment subclass.c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"   (CastingFragmentCorruptError.__annotate__S       N NS N3 Nr   c                	,   < \         SV `  VR VR7       R# )casting fragmentrL   ro   rM   Nr%   r&   r'   rL   rM   r)   s   &&&r   r&   $CastingFragmentCorruptError.__init__S      d);WMr   r   rV   r+   r-   s   @r   rv   rv   P      $N N Nr   rv   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )EditorialConfigCorruptErroriW  zEditorial-config subclass.c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"   (EditorialConfigCorruptError.__annotate__Z  ry   r   c                	,   < \         SV `  VR VR7       R# )editorial configr|   Nr}   r~   s   &&&r   r&   $EditorialConfigCorruptError.__init__Z  r   r   r   rV   r+   r-   s   @r   r   r   W  r   r   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )RecommendationsCorruptErrori^  zRecommendations-state subclass.c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"   (RecommendationsCorruptError.__annotate__a  s     M MS M3 Mr   c                	,   < \         SV `  VR VR7       R# )recommendationsr|   Nr}   r~   s   &&&r   r&   $RecommendationsCorruptError.__init__a  s    d):GLr   r   rV   r+   r-   s   @r   r   r   ^  s    )M M Mr   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )#PromptCompilerOverridesCorruptErrorie  z#Prompt-compiler overrides subclass.c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"   0PromptCompilerOverridesCorruptError.__annotate__h  s     W WS W3 Wr   c                	,   < \         SV `  VR VR7       R# )prompt-compiler overridesr|   Nr}   r~   s   &&&r   r&   ,PromptCompilerOverridesCorruptError.__init__h  s    d)DgVr   r   rV   r+   r-   s   @r   r   r   e  s    -W W Wr   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )ChatSessionsCorruptErroril  z<Chat-sessions store subclass (~/.recoil/chat-sessions.json).c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"   %ChatSessionsCorruptError.__annotate__o  s     K KS K3 Kr   c                	,   < \         SV `  VR VR7       R# )chat sessionsr|   Nr}   r~   s   &&&r   r&   !ChatSessionsCorruptError.__init__o  s    d'Jr   r   rV   r+   r-   s   @r   r   r   l  s    FK K Kr   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )ProposalCorruptErroris  zHProposal JSON file subclass (~/.recoil/proposals/<project>/<uuid>.json).c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"   !ProposalCorruptError.__annotate__v  s     F FS F3 Fr   c                	,   < \         SV `  VR VR7       R# )proposalr|   Nr}   r~   s   &&&r   r&   ProposalCorruptError.__init__v  s    dWEr   r   rV   r+   r-   s   @r   r   r   s  s    RF F Fr   r   c                  2   a  ] tR tRtRtR V 3R lltRtV ;t# )ExecutionStoreCorruptErroriz  u   Raised when a shot JSON file in ExecutionStore fails to decode.

Replaces the prior silent `json.JSONDecodeError → log + return None`
behavior. The operator must triage the corrupt file (rm + re-emit, or
git restore).
c               $    V ^8  d   QhRRRRRR/# )r   rL   r    parse_errorreturnNoner   )r!   s   "r   r"   'ExecutionStoreCorruptError.__annotate__  s!     
 
S 
s 
t 
r   c                	L   < Wn         W n        \        SV `  R V RV R24       R# )zExecutionStoreCorruptError: rD   u<    — manual triage required (rm + regenerate or git restore)N)rL   r   r%   r&   )r'   rL   r   r)   s   &&&r   r&   #ExecutionStoreCorruptError.__init__  s5    	&*4&;- @F F	
r   )r   rL   r+   r-   s   @r   r   r   z  s    
 
r   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )ConfigParseErrori  zRaised when a config file (json/yaml) parses but its shape is invalid.

Distinct from SchemaValidationError (raised by Pydantic schemas);
this is raised by hand-written validators that pre-date Phase A.1.
c                    V ^8  d   QhRRRR/# rK   r   )r!   s   "r   r"   ConfigParseError.__annotate__  rO   r   c                	d   < Wn         R V 2pV'       d   VRV 2,          p\        SV `	  V4       R# )zcould not parse config rD   NrQ   rR   s   &&& r   r&   ConfigParseError.__init__  s4    	(/b	N"Dr   rU   rV   r+   r-   s   @r   r   r     s      r   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )PromptValidatorConfigErrori  uJ   Prompt-validator-config subclass — surfaces the offending validator key.c               $    V ^8  d   QhRRRRRR/# )r   rL   r    validator_namerM   r   )r!   s   "r   r"   'PromptValidatorConfigError.__annotate__  s&     J JS J# JS Jr   c                	z   < W n         V'       d   R V: R2MRp\        SV `	  W V 2P                  4       R7       R# )z
validator= r>   )rL   rM   N)r   r%   r&   strip)r'   rL   r   rM   prefixr)   s   &&&& r   r&   #PromptValidatorConfigError.__init__  s>    ,5C:n/q1dhwi,@,F,F,HIr   )r   )r>   r>   r+   r-   s   @r   r   r     s    TJ J Jr   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )KeyframeContextLookupErrori  zRaised when a keyframe context lookup fails (missing shot id, missing
pass id, etc.) where the prior code returned None silently.
c               $    V ^8  d   QhRRRRRR/# )r   lookup_kindr    keyrM   r   )r!   s   "r   r"   'KeyframeContextLookupError.__annotate__  s!      C c C r   c                	x   < Wn         W n        R V RV: 2pV'       d   VRV 2,          p\        SV `  V4       R# )zkeyframe context z lookup failed for key=rD   N)r   r   r%   r&   )r'   r   r   rM   rS   r)   s   &&&& r   r&   #KeyframeContextLookupError.__init__  sA    &";-/FsgNb	N"Dr   )r   r   rV   r+   r-   s   @r   r   r     s      r   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )ExecutionStoreUnavailableErrori  a
  Raised by `verdict_executionstore_*` callers when the ExecutionStore
is unreachable in the current process (typical: cross-process readers).

Callers may catch + fire `verdict_executionstore_unavailable`
sanctioned fallback. For raisers, this is the canonical type.
c                   V ^8  d   QhRR/# )r   rM   r    r   )r!   s   "r   r"   +ExecutionStoreUnavailableError.__annotate__  s       r   c                	R   < R pV'       d   VRV 2,          p\         SV `  V4       R# )z.execution store unavailable in current processrD   Nr}   )r'   rM   rS   r)   s   && r   r&   'ExecutionStoreUnavailableError.__init__  s(    ?b	N"Dr   r   rV   r+   r-   s   @r   r   r     s      r   r   c                  >   a  ] tR tRtRtRRRR/R V 3R llltRtV ;t# )	VerdictAutofillErrori  zRaised when a verdict-autofill operation fails for a reason other
than ExecutionStore unavailability (e.g., the autofill source itself
raised, or a downstream merge step rejected the autofill).
r   r>   rM   c                    V ^8  d   QhRRRR/# )r   r   r    rM   r   )r!   s   "r   r"   !VerdictAutofillError.__annotate__  s      # S r   c               	   < Wn         R pV'       d   VRV R2,          pV'       d   VRV 2,          p\        SV `	  V4       R# )zverdict autofill failedz	 (source=)rD   N)r   r%   r&   )r'   r   rM   rS   r)   s   &$$ r   r&   VerdictAutofillError.__init__  sC    (ixq))Db	N"Dr   )r   r+   r-   s   @r   r   r     s%    
 2   r   r   c                  6   a  ] tR tRtRtRR V 3R llltRtV ;t# )ModelProfileLookupErrori  a  Raised when a model-profile lookup fails (missing model id, missing
rate field, or schema mismatch) where the prior code returned a hard-
coded default cost / feature flag silently.

Inherits from KeyError so existing callers that catch KeyError on
``get_profile(...)`` still trip; the typed name lets callers narrow
when they want to distinguish profile lookup failure from any other
KeyError in the call site.
c                    V ^8  d   QhRRRR/# )r   model_idr    rM   r   )r!   s   "r   r"   $ModelProfileLookupError.__annotate__  s       s r   c                	f   < Wn         R V: 2pV'       d   VRV 2,          p\        SV `	  V4       R# )z)model profile lookup failed for model_id=rD   N)r   r%   r&   )r'   r   rM   rS   r)   s   &&& r   r&    ModelProfileLookupError.__init__  s4     :8,Gb	N"Dr   )r   rV   r+   r-   s   @r   r   r     s      r   r   N)rt   r{   r   r   r   r   )r   r   r   r   r   r/   r9   r;   rG   rI   rX   r`   rg   rm   rv   r   r   r   r   r   r   r   r   r   r   r   r   )'r   
__future__r   typingr   r   rp   	Exceptionr   r   
ValueErrorr   r   RuntimeErrorr   r/   r9   r;   rG   rI   rX   r`   rg   rm   rv   r   r   r   r   r   r   r   r   KeyErrorr   r   r   r   __all__r   r   r   <module>r      s  'R # $  	) 		K 		Z 		K 	| >"| "R* , Bl $z (l 4*  *  ,N"< NN"< NM"< MW*D WK9 KF5 F
 
,z J!1 J \ <  h ."r   