
    Hj                    X    d Z ddlmZ ddlmZmZmZmZ ddlm	Z	 dZ
d	dZ	 	 	 	 	 	 d
dZy)u  W21B-wave-4 C4: background_prompt projection-card consumer guard.

Deterministic decision the BG prompt consumer makes per bg: whether to
inject the anchor projection card's ``bg_plate_visible_description`` into
the background plate prompt, or fall back to the verified v10 prompt path.

This is the REAL consumer guard for the C2/C3 source_hash + card_id
contract (Codex C4 review Required): the plan node's projection_card_id /
hash / state are NOT trusted blindly. The consumer re-joins the
``shot_projection_card`` checkpoint and verifies the same content-addressed
card_id (== hash) AND the checkpoint's own card_state before injecting.

Fail-closed (wiring brief §6/§9 + Codex C4 lock):
  - pass-only injection. needs_review / blocked / not_available /
    not_applicable -> NO injection (v10 fallback). needs_review is a
    diagnostic-only state in v0; it is never injected.
  - missing checkpoint entry -> projection_card_missing.
  - card_id mismatch (plan built against an older card) ->
    projection_card_stale.
  - checkpoint card_state no longer pass -> projection_card_state_changed.
  - empty plate prose -> projection_card_empty_plate.
  - self-defined internal-token leak in the plate prose ->
    projection_card_leak (reuses the C2 leak check; Korean meaning
    untouched).

Only ``bg_plate_visible_description`` ever reaches the prompt surface —
scene_visible_description / structured visible_items / marker_registry /
card_id / enum literals are never exposed. NO LLM / VLM / image / DB.
    )annotations)AnyDictOptionalTuple)find_plate_prose_leakspassc                    dd|| |ddS )NF injectplate_prosefallback_reasonsource_bg_idanchor_shot_idcard_id r   r   reasons      g/Users/manta/Documents/Projects/TheRoad-I1/backend/app/modules/pipeline/background_prompt_projection.py_empty_resultr   (   s    !$(     c                   | j                  d      }t        | j                  d      xs d      }t        | j                  d      xs d      }t        | j                  d      xs d      }t        | j                  d      xs d      }|t        k7  r t        |||rt        |            S d      S |r|r||k7  rt        ||d	      S |j                  ||f      }t	        |t
              st        ||d
      S |j                  d      xs i }t        |j                  d      xs d      }	|	r
|	|k7  s|	|k7  rt        ||d	      S |j                  d      t        k7  rt        ||d      S |j                  d      xs i }
|
j                  d      }t	        |t              r|j                         st        ||d      S t        ||
|	      }|rt        ||d      S d|d|||	dS )u  Decide whether to inject a projection card's plate prose for one bg.

    ``plan_node``: the shot_aware_bg_render_plan node (carrying the C3
    projection-card fields). ``card_lookup``: ``{(bg_id, shot_id):
    card_entry}`` re-keyed from the shot_projection_card checkpoint's
    ``data.cards`` (the authoritative card source — the plan node is only a
    pointer).

    Returns ``{inject, plate_prose, fallback_reason, source_bg_id,
    anchor_shot_id, card_id}``. ``inject`` is True only on the fully-verified
    pass path; otherwise ``inject`` is False with an explicit
    ``fallback_reason`` and the caller renders the verified v10 prompt.
    projection_card_stateprojection_card_source_bg_idr   r   projection_card_idprojection_card_hashno_projection_card_stater   projection_card_staleprojection_card_missingcardr   
card_stateprojection_card_state_changed
vlm_outputbg_plate_visible_descriptionprojection_card_empty_plate)r   r$   r   projection_card_leakTr   )getstr_PASSr   
isinstancedictstripr   )	plan_nodecard_lookupstater   r   expected_card_idexpected_hashentryenvelopeactual_card_idr$   r   leakss                r   "resolve_projection_plate_injectionr7   3   s&   $ MM12Ey}}%CDJKL'78>B?N9==)=>D"E	&<=CDM ~%)!&3u:
 	
 -G
 	
 =4D4U%)*
 	
 OO\>:;EeT"%),
 	
 yy &BHi06B7N --]*%)*
 	
 yy%'%)2
 	
 l+1rJ..!?@Kk3'{/@/@/B%)0
 	
 #E
 %))
 	
 "$(! r   N)r   r)   r   r)   r   r)   returnDict[str, Any])r.   r9   r/   z%Dict[Tuple[str, str], Dict[str, Any]]r8   r9   )__doc__
__future__r   typingr   r   r   r   )app.modules.pipeline.shot_projection_cardr   r*   r   r7   r   r   r   <module>r>      sI   : # - - L 	oo 7o 	or   