Add Krea2 footjob pose candidate
This commit is contained in:
@@ -143,6 +143,42 @@
|
||||
"guide_section": "",
|
||||
"notes": "Atlas supports low-head geometry, but this route still needs controlled fixed-seed tests before promotion to proven."
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "pov_footjob_frontal_sole_stroke",
|
||||
"family": "footjob",
|
||||
"status": "candidate",
|
||||
"atlas_folders": ["footjob"],
|
||||
"action_family": "outercourse",
|
||||
"position_keys": ["footjob"],
|
||||
"canonical_geometry": "Frontal first-person footjob view: viewer reclines with thighs framing the lower foreground, penis upright near the center, and the woman sits opposite with both soles and toes pressing around the shaft while her body and face stay behind the feet.",
|
||||
"prompt_cues": [
|
||||
"POV footjob position",
|
||||
"viewer reclines with thighs framing the lower foreground",
|
||||
"woman sits opposite facing him with legs open toward the camera",
|
||||
"both soles press around the upright penis",
|
||||
"toes curl around the shaft as the feet stroke from base toward glans",
|
||||
"woman's body and face remain visible behind her feet"
|
||||
],
|
||||
"avoid_cues": [
|
||||
"generic foot contact without both soles around the shaft",
|
||||
"hands replacing the feet as the main contact",
|
||||
"mouth or hand action competing with the footjob",
|
||||
"feet off to the side without centered penis contact"
|
||||
],
|
||||
"reference_images": [
|
||||
"footjob/59_footjob.png",
|
||||
"footjob/86_footjob.png"
|
||||
],
|
||||
"generator_hook": {
|
||||
"module": "krea_pov_actions.py",
|
||||
"route_terms": ["footjob", "foot job", "feet stroking"]
|
||||
},
|
||||
"evidence": {
|
||||
"fixed_seed_tests": [],
|
||||
"guide_section": "",
|
||||
"notes": "Small atlas family with consistent frontal sole-contact geometry; needs fixed-seed Krea2 tests before promotion to proven."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -99,3 +99,13 @@ The handjob folder repeats a centered first-person layout: the viewer's thighs
|
||||
frame the lower edges, the woman faces the viewer between his legs, and her hand
|
||||
is the contact anchor on the shaft. Prompt the woman's hand ownership directly;
|
||||
viewer hands should not cover the action unless that is the intended variant.
|
||||
|
||||
## Candidate Notes
|
||||
|
||||
### Footjob
|
||||
|
||||
The footjob folder is small but visually consistent: the viewer reclines with
|
||||
thighs framing the lower foreground, the penis is upright near the center, and
|
||||
the woman's soles/toes are the contact anchor while her body and face remain
|
||||
behind the feet. Treat `pov_footjob_frontal_sole_stroke` as a candidate until it
|
||||
has fixed-seed Krea2 evidence.
|
||||
|
||||
+31
-4
@@ -6788,6 +6788,7 @@ def smoke_krea2_pose_variant_catalog_policy() -> None:
|
||||
"pov_boobjob_upright_cleavage",
|
||||
"pov_handjob_upright_centered",
|
||||
"pov_ballsucking_low_head",
|
||||
"pov_footjob_frontal_sole_stroke",
|
||||
],
|
||||
f"Krea2 pose-variant outercourse filtering changed unexpectedly: {outercourse}",
|
||||
)
|
||||
@@ -6799,6 +6800,12 @@ 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")
|
||||
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(
|
||||
any("both soles press" in str(cue) for cue in footjob.get("prompt_cues", [])),
|
||||
"Footjob variant lost sole-contact cue",
|
||||
)
|
||||
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(all("bg" not in str(path).lower() for path in refs), "Reference paths should not include background-only atlas images")
|
||||
@@ -6856,16 +6863,26 @@ def smoke_krea2_tuning_report_policy() -> None:
|
||||
ballsucking = by_key.get("pov_ballsucking_low_head") or {}
|
||||
_expect(ballsucking.get("coverage_state") == "needs_fixed_seed_tests", "Ballsucking report should need fixed-seed tests")
|
||||
_expect(ballsucking.get("accepted_evidence_count") == 0, "Ballsucking report should not have accepted evidence yet")
|
||||
footjob = by_key.get("pov_footjob_frontal_sole_stroke") or {}
|
||||
_expect(footjob.get("coverage_state") == "needs_fixed_seed_tests", "Footjob report should need fixed-seed tests")
|
||||
_expect(footjob.get("accepted_evidence_count") == 0, "Footjob report should not have accepted evidence yet")
|
||||
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("candidate") == 1, "Krea2 tuning report candidate count changed")
|
||||
_expect(summary.get("status_counts", {}).get("candidate") == 2, "Krea2 tuning report candidate count changed")
|
||||
_expect(
|
||||
summary.get("variants_without_accepted_evidence") == ["pov_ballsucking_low_head"],
|
||||
summary.get("variants_without_accepted_evidence") == [
|
||||
"pov_ballsucking_low_head",
|
||||
"pov_footjob_frontal_sole_stroke",
|
||||
],
|
||||
f"Krea2 tuning report missing-evidence set changed: {summary.get('variants_without_accepted_evidence')}",
|
||||
)
|
||||
plans = krea2_tuning_report.next_test_plans()
|
||||
_expect([plan.get("key") for plan in plans] == ["pov_ballsucking_low_head"], "Krea2 tuning report next plans changed")
|
||||
ballsucking_plan = plans[0]
|
||||
_expect(
|
||||
[plan.get("key") for plan in plans] == ["pov_ballsucking_low_head", "pov_footjob_frontal_sole_stroke"],
|
||||
"Krea2 tuning report next plans changed",
|
||||
)
|
||||
plan_by_key = {plan.get("key"): plan for plan in plans}
|
||||
ballsucking_plan = plan_by_key["pov_ballsucking_low_head"]
|
||||
_expect(
|
||||
"woman bends forward and kneels very low" in " ".join(ballsucking_plan.get("prompt_cues") or []),
|
||||
"Ballsucking test plan lost atlas-backed prompt cue",
|
||||
@@ -6878,6 +6895,15 @@ def smoke_krea2_tuning_report_policy() -> None:
|
||||
any(str(path).endswith("ballsucking/101_ballsucking.png") for path in ballsucking_plan.get("reference_paths") or []),
|
||||
"Ballsucking test plan lost atlas reference path",
|
||||
)
|
||||
footjob_plan = plan_by_key["pov_footjob_frontal_sole_stroke"]
|
||||
_expect(
|
||||
"both soles press" in " ".join(footjob_plan.get("prompt_cues") or []),
|
||||
"Footjob test plan lost sole-contact cue",
|
||||
)
|
||||
_expect(
|
||||
any(str(path).endswith("footjob/59_footjob.png") for path in footjob_plan.get("reference_paths") or []),
|
||||
"Footjob test plan lost atlas reference path",
|
||||
)
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
atlas_root = Path(tmpdir)
|
||||
for folder in ("doggy", "doggy_control", "custom_pose", "custom_pose_control", "bg", "woman", "doggy_bg"):
|
||||
@@ -6910,6 +6936,7 @@ def smoke_krea2_tuning_report_policy() -> None:
|
||||
_expect("pov_custom_pose_candidate" in atlas_markdown, "Krea2 tuning report markdown lost suggested gap key")
|
||||
markdown = krea2_tuning_report.markdown_report()
|
||||
_expect("pov_ballsucking_low_head" in markdown, "Krea2 tuning report markdown lost candidate variant")
|
||||
_expect("pov_footjob_frontal_sole_stroke" in markdown, "Krea2 tuning report markdown lost footjob candidate variant")
|
||||
_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("Avoid cues" in markdown, "Krea2 tuning report markdown lost next-test avoid section")
|
||||
|
||||
Reference in New Issue
Block a user