diff --git a/docs/prompt-pool-routing-map.md b/docs/prompt-pool-routing-map.md index 860b3fd..30cde8a 100644 --- a/docs/prompt-pool-routing-map.md +++ b/docs/prompt-pool-routing-map.md @@ -727,6 +727,10 @@ Important POV rule: - In POV rows, location anchors must stay behind, beside, or at the frame edges. The foreground belongs to the POV body/hands and visible partner/action. +- Profile `foreground` anchors such as desk edges, counters, shelves, doors, or + pillars are normal non-POV placement aids. POV camera text should not reuse + them as viewer-side objects; it should reserve the lower foreground for POV + body or hand cues. ## Formatter Routes diff --git a/scene_camera_adapters.py b/scene_camera_adapters.py index da557a5..c43ab96 100644 --- a/scene_camera_adapters.py +++ b/scene_camera_adapters.py @@ -937,10 +937,10 @@ def scene_distance_detail( subject, _pronoun = scene_subject_terms(subject_kind, pov_labels) if pov_labels: if "wide" in distance or "full-body" in distance or "full body" in distance: - return f"wide POV keeps {subject} readable with {profile['place']} context behind them" + return f"wide POV keeps {subject} readable with {profile['place']} context behind them and environmental anchors only beside or beyond the action" if "close" in distance: return f"close POV keeps {subject} dominant with {profile['place']} context only at the sides or background" - return f"medium POV keeps {subject} dominant with room context behind them" + return f"medium POV keeps {subject} dominant with room context beside or behind them" if "wide" in distance or "full-body" in distance or "full body" in distance: return f"wide crop keeps the {profile['foreground']}, {profile['midground']}, and {profile['background']} readable" if "close" in distance: @@ -969,7 +969,7 @@ def scene_elevation_detail( if "low-angle" in elevation: return f"low angle keeps POV body cues low while the {profile['background']} rises behind {pronoun}" if "elevated" in elevation: - return f"elevated POV keeps the viewer's eye line slightly higher than {subject}, with {profile['foreground']} only behind or at the side edges" + return f"elevated POV keeps the viewer's eye line slightly higher than {subject}, with location anchors only beside or behind {pronoun}" if "high-angle" in elevation: return f"high angle looks down from the viewer's position with {profile['midground']} only in the background" return f"eye-level angle keeps {profile['midground']} behind {pronoun}" @@ -1022,7 +1022,8 @@ def scene_camera_directive( if pov_labels: return ( f"{profile['layout_label']} from POV{geometry_clause}: {direction_detail}. " - f"{distance_detail}; {elevation_detail}; use the multiangle camera only as first-person spatial geometry." + f"{distance_detail}; {elevation_detail}; lower foreground is reserved for POV body or hand cues; " + f"use the multiangle camera only as first-person spatial geometry." ) return ( f"{profile['layout_label']}{geometry_clause}: {direction_detail}; " diff --git a/tools/prompt_smoke.py b/tools/prompt_smoke.py index 898f8c4..2cafdc2 100644 --- a/tools/prompt_smoke.py +++ b/tools/prompt_smoke.py @@ -6018,6 +6018,8 @@ def smoke_insta_pair_camera_split() -> None: _expect("back-right quarter view" in hard_scene, "hard camera scene missed hard orbit direction") _expect("low-angle shot" in soft_scene, "soft camera scene missed soft elevation") _expect("elevated shot" in hard_scene, "hard camera scene missed hard elevation") + _expect("near desk edge" in soft_scene, "non-POV camera scene lost coworking foreground anchor") + _expect("laptop corner" in soft_scene, "non-POV camera scene lost coworking foreground detail") _expect("front-right quarter view" in str(pair.get("softcore_camera_directive")), "soft pair camera directive was not preserved") _expect("back-right quarter view" in str(pair.get("hardcore_camera_directive")), "hard pair camera directive was not preserved") soft_row = pair.get("softcore_row") or {} @@ -6065,9 +6067,19 @@ def smoke_pov_camera_scene() -> None: scene_directive = _expect_text("pov_camera_scene.hard_camera_scene", hard_row.get("camera_scene_directive"), 40) _expect("from POV" in scene_directive, "POV camera scene should be marked as first-person") _expect("not in the lower foreground" in scene_directive, "POV camera scene should keep location anchors out of lower foreground") + _expect( + "near desk edge" not in scene_directive and "laptop corner" not in scene_directive and "chair back" not in scene_directive, + "POV camera scene should not reuse coworking foreground anchors as viewer-side objects", + ) + _expect( + "lower foreground is reserved for POV body or hand cues" in scene_directive, + "POV camera scene should reserve the lower foreground for first-person body cues", + ) krea = krea_formatter.format_krea2_prompt("", metadata_json=_json(pair), target="hardcore") prompt = krea.get("krea_prompt") or "" _expect("from POV" in prompt, "Krea POV prompt lost camera-scene directive") + _expect("laptop corner" not in prompt, "Krea POV prompt leaked foreground desk anchor into camera scene") + _expect("lower foreground is reserved for POV body or hand cues" in prompt, "Krea POV prompt lost POV foreground reservation") _expect("Camera:" not in prompt, "Krea POV prompt should not emit normal third-person camera directive")