Add Krea2 ballsucking route scaffold

This commit is contained in:
2026-06-29 10:20:58 +02:00
parent 364c42103b
commit 284c6279e6
6 changed files with 59 additions and 15 deletions
+2
View File
@@ -1661,6 +1661,8 @@ def run_simulation(seed: int = 3901, *, include_prompts: bool = False) -> dict[s
cases.extend(_pair_reports("insta_pair.penetration", penetration_pair, include_prompts=include_prompts))
pov_pair = _insta_pair_case(seed + 2, pov=True, position="penis_licking", focus="outercourse_only", family="outercourse")
cases.extend(_pair_reports("insta_pair.pov_outercourse", pov_pair, include_prompts=include_prompts))
ballsucking_pair = _insta_pair_case(seed + 5, pov=True, position="testicle_sucking", focus="outercourse_only", family="outercourse")
cases.extend(_pair_reports("insta_pair.pov_ballsucking", ballsucking_pair, include_prompts=include_prompts))
coverage_checks = _route_family_coverage_checks(cases)
axis_checks = _seed_axis_checks(seed + 3)
pair_seed_checks = _pair_seed_checks(seed + 4)
+28 -10
View File
@@ -6845,6 +6845,11 @@ def smoke_krea2_pose_variant_catalog_policy() -> None:
handjob["prompt_cues"].append("mutation should not leak")
clean_handjob = krea2_pose_variant_catalog.get_variant("pov_handjob_upright_centered")
_expect("mutation should not leak" not in clean_handjob.get("prompt_cues", []), "Catalog loader leaked caller mutation")
ballsucking = krea2_pose_variant_catalog.get_variant("pov_ballsucking_low_head")
_expect(
any("chest low over the viewer's pelvis" in str(cue) for cue in ballsucking.get("prompt_cues", [])),
"Ballsucking variant lost low-body pelvis cue",
)
footjob = krea2_pose_variant_catalog.get_variant("pov_footjob_frontal_sole_stroke")
_expect(footjob.get("status") == "candidate", "Footjob variant should remain a candidate until fixed-seed evidence exists")
_expect(
@@ -7084,6 +7089,8 @@ def smoke_krea2_prompt_guide_policy() -> None:
guide = (ROOT / "docs" / "krea2-prompt-guide.md").read_text(encoding="utf-8")
_expect("## Climax / Ejaculation Wording" in guide, "Krea2 prompt guide lost climax wording section")
_expect("ejaculates semen" in guide, "Krea2 prompt guide lost explicit semen wording rule")
_expect("### Ballsucking / Testicle Sucking" in guide, "Krea2 prompt guide lost ballsucking section")
_expect("chest low over the viewer's pelvis" in guide, "Krea2 prompt guide lost low-body ballsucking cue")
_expect("## Stronger-Control / Low-Priority Cases" in guide, "Krea2 prompt guide lost stronger-control section")
_expect("pov_sixty_nine_close_reversed_oral" in guide, "Krea2 prompt guide lost sixty-nine unstable route")
_expect("hardest" in guide and "low-priority" in guide, "Krea2 prompt guide lost hardest low-priority wording")
@@ -7527,8 +7534,8 @@ def smoke_pov_outercourse_position_routes() -> None:
(
"pov_outercourse_testicle",
"testicle_sucking",
("face below the pov viewer's penis at testicle height", "penis points upward"),
("face is below the viewer's penis at testicle height", "mouth and tongue licking", "penis points upward"),
("chest low over the pov viewer's pelvis", "face below the pov viewer's penis at testicle height", "penis points upward"),
("chest low over the viewer's pelvis", "face is below the viewer's penis at testicle height", "mouth and tongue licking", "penis points upward"),
),
(
"pov_outercourse_penis_licking",
@@ -9027,17 +9034,17 @@ def smoke_prompt_route_simulation_policy() -> None:
report = prompt_route_simulation.run_simulation(seed=3901, include_prompts=False)
summary = report.get("summary") or {}
quality = report.get("quality") or {}
_expect(summary.get("cases") == 14, "Prompt route simulation case count changed unexpectedly")
_expect(summary.get("cases") == 16, "Prompt route simulation case count changed unexpectedly")
_expect(summary.get("coverage_checks") == 2, "Prompt route simulation lost family coverage checks")
_expect(summary.get("axis_checks") == 6, "Prompt route simulation lost axis check coverage")
_expect(summary.get("pair_seed_checks") == 7, "Prompt route simulation lost pair seed check coverage")
_expect(summary.get("issues") == 0, f"Prompt route simulation reported issues: {report.get('issues')}")
_expect(quality.get("route_cases") == 14, "Prompt route simulation quality summary lost route case count")
_expect(quality.get("route_cases") == 16, "Prompt route simulation quality summary lost route case count")
_expect(quality.get("route_issues") == 0, f"Prompt route simulation quality reported route issues: {quality}")
_expect(quality.get("check_issues") == 0, f"Prompt route simulation quality reported check issues: {quality}")
_expect((quality.get("targets") or {}).get("single", {}).get("cases") == 10, "Prompt route simulation quality lost single target count")
_expect((quality.get("targets") or {}).get("softcore", {}).get("cases") == 2, "Prompt route simulation quality lost softcore target count")
_expect((quality.get("targets") or {}).get("hardcore", {}).get("cases") == 2, "Prompt route simulation quality lost hardcore target count")
_expect((quality.get("targets") or {}).get("softcore", {}).get("cases") == 3, "Prompt route simulation quality lost softcore target count")
_expect((quality.get("targets") or {}).get("hardcore", {}).get("cases") == 3, "Prompt route simulation quality lost hardcore target count")
_expect(not quality.get("issue_buckets"), "Prompt route simulation quality should have no issue buckets on clean baseline")
_expect(not quality.get("weakest_cases"), "Prompt route simulation quality should have no weak cases on clean baseline")
cases = {case.get("name"): case for case in report.get("cases") or []}
@@ -9052,6 +9059,7 @@ def smoke_prompt_route_simulation_policy() -> None:
"hardcore.single.group",
"hardcore.single.climax",
"insta_pair.penetration.hardcore",
"insta_pair.pov_ballsucking.hardcore",
):
_expect(route_name in cases, f"Prompt route simulation lost route family case {route_name}")
coverage_checks = {check.get("name"): check for check in report.get("coverage_checks") or []}
@@ -9079,6 +9087,16 @@ def smoke_prompt_route_simulation_policy() -> None:
"penis_licking" in (pov_summary.get("position_keys") or []),
"Prompt route simulation lost selected outercourse key from position_keys",
)
ballsucking_hard = cases.get("insta_pair.pov_ballsucking.hardcore") or {}
ballsucking_summary = ballsucking_hard.get("summary") or {}
_expect(
ballsucking_summary.get("position_key") == "testicle_sucking",
"Prompt route simulation should include a dedicated ballsucking/testicle POV route",
)
_expect(
"testicle_sucking" in (ballsucking_summary.get("position_keys") or []),
"Prompt route simulation ballsucking route lost selected testicle_sucking key",
)
axis_checks = {check.get("name"): check for check in report.get("axis_checks") or []}
for check_name in (
"seed_axis.locked_determinism",
@@ -9144,14 +9162,14 @@ def smoke_prompt_route_simulation_policy() -> None:
sweep_quality = sweep.get("quality") or {}
_expect(sweep_summary.get("runs") == 3, "Prompt route simulation sweep lost run coverage")
_expect(sweep_summary.get("seeds") == [3901, 4002, 4103], "Prompt route simulation sweep seed sequence changed")
_expect(sweep_summary.get("cases") == 42, "Prompt route simulation sweep case count changed")
_expect(sweep_summary.get("cases") == 48, "Prompt route simulation sweep case count changed")
_expect(sweep_summary.get("issues") == 0, f"Prompt route simulation sweep reported issues: {sweep.get('issues')}")
_expect(sweep_quality.get("route_cases") == 42, "Prompt route simulation sweep quality lost route case count")
_expect(sweep_quality.get("route_cases") == 48, "Prompt route simulation sweep quality lost route case count")
_expect(sweep_quality.get("route_issues") == 0, f"Prompt route simulation sweep quality reported route issues: {sweep_quality}")
_expect(sweep_quality.get("check_issues") == 0, f"Prompt route simulation sweep quality reported check issues: {sweep_quality}")
_expect((sweep_quality.get("targets") or {}).get("single", {}).get("cases") == 30, "Prompt route simulation sweep quality lost single target count")
_expect((sweep_quality.get("targets") or {}).get("softcore", {}).get("cases") == 6, "Prompt route simulation sweep quality lost softcore target count")
_expect((sweep_quality.get("targets") or {}).get("hardcore", {}).get("cases") == 6, "Prompt route simulation sweep quality lost hardcore target count")
_expect((sweep_quality.get("targets") or {}).get("softcore", {}).get("cases") == 9, "Prompt route simulation sweep quality lost softcore target count")
_expect((sweep_quality.get("targets") or {}).get("hardcore", {}).get("cases") == 9, "Prompt route simulation sweep quality lost hardcore target count")
def smoke_node_camera_registration() -> None: