"""No-generation prep artifacts for the normal-camera atlas.""" from __future__ import annotations import argparse import html import json import re from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parent CATALOG_DIR = ROOT / "categories" DEFAULT_OUTPUT_DIR = ROOT / "ab_batches" / "normal_camera" PRIORITY_PLAN_SCHEMA = "sxcp_normal_camera_priority_plan_v1" PROMPT_CUE_BATCH_SCHEMA = "sxcp_normal_camera_prompt_cue_batch_v1" SCORE_SHEET_SCHEMA = "sxcp_normal_camera_score_sheet_v1" UNUSED_POOL_BACKLOG_SCHEMA = "sxcp_normal_camera_unused_pool_backlog_v1" REVIEW_MANIFEST_SCHEMA = "sxcp_normal_camera_review_manifest_v1" NEEDS_SAMPLES_ACQUISITION_SCHEMA = "sxcp_normal_camera_needs_samples_acquisition_v1" DEFAULT_REVIEW_DIR = DEFAULT_OUTPUT_DIR / "review" NEEDS_SAMPLES_TARGET_REFERENCE_COUNT = 12 DEFAULT_REVIEW_FOLDERS: tuple[str, ...] = ( "reverse cowgirl", "breasts exposed", "pussy spread", "anal random", "couple kissing", "cowgirl - back view - 3-4 angle", "cowgirl - side view", "woman solo showing her hass - back view", "doggy on all four - back view - 3-4 angle", "doggy on all four - side view", "doggy all four - front view", "doggy - front view ", "handjob standing - side view", "wand", "breast sucking - side view", "fuck from front standing - side view", "doggy - back view - 3-4 angle", "penis worship", "fuck from behind standing - woman backside - side view", "piledriver", "blowjob - laying - front view", "breast - touching - front view", "ballsucking - laying", "ballsucking - standing", "face sitting", "pussy licking - backv iew", "removing pants", "rimjob", "footjob", "reverse cowgirl - leg up", "reverse cowgirl -pretzel", "fist", "anal cowgirl", "anal doggy - side view", "anal fuck from behind laying - back view - 3-4 angle", "anal reverse congress", "anus lickiing", "blowjob laying - back view - 3-4 angle", "doggy press - back side", "face sitting - front view", "handjob - standing -low angle", "pussy licking leg up - back view - 3-4 angle", "pussy licking standing woman", "under desk", "pretzel", "woman ass exposed", "reverse congress - front view", "boobjob", "fingering", "69", ) REVIEW_BUCKET_VALUES: dict[str, str] = { "back_view": "Rear-facing normal-camera view where back/hips face camera.", "back_three_quarter": "Rear-offset normal-camera view with enough side/torso context.", "side_view": "Profile or near-profile lateral view with the body/action axis across frame.", "front_view": "Front-facing normal-camera view where the contact plane faces camera.", "front_three_quarter": "Front-offset normal-camera view.", "top_or_low_special": "Overhead, high-downward, low-angle, or under-view special camera.", "reject_or_unclear": "POV-like, mismatched, unclear, duplicate-only, or too mixed for cue drafting.", } SOURCE_FOLDER_ALIASES: dict[str, dict[str, str]] = { "doggy - front view": { "canonical_folder": "doggy - front view", "alias_reason": "Duplicate source-folder display name; preserved separately from trailing-space source folder.", }, "doggy - front view ": { "canonical_folder": "doggy - front view", "alias_reason": "Trailing-space source folder preserved exactly for path stability.", }, "handjob - standing -low angle": { "canonical_folder": "handjob - standing - low angle", "alias_reason": "Spacing typo normalized for review metadata while preserving exact source path.", }, "pussy licking - backv iew": { "canonical_folder": "pussy licking - back view", "alias_reason": "Folder-name typo normalized for review metadata while preserving exact source path.", }, "reverse cowgirl -pretzel": { "canonical_folder": "reverse cowgirl - pretzel", "alias_reason": "Missing-space folder label normalized for review metadata while preserving exact source path.", }, "anus lickiing": { "canonical_folder": "anus licking", "alias_reason": "Folder-name typo normalized for review metadata while preserving exact source path.", }, "woman solo showing her hass - back view": { "canonical_folder": "woman solo showing her ass - back view", "alias_reason": "Folder-name typo normalized for review metadata while preserving exact source path.", }, } REVIEW_SELECTED_SUBVARIANTS: dict[str, list[dict[str, Any]]] = { "cowgirl - back view - 3-4 angle": [ { "variant_key": "normal_cowgirl_back_three_quarter", "review_bucket": "back_three_quarter", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "cowgirl - back view - 3-4 angle/0002.jpg", "cowgirl - back view - 3-4 angle/0003_4.jpg", "cowgirl - back view - 3-4 angle/0006.jpg", "cowgirl - back view - 3-4 angle/0008_2.jpg", "cowgirl - back view - 3-4 angle/16.jpg", "cowgirl - back view - 3-4 angle/22.jpg", "cowgirl - back view - 3-4 angle/41.jpg", "cowgirl - back view - 3-4 angle/82.jpg", "cowgirl - back view - 3-4 angle/90.jpg", "cowgirl - back view - 3-4 angle/145.jpg", "cowgirl - back view - 3-4 angle/160.jpg", "cowgirl - back view - 3-4 angle/172.jpg", "cowgirl - back view - 3-4 angle/225.jpg", "cowgirl - back view - 3-4 angle/241_2.jpg", "cowgirl - back view - 3-4 angle/248.jpg", ], "evidence_notes": ( "Residual-pool review confirmed the existing route as a broad but coherent " "rear three-quarter cowgirl family. References were expanded rather than " "splitting a near-duplicate route." ), } ], "cowgirl - side view": [ { "variant_key": "normal_cowgirl_side_profile", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "cowgirl - side view/0003.jpg", "cowgirl - side view/0004_2.jpg", "cowgirl - side view/0005.jpg", "cowgirl - side view/0007.jpg", "cowgirl - side view/0009.jpg", "cowgirl - side view/0011.jpg", "cowgirl - side view/0015.jpg", "cowgirl - side view/118.jpg", "cowgirl - side view/195.jpg", "cowgirl - side view/2.jpg", "cowgirl - side view/200.jpg", "cowgirl - side view/255.jpg", "cowgirl - side view/280.jpg", "cowgirl - side view/86.jpg", "cowgirl - side view/86_2.jpg", ], "evidence_notes": ( "Residual-pool review confirmed the existing side-profile cowgirl route " "as a coherent lateral camera family. References were expanded while " "front-drifting, rear-drifting, and tight-crop examples remain outside " "the selected subset." ), } ], "doggy on all four - back view - 3-4 angle": [ { "variant_key": "normal_doggy_all_fours_back_three_quarter", "review_bucket": "back_three_quarter", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "doggy on all four - back view - 3-4 angle/0002.jpg", "doggy on all four - back view - 3-4 angle/0003.jpg", "doggy on all four - back view - 3-4 angle/0013.jpg", "doggy on all four - back view - 3-4 angle/0014.jpg", "doggy on all four - back view - 3-4 angle/0019.jpg", "doggy on all four - back view - 3-4 angle/0020.jpg", "doggy on all four - back view - 3-4 angle/206.jpg", "doggy on all four - back view - 3-4 angle/267.jpg", "doggy on all four - back view - 3-4 angle/302.jpg", "doggy on all four - back view - 3-4 angle/327.jpg", "doggy on all four - back view - 3-4 angle/550_2.jpg", "doggy on all four - back view - 3-4 angle/608_2.jpg", "doggy on all four - back view - 3-4 angle/611.jpg", "doggy on all four - back view - 3-4 angle/70.jpg", "doggy on all four - back view - 3-4 angle/97.jpg", ], "evidence_notes": ( "Residual-pool review confirmed the existing all-fours rear three-quarter " "route as a coherent camera family. References were expanded while low, " "front-drifting, and tight-crop outliers remain outside the selected subset." ), } ], "doggy on all four - side view": [ { "variant_key": "normal_doggy_all_fours_side_view", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-06-29", "reference_images": [ "doggy on all four - side view/0020.jpg", "doggy on all four - side view/192.jpg", "doggy on all four - side view/2.jpg", "doggy on all four - side view/204.jpg", "doggy on all four - side view/254.jpg", "doggy on all four - side view/254_2.jpg", "doggy on all four - side view/254_3.jpg", "doggy on all four - side view/271.jpg", "doggy on all four - side view/271_2.jpg", "doggy on all four - side view/362.jpg", "doggy on all four - side view/495.jpg", "doggy on all four - side view/556.jpg", "doggy on all four - side view/86.jpg", "doggy on all four - side view/99.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing selected side-view subset unchanged. " "The remaining source images mix standing, bed, chair, close, and front-drifting " "frames, so no additional references were promoted in this pass." ), } ], "doggy all four - front view": [ { "variant_key": "normal_doggy_all_fours_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "doggy all four - front view/0016.jpg", "doggy all four - front view/48.jpg", "doggy all four - front view/58.jpg", "doggy all four - front view/64.jpg", "doggy all four - front view/69.jpg", "doggy all four - front view/77.jpg", "doggy all four - front view/83.jpg", "doggy all four - front view/97.jpg", "doggy all four - front view/171.jpg", "doggy all four - front view/197.jpg", "doggy all four - front view/204.jpg", "doggy all four - front view/221.jpg", "doggy all four - front view/290.jpg", "doggy all four - front view/596.jpg", "doggy all four - front view/598.jpg", ], "evidence_notes": ( "Residual-pool review confirmed a repeated front all-fours normal-camera " "family with face and forearms readable in front while the partner remains " "behind. Side-drifting, seated, tight-close, and vertical-crop outliers " "remain outside the selected subset." ), } ], "doggy - front view ": [ { "variant_key": "normal_doggy_generic_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "doggy - front view/11.jpg", "doggy - front view/5.jpg", "doggy - front view/6.jpg", "doggy - front view /0003.jpg", "doggy - front view /253.jpg", "doggy - front view /262.jpg", "doggy - front view /349.jpg", "doggy - front view /354.jpg", "doggy - front view /41.jpg", "doggy - front view /49.jpg", "doggy - front view /505.jpg", "doggy - front view /537.jpg", "doggy - front view /541.jpg", "doggy - front view /567.jpg", "doggy - front view /627.jpg", ], "evidence_notes": ( "Residual-pool review expanded the existing grouped generic front-view route " "for the duplicate trailing-space source folder. The selected references " "repeat a front-facing third-person doggy camera while one weak top/down " "close crop remains outside the route." ), } ], "wand": [ { "variant_key": "normal_wand_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "wand/0005.jpg", "wand/508.jpg", "wand/75.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the folder as a mixed source-pool anchor. " "The source images include useful front-close tool-contact material, but " "side, portrait-close, and wider posture variation keep the full folder " "from being one locked prompt-ready route." ), }, { "variant_key": "normal_wand_front_close_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "wand/0005.jpg", "wand/0015.jpg", "wand/217.jpg", "wand/532.jpg", "wand/561.jpg", "wand/611.jpg", "wand/75.jpg", ], "evidence_notes": ( "Contact-sheet review found a repeated front-close third-person family " "where the contact plane is centered and the wand remains readable as one " "continuous object. Side, portrait-close, and wider posture outliers remain " "outside this selected subset." ), }, ], "handjob standing - side view": [ { "variant_key": "normal_handjob_standing_side_profile", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-06-29", "reference_images": [ "handjob standing - side view/16.jpg", "handjob standing - side view/105.jpg", "handjob standing - side view/171.jpg", "handjob standing - side view/174.jpg", "handjob standing - side view/175.jpg", "handjob standing - side view/305.jpg", "handjob standing - side view/549.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing standing side-profile subset unchanged. " "The remaining source images mix kneeling, seated, close portrait, near-front, " "and oral-adjacent frames, so no additional references were promoted in this pass." ), } ], "penis worship": [ { "variant_key": "normal_penis_worship_foreground_close_reference_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-06-29", "reference_images": [ "penis worship/0001.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing foreground-close source-pool anchor " "unchanged. The remaining images are foreground-heavy and drift through front " "or near-POV framing, so no prompt-ready expansion was promoted in this pass." ), }, { "variant_key": "normal_penis_worship_top_view", "review_bucket": "top_or_low_special", "status": "needs_samples", "selection_date": "2026-06-29", "reference_images": [ "penis worship/510.jpg", "penis worship/517.jpg", "penis worship/519.jpg", "penis worship/520.jpg", "penis worship/603_4.jpg", "penis worship/607_2.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing user-selected top-view anchors " "unchanged. The folder still needs cleaner repeated samples before this " "orientation can become a pre-A/B route." ), }, { "variant_key": "normal_penis_worship_side_view", "review_bucket": "side_view", "status": "needs_samples", "selection_date": "2026-06-29", "reference_images": [ "penis worship/0003.jpg", "penis worship/0004.jpg", "penis worship/0008_2.jpg", "penis worship/0016.jpg", "penis worship/505.jpg", "penis worship/566.jpg", "penis worship/566_2.jpg", "penis worship/618.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing user-selected side-view anchors " "unchanged. The residual folder does not add a cleaner repeated lateral " "camera subset in this pass." ), }, { "variant_key": "normal_penis_worship_laying_partner_vertical_side_view", "review_bucket": "side_view", "status": "needs_samples", "selection_date": "2026-06-29", "reference_images": [ "penis worship/0002_2.jpg", "penis worship/0006.jpg", "penis worship/0011.jpg", "penis worship/608.jpg", "penis worship/609.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing laying-partner vertical side-view " "anchors unchanged. The remaining frames stay too mixed for promotion." ), }, ], "piledriver": [ { "variant_key": "normal_piledriver_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-06-29", "reference_images": [ "piledriver/0001.jpg", "piledriver/0012_2.jpg", "piledriver/617.jpg", ], "evidence_notes": ( "Residual-pool review preserved the existing mixed source-pool anchor. " "The full folder remains too broad for one camera route because it mixes " "tight top crops, side drifts, and selected high/front-down examples." ), }, { "variant_key": "normal_piledriver_high_front_down_view", "review_bucket": "top_or_low_special", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "piledriver/0002.jpg", "piledriver/0004_2.jpg", "piledriver/0005.jpg", "piledriver/0006_2.jpg", "piledriver/0009.jpg", "piledriver/0009_2.jpg", "piledriver/0012.jpg", "piledriver/0013.jpg", "piledriver/282.jpg", "piledriver/317.jpg", "piledriver/317_2.jpg", "piledriver/318.jpg", "piledriver/319.jpg", "piledriver/494_2.jpg", "piledriver/538.jpg", ], "evidence_notes": ( "Residual-pool review found a repeated high/front-down piledriver " "camera family where the folded body remains readable below the partner. " "Tight top crops, side drifts, and mixed examples remain outside this route." ), }, ], "blowjob - laying - front view": [ { "variant_key": "normal_blowjob_laying_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "blowjob - laying - front view/0001.jpg", "blowjob - laying - front view/0003.jpg", "blowjob - laying - front view/0004.jpg", "blowjob - laying - front view/0010.jpg", "blowjob - laying - front view/0010_2.jpg", "blowjob - laying - front view/0018.jpg", "blowjob - laying - front view/48.jpg", "blowjob - laying - front view/69.jpg", "blowjob - laying - front view/91.jpg", "blowjob - laying - front view/94.jpg", "blowjob - laying - front view/122.jpg", "blowjob - laying - front view/171.jpg", "blowjob - laying - front view/184.jpg", "blowjob - laying - front view/274.jpg", "blowjob - laying - front view/512.jpg", ], "evidence_notes": ( "Residual-pool review confirmed the existing front-facing laying " "oral-contact route as a broad but coherent third-person camera family. " "Side-drifting, wide couch/bed, and weak close-crop examples remain outside " "the selected subset." ), } ], "breast - touching - front view": [ { "variant_key": "normal_breast_contact_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "breast - touching - front view/0006.jpg", "breast - touching - front view/0006_2.jpg", "breast - touching - front view/12.jpg", "breast - touching - front view/0014.jpg", "breast - touching - front view/0015.jpg", "breast - touching - front view/16.jpg", "breast - touching - front view/56.jpg", "breast - touching - front view/72.jpg", "breast - touching - front view/183.jpg", "breast - touching - front view/220.jpg", "breast - touching - front view/246.jpg", "breast - touching - front view/248.jpg", "breast - touching - front view/281.jpg", "breast - touching - front view/348.jpg", "breast - touching - front view/361.jpg", ], "evidence_notes": ( "Residual-pool review confirmed the existing front breast-contact " "route as a coherent third-person camera family across standing, " "seated, and kneeling contexts. Side-drifting, costume/standing " "outliers, and weak-contact crops remain outside the selected subset." ), } ], "ballsucking - standing": [ { "variant_key": "normal_ballsucking_standing_partner_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-06-29", "reference_images": [ "ballsucking - standing/0017.jpg", "ballsucking - standing/252.jpg", "ballsucking - standing/624.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the existing mixed source-pool anchor. " "The standing-partner context is useful, but the full folder still mixes " "close, side, front, and one water-close outlier; the outlier is anchored " "here rather than in the pre-A/B split." ), }, { "variant_key": "normal_ballsucking_standing_low_side_view", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "ballsucking - standing/0014.jpg", "ballsucking - standing/130.jpg", "ballsucking - standing/137.jpg", "ballsucking - standing/207.jpg", "ballsucking - standing/222.jpg", "ballsucking - standing/252.jpg", "ballsucking - standing/333.jpg", "ballsucking - standing/34.jpg", "ballsucking - standing/540.jpg", "ballsucking - standing/589.jpg", "ballsucking - standing/624.jpg", ], "evidence_notes": ( "Contact-sheet review found a repeated standing-partner, low-performer " "side or near-side camera family. The water-close crop remains outside " "this selected subset." ), }, ], "face sitting": [ { "variant_key": "normal_face_sitting_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "face sitting/0005.jpg", "face sitting/0021.jpg", "face sitting/354.jpg", "face sitting/533.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the full folder as a mixed source-pool " "anchor. Three samples are front or near-front face-sitting references, " "while one rear/back-view outlier makes the folder too mixed and thin " "for a selected pre-A/B route." ), }, ], "pussy licking - backv iew": [ { "variant_key": "normal_pussy_licking_backview_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "pussy licking - backv iew/220.jpg", "pussy licking - backv iew/567.jpg", "pussy licking - backv iew/614.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the full folder as a mixed source-pool " "anchor. The folder label says back view, but the reviewed images read " "as elevated front or high-oblique third-person oral-contact references; " "the three-image set is too thin for a selected pre-A/B route." ), }, ], "removing pants": [ { "variant_key": "normal_removing_pants_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "removing pants/0005.jpg", "removing pants/0006.jpg", "removing pants/0016.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the full folder as a mixed source-pool " "anchor. The three samples are near-duplicate close action references " "with strong foreground crop, so they should not become a locked " "normal-camera route without more matched, wider non-POV samples." ), }, ], "ballsucking - laying": [ { "variant_key": "normal_ballsucking_laying_close_reference_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "ballsucking - laying/271.jpg", "ballsucking - laying/591.jpg", ], "evidence_notes": ( "Contact-sheet review records the existing two-sample laying close-reference " "source pool as needs_samples. The folder is fully represented but too thin " "and crop-variable for a selected pre-A/B route." ), }, ], "rimjob": [ { "variant_key": "normal_rimjob_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "rimjob/0003.jpg", "rimjob/0010.jpg", "rimjob/0018.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the full folder as a mixed source-pool " "anchor. The three samples mix close side/back oral-contact framing " "with wider kneeling context and are too thin for a selected pre-A/B route." ), }, ], "footjob": [ { "variant_key": "normal_footjob_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "footjob/265.jpg", "footjob/265_2.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the full folder as a mixed source-pool " "anchor. The two samples share the foot-contact action but vary between " "seated front context and tighter crop, so more matched samples are needed." ), }, ], "reverse cowgirl - leg up": [ { "variant_key": "normal_reverse_cowgirl_leg_up_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "reverse cowgirl - leg up/266.jpg", "reverse cowgirl - leg up/267.jpg", ], "evidence_notes": ( "Contact-sheet review preserved this as a two-sample leg-up posture " "source pool. The folder is useful cue evidence but too thin for a " "selected normal-camera route." ), }, ], "reverse cowgirl -pretzel": [ { "variant_key": "normal_reverse_cowgirl_pretzel_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "reverse cowgirl -pretzel/0007.jpg", "reverse cowgirl -pretzel/617.jpg", ], "evidence_notes": ( "Contact-sheet review preserved this as a two-sample pretzel-posture " "source pool. The folder is useful cue evidence but too thin for a " "selected normal-camera route." ), }, ], "fist": [ { "variant_key": "normal_fist_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "fist/337.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the one available manual-contact " "reference as coverage evidence only. A single image cannot define " "a stable normal-camera route." ), }, ], "anal cowgirl": [ { "variant_key": "normal_anal_cowgirl_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["anal cowgirl/49.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one available sample as coverage " "evidence only. A single image cannot define a stable normal-camera route." ), }, ], "anal doggy - side view": [ { "variant_key": "normal_anal_doggy_side_view_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["anal doggy - side view/16.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one side-view sample as coverage " "evidence only. The label is plausible, but a single image is too thin " "for a selected pre-A/B route." ), }, ], "anal fuck from behind laying - back view - 3-4 angle": [ { "variant_key": "normal_anal_laying_back_three_quarter_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["anal fuck from behind laying - back view - 3-4 angle/14.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one rear three-quarter sample as " "coverage evidence only. A single image cannot define a stable " "normal-camera route." ), }, ], "anal reverse congress": [ { "variant_key": "normal_anal_reverse_congress_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["anal reverse congress/160.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one available sample as coverage " "evidence only. A single image cannot define a stable normal-camera route." ), }, ], "anus lickiing": [ { "variant_key": "normal_anus_licking_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["anus lickiing/0004.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one available sample as coverage " "evidence only. A single image cannot define a stable normal-camera route." ), }, ], "blowjob laying - back view - 3-4 angle": [ { "variant_key": "normal_blowjob_laying_back_three_quarter_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["blowjob laying - back view - 3-4 angle/14.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one rear-offset laying oral-contact " "sample as coverage evidence only. A single image cannot define a stable " "normal-camera route." ), }, ], "doggy press - back side": [ { "variant_key": "normal_doggy_press_back_side_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["doggy press - back side/0011.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one back-side doggy-press sample as " "coverage evidence only. A single image cannot define a stable " "normal-camera route." ), }, ], "face sitting - front view": [ { "variant_key": "normal_face_sitting_front_view_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["face sitting - front view/56.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one front-view face-sitting sample " "as coverage evidence only. A single image is too thin for a selected " "pre-A/B route." ), }, ], "handjob - standing -low angle": [ { "variant_key": "normal_handjob_standing_low_angle_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["handjob - standing -low angle/552.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one standing low-angle manual-contact " "sample as coverage evidence only. A single image is too thin for a " "selected pre-A/B route." ), }, ], "pussy licking leg up - back view - 3-4 angle": [ { "variant_key": "normal_pussy_licking_leg_up_back_three_quarter_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["pussy licking leg up - back view - 3-4 angle/0009.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one leg-up rear-offset oral-contact " "sample as coverage evidence only. A single image cannot define a stable " "normal-camera route." ), }, ], "pussy licking standing woman": [ { "variant_key": "normal_pussy_licking_standing_woman_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["pussy licking standing woman/13.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one standing-woman oral-contact " "sample as coverage evidence only. A single image cannot define a stable " "normal-camera route." ), }, ], "under desk": [ { "variant_key": "normal_under_desk_single_reference_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": ["under desk/347.jpg"], "evidence_notes": ( "Contact-sheet review preserved the one under-desk context sample as " "coverage evidence only. A single image cannot define a stable " "normal-camera route." ), }, ], "pretzel": [ { "variant_key": "normal_pretzel_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "pretzel/0001.jpg", "pretzel/0006.jpg", ], "evidence_notes": ( "Contact-sheet review records the existing two-sample pretzel mixed-camera " "source pool as needs_samples. The folder is fully represented but too thin " "for a selected pre-A/B route." ), }, ], "woman ass exposed": [ { "variant_key": "normal_display_rear_exposed_body_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "woman ass exposed/40.jpg", "woman ass exposed/49.jpg", "woman ass exposed/52.jpg", "woman ass exposed/58.jpg", ], "evidence_notes": ( "Contact-sheet review records the existing rear exposed-body source pool " "with all four folder images. The folder is fully represented but remains " "too thin and camera-variable for a selected pre-A/B route." ), }, ], "reverse congress - front view": [ { "variant_key": "normal_reverse_congress_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "reverse congress - front view/0012.jpg", "reverse congress - front view/0012_2.jpg", "reverse congress - front view/0013.jpg", "reverse congress - front view/61.jpg", "reverse congress - front view/105.jpg", "reverse congress - front view/105_2.jpg", "reverse congress - front view/122.jpg", "reverse congress - front view/183.jpg", "reverse congress - front view/189.jpg", "reverse congress - front view/289.jpg", "reverse congress - front view/289_2.jpg", "reverse congress - front view/291.jpg", "reverse congress - front view/542.jpg", "reverse congress - front view/542_2.jpg", "reverse congress - front view/563_2.jpg", ], "evidence_notes": ( "Residual-pool review confirmed the existing front-facing reverse-congress " "route as a coherent lifted/front camera family. Tight low crops, " "side/bed drift, and seated-only outliers remain outside the selected subset." ), } ], "boobjob": [ { "variant_key": "normal_boobjob_front_close_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-06-29", "reference_images": [ "boobjob/0017.jpg", "boobjob/259.jpg", "boobjob/91.jpg", ], "evidence_notes": ( "Residual-pool review preserved the existing mixed source-pool anchor. " "The full folder includes useful front-close material, but side, standing, " "foreground-heavy, and downward/crop-drifting examples keep it from being " "one locked prompt-ready camera route." ), }, { "variant_key": "normal_boobjob_front_close_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "boobjob/0017.jpg", "boobjob/0018_2.jpg", "boobjob/141.jpg", "boobjob/186.jpg", "boobjob/218.jpg", "boobjob/259.jpg", "boobjob/327.jpg", "boobjob/588.jpg", "boobjob/592.jpg", "boobjob/598.jpg", "boobjob/615.jpg", "boobjob/618.jpg", ], "evidence_notes": ( "Residual-pool review found a repeated front-close third-person family " "where face or upper body remains readable and the contact action stays " "centered. Side, standing, foreground-heavy, and downward/crop-drifting " "outliers remain outside this selected subset." ), }, ], "fingering": [ { "variant_key": "normal_fingering_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "fingering/0001.jpg", "fingering/195.jpg", "fingering/603.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the folder as a mixed source-pool anchor. " "The images include useful manual-contact examples, but upright, standing, " "side, and oral-adjacent frames keep the full folder from being one locked " "prompt-ready route." ), }, { "variant_key": "normal_fingering_reclined_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "fingering/0004.jpg", "fingering/0006.jpg", "fingering/0013.jpg", "fingering/0015.jpg", "fingering/39.jpg", "fingering/50.jpg", "fingering/132.jpg", "fingering/133.jpg", "fingering/279.jpg", "fingering/603.jpg", ], "evidence_notes": ( "Contact-sheet review found a repeated reclined front-view manual-contact " "family where the camera faces the open-thigh contact plane and face or " "upper body remains readable. Upright chair, standing, side, and stronger " "oral-adjacent outliers remain outside this selected subset." ), }, ], "69": [ { "variant_key": "normal_sixty_nine_mixed_camera_folder_pool", "review_bucket": "reject_or_unclear", "status": "needs_samples", "selection_date": "2026-07-02", "reference_images": [ "69/0002.jpg", "69/196.jpg", "69/624.jpg", ], "evidence_notes": ( "Contact-sheet review preserved the folder as a mixed source-pool anchor. " "The source images include useful mutual oral-contact examples, but " "side/downward, upright seated, and wider room-context frames keep the " "full folder from being one locked prompt-ready route." ), }, { "variant_key": "normal_sixty_nine_front_close_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "69/0002.jpg", "69/0008.jpg", "69/0016.jpg", "69/19.jpg", "69/166.jpg", "69/292.jpg", "69/624.jpg", ], "evidence_notes": ( "Contact-sheet review found a repeated front-close third-person family " "where the upper subject faces camera and the opposed oral-contact pose " "stays centered. Side/downward, upright seated, and wider room-context " "outliers remain outside this selected subset." ), }, ], "breast sucking - side view": [ { "variant_key": "normal_breast_sucking_side_view", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "breast sucking - side view/0003.jpg", "breast sucking - side view/0005.jpg", "breast sucking - side view/0007.jpg", "breast sucking - side view/0009.jpg", "breast sucking - side view/0010_2.jpg", "breast sucking - side view/182.jpg", "breast sucking - side view/186.jpg", "breast sucking - side view/218.jpg", "breast sucking - side view/234.jpg", "breast sucking - side view/244.jpg", "breast sucking - side view/257.jpg", "breast sucking - side view/267.jpg", "breast sucking - side view/269.jpg", "breast sucking - side view/356.jpg", "breast sucking - side view/99.jpg", ], "evidence_notes": ( "Residual-pool review confirmed a repeated side/near-side mouth-contact " "family across standing and seated contexts. References were expanded " "while front-only, hand-touch-only, and weak-contact examples remain outside " "the selected subset." ), } ], "fuck from front standing - side view": [ { "variant_key": "normal_standing_from_front_side_view", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-06-29", "reference_images": [ "fuck from front standing - side view/0001.jpg", "fuck from front standing - side view/252.jpg", "fuck from front standing - side view/73.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing selected standing from-front side-view " "subset unchanged. The remaining source images include usable side/near-side " "frames, but too many drift into suspended/lifted, close-crop, couch, or " "front-heavy framing for a safe reference expansion." ), } ], "fuck from behind standing - woman backside - side view": [ { "variant_key": "normal_doggy_standing_backside_side_view_folder_pool", "review_bucket": "side_view", "status": "needs_samples", "selection_date": "2026-06-29", "reference_images": [ "fuck from behind standing - woman backside - side view/0008.jpg", "fuck from behind standing - woman backside - side view/288.jpg", "fuck from behind standing - woman backside - side view/68_2.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing folder-pool anchor unchanged. " "The folder has standing side/rear-lateral material, but the unselected " "images mix lifted, seated, bed/couch, front-drifting, and portrait-like " "frames rather than a cleaner prompt-ready split." ), }, { "variant_key": "normal_doggy_standing_backside_side_view", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-06-29", "reference_images": [ "fuck from behind standing - woman backside - side view/0010.jpg", "fuck from behind standing - woman backside - side view/0012.jpg", "fuck from behind standing - woman backside - side view/186.jpg", "fuck from behind standing - woman backside - side view/186_2.jpg", "fuck from behind standing - woman backside - side view/196.jpg", "fuck from behind standing - woman backside - side view/257.jpg", "fuck from behind standing - woman backside - side view/286.jpg", "fuck from behind standing - woman backside - side view/288.jpg", "fuck from behind standing - woman backside - side view/343.jpg", "fuck from behind standing - woman backside - side view/343_2.jpg", "fuck from behind standing - woman backside - side view/343_3.jpg", "fuck from behind standing - woman backside - side view/345.jpg", "fuck from behind standing - woman backside - side view/345_2.jpg", "fuck from behind standing - woman backside - side view/542.jpg", "fuck from behind standing - woman backside - side view/68.jpg", "fuck from behind standing - woman backside - side view/68_2.jpg", ], "evidence_notes": ( "Residual-pool review kept the existing standing backside side-view route " "unchanged. It already has a coherent reviewed subset; remaining images " "do not add a distinct repeated camera family in this pass." ), }, ], "doggy - back view - 3-4 angle": [ { "variant_key": "normal_doggy_generic_back_three_quarter", "review_bucket": "back_three_quarter", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "doggy - back view - 3-4 angle/0002.jpg", "doggy - back view - 3-4 angle/0002_2.jpg", "doggy - back view - 3-4 angle/0008_2.jpg", "doggy - back view - 3-4 angle/0013.jpg", "doggy - back view - 3-4 angle/0015.jpg", "doggy - back view - 3-4 angle/0017.jpg", "doggy - back view - 3-4 angle/0021.jpg", "doggy - back view - 3-4 angle/132.jpg", "doggy - back view - 3-4 angle/145.jpg", "doggy - back view - 3-4 angle/183.jpg", "doggy - back view - 3-4 angle/185.jpg", "doggy - back view - 3-4 angle/227.jpg", "doggy - back view - 3-4 angle/39.jpg", "doggy - back view - 3-4 angle/41.jpg", "doggy - back view - 3-4 angle/77.jpg", ], "evidence_notes": ( "Residual-pool review confirmed the existing generic rear three-quarter " "route as a coherent back-offset camera family. References were expanded " "while low/close and laying-drift examples remain outside the selected subset." ), } ], "woman solo showing her hass - back view": [ { "variant_key": "normal_display_rear_body_standing_back_view", "review_bucket": "back_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "woman solo showing her hass - back view/0002.jpg", "woman solo showing her hass - back view/0006.jpg", "woman solo showing her hass - back view/0006_3.jpg", "woman solo showing her hass - back view/0007_2.jpg", "woman solo showing her hass - back view/173.jpg", "woman solo showing her hass - back view/197.jpg", "woman solo showing her hass - back view/230.jpg", "woman solo showing her hass - back view/235.jpg", "woman solo showing her hass - back view/287.jpg", "woman solo showing her hass - back view/293.jpg", "woman solo showing her hass - back view/300.jpg", "woman solo showing her hass - back view/321.jpg", ], "evidence_notes": ( "Residual-pool review found a repeated upright standing rear-body display " "family. Seated, kneeling, side-leaning, and close-crop rear examples remain " "in the broad source pool or existing rear-body route." ), } ], "couple kissing": [ { "variant_key": "normal_couple_kissing_upright_side_profile", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "couple kissing/0001_2.jpg", "couple kissing/0003.jpg", "couple kissing/0005_2.jpg", "couple kissing/16.jpg", "couple kissing/159.jpg", "couple kissing/247.jpg", "couple kissing/247_2.jpg", "couple kissing/253.jpg", "couple kissing/253_2.jpg", "couple kissing/322.jpg", "couple kissing/354.jpg", "couple kissing/379.jpg", ], "evidence_notes": ( "Paged review found a repeated upright side-profile kissing family. " "Seated, bed, close-crop, and front-facing examples remain in the mixed source pool." ), } ], "anal random": [ { "variant_key": "normal_anal_random_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "anal random/0005.jpg", "anal random/0006.jpg", "anal random/0015.jpg", "anal random/160_3.jpg", "anal random/188.jpg", "anal random/347_3.jpg", "anal random/347_10.jpg", "anal random/347_11.jpg", "anal random/366.jpg", "anal random/366_3.jpg", "anal random/366_4.jpg", ], "evidence_notes": ( "Paged review found a repeated front-view anal camera family. " "Side, rear, standing, and overhead-like frames remain in the mixed source pool." ), }, { "variant_key": "normal_anal_random_back_side_offset_view", "review_bucket": "back_three_quarter", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "anal random/0003.jpg", "anal random/0003_3.jpg", "anal random/0010.jpg", "anal random/0013.jpg", "anal random/119.jpg", "anal random/119_2.jpg", "anal random/119_3.jpg", "anal random/124_2.jpg", "anal random/124_8.jpg", "anal random/347_4.jpg", "anal random/347_5.jpg", "anal random/347_8.jpg", ], "evidence_notes": ( "Residual-pool review found a repeated rear/side-offset anal camera family " "with third-person framing. Front-view, standing, overhead-like, and tight " "close-crop frames remain in the mixed source pool." ), } ], "breasts exposed": [ { "variant_key": "normal_display_breasts_exposed_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "breasts exposed/0001_3.jpg", "breasts exposed/0006.jpg", "breasts exposed/0008_2.jpg", "breasts exposed/0011_2.jpg", "breasts exposed/141.jpg", "breasts exposed/181.jpg", "breasts exposed/263.jpg", "breasts exposed/302.jpg", "breasts exposed/327.jpg", "breasts exposed/346.jpg", "breasts exposed/594_2.jpg", "breasts exposed/624.jpg", ], "evidence_notes": ( "Paged review found a repeated camera-facing full-body display family " "inside the broad mixed source folder. Seated, side-offset, and tight " "upper-body crops stay separate from this selected subset." ), }, { "variant_key": "normal_display_breasts_exposed_side_offset_view", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "breasts exposed/83.jpg", "breasts exposed/196.jpg", "breasts exposed/235.jpg", "breasts exposed/267.jpg", "breasts exposed/271.jpg", "breasts exposed/305.jpg", "breasts exposed/353.jpg", "breasts exposed/373.jpg", "breasts exposed/590.jpg", "breasts exposed/590_2.jpg", ], "evidence_notes": ( "Paged review found a repeated side-offset display family with lateral " "torso orientation and normal third-person framing." ), }, { "variant_key": "normal_display_breasts_exposed_standing_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "breasts exposed/0002_2.jpg", "breasts exposed/0003.jpg", "breasts exposed/49.jpg", "breasts exposed/138.jpg", "breasts exposed/155.jpg", "breasts exposed/169.jpg", "breasts exposed/190.jpg", "breasts exposed/230.jpg", "breasts exposed/242.jpg", "breasts exposed/302_2.jpg", "breasts exposed/332.jpg", "breasts exposed/368.jpg", ], "evidence_notes": ( "Residual-pool review found a repeated upright standing front-view display " "family. Seated, kneeling, side-offset, and tight crop examples remain in the " "mixed source pool." ), }, { "variant_key": "normal_display_breasts_exposed_seated_kneeling_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "breasts exposed/0001_2.jpg", "breasts exposed/0007_2.jpg", "breasts exposed/101_2.jpg", "breasts exposed/154.jpg", "breasts exposed/165.jpg", "breasts exposed/173.jpg", "breasts exposed/259.jpg", "breasts exposed/285.jpg", "breasts exposed/293.jpg", "breasts exposed/322.jpg", "breasts exposed/328.jpg", "breasts exposed/523.jpg", ], "evidence_notes": ( "Residual-pool review found a repeated seated or kneeling front-view display " "family. Standing, side-offset, couple/action, and tight crop examples remain " "outside this selected subset." ), }, ], "pussy spread": [ { "variant_key": "normal_display_front_open_leg_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "pussy spread/0002_3.jpg", "pussy spread/0003_4.jpg", "pussy spread/0012.jpg", "pussy spread/0015.jpg", "pussy spread/0017.jpg", "pussy spread/80.jpg", "pussy spread/130.jpg", "pussy spread/153.jpg", "pussy spread/296.jpg", "pussy spread/297.jpg", "pussy spread/328.jpg", "pussy spread/367.jpg", ], "evidence_notes": ( "Paged review found a repeated camera-facing front-view display family " "with enough body and room context to stay separate from tight low-close crops." ), }, { "variant_key": "normal_display_front_open_leg_low_close", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "pussy spread/1.jpg", "pussy spread/1_2.jpg", "pussy spread/0003.jpg", "pussy spread/0003_2.jpg", "pussy spread/0003_3.jpg", "pussy spread/0010_2.jpg", "pussy spread/0016.jpg", "pussy spread/0016_2.jpg", "pussy spread/41.jpg", "pussy spread/201.jpg", "pussy spread/217_2.jpg", "pussy spread/223.jpg", ], "evidence_notes": ( "Paged review found a repeated low-close front-view display family " "where the foreground body plane dominates the composition." ), }, { "variant_key": "normal_display_front_open_leg_side_offset_view", "review_bucket": "side_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "pussy spread/0007.jpg", "pussy spread/0008.jpg", "pussy spread/73.jpg", "pussy spread/121.jpg", "pussy spread/134.jpg", "pussy spread/154_3.jpg", "pussy spread/163.jpg", "pussy spread/175.jpg", "pussy spread/256.jpg", "pussy spread/308.jpg", "pussy spread/311.jpg", "pussy spread/368.jpg", ], "evidence_notes": ( "Residual-pool review found a repeated side-offset seated or reclined " "open-leg display family. Straight front, low-close, and one-off crop " "variants remain in the mixed source pool." ), }, ], "reverse cowgirl": [ { "variant_key": "normal_reverse_cowgirl_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "reverse cowgirl/0001.jpg", "reverse cowgirl/0004.jpg", "reverse cowgirl/0005_4.jpg", "reverse cowgirl/0014.jpg", "reverse cowgirl/79.jpg", "reverse cowgirl/82.jpg", "reverse cowgirl/145.jpg", "reverse cowgirl/260.jpg", "reverse cowgirl/288.jpg", "reverse cowgirl/319.jpg", "reverse cowgirl/527.jpg", "reverse cowgirl/608.jpg", ], "evidence_notes": ( "Paged review found a repeated front-facing reverse-cowgirl camera family " "across the large mixed source folder. Rear and side labels remain covered " "by the existing dedicated source folders until cleaner selected subsets are chosen." ), }, { "variant_key": "normal_reverse_cowgirl_front_three_quarter", "review_bucket": "front_three_quarter", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "reverse cowgirl/153.jpg", "reverse cowgirl/153_2.jpg", "reverse cowgirl/239_2.jpg", "reverse cowgirl/239_3.jpg", "reverse cowgirl/241.jpg", "reverse cowgirl/241_2.jpg", "reverse cowgirl/241_3.jpg", "reverse cowgirl/257.jpg", "reverse cowgirl/287.jpg", "reverse cowgirl/323_2.jpg", "reverse cowgirl/609.jpg", "reverse cowgirl/609_2.jpg", ], "evidence_notes": ( "Paged review found a repeated front-offset reverse-cowgirl camera family " "where the woman's body turns partly toward camera while the partner remains " "visible below or behind her in third person." ), }, { "variant_key": "normal_reverse_cowgirl_low_close_front_view", "review_bucket": "front_view", "status": "pre_ab_candidate", "selection_date": "2026-07-02", "reference_images": [ "reverse cowgirl/0009.jpg", "reverse cowgirl/0009_2.jpg", "reverse cowgirl/0009_3.jpg", "reverse cowgirl/0015.jpg", "reverse cowgirl/0015_2.jpg", "reverse cowgirl/0016_2.jpg", "reverse cowgirl/170.jpg", "reverse cowgirl/261.jpg", "reverse cowgirl/332.jpg", "reverse cowgirl/332_2.jpg", "reverse cowgirl/551.jpg", "reverse cowgirl/618.jpg", ], "evidence_notes": ( "Residual-pool review found a repeated low-close front-view reverse-cowgirl " "family where the foreground contact plane dominates while the subject remains " "visible in third-person framing. Wider room-context front views stay in the " "existing front-view subset." ), } ] } ACCEPTANCE_GATES: tuple[str, ...] = ( "camera_geometry", "pose_ownership", "workspace_continuity", "clothing_visibility", "subject_identity", "body_proportion_control", "prompt_noise", "atlas_reference_match", ) GATE_DESCRIPTIONS: dict[str, str] = { "camera_geometry": "Camera angle, elevation, side/front/back orientation, and framing match the atlas family.", "pose_ownership": "The visible actors own the pose correctly, with no POV body cues leaking into normal-camera framing.", "workspace_continuity": "Workspace/lounge details support the camera angle instead of fighting the pose.", "clothing_visibility": "Clothing cues stay attached to the intended visible subject and only describe garments visible in this pose.", "subject_identity": "The same woman identity, face, hair, eyes, and body type remain stable across fixed-seed variants.", "body_proportion_control": "Penis/body proportions and limb lengths stay plausible for the selected atlas framing.", "prompt_noise": "Prompt text uses direct visual cues, with option, negative, and instruction-like wording removed from positive text.", "atlas_reference_match": "The generated frame can be matched back to the selected atlas references for this variant.", } PROMPT_NOISE_PATTERNS: tuple[tuple[str, re.Pattern[str]], ...] = ( ("option_word", re.compile(r"\b(?:may|optionally|either|or)\b", flags=re.IGNORECASE)), ("negative_word", re.compile(r"\b(?:without|never|no|not)\b", flags=re.IGNORECASE)), ("contrast_wording", re.compile(r"\brather than\b", flags=re.IGNORECASE)), ("instruction_wording", re.compile(r"\b(?:avoid|exclude|prevent|forbid|should|must)\b", flags=re.IGNORECASE)), ) def _load_json(path: Path) -> dict[str, Any]: return json.loads(path.read_text(encoding="utf-8")) def load_atlas() -> dict[str, Any]: return _load_json(CATALOG_DIR / "normal_camera_atlas.json") def load_variants() -> dict[str, Any]: return _load_json(CATALOG_DIR / "normal_camera_variants.json") def _limited(items: list[dict[str, Any]], limit: int | None) -> list[dict[str, Any]]: if limit is None: return items if limit < 0: raise ValueError("limit must be non-negative") return items[:limit] def _natural_sort_key(text: str) -> list[int | str]: return [int(part) if part.isdigit() else part.lower() for part in re.split(r"(\d+)", text)] def _safe_artifact_stem(text: str) -> str: stem = re.sub(r"[^a-z0-9]+", "_", text.lower()).strip("_") return stem or "folder" def _folder_alias(folder_name: str) -> dict[str, Any]: alias = SOURCE_FOLDER_ALIASES.get(folder_name) or {} canonical_folder = str(alias.get("canonical_folder") or folder_name) return { "exact_source_folder": folder_name, "canonical_folder": canonical_folder, "canonical_key": _safe_artifact_stem(canonical_folder), "alias_applied": bool(alias), "alias_reason": str(alias.get("alias_reason") or ""), } def _atlas_folder_rows() -> list[dict[str, Any]]: return list(load_atlas().get("folders") or []) def _atlas_folder_row(folder_name: str) -> dict[str, Any]: for folder in _atlas_folder_rows(): if folder.get("folder") == folder_name: return folder raise KeyError(f"unknown normal-camera atlas folder: {folder_name}") def _variant_reference_map() -> dict[str, set[str]]: refs_by_folder: dict[str, set[str]] = {} for variant in load_variants().get("variants") or []: for ref in _reference_images(variant): folder = ref.rsplit("/", 1)[0] refs_by_folder.setdefault(folder, set()).add(ref) return refs_by_folder def _covered_variant_folders() -> set[str]: covered: set[str] = set() for variant in load_variants().get("variants") or []: for folder in variant.get("atlas_folders") or []: folder_text = str(folder) if folder_text.strip(): covered.add(folder_text) return covered def _folder_image_refs(folder_name: str) -> list[str]: atlas_root = Path(str(load_atlas().get("atlas_root") or "")) source_dir = atlas_root / folder_name if source_dir.is_dir(): image_names = sorted( (path.name for path in source_dir.iterdir() if path.is_file() and path.suffix.lower() == ".jpg"), key=_natural_sort_key, ) return [f"{folder_name}/{name}" for name in image_names] return [str(ref) for ref in _atlas_folder_row(folder_name).get("reference_images") or [] if str(ref).strip()] def _variant_rows(status: str | None = None, limit: int | None = None) -> list[dict[str, Any]]: variants = load_variants().get("variants") or [] rows = [variant for variant in variants if not status or variant.get("status") == status] return _limited(rows, limit) def _reference_images(variant: dict[str, Any]) -> list[str]: return [str(ref) for ref in variant.get("reference_images") or [] if str(ref).strip()] def _source_prompt_cues(variant: dict[str, Any]) -> list[str]: return [str(cue).strip() for cue in variant.get("prompt_cues") or [] if str(cue).strip()] def _avoid_cues(variant: dict[str, Any]) -> list[str]: return [str(cue).strip() for cue in variant.get("avoid_cues") or [] if str(cue).strip()] def _prompt_noise(cue: str) -> list[str]: return [name for name, pattern in PROMPT_NOISE_PATTERNS if pattern.search(cue)] def _prompt_cue_review(variant: dict[str, Any]) -> dict[str, Any]: positive_cues: list[str] = [] blocked_cues: list[dict[str, Any]] = [] for cue in _source_prompt_cues(variant): issues = _prompt_noise(cue) if issues: blocked_cues.append({"cue": cue, "issues": issues}) else: positive_cues.append(cue) state = "prompt_ready" if positive_cues and not blocked_cues else "needs_prompt_cleanup" return { "state": state, "positive_prompt_cues": positive_cues, "blocked_prompt_cues": blocked_cues, "prompt_text": ". ".join(positive_cues) + ("." if positive_cues else ""), } def _unused_pool_suggested_action(folder: dict[str, Any], covered_by_variants: bool) -> str: if not covered_by_variants: return "review_contact_sheet" if folder.get("camera_view") == "mixed_or_unspecified" or folder.get("catalog_status") == "action_reference_only": return "split_or_expand_selected_reference_subvariants" return "mine_remaining_reference_images" def build_unused_pool_backlog(limit: int | None = None) -> dict[str, Any]: refs_by_folder = _variant_reference_map() covered_folders = _covered_variant_folders() rows: list[dict[str, Any]] = [] for folder in _atlas_folder_rows(): image_count = int(folder.get("image_count") or 0) if image_count <= 0: continue folder_name = str(folder.get("folder") or "") selected_reference_count = len(refs_by_folder.get(folder_name, set())) remaining_image_count = max(image_count - selected_reference_count, 0) if remaining_image_count <= 0: continue covered_by_variants = folder_name in covered_folders rows.append( { "folder": folder_name, "folder_alias": _folder_alias(folder_name), "image_count": image_count, "selected_reference_count": selected_reference_count, "remaining_image_count": remaining_image_count, "covered_by_variants": covered_by_variants, "camera_view": folder.get("camera_view"), "action_family": folder.get("action_family"), "catalog_status": folder.get("catalog_status"), "suggested_action": _unused_pool_suggested_action(folder, covered_by_variants), } ) rows.sort(key=lambda row: (-int(row["remaining_image_count"]), str(row["folder"]))) selected = _limited(rows, limit) return { "schema": UNUSED_POOL_BACKLOG_SCHEMA, "no_generation": True, "atlas_root": load_atlas().get("atlas_root"), "source_inventory": "categories/normal_camera_atlas.json", "source_variant_catalog": "categories/normal_camera_variants.json", "selection": "non-empty folders with unselected images, sorted by remaining image count", "available_folder_count": len(rows), "selected_count": len(selected), "folders": selected, } def _selected_review_items(folder_name: str) -> dict[str, dict[str, Any]]: items: dict[str, dict[str, Any]] = {} for selected in REVIEW_SELECTED_SUBVARIANTS.get(folder_name, []): for ref in selected.get("reference_images") or []: ref_text = str(ref) if not ref_text.strip(): continue items[ref_text] = { "reference_image": ref_text, "review_decision": "selected_reference", "review_bucket": selected.get("review_bucket"), "variant_key": selected.get("variant_key"), "selection_date": selected.get("selection_date"), "review_notes": selected.get("evidence_notes") or "", } return items def _review_items(folder_name: str, image_refs: list[str]) -> list[dict[str, Any]]: selected_by_ref = _selected_review_items(folder_name) items: list[dict[str, Any]] = [] for index, ref in enumerate(image_refs, start=1): selected = selected_by_ref.get(ref) if selected: item = dict(selected) item["index"] = index else: item = { "index": index, "reference_image": ref, "review_decision": "residual_unassigned", "review_bucket": "unassigned", "variant_key": None, "selection_date": None, "review_notes": "", "exclusion_reason": "outside_selected_subvariants_or_pending_manual_bucket", } items.append(item) return items def _contact_sheet_pages( image_refs: list[str], page_size: int, review_items_by_ref: dict[str, dict[str, Any]] | None = None, ) -> list[dict[str, Any]]: pages: list[dict[str, Any]] = [] for page_index, start in enumerate(range(0, len(image_refs), page_size), start=1): page_refs = image_refs[start : start + page_size] pages.append( { "page": page_index, "html_anchor": f"page-{page_index:02d}", "start_index": start + 1, "end_index": start + len(page_refs), "image_count": len(page_refs), "images": [ { "index": start + offset + 1, "reference_image": ref, "review_bucket": (review_items_by_ref or {}).get(ref, {}).get("review_bucket") or "unassigned", "review_decision": (review_items_by_ref or {}).get(ref, {}).get("review_decision") or "residual_unassigned", "variant_key": (review_items_by_ref or {}).get(ref, {}).get("variant_key"), "notes": (review_items_by_ref or {}).get(ref, {}).get("review_notes") or "", } for offset, ref in enumerate(page_refs) ], } ) return pages def build_review_manifest(folder_name: str, page_size: int = 40) -> dict[str, Any]: if page_size <= 0: raise ValueError("page_size must be positive") folder = _atlas_folder_row(folder_name) image_refs = _folder_image_refs(folder_name) review_items = _review_items(folder_name, image_refs) review_items_by_ref = {str(item["reference_image"]): item for item in review_items} return { "schema": REVIEW_MANIFEST_SCHEMA, "no_generation": True, "atlas_root": load_atlas().get("atlas_root"), "folder": folder_name, "folder_alias": _folder_alias(folder_name), "image_count": len(image_refs), "action_family": folder.get("action_family"), "source_camera_view": folder.get("camera_view"), "source_catalog_status": folder.get("catalog_status"), "review_state": "contact_sheet_ready", "methodology": [ "Treat this folder as a cue-expansion pool, not automatic prompt truth.", "Cluster only repeated non-POV camera/pose families.", "Draft positive-only visual prompt cues from selected atlas references.", "Keep weak, mixed, or one-off groups as needs_samples.", ], "review_bucket_values": REVIEW_BUCKET_VALUES, "selected_subvariants": REVIEW_SELECTED_SUBVARIANTS.get(folder_name, []), "review_items": review_items, "contact_sheet_pages": _contact_sheet_pages(image_refs, page_size, review_items_by_ref), } def build_contact_sheet_html(folder_name: str, page_size: int = 40) -> str: manifest = build_review_manifest(folder_name, page_size) atlas_root = Path(str(manifest.get("atlas_root") or "")) title = f"Normal Camera Review Contact Sheet: {folder_name}" review_items_by_ref = {str(item.get("reference_image")): item for item in manifest.get("review_items") or []} alias = manifest.get("folder_alias") or {} lines = [ "", '', "
", '', f"| Source folder | Canonical label | Images | Selected refs | Residual | Manifest | Contact sheet |
|---|---|---|---|---|---|---|
{html.escape(str(row.get('folder') or ''))} | "
f"{html.escape(str(alias.get('canonical_folder') or ''))} | "
f"{html.escape(str(row.get('image_count') or 0))} | " f"{html.escape(str(row.get('selected_reference_count') or 0))} | " f"{html.escape(str(row.get('residual_unassigned_count') or 0))} | " f'manifest | ' f'contact sheet | ' "