Add multi-seed route simulation sweep
This commit is contained in:
@@ -106,7 +106,7 @@
|
|||||||
"item_templates": [
|
"item_templates": [
|
||||||
"{tease_act} in {position}, with {touch_detail}, {clothing_detail}, and {mood_detail}",
|
"{tease_act} in {position}, with {touch_detail}, {clothing_detail}, and {mood_detail}",
|
||||||
"{position} featuring {tease_act}, {body_contact}, {touch_detail}, and {visibility}",
|
"{position} featuring {tease_act}, {body_contact}, {touch_detail}, and {visibility}",
|
||||||
"hardcore foreplay setup: {tease_act}, {clothing_detail}, {face_detail}, and {body_contact}",
|
"hardcore foreplay setup with {tease_act}, {clothing_detail}, {face_detail}, and {body_contact}",
|
||||||
"{tease_act} on {surface}, with {touch_detail}, {mood_detail}, and {visibility}",
|
"{tease_act} on {surface}, with {touch_detail}, {mood_detail}, and {visibility}",
|
||||||
"{position} while {tease_act}, with {face_detail}, {clothing_detail}, and {touch_detail}"
|
"{position} while {tease_act}, with {face_detail}, {clothing_detail}, and {touch_detail}"
|
||||||
],
|
],
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
"{manual_act} in {position}, with {manual_detail}, {body_contact}, and {visibility}",
|
"{manual_act} in {position}, with {manual_detail}, {body_contact}, and {visibility}",
|
||||||
"{position} featuring {manual_act}, {hand_detail}, {reaction_detail}, and {visibility}",
|
"{position} featuring {manual_act}, {hand_detail}, {reaction_detail}, and {visibility}",
|
||||||
"{manual_act} on {surface}, with {manual_detail}, {hand_detail}, and {reaction_detail}",
|
"{manual_act} on {surface}, with {manual_detail}, {hand_detail}, and {reaction_detail}",
|
||||||
"manual stimulation setup: {position}, {manual_act}, {body_contact}, and {visibility}",
|
"manual stimulation setup with {position}, {manual_act}, {body_contact}, and {visibility}",
|
||||||
"{position} while {manual_act}, with {hand_detail}, {manual_detail}, and {reaction_detail}"
|
"{position} while {manual_act}, with {hand_detail}, {manual_detail}, and {reaction_detail}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
@@ -339,7 +339,7 @@
|
|||||||
"{worship_act} in {position}, with {touch_detail}, {face_detail}, and {visibility}",
|
"{worship_act} in {position}, with {touch_detail}, {face_detail}, and {visibility}",
|
||||||
"{position} featuring {worship_act}, {body_contact}, {touch_detail}, and {reaction_detail}",
|
"{position} featuring {worship_act}, {body_contact}, {touch_detail}, and {reaction_detail}",
|
||||||
"{worship_act} on {surface}, with {body_contact}, {face_detail}, and {visibility}",
|
"{worship_act} on {surface}, with {body_contact}, {face_detail}, and {visibility}",
|
||||||
"body worship setup: {position}, {worship_act}, {touch_detail}, and {reaction_detail}",
|
"body worship setup with {position}, {worship_act}, {touch_detail}, and {reaction_detail}",
|
||||||
"{position} while {worship_act}, with {body_contact}, {face_detail}, and {visibility}"
|
"{position} while {worship_act}, with {body_contact}, {face_detail}, and {visibility}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
@@ -452,7 +452,7 @@
|
|||||||
"{transition_act} in {position}, with {clothing_detail}, {hand_detail}, and {visibility}",
|
"{transition_act} in {position}, with {clothing_detail}, {hand_detail}, and {visibility}",
|
||||||
"{position} featuring {transition_act}, {body_contact}, {clothing_detail}, and {movement_detail}",
|
"{position} featuring {transition_act}, {body_contact}, {clothing_detail}, and {movement_detail}",
|
||||||
"{transition_act} on {surface}, with {hand_detail}, {body_contact}, and {visibility}",
|
"{transition_act} on {surface}, with {hand_detail}, {body_contact}, and {visibility}",
|
||||||
"position transition: {position}, {transition_act}, {movement_detail}, and {clothing_detail}",
|
"position transition with {position}, {transition_act}, {movement_detail}, and {clothing_detail}",
|
||||||
"{position} while {transition_act}, with {hand_detail}, {body_contact}, and {visibility}"
|
"{position} while {transition_act}, with {hand_detail}, {body_contact}, and {visibility}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
@@ -561,7 +561,7 @@
|
|||||||
"{control_act} in {position}, with {hand_detail}, {body_contact}, and {visibility}",
|
"{control_act} in {position}, with {hand_detail}, {body_contact}, and {visibility}",
|
||||||
"{position} featuring {control_act}, {power_detail}, {hand_detail}, and {reaction_detail}",
|
"{position} featuring {control_act}, {power_detail}, {hand_detail}, and {reaction_detail}",
|
||||||
"{control_act} on {surface}, with {body_contact}, {power_detail}, and {visibility}",
|
"{control_act} on {surface}, with {body_contact}, {power_detail}, and {visibility}",
|
||||||
"consensual control setup: {position}, {control_act}, {hand_detail}, and {reaction_detail}",
|
"consensual control setup with {position}, {control_act}, {hand_detail}, and {reaction_detail}",
|
||||||
"{position} while {control_act}, with {power_detail}, {body_contact}, and {visibility}"
|
"{position} while {control_act}, with {power_detail}, {body_contact}, and {visibility}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
@@ -675,7 +675,7 @@
|
|||||||
"{performance_act} in {position}, with {presentation_detail}, {hand_detail}, and {visibility}",
|
"{performance_act} in {position}, with {presentation_detail}, {hand_detail}, and {visibility}",
|
||||||
"{position} featuring {performance_act}, {camera_detail}, {presentation_detail}, and {reaction_detail}",
|
"{position} featuring {performance_act}, {camera_detail}, {presentation_detail}, and {reaction_detail}",
|
||||||
"{performance_act} on {surface}, with {hand_detail}, {camera_detail}, and {visibility}",
|
"{performance_act} on {surface}, with {hand_detail}, {camera_detail}, and {visibility}",
|
||||||
"creator-performance setup: {position}, {performance_act}, {presentation_detail}, and {reaction_detail}",
|
"creator-performance setup with {position}, {performance_act}, {presentation_detail}, and {reaction_detail}",
|
||||||
"{position} while {performance_act}, with {camera_detail}, {hand_detail}, and {visibility}"
|
"{position} while {performance_act}, with {camera_detail}, {hand_detail}, and {visibility}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
@@ -783,7 +783,7 @@
|
|||||||
"{coordination_act} with {arrangement}, {touch_detail}, {reaction_detail}, and {visibility}",
|
"{coordination_act} with {arrangement}, {touch_detail}, {reaction_detail}, and {visibility}",
|
||||||
"{arrangement} featuring {coordination_act}, {body_contact}, {watching_detail}, and {visibility}",
|
"{arrangement} featuring {coordination_act}, {body_contact}, {watching_detail}, and {visibility}",
|
||||||
"{coordination_act} on {surface}, with {touch_detail}, {watching_detail}, and {body_contact}",
|
"{coordination_act} on {surface}, with {touch_detail}, {watching_detail}, and {body_contact}",
|
||||||
"group coordination setup: {arrangement}, {coordination_act}, {watching_detail}, and {visibility}",
|
"group coordination setup with {arrangement}, {coordination_act}, {watching_detail}, and {visibility}",
|
||||||
"{arrangement} while {coordination_act}, with {touch_detail}, {reaction_detail}, and {visibility}"
|
"{arrangement} while {coordination_act}, with {touch_detail}, {reaction_detail}, and {visibility}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
@@ -889,7 +889,7 @@
|
|||||||
"{aftercare_act} in {position}, with {cleanup_detail}, {body_contact}, and {visibility}",
|
"{aftercare_act} in {position}, with {cleanup_detail}, {body_contact}, and {visibility}",
|
||||||
"{position} featuring {aftercare_act}, {touch_detail}, {cleanup_detail}, and {reaction_detail}",
|
"{position} featuring {aftercare_act}, {touch_detail}, {cleanup_detail}, and {reaction_detail}",
|
||||||
"{aftercare_act} on {surface}, with {body_contact}, {touch_detail}, and {visibility}",
|
"{aftercare_act} on {surface}, with {body_contact}, {touch_detail}, and {visibility}",
|
||||||
"post-sex aftermath setup: {position}, {aftercare_act}, {cleanup_detail}, and {reaction_detail}",
|
"post-sex aftermath setup with {position}, {aftercare_act}, {cleanup_detail}, and {reaction_detail}",
|
||||||
"{position} while {aftercare_act}, with {touch_detail}, {body_contact}, and {visibility}"
|
"{position} while {aftercare_act}, with {touch_detail}, {body_contact}, and {visibility}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
@@ -1178,7 +1178,7 @@
|
|||||||
"{oral_act} on {surface}, {hand_detail}, {mouth_detail}, and {climax_hint}",
|
"{oral_act} on {surface}, {hand_detail}, {mouth_detail}, and {climax_hint}",
|
||||||
"{angle} view of {oral_act}, with {visibility}, {body_contact}, and {expression_detail}",
|
"{angle} view of {oral_act}, with {visibility}, {body_contact}, and {expression_detail}",
|
||||||
"{position} while {oral_act}, with {saliva_detail}, {hand_detail}, and {climax_hint}",
|
"{position} while {oral_act}, with {saliva_detail}, {hand_detail}, and {climax_hint}",
|
||||||
"explicit mouth-to-genitals pose: {oral_act}, {mouth_detail}, {body_contact}, and {visibility}"
|
"explicit mouth-to-genitals pose with {oral_act}, {mouth_detail}, {body_contact}, and {visibility}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
"angle": [
|
"angle": [
|
||||||
@@ -1330,7 +1330,7 @@
|
|||||||
},
|
},
|
||||||
"{position} featuring {outer_act}, {body_contact}, {texture_detail}, seen from a {angle} view",
|
"{position} featuring {outer_act}, {body_contact}, {texture_detail}, seen from a {angle} view",
|
||||||
"{angle} view of {outer_act}, with {visibility}, {contact_detail}, and {expression_detail}",
|
"{angle} view of {outer_act}, with {visibility}, {contact_detail}, and {expression_detail}",
|
||||||
"explicit non-penetrative sex pose: {outer_act}, {position}, {contact_detail}, and {visibility}",
|
"explicit non-penetrative sex pose with {outer_act}, {position}, {contact_detail}, and {visibility}",
|
||||||
"{outer_act} on {surface}, with {hand_detail}, {body_contact}, and {texture_detail}",
|
"{outer_act} on {surface}, with {hand_detail}, {body_contact}, and {texture_detail}",
|
||||||
"{position} while {outer_act}, with {texture_detail}, {hand_detail}, and {visibility}"
|
"{position} while {outer_act}, with {texture_detail}, {hand_detail}, and {visibility}"
|
||||||
],
|
],
|
||||||
@@ -1479,7 +1479,7 @@
|
|||||||
"{double_act} on {surface}, with {leg_detail}, {intensity}, and {climax_hint}",
|
"{double_act} on {surface}, with {leg_detail}, {intensity}, and {climax_hint}",
|
||||||
"{angle} view of {double_act}, {body_arrangement}, {mouth_detail}, and {visibility}",
|
"{angle} view of {double_act}, {body_arrangement}, {mouth_detail}, and {visibility}",
|
||||||
"{anal_act} with {thrust_detail}, {hand_detail}, {body_contact}, and {climax_hint}",
|
"{anal_act} with {thrust_detail}, {hand_detail}, {body_contact}, and {climax_hint}",
|
||||||
"explicit double-contact sex pose: {double_act}, {leg_detail}, {visibility}, and {intensity}"
|
"explicit double-contact sex pose with {double_act}, {leg_detail}, {visibility}, and {intensity}"
|
||||||
],
|
],
|
||||||
"item_axes": {
|
"item_axes": {
|
||||||
"anal_act": [
|
"anal_act": [
|
||||||
@@ -1698,7 +1698,7 @@
|
|||||||
"{threesome_act} with {body_arrangement}, {oral_detail}, {penetration_detail}, and {visibility}",
|
"{threesome_act} with {body_arrangement}, {oral_detail}, {penetration_detail}, and {visibility}",
|
||||||
"{body_arrangement} while {threesome_act}, with {hand_detail}, {mouth_detail}, and {climax_hint}",
|
"{body_arrangement} while {threesome_act}, with {hand_detail}, {mouth_detail}, and {climax_hint}",
|
||||||
"{angle} threesome view featuring {threesome_act}, {body_contact}, {penetration_detail}, and {visibility}",
|
"{angle} threesome view featuring {threesome_act}, {body_contact}, {penetration_detail}, and {visibility}",
|
||||||
"hardcore threesome pose: {threesome_act}, {body_arrangement}, {oral_detail}, and {climax_hint}",
|
"hardcore threesome pose with {threesome_act}, {body_arrangement}, {oral_detail}, and {climax_hint}",
|
||||||
"{threesome_act} on {surface}, with {hand_detail}, {body_contact}, and {visibility}",
|
"{threesome_act} on {surface}, with {hand_detail}, {body_contact}, and {visibility}",
|
||||||
"{angle} view of {body_arrangement}, {penetration_detail}, {mouth_detail}, and {intensity}",
|
"{angle} view of {body_arrangement}, {penetration_detail}, {mouth_detail}, and {intensity}",
|
||||||
"three-body explicit sex pose with {threesome_act}, {oral_detail}, {hand_detail}, and {visibility}",
|
"three-body explicit sex pose with {threesome_act}, {oral_detail}, {hand_detail}, and {visibility}",
|
||||||
@@ -1885,7 +1885,7 @@
|
|||||||
"{group_act} with {arrangement}, {contact_detail}, {fluid_detail}, and {visibility}",
|
"{group_act} with {arrangement}, {contact_detail}, {fluid_detail}, and {visibility}",
|
||||||
"{arrangement} featuring {group_act}, {oral_detail}, {penetration_detail}, and {intensity}",
|
"{arrangement} featuring {group_act}, {oral_detail}, {penetration_detail}, and {intensity}",
|
||||||
"{angle} group-sex view with {group_act}, {contact_detail}, {climax_detail}, and {visibility}",
|
"{angle} group-sex view with {group_act}, {contact_detail}, {climax_detail}, and {visibility}",
|
||||||
"hardcore orgy pose: {arrangement}, {group_act}, {oral_detail}, and {fluid_detail}",
|
"hardcore orgy pose with {arrangement}, {group_act}, {oral_detail}, and {fluid_detail}",
|
||||||
"{group_act} on {surface}, with {penetration_detail}, {contact_detail}, and {visibility}",
|
"{group_act} on {surface}, with {penetration_detail}, {contact_detail}, and {visibility}",
|
||||||
"{angle} view of {arrangement}, {fluid_detail}, {intensity}, and {climax_detail}",
|
"{angle} view of {arrangement}, {fluid_detail}, {intensity}, and {climax_detail}",
|
||||||
"explicit adult group pile with {group_act}, {oral_detail}, {penetration_detail}, and {visibility}",
|
"explicit adult group pile with {group_act}, {oral_detail}, {penetration_detail}, and {visibility}",
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ The map audit currently sees:
|
|||||||
- Insta/OF side-target training captions no longer prepend shared cast
|
- Insta/OF side-target training captions no longer prepend shared cast
|
||||||
descriptors when the selected side row already emits its own cast prose, and
|
descriptors when the selected side row already emits its own cast prose, and
|
||||||
route simulation flags repeated cast descriptors.
|
route simulation flags repeated cast descriptors.
|
||||||
|
- Route simulation now has an opt-in multi-seed sweep, and the smoke suite runs
|
||||||
|
a three-seed sweep so representative route/noise checks are not proven by one
|
||||||
|
lucky seed only.
|
||||||
|
|
||||||
## Architectural Finding
|
## Architectural Finding
|
||||||
|
|
||||||
|
|||||||
@@ -1021,9 +1021,13 @@ issues for:
|
|||||||
scene, soft outfit, and composition axes stable;
|
scene, soft outfit, and composition axes stable;
|
||||||
- pose-axis rerolls changing cast/scene metadata or failing to move pose/action
|
- pose-axis rerolls changing cast/scene metadata or failing to move pose/action
|
||||||
metadata.
|
metadata.
|
||||||
|
- multi-seed route sweeps that repeat the same route/noise/seed checks across
|
||||||
|
spaced seeds to catch random-pool drift hidden by a single clean seed.
|
||||||
|
|
||||||
Use `--json --include-prompts` when you need the exact raw and formatted text
|
Use `--json --include-prompts` when you need the exact raw and formatted text
|
||||||
for debugging a route.
|
for debugging a route. Use `--sweep-count 5 --seed-step 101` when changing pool
|
||||||
|
selection, route terms, or formatter noise rules and you need more than one
|
||||||
|
seed of evidence.
|
||||||
|
|
||||||
## Editing Cheatsheet
|
## Editing Cheatsheet
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ AUDIT_DOC_SNIPPETS: tuple[tuple[str, str], ...] = (
|
|||||||
"docs/prompt-pool-routing-map.md",
|
"docs/prompt-pool-routing-map.md",
|
||||||
"repeated cast descriptors in training-caption formatter output",
|
"repeated cast descriptors in training-caption formatter output",
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"docs/prompt-pool-routing-map.md",
|
||||||
|
"multi-seed route sweeps",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
PROMPT_ROW_READ_SCAN_GLOBS: tuple[str, ...] = (
|
PROMPT_ROW_READ_SCAN_GLOBS: tuple[str, ...] = (
|
||||||
|
|||||||
@@ -308,6 +308,7 @@ HARDCORE_ROUTE_CASES = (
|
|||||||
"subcategory": "Foreplay and teasing",
|
"subcategory": "Foreplay and teasing",
|
||||||
"focus": "foreplay_only",
|
"focus": "foreplay_only",
|
||||||
"family": "foreplay",
|
"family": "foreplay",
|
||||||
|
"positions": ("undressing",),
|
||||||
"expected_route": {"action_family": "foreplay", "position_family": "foreplay"},
|
"expected_route": {"action_family": "foreplay", "position_family": "foreplay"},
|
||||||
"expected_terms": {
|
"expected_terms": {
|
||||||
"krea": ("clothing",),
|
"krea": ("clothing",),
|
||||||
@@ -317,12 +318,13 @@ HARDCORE_ROUTE_CASES = (
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hardcore.single.interaction",
|
"name": "hardcore.single.interaction",
|
||||||
"subcategory": "Aftercare and cleanup",
|
"subcategory": "Clothing and position transitions",
|
||||||
"focus": "interaction_only",
|
"focus": "interaction_only",
|
||||||
"family": "interaction",
|
"family": "interaction",
|
||||||
|
"positions": ("position_transition",),
|
||||||
"expected_route": {"action_family": "foreplay", "position_family": "interaction"},
|
"expected_route": {"action_family": "foreplay", "position_family": "interaction"},
|
||||||
"expected_terms": {
|
"expected_terms": {
|
||||||
"krea": ("mid-transition",),
|
"krea": ("clothing",),
|
||||||
"sdxl": ("interaction",),
|
"sdxl": ("interaction",),
|
||||||
"caption": ("interaction beat",),
|
"caption": ("interaction beat",),
|
||||||
},
|
},
|
||||||
@@ -332,9 +334,10 @@ HARDCORE_ROUTE_CASES = (
|
|||||||
"subcategory": "Anal and double penetration",
|
"subcategory": "Anal and double penetration",
|
||||||
"focus": "anal_only",
|
"focus": "anal_only",
|
||||||
"family": "anal",
|
"family": "anal",
|
||||||
|
"positions": ("doggy", "face_down_ass_up"),
|
||||||
"expected_route": {"action_family": "anal", "position_family": "anal"},
|
"expected_route": {"action_family": "anal", "position_family": "anal"},
|
||||||
"expected_terms": {
|
"expected_terms": {
|
||||||
"krea": ("anal",),
|
"krea": ("ass",),
|
||||||
"sdxl": ("anal sex",),
|
"sdxl": ("anal sex",),
|
||||||
"caption": ("anal action",),
|
"caption": ("anal action",),
|
||||||
},
|
},
|
||||||
@@ -853,7 +856,13 @@ def _regular_single_case(seed: int) -> dict[str, Any]:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _hardcore_single_case(seed: int, subcategory: str, focus: str, family: str) -> dict[str, Any]:
|
def _hardcore_single_case(
|
||||||
|
seed: int,
|
||||||
|
subcategory: str,
|
||||||
|
focus: str,
|
||||||
|
family: str,
|
||||||
|
positions: list[str] | tuple[str, ...] | str = (),
|
||||||
|
) -> dict[str, Any]:
|
||||||
women_count, men_count, character_cast = {
|
women_count, men_count, character_cast = {
|
||||||
"threesome": (1, 2, _character_cast_subjects(("woman", "man", "man"))),
|
"threesome": (1, 2, _character_cast_subjects(("woman", "man", "man"))),
|
||||||
"group": (2, 2, _character_cast_subjects(("woman", "woman", "man", "man"))),
|
"group": (2, 2, _character_cast_subjects(("woman", "woman", "man", "man"))),
|
||||||
@@ -881,7 +890,7 @@ def _hardcore_single_case(seed: int, subcategory: str, focus: str, family: str)
|
|||||||
women_count=women_count,
|
women_count=women_count,
|
||||||
men_count=men_count,
|
men_count=men_count,
|
||||||
character_cast=character_cast,
|
character_cast=character_cast,
|
||||||
hardcore_position_config=_position_filter(focus, family, []),
|
hardcore_position_config=_position_filter(focus, family, positions),
|
||||||
location_config=_coworking_location_config(),
|
location_config=_coworking_location_config(),
|
||||||
camera_config=_orbit_camera(horizontal_angle=35, vertical_angle=0, zoom=6.5),
|
camera_config=_orbit_camera(horizontal_angle=35, vertical_angle=0, zoom=6.5),
|
||||||
)
|
)
|
||||||
@@ -1404,6 +1413,7 @@ def run_simulation(seed: int = 3901, *, include_prompts: bool = False) -> dict[s
|
|||||||
str(route_case["subcategory"]),
|
str(route_case["subcategory"]),
|
||||||
str(route_case["focus"]),
|
str(route_case["focus"]),
|
||||||
str(route_case["family"]),
|
str(route_case["family"]),
|
||||||
|
route_case.get("positions") or (),
|
||||||
)
|
)
|
||||||
cases.append(
|
cases.append(
|
||||||
_case_report(
|
_case_report(
|
||||||
@@ -1459,6 +1469,38 @@ def run_simulation(seed: int = 3901, *, include_prompts: bool = False) -> dict[s
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def run_simulation_sweep(
|
||||||
|
seed: int = 3901,
|
||||||
|
*,
|
||||||
|
count: int = 3,
|
||||||
|
seed_step: int = 101,
|
||||||
|
include_prompts: bool = False,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
count = max(1, int(count))
|
||||||
|
seed_step = int(seed_step)
|
||||||
|
seeds = [seed + index * seed_step for index in range(count)]
|
||||||
|
runs = [run_simulation(seed=current_seed, include_prompts=include_prompts) for current_seed in seeds]
|
||||||
|
issues: list[dict[str, Any]] = []
|
||||||
|
for run in runs:
|
||||||
|
run_seed = (run.get("summary") or {}).get("seed")
|
||||||
|
issues.extend({"seed": run_seed, **issue} for issue in run.get("issues") or [])
|
||||||
|
return {
|
||||||
|
"summary": {
|
||||||
|
"seed": seed,
|
||||||
|
"seed_step": seed_step,
|
||||||
|
"seeds": seeds,
|
||||||
|
"runs": len(runs),
|
||||||
|
"cases": sum((run.get("summary") or {}).get("cases", 0) for run in runs),
|
||||||
|
"coverage_checks": sum((run.get("summary") or {}).get("coverage_checks", 0) for run in runs),
|
||||||
|
"axis_checks": sum((run.get("summary") or {}).get("axis_checks", 0) for run in runs),
|
||||||
|
"pair_seed_checks": sum((run.get("summary") or {}).get("pair_seed_checks", 0) for run in runs),
|
||||||
|
"issues": len(issues),
|
||||||
|
},
|
||||||
|
"issues": issues,
|
||||||
|
"runs": runs,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _print_text_report(report: dict[str, Any]) -> None:
|
def _print_text_report(report: dict[str, Any]) -> None:
|
||||||
summary = report.get("summary") or {}
|
summary = report.get("summary") or {}
|
||||||
print(
|
print(
|
||||||
@@ -1490,17 +1532,49 @@ def _print_text_report(report: dict[str, Any]) -> None:
|
|||||||
print(f" ISSUE {issue}")
|
print(f" ISSUE {issue}")
|
||||||
|
|
||||||
|
|
||||||
|
def _print_sweep_report(report: dict[str, Any]) -> None:
|
||||||
|
summary = report.get("summary") or {}
|
||||||
|
seeds = ", ".join(str(seed) for seed in (summary.get("seeds") or []))
|
||||||
|
print(
|
||||||
|
f"Prompt route simulation sweep: seed={summary.get('seed')} "
|
||||||
|
f"seed_step={summary.get('seed_step')} runs={summary.get('runs')} "
|
||||||
|
f"seeds={seeds} cases={summary.get('cases')} coverage_checks={summary.get('coverage_checks')} "
|
||||||
|
f"axis_checks={summary.get('axis_checks')} pair_seed_checks={summary.get('pair_seed_checks')} "
|
||||||
|
f"issues={summary.get('issues')}"
|
||||||
|
)
|
||||||
|
for run in report.get("runs") or []:
|
||||||
|
run_summary = run.get("summary") or {}
|
||||||
|
print(
|
||||||
|
f"- seed {run_summary.get('seed')}: "
|
||||||
|
f"cases={run_summary.get('cases')} issues={run_summary.get('issues')}"
|
||||||
|
)
|
||||||
|
for issue in run.get("issues") or []:
|
||||||
|
print(f" ISSUE {issue.get('case')}: {issue.get('issue')}")
|
||||||
|
|
||||||
|
|
||||||
def main(argv: list[str] | None = None) -> int:
|
def main(argv: list[str] | None = None) -> int:
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument("--seed", type=int, default=3901, help="Base seed for deterministic simulations.")
|
parser.add_argument("--seed", type=int, default=3901, help="Base seed for deterministic simulations.")
|
||||||
|
parser.add_argument("--sweep-count", type=int, default=1, help="Run this many seed-spaced simulations.")
|
||||||
|
parser.add_argument("--seed-step", type=int, default=101, help="Seed increment used by --sweep-count.")
|
||||||
parser.add_argument("--json", action="store_true", help="Print the full JSON report.")
|
parser.add_argument("--json", action="store_true", help="Print the full JSON report.")
|
||||||
parser.add_argument("--include-prompts", action="store_true", help="Include raw and formatted prompt text in the report.")
|
parser.add_argument("--include-prompts", action="store_true", help="Include raw and formatted prompt text in the report.")
|
||||||
parser.add_argument("--fail-on-issues", action="store_true", help="Exit with code 1 when any issue is reported.")
|
parser.add_argument("--fail-on-issues", action="store_true", help="Exit with code 1 when any issue is reported.")
|
||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
|
|
||||||
report = run_simulation(seed=args.seed, include_prompts=args.include_prompts)
|
if args.sweep_count > 1:
|
||||||
|
report = run_simulation_sweep(
|
||||||
|
seed=args.seed,
|
||||||
|
count=args.sweep_count,
|
||||||
|
seed_step=args.seed_step,
|
||||||
|
include_prompts=args.include_prompts,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
report = run_simulation(seed=args.seed, include_prompts=args.include_prompts)
|
||||||
if args.json:
|
if args.json:
|
||||||
print(json.dumps(report, ensure_ascii=True, indent=2, sort_keys=True))
|
print(json.dumps(report, ensure_ascii=True, indent=2, sort_keys=True))
|
||||||
|
elif args.sweep_count > 1:
|
||||||
|
_print_sweep_report(report)
|
||||||
else:
|
else:
|
||||||
_print_text_report(report)
|
_print_text_report(report)
|
||||||
return 1 if args.fail_on_issues and report.get("issues") else 0
|
return 1 if args.fail_on_issues and report.get("issues") else 0
|
||||||
|
|||||||
@@ -8025,6 +8025,12 @@ def smoke_prompt_route_simulation_policy() -> None:
|
|||||||
pair_seed_checks["pair_seed.pose_reroll"].get("changed") is True,
|
pair_seed_checks["pair_seed.pose_reroll"].get("changed") is True,
|
||||||
"Pair pose reroll should prove hard action can reroll while soft/cast/scene axes stay locked",
|
"Pair pose reroll should prove hard action can reroll while soft/cast/scene axes stay locked",
|
||||||
)
|
)
|
||||||
|
sweep = prompt_route_simulation.run_simulation_sweep(seed=3901, count=3, seed_step=101, include_prompts=False)
|
||||||
|
sweep_summary = sweep.get("summary") 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("issues") == 0, f"Prompt route simulation sweep reported issues: {sweep.get('issues')}")
|
||||||
|
|
||||||
|
|
||||||
def smoke_node_camera_registration() -> None:
|
def smoke_node_camera_registration() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user