Add Krea2 blowjob top-view candidate

This commit is contained in:
2026-06-29 05:09:40 +02:00
parent 858fbe8d46
commit 00e371e4b6
3 changed files with 74 additions and 1 deletions
+38
View File
@@ -253,6 +253,44 @@
"guide_section": "", "guide_section": "",
"notes": "Atlas shows a repeated open-thigh presentation/setup pose; needs fixed-seed Krea2 tests before promotion to proven." "notes": "Atlas shows a repeated open-thigh presentation/setup pose; needs fixed-seed Krea2 tests before promotion to proven."
} }
},
{
"key": "pov_blowjob_top_down_vertical_shaft",
"family": "blowjob_top_view",
"status": "candidate",
"atlas_folders": ["blowjob_top_view"],
"action_family": "oral",
"position_keys": ["reclining_oral", "penis_licking"],
"canonical_geometry": "Top-down first-person oral view: the viewer looks down from chest or pelvis height, viewer torso or thighs stay at the lower edge, shaft is vertical and centered in the foreground, and the woman kneels below looking upward with mouth and hand aligned to the shaft.",
"prompt_cues": [
"POV top-down oral position",
"viewer looks down from chest or pelvis height",
"viewer torso or thighs stay at the lower edge",
"shaft is vertical and centered in the foreground",
"woman kneels below the viewer looking upward",
"her mouth and hand align to the centered shaft"
],
"avoid_cues": [
"side-view oral framing",
"woman standing level with the viewer",
"shaft angled sideways or cropped away from the mouth",
"hands replacing the mouth as the main oral contact",
"camera placed behind the woman instead of above the viewer"
],
"reference_images": [
"blowjob_top_view/102_blowjob_top_view.png",
"blowjob_top_view/2_blowjob_top_view.png",
"blowjob_top_view/85_blowjob_top_view.png"
],
"generator_hook": {
"module": "krea_pov_actions.py",
"route_terms": ["blowjob_top_view", "top-down oral", "oral"]
},
"evidence": {
"fixed_seed_tests": [],
"guide_section": "",
"notes": "Atlas shows a repeated top-down oral POV with a centered vertical shaft; needs fixed-seed Krea2 tests before promotion to proven."
}
} }
] ]
} }
+9
View File
@@ -125,3 +125,12 @@ action: the woman faces the camera with legs raised or knees held wide, thighs
forming a wide V-frame, and her face and torso visible behind the open-leg pose. forming a wide V-frame, and her face and torso visible behind the open-leg pose.
Treat `pov_spread_open_thigh_presentation` as a candidate until it has Treat `pov_spread_open_thigh_presentation` as a candidate until it has
fixed-seed Krea2 evidence. fixed-seed Krea2 evidence.
### Blowjob Top View
The `blowjob_top_view` folder repeats a top-down first-person oral layout: the
viewer looks down from chest or pelvis height, viewer torso or thighs sit at the
lower edge, the shaft is vertical and centered, and the woman kneels below
looking upward with mouth and hand aligned to it. Treat
`pov_blowjob_top_down_vertical_shaft` as a candidate until it has fixed-seed
Krea2 evidence.
+27 -1
View File
@@ -6802,6 +6802,11 @@ def smoke_krea2_pose_variant_catalog_policy() -> None:
interaction == ["pov_spread_open_thigh_presentation"], interaction == ["pov_spread_open_thigh_presentation"],
f"Krea2 pose-variant interaction filtering changed unexpectedly: {interaction}", f"Krea2 pose-variant interaction filtering changed unexpectedly: {interaction}",
) )
oral = krea2_pose_variant_catalog.variant_keys(action_family="oral")
_expect(
oral == ["pov_blowjob_top_down_vertical_shaft"],
f"Krea2 pose-variant oral filtering changed unexpectedly: {oral}",
)
handjob = krea2_pose_variant_catalog.get_variant("pov_handjob_upright_centered") handjob = krea2_pose_variant_catalog.get_variant("pov_handjob_upright_centered")
_expect( _expect(
any("woman's right hand wraps" in str(cue) for cue in handjob.get("prompt_cues", [])), any("woman's right hand wraps" in str(cue) for cue in handjob.get("prompt_cues", [])),
@@ -6828,6 +6833,12 @@ def smoke_krea2_pose_variant_catalog_policy() -> None:
any("legs raised or knees held wide" in str(cue) for cue in spread.get("prompt_cues", [])), any("legs raised or knees held wide" in str(cue) for cue in spread.get("prompt_cues", [])),
"Spread variant lost open-thigh cue", "Spread variant lost open-thigh cue",
) )
oral_top = krea2_pose_variant_catalog.get_variant("pov_blowjob_top_down_vertical_shaft")
_expect(oral_top.get("status") == "candidate", "Blowjob top-view variant should remain a candidate until fixed-seed evidence exists")
_expect(
any("shaft is vertical and centered" in str(cue) for cue in oral_top.get("prompt_cues", [])),
"Blowjob top-view variant lost vertical-shaft cue",
)
refs = krea2_pose_variant_catalog.reference_paths("pov_boobjob_upright_cleavage") refs = krea2_pose_variant_catalog.reference_paths("pov_boobjob_upright_cleavage")
_expect(refs and all(path.name.endswith(".png") for path in refs), "Boobjob reference paths are not image paths") _expect(refs and all(path.name.endswith(".png") for path in refs), "Boobjob reference paths are not image paths")
_expect(all("bg" not in str(path).lower() for path in refs), "Reference paths should not include background-only atlas images") _expect(all("bg" not in str(path).lower() for path in refs), "Reference paths should not include background-only atlas images")
@@ -6894,15 +6905,19 @@ def smoke_krea2_tuning_report_policy() -> None:
spread = by_key.get("pov_spread_open_thigh_presentation") or {} spread = by_key.get("pov_spread_open_thigh_presentation") or {}
_expect(spread.get("coverage_state") == "needs_fixed_seed_tests", "Spread report should need fixed-seed tests") _expect(spread.get("coverage_state") == "needs_fixed_seed_tests", "Spread report should need fixed-seed tests")
_expect(spread.get("accepted_evidence_count") == 0, "Spread report should not have accepted evidence yet") _expect(spread.get("accepted_evidence_count") == 0, "Spread report should not have accepted evidence yet")
oral_top = by_key.get("pov_blowjob_top_down_vertical_shaft") or {}
_expect(oral_top.get("coverage_state") == "needs_fixed_seed_tests", "Blowjob top-view report should need fixed-seed tests")
_expect(oral_top.get("accepted_evidence_count") == 0, "Blowjob top-view report should not have accepted evidence yet")
summary = krea2_tuning_report.coverage_summary() summary = krea2_tuning_report.coverage_summary()
_expect(summary.get("status_counts", {}).get("proven") == 3, "Krea2 tuning report proven count changed") _expect(summary.get("status_counts", {}).get("proven") == 3, "Krea2 tuning report proven count changed")
_expect(summary.get("status_counts", {}).get("candidate") == 4, "Krea2 tuning report candidate count changed") _expect(summary.get("status_counts", {}).get("candidate") == 5, "Krea2 tuning report candidate count changed")
_expect( _expect(
summary.get("variants_without_accepted_evidence") == [ summary.get("variants_without_accepted_evidence") == [
"pov_ballsucking_low_head", "pov_ballsucking_low_head",
"pov_footjob_frontal_sole_stroke", "pov_footjob_frontal_sole_stroke",
"pov_fingering_reclined_open_thighs", "pov_fingering_reclined_open_thighs",
"pov_spread_open_thigh_presentation", "pov_spread_open_thigh_presentation",
"pov_blowjob_top_down_vertical_shaft",
], ],
f"Krea2 tuning report missing-evidence set changed: {summary.get('variants_without_accepted_evidence')}", f"Krea2 tuning report missing-evidence set changed: {summary.get('variants_without_accepted_evidence')}",
) )
@@ -6914,6 +6929,7 @@ def smoke_krea2_tuning_report_policy() -> None:
"pov_footjob_frontal_sole_stroke", "pov_footjob_frontal_sole_stroke",
"pov_fingering_reclined_open_thighs", "pov_fingering_reclined_open_thighs",
"pov_spread_open_thigh_presentation", "pov_spread_open_thigh_presentation",
"pov_blowjob_top_down_vertical_shaft",
], ],
"Krea2 tuning report next plans changed", "Krea2 tuning report next plans changed",
) )
@@ -6958,6 +6974,15 @@ def smoke_krea2_tuning_report_policy() -> None:
any(str(path).endswith("spread/100_spread_.png") for path in spread_plan.get("reference_paths") or []), any(str(path).endswith("spread/100_spread_.png") for path in spread_plan.get("reference_paths") or []),
"Spread test plan lost atlas reference path", "Spread test plan lost atlas reference path",
) )
oral_top_plan = plan_by_key["pov_blowjob_top_down_vertical_shaft"]
_expect(
"shaft is vertical and centered" in " ".join(oral_top_plan.get("prompt_cues") or []),
"Blowjob top-view test plan lost vertical-shaft cue",
)
_expect(
any(str(path).endswith("blowjob_top_view/102_blowjob_top_view.png") for path in oral_top_plan.get("reference_paths") or []),
"Blowjob top-view test plan lost atlas reference path",
)
with tempfile.TemporaryDirectory() as tmpdir: with tempfile.TemporaryDirectory() as tmpdir:
atlas_root = Path(tmpdir) atlas_root = Path(tmpdir)
for folder in ("doggy", "doggy_control", "custom_pose", "custom_pose_control", "bg", "woman", "doggy_bg"): for folder in ("doggy", "doggy_control", "custom_pose", "custom_pose_control", "bg", "woman", "doggy_bg"):
@@ -6993,6 +7018,7 @@ def smoke_krea2_tuning_report_policy() -> None:
_expect("pov_footjob_frontal_sole_stroke" in markdown, "Krea2 tuning report markdown lost footjob candidate variant") _expect("pov_footjob_frontal_sole_stroke" in markdown, "Krea2 tuning report markdown lost footjob candidate variant")
_expect("pov_fingering_reclined_open_thighs" in markdown, "Krea2 tuning report markdown lost fingering candidate variant") _expect("pov_fingering_reclined_open_thighs" in markdown, "Krea2 tuning report markdown lost fingering candidate variant")
_expect("pov_spread_open_thigh_presentation" in markdown, "Krea2 tuning report markdown lost spread candidate variant") _expect("pov_spread_open_thigh_presentation" in markdown, "Krea2 tuning report markdown lost spread candidate variant")
_expect("pov_blowjob_top_down_vertical_shaft" in markdown, "Krea2 tuning report markdown lost blowjob top-view candidate variant")
_expect("needs_fixed_seed_tests" in markdown, "Krea2 tuning report markdown lost coverage state") _expect("needs_fixed_seed_tests" in markdown, "Krea2 tuning report markdown lost coverage state")
_expect("Prompt cues" in markdown, "Krea2 tuning report markdown lost next-test cue section") _expect("Prompt cues" in markdown, "Krea2 tuning report markdown lost next-test cue section")
_expect("Avoid cues" in markdown, "Krea2 tuning report markdown lost next-test avoid section") _expect("Avoid cues" in markdown, "Krea2 tuning report markdown lost next-test avoid section")