agentevolve-optimizer 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (414) hide show
  1. agent_evolve/__init__.py +722 -0
  2. agent_evolve/agentic.py +2800 -0
  3. agent_evolve/api.py +767 -0
  4. agent_evolve/application/__init__.py +1580 -0
  5. agent_evolve/application/action_allocation.py +744 -0
  6. agent_evolve/application/action_allocation_frame.py +347 -0
  7. agent_evolve/application/action_allocation_frame_commit.py +185 -0
  8. agent_evolve/application/action_allocation_frame_commit_v3.py +184 -0
  9. agent_evolve/application/action_allocation_frame_v3.py +338 -0
  10. agent_evolve/application/action_archive_value.py +497 -0
  11. agent_evolve/application/action_evidence_consistency.py +455 -0
  12. agent_evolve/application/action_forecast_partitioning.py +1471 -0
  13. agent_evolve/application/action_metric_projection.py +211 -0
  14. agent_evolve/application/action_role_value.py +680 -0
  15. agent_evolve/application/action_score_authorities.py +363 -0
  16. agent_evolve/application/action_structural_signature.py +116 -0
  17. agent_evolve/application/action_target_realization.py +402 -0
  18. agent_evolve/application/agentic_evolution.py +7734 -0
  19. agent_evolve/application/agentic_portfolio_residual_expert.py +835 -0
  20. agent_evolve/application/anchor_residual_identification.py +463 -0
  21. agent_evolve/application/archive_conditioned_action_target.py +208 -0
  22. agent_evolve/application/artifact_journal.py +246 -0
  23. agent_evolve/application/artifact_replay.py +347 -0
  24. agent_evolve/application/budgeted_optimizer.py +1828 -0
  25. agent_evolve/application/calibrated_campaign.py +485 -0
  26. agent_evolve/application/calibrated_current_prefix_forecast_opportunity.py +322 -0
  27. agent_evolve/application/calibrated_positive_gain_opportunity.py +1581 -0
  28. agent_evolve/application/campaign_capacity_recourse.py +254 -0
  29. agent_evolve/application/campaign_contextual_outcomes.py +119 -0
  30. agent_evolve/application/campaign_diagnostic_blocks.py +930 -0
  31. agent_evolve/application/campaign_evidence_registry.py +262 -0
  32. agent_evolve/application/campaign_execution.py +2537 -0
  33. agent_evolve/application/campaign_generation_audit.py +942 -0
  34. agent_evolve/application/campaign_learning.py +1812 -0
  35. agent_evolve/application/campaign_learning_runtime.py +1977 -0
  36. agent_evolve/application/campaign_search_phase.py +227 -0
  37. agent_evolve/application/campaign_selector_context_extension.py +220 -0
  38. agent_evolve/application/campaign_variation_envelope.py +649 -0
  39. agent_evolve/application/campaign_variation_trace.py +451 -0
  40. agent_evolve/application/candidate_archive_consequence.py +128 -0
  41. agent_evolve/application/causal_opportunity_portfolio_gate.py +385 -0
  42. agent_evolve/application/composite_outcome_updater.py +145 -0
  43. agent_evolve/application/composition_portfolio_selection.py +363 -0
  44. agent_evolve/application/concurrent_stage.py +144 -0
  45. agent_evolve/application/contextual_action_allocation.py +181 -0
  46. agent_evolve/application/contextual_campaign_outcomes.py +267 -0
  47. agent_evolve/application/contextual_campaign_planning.py +1366 -0
  48. agent_evolve/application/contextual_delayed_credit.py +651 -0
  49. agent_evolve/application/contextual_search_controller.py +2374 -0
  50. agent_evolve/application/current_prefix_forecast_opportunity.py +714 -0
  51. agent_evolve/application/decision_metric_projection.py +112 -0
  52. agent_evolve/application/derived_action_semantics.py +129 -0
  53. agent_evolve/application/detailed_evaluation.py +449 -0
  54. agent_evolve/application/earned_lineage.py +1011 -0
  55. agent_evolve/application/effective_choice_audit.py +484 -0
  56. agent_evolve/application/empirical_consequence_calibration.py +908 -0
  57. agent_evolve/application/evaluation_accounting.py +325 -0
  58. agent_evolve/application/evaluation_cache.py +199 -0
  59. agent_evolve/application/evaluation_escrow.py +547 -0
  60. agent_evolve/application/evaluation_recourse.py +253 -0
  61. agent_evolve/application/event_recorder.py +151 -0
  62. agent_evolve/application/evolution_campaign.py +1840 -0
  63. agent_evolve/application/executable_hypothesis.py +323 -0
  64. agent_evolve/application/factorial_branch_pilot.py +772 -0
  65. agent_evolve/application/finite_acquisition_capacity_recourse.py +672 -0
  66. agent_evolve/application/finite_acquisition_residual_expert.py +373 -0
  67. agent_evolve/application/finite_acquisition_variation_envelope.py +802 -0
  68. agent_evolve/application/finite_action_hypothesis_semantics.py +446 -0
  69. agent_evolve/application/finite_action_selection.py +188 -0
  70. agent_evolve/application/finite_action_set.py +306 -0
  71. agent_evolve/application/finite_action_transition.py +537 -0
  72. agent_evolve/application/finite_variation_eligibility.py +296 -0
  73. agent_evolve/application/forecast_geometry_portfolio.py +799 -0
  74. agent_evolve/application/forecast_opportunity_shadow_calibration.py +316 -0
  75. agent_evolve/application/front_proximity_admission.py +311 -0
  76. agent_evolve/application/front_proximity_parent_basis.py +458 -0
  77. agent_evolve/application/frozen_hurdle_score.py +659 -0
  78. agent_evolve/application/g3_causal_screen.py +2257 -0
  79. agent_evolve/application/g3_causal_validation.py +1046 -0
  80. agent_evolve/application/g3_postseal_curation.py +818 -0
  81. agent_evolve/application/gated_agentic_generator.py +205 -0
  82. agent_evolve/application/generation_feedback.py +293 -0
  83. agent_evolve/application/generative_proposal_journal.py +185 -0
  84. agent_evolve/application/geometry_conditional_elasticity.py +453 -0
  85. agent_evolve/application/global_wave_action_allocation.py +1151 -0
  86. agent_evolve/application/head_mass_conditional_seat.py +268 -0
  87. agent_evolve/application/identifiable_reflection_evidence.py +1147 -0
  88. agent_evolve/application/identifiable_reflection_learning.py +395 -0
  89. agent_evolve/application/identifiable_reflection_request.py +364 -0
  90. agent_evolve/application/in_memory_residual_archive.py +341 -0
  91. agent_evolve/application/insight_memory.py +1804 -0
  92. agent_evolve/application/live_runtime_manifest.py +758 -0
  93. agent_evolve/application/llm_task_queue.py +769 -0
  94. agent_evolve/application/matched_finite_action_block.py +409 -0
  95. agent_evolve/application/materialized_action_broker.py +2328 -0
  96. agent_evolve/application/materialized_action_constraints.py +83 -0
  97. agent_evolve/application/materialized_variation.py +211 -0
  98. agent_evolve/application/multi_option_evolution.py +1536 -0
  99. agent_evolve/application/outcome_adaptive_action_racing.py +2827 -0
  100. agent_evolve/application/outcome_adaptive_residual_campaign_runtime.py +580 -0
  101. agent_evolve/application/outcome_adaptive_residual_portfolio_evolution.py +3671 -0
  102. agent_evolve/application/outcome_conditioned_portfolio_selection.py +1374 -0
  103. agent_evolve/application/outcome_relation.py +193 -0
  104. agent_evolve/application/paired_allocation_comparison.py +241 -0
  105. agent_evolve/application/paired_block_schedule.py +127 -0
  106. agent_evolve/application/parent_measurement.py +226 -0
  107. agent_evolve/application/pareto_archive.py +811 -0
  108. agent_evolve/application/portfolio_campaign_runtime.py +4739 -0
  109. agent_evolve/application/portfolio_evolution.py +2950 -0
  110. agent_evolve/application/portfolio_hypothesis_observations.py +814 -0
  111. agent_evolve/application/portfolio_memory_attribution.py +581 -0
  112. agent_evolve/application/portfolio_memory_dose.py +788 -0
  113. agent_evolve/application/portfolio_memory_matched_control.py +938 -0
  114. agent_evolve/application/portfolio_memory_transfer.py +297 -0
  115. agent_evolve/application/portfolio_optimization_memory.py +363 -0
  116. agent_evolve/application/portfolio_outcome_feedback.py +1613 -0
  117. agent_evolve/application/portfolio_projection.py +335 -0
  118. agent_evolve/application/portfolio_recombination.py +2032 -0
  119. agent_evolve/application/post_evolution_reflection.py +834 -0
  120. agent_evolve/application/postcommit_rank_authority.py +245 -0
  121. agent_evolve/application/precommitted_portfolio_racing.py +2762 -0
  122. agent_evolve/application/prequential_archive_opportunity_calibration.py +1154 -0
  123. agent_evolve/application/prequential_residual_exploration.py +343 -0
  124. agent_evolve/application/prequential_score_portfolio.py +954 -0
  125. agent_evolve/application/projections.py +292 -0
  126. agent_evolve/application/protected_action_committee.py +1027 -0
  127. agent_evolve/application/protected_branch_pilot.py +376 -0
  128. agent_evolve/application/protected_current_prefix_forecast_opportunity.py +552 -0
  129. agent_evolve/application/provider_replay.py +910 -0
  130. agent_evolve/application/rank_balanced_causal_pilot.py +1372 -0
  131. agent_evolve/application/recombination_residual_expert.py +403 -0
  132. agent_evolve/application/reflection_workflow.py +571 -0
  133. agent_evolve/application/region_conditional_credit.py +911 -0
  134. agent_evolve/application/residual_campaign_runtime.py +531 -0
  135. agent_evolve/application/residual_headroom_campaign_runtime.py +459 -0
  136. agent_evolve/application/residual_headroom_ledger.py +1544 -0
  137. agent_evolve/application/residual_learning_transaction.py +396 -0
  138. agent_evolve/application/residual_portfolio_evolution.py +1228 -0
  139. agent_evolve/application/residual_reachability.py +749 -0
  140. agent_evolve/application/residual_stage_credit.py +499 -0
  141. agent_evolve/application/same_prefix_paired_audit.py +1580 -0
  142. agent_evolve/application/semantic_coverage_score_portfolio.py +838 -0
  143. agent_evolve/application/sequential_lineage_allocation.py +1017 -0
  144. agent_evolve/application/sequential_market_replay.py +1395 -0
  145. agent_evolve/application/sequential_residual_campaign_runtime.py +305 -0
  146. agent_evolve/application/sequential_residual_portfolio_evolution.py +940 -0
  147. agent_evolve/application/single_score_action_allocation.py +299 -0
  148. agent_evolve/application/source_exposure_allocation.py +906 -0
  149. agent_evolve/application/staged_memory.py +210 -0
  150. agent_evolve/application/stratified_cold_start_allocation.py +732 -0
  151. agent_evolve/application/support_guarded_hurdle_score.py +549 -0
  152. agent_evolve/application/target_conditioned_action_forecast.py +595 -0
  153. agent_evolve/application/target_conditioned_campaign.py +566 -0
  154. agent_evolve/application/treatment_assignment.py +201 -0
  155. agent_evolve/application/trusted_objective_evidence.py +217 -0
  156. agent_evolve/application/two_stage_action_evolution.py +1131 -0
  157. agent_evolve/application/v8lite_allocation_policy.py +1083 -0
  158. agent_evolve/application/v9_candidate_policy.py +1303 -0
  159. agent_evolve/bootstrap.py +108 -0
  160. agent_evolve/campaign_presets.py +517 -0
  161. agent_evolve/campaign_profiles.py +452 -0
  162. agent_evolve/campaign_variation_topology.py +288 -0
  163. agent_evolve/campaign_workload.py +950 -0
  164. agent_evolve/cli.py +797 -0
  165. agent_evolve/contract.py +241 -0
  166. agent_evolve/core/__init__.py +91 -0
  167. agent_evolve/core/action_semantics.py +411 -0
  168. agent_evolve/core/authored.py +105 -0
  169. agent_evolve/core/formatting.py +286 -0
  170. agent_evolve/core/optimization_semantics.py +324 -0
  171. agent_evolve/core/problem.py +167 -0
  172. agent_evolve/core/results.py +323 -0
  173. agent_evolve/core/stats.py +70 -0
  174. agent_evolve/core/telemetry.py +100 -0
  175. agent_evolve/domain/__init__.py +89 -0
  176. agent_evolve/domain/artifact.py +162 -0
  177. agent_evolve/domain/durable_text.py +68 -0
  178. agent_evolve/domain/event.py +1454 -0
  179. agent_evolve/domain/finite_action_set.py +426 -0
  180. agent_evolve/domain/finite_variation.py +526 -0
  181. agent_evolve/domain/generative_emission.py +559 -0
  182. agent_evolve/domain/ids.py +163 -0
  183. agent_evolve/domain/inline_text.py +106 -0
  184. agent_evolve/domain/insight.py +27 -0
  185. agent_evolve/domain/lineage.py +737 -0
  186. agent_evolve/domain/llm_task_queue.py +960 -0
  187. agent_evolve/domain/outcome.py +96 -0
  188. agent_evolve/domain/patch.py +854 -0
  189. agent_evolve/domain/typed_json.py +542 -0
  190. agent_evolve/domain/variation_space.py +158 -0
  191. agent_evolve/driver.py +1014 -0
  192. agent_evolve/harness/__init__.py +29 -0
  193. agent_evolve/harness/base.py +242 -0
  194. agent_evolve/harness/directives.py +163 -0
  195. agent_evolve/harness/generative_seal.py +479 -0
  196. agent_evolve/harness/registry.py +41 -0
  197. agent_evolve/infrastructure/__init__.py +39 -0
  198. agent_evolve/infrastructure/artifacts/__init__.py +6 -0
  199. agent_evolve/infrastructure/artifacts/_verification.py +67 -0
  200. agent_evolve/infrastructure/artifacts/filesystem.py +343 -0
  201. agent_evolve/infrastructure/artifacts/in_memory.py +73 -0
  202. agent_evolve/infrastructure/asyncio_runtime.py +109 -0
  203. agent_evolve/infrastructure/authored_runtime.py +188 -0
  204. agent_evolve/infrastructure/authored_worker.py +171 -0
  205. agent_evolve/infrastructure/clock.py +53 -0
  206. agent_evolve/infrastructure/events/__init__.py +6 -0
  207. agent_evolve/infrastructure/events/_validation.py +89 -0
  208. agent_evolve/infrastructure/events/in_memory.py +56 -0
  209. agent_evolve/infrastructure/events/jsonl.py +193 -0
  210. agent_evolve/infrastructure/exception_provenance.py +215 -0
  211. agent_evolve/infrastructure/ids.py +118 -0
  212. agent_evolve/infrastructure/lineage_codec.py +1836 -0
  213. agent_evolve/infrastructure/outcome_adaptive_phase_journal.py +170 -0
  214. agent_evolve/infrastructure/residual_headroom_journal.py +221 -0
  215. agent_evolve/infrastructure/resource_lease.py +370 -0
  216. agent_evolve/infrastructure/sanitization/__init__.py +8 -0
  217. agent_evolve/infrastructure/sanitization/strict_json.py +484 -0
  218. agent_evolve/infrastructure/sequential_phase_journal.py +170 -0
  219. agent_evolve/infrastructure/stream_liveness.py +383 -0
  220. agent_evolve/infrastructure/subprocess_boundary.py +136 -0
  221. agent_evolve/integrations/__init__.py +1 -0
  222. agent_evolve/integrations/botorch/__init__.py +28 -0
  223. agent_evolve/integrations/botorch/finite_qlognehvi.py +190 -0
  224. agent_evolve/integrations/botorch/finite_qlognehvi_batch.py +155 -0
  225. agent_evolve/integrations/botorch/finite_qlognehvi_batch_identity.py +20 -0
  226. agent_evolve/integrations/botorch/finite_qlognehvi_batch_worker.py +55 -0
  227. agent_evolve/integrations/botorch/finite_qlognehvi_identity.py +22 -0
  228. agent_evolve/integrations/botorch/finite_qlognehvi_worker.py +55 -0
  229. agent_evolve/integrations/botorch/subprocess_qlognehvi.py +261 -0
  230. agent_evolve/integrations/botorch/subprocess_qlognehvi_batch.py +273 -0
  231. agent_evolve/integrations/completion.py +242 -0
  232. agent_evolve/integrations/pydantic_ai/__init__.py +441 -0
  233. agent_evolve/integrations/pydantic_ai/action_forecast.py +1068 -0
  234. agent_evolve/integrations/pydantic_ai/agentic_generator.py +2308 -0
  235. agent_evolve/integrations/pydantic_ai/async_generator.py +1604 -0
  236. agent_evolve/integrations/pydantic_ai/boundary_codec.py +1526 -0
  237. agent_evolve/integrations/pydantic_ai/calibrated_portfolio_campaign.py +756 -0
  238. agent_evolve/integrations/pydantic_ai/calibrated_portfolio_selection.py +7537 -0
  239. agent_evolve/integrations/pydantic_ai/campaign_acquisition.py +609 -0
  240. agent_evolve/integrations/pydantic_ai/execution_binding.py +138 -0
  241. agent_evolve/integrations/pydantic_ai/forecast_geometry_action_committee.py +217 -0
  242. agent_evolve/integrations/pydantic_ai/harness.py +159 -0
  243. agent_evolve/integrations/pydantic_ai/heterogeneous_model_execution.py +306 -0
  244. agent_evolve/integrations/pydantic_ai/hierarchical_residual_adaptive_semantic_view.py +179 -0
  245. agent_evolve/integrations/pydantic_ai/json_schema_dialect.py +108 -0
  246. agent_evolve/integrations/pydantic_ai/materialized_hierarchical_residual_expert.py +952 -0
  247. agent_evolve/integrations/pydantic_ai/materialized_portfolio_judge.py +520 -0
  248. agent_evolve/integrations/pydantic_ai/model_execution_profile.py +659 -0
  249. agent_evolve/integrations/pydantic_ai/outbound_request_manifest.py +1170 -0
  250. agent_evolve/integrations/pydantic_ai/portable_residual_consequence_features.py +575 -0
  251. agent_evolve/integrations/pydantic_ai/portfolio_selection.py +422 -0
  252. agent_evolve/integrations/pydantic_ai/progress_aware_openrouter.py +416 -0
  253. agent_evolve/integrations/pydantic_ai/provider_attempt_join.py +1523 -0
  254. agent_evolve/integrations/pydantic_ai/provider_free_calibrated_runner.py +607 -0
  255. agent_evolve/integrations/pydantic_ai/queued_runner.py +2634 -0
  256. agent_evolve/integrations/pydantic_ai/reconciled_residual_reachability.py +1417 -0
  257. agent_evolve/integrations/pydantic_ai/residual_forecast_geometry.py +445 -0
  258. agent_evolve/integrations/pydantic_ai/residual_reachability.py +674 -0
  259. agent_evolve/integrations/pydantic_ai/residual_semantic_cells.py +239 -0
  260. agent_evolve/integrations/pydantic_ai/sealed_output_replay.py +1068 -0
  261. agent_evolve/integrations/pydantic_ai/semantic_coverage_residual_portfolio.py +770 -0
  262. agent_evolve/integrations/pydantic_ai/semantic_decision_replay.py +383 -0
  263. agent_evolve/integrations/pydantic_ai/support_adaptive_residual_portfolio.py +135 -0
  264. agent_evolve/integrations/pydantic_ai/trusted_residual_prompt_context.py +143 -0
  265. agent_evolve/integrations/pydantic_ai/validated_openrouter_model.py +107 -0
  266. agent_evolve/integrations/pymoo_adapter.py +242 -0
  267. agent_evolve/policies/__init__.py +17 -0
  268. agent_evolve/policies/check.py +469 -0
  269. agent_evolve/policies/emit_scaffold.py +451 -0
  270. agent_evolve/policies/feedback/__init__.py +37 -0
  271. agent_evolve/policies/feedback/held_out_asn.py +1325 -0
  272. agent_evolve/policies/genetic.py +607 -0
  273. agent_evolve/policies/llm_backoff.py +183 -0
  274. agent_evolve/policies/llm_chooser.py +226 -0
  275. agent_evolve/policies/llm_generator.py +1760 -0
  276. agent_evolve/policies/llm_init.py +267 -0
  277. agent_evolve/policies/llm_operator.py +109 -0
  278. agent_evolve/policies/llm_prior.py +194 -0
  279. agent_evolve/policies/llm_surrogate.py +334 -0
  280. agent_evolve/policies/measurement_evidence.py +704 -0
  281. agent_evolve/policies/memory/__init__.py +223 -0
  282. agent_evolve/policies/memory/balanced_subset_blocks.py +707 -0
  283. agent_evolve/policies/memory/compatibility_matching.py +593 -0
  284. agent_evolve/policies/memory/global_falsification.py +1841 -0
  285. agent_evolve/policies/memory/prompt_shape.py +503 -0
  286. agent_evolve/policies/memory/randomized_subset.py +714 -0
  287. agent_evolve/policies/memory/staged_causal.py +1270 -0
  288. agent_evolve/policies/memory/treatment_compliance.py +759 -0
  289. agent_evolve/policies/objective_resolution/__init__.py +17 -0
  290. agent_evolve/policies/objective_resolution/fixed_grid.py +364 -0
  291. agent_evolve/policies/operator_portfolio.py +407 -0
  292. agent_evolve/policies/reguidance.py +1133 -0
  293. agent_evolve/policies/reward/__init__.py +83 -0
  294. agent_evolve/policies/reward/affine_candidate_consequence.py +156 -0
  295. agent_evolve/policies/reward/affine_candidate_consequence_3d.py +159 -0
  296. agent_evolve/policies/reward/affine_hypervolume.py +490 -0
  297. agent_evolve/policies/reward/affine_hypervolume_3d.py +567 -0
  298. agent_evolve/policies/reward/contextual_marginal_utility.py +318 -0
  299. agent_evolve/policies/reward/frozen_archive.py +360 -0
  300. agent_evolve/policies/reward/frozen_wave_archive.py +368 -0
  301. agent_evolve/policies/search_state.py +208 -0
  302. agent_evolve/policies/selection/__init__.py +345 -0
  303. agent_evolve/policies/selection/acquisition_certified_slate.py +684 -0
  304. agent_evolve/policies/selection/affine_frontier_context.py +330 -0
  305. agent_evolve/policies/selection/affine_frontier_target.py +473 -0
  306. agent_evolve/policies/selection/archive_elite.py +1346 -0
  307. agent_evolve/policies/selection/calibrated_portfolio_binding.py +640 -0
  308. agent_evolve/policies/selection/calibrated_slate.py +1394 -0
  309. agent_evolve/policies/selection/calibrated_slate_codec.py +579 -0
  310. agent_evolve/policies/selection/common_candidate_pool.py +685 -0
  311. agent_evolve/policies/selection/diagnostic_sampling.py +319 -0
  312. agent_evolve/policies/selection/disjoint_pairs.py +479 -0
  313. agent_evolve/policies/selection/elite_explorer.py +719 -0
  314. agent_evolve/policies/selection/finite_action.py +187 -0
  315. agent_evolve/policies/selection/finite_option_prompt_projection.py +377 -0
  316. agent_evolve/policies/selection/finite_palette_evidence.py +247 -0
  317. agent_evolve/policies/selection/forecast_calibration.py +922 -0
  318. agent_evolve/policies/selection/frontier_probe_slate.py +814 -0
  319. agent_evolve/policies/selection/frozen_archive_pairs.py +762 -0
  320. agent_evolve/policies/selection/full_support_slate.py +91 -0
  321. agent_evolve/policies/selection/meaningful_direction.py +240 -0
  322. agent_evolve/policies/selection/memory_dose_feasibility.py +259 -0
  323. agent_evolve/policies/selection/model_anchored_slate.py +826 -0
  324. agent_evolve/policies/selection/phenotype_recourse.py +979 -0
  325. agent_evolve/policies/selection/proposal_support.py +368 -0
  326. agent_evolve/policies/selection/random_portfolio.py +254 -0
  327. agent_evolve/policies/selection/regret_bounded_slate.py +1084 -0
  328. agent_evolve/policies/selection/residual_frontier.py +463 -0
  329. agent_evolve/policies/selection/residual_frontier_target.py +605 -0
  330. agent_evolve/policies/selection/structural_posterior_slate.py +1571 -0
  331. agent_evolve/policies/selection/target_conditioned_allocator.py +648 -0
  332. agent_evolve/policies/selection/target_conditioned_features.py +812 -0
  333. agent_evolve/policies/selection/target_conditioned_prequential.py +1527 -0
  334. agent_evolve/policies/selection/task_keyed_palette.py +906 -0
  335. agent_evolve/policies/semantics.py +147 -0
  336. agent_evolve/policies/structure.py +362 -0
  337. agent_evolve/policies/structured_output_budget.py +62 -0
  338. agent_evolve/policies/surrogate.py +696 -0
  339. agent_evolve/policies/variation/__init__.py +1 -0
  340. agent_evolve/policies/variation/compositional_finite_catalog.py +426 -0
  341. agent_evolve/policies/variation/crossover_inheritance.py +575 -0
  342. agent_evolve/policies/variation/disjoint_recombination.py +611 -0
  343. agent_evolve/policies/variation/exact_composition_capacity.py +214 -0
  344. agent_evolve/policies/variation/exact_parent_crossover.py +950 -0
  345. agent_evolve/policies/variation/multiscale_restart_catalog.py +372 -0
  346. agent_evolve/policies/variation/source_union_finite_catalog.py +403 -0
  347. agent_evolve/policies/variation/typed_patch.py +1981 -0
  348. agent_evolve/policies/weighted_prior.py +394 -0
  349. agent_evolve/ports/__init__.py +383 -0
  350. agent_evolve/ports/action_allocation.py +733 -0
  351. agent_evolve/ports/action_allocation_frame.py +1153 -0
  352. agent_evolve/ports/action_allocation_frame_commit.py +294 -0
  353. agent_evolve/ports/action_allocation_frame_commit_v3.py +432 -0
  354. agent_evolve/ports/action_allocation_frame_v3.py +995 -0
  355. agent_evolve/ports/action_forecast.py +1568 -0
  356. agent_evolve/ports/action_metric_projection.py +165 -0
  357. agent_evolve/ports/agentic_generator.py +1561 -0
  358. agent_evolve/ports/archive_context.py +136 -0
  359. agent_evolve/ports/artifact_sanitizer.py +44 -0
  360. agent_evolve/ports/artifact_store.py +225 -0
  361. agent_evolve/ports/clock.py +13 -0
  362. agent_evolve/ports/contextual_search_allocation.py +827 -0
  363. agent_evolve/ports/decision_metric_projection.py +258 -0
  364. agent_evolve/ports/event_store.py +55 -0
  365. agent_evolve/ports/executable_hypothesis.py +557 -0
  366. agent_evolve/ports/finite_acquisition.py +377 -0
  367. agent_evolve/ports/finite_acquisition_batch.py +296 -0
  368. agent_evolve/ports/finite_acquisition_batch_json.py +164 -0
  369. agent_evolve/ports/finite_acquisition_json.py +247 -0
  370. agent_evolve/ports/finite_acquisition_space.py +168 -0
  371. agent_evolve/ports/finite_action_selection.py +348 -0
  372. agent_evolve/ports/finite_action_set.py +256 -0
  373. agent_evolve/ports/frontier_target.py +396 -0
  374. agent_evolve/ports/generation_failure.py +43 -0
  375. agent_evolve/ports/hard_feasibility.py +233 -0
  376. agent_evolve/ports/id_factory.py +34 -0
  377. agent_evolve/ports/llm_task_queue.py +93 -0
  378. agent_evolve/ports/objective_resolution.py +419 -0
  379. agent_evolve/ports/paired_allocation_comparison.py +401 -0
  380. agent_evolve/ports/paired_block_schedule.py +475 -0
  381. agent_evolve/ports/parent_measurement.py +336 -0
  382. agent_evolve/ports/portfolio_memory_dose.py +643 -0
  383. agent_evolve/ports/portfolio_selection.py +3169 -0
  384. agent_evolve/ports/postcommit_rank_authority.py +467 -0
  385. agent_evolve/ports/presented_action_evidence.py +794 -0
  386. agent_evolve/ports/resource_lease.py +162 -0
  387. agent_evolve/ports/structured_generator.py +734 -0
  388. agent_evolve/ports/structured_output_budget.py +120 -0
  389. agent_evolve/ports/subprocess_boundary.py +138 -0
  390. agent_evolve/ports/treatment_assignment.py +466 -0
  391. agent_evolve/ports/variation_catalog.py +76 -0
  392. agent_evolve/ports/variation_source.py +226 -0
  393. agent_evolve/proposal_mode.py +157 -0
  394. agent_evolve/proposers/__init__.py +10 -0
  395. agent_evolve/proposers/random_proposer.py +188 -0
  396. agent_evolve/provider_accounting.py +163 -0
  397. agent_evolve/py.typed +0 -0
  398. agent_evolve/reference_method.py +1570 -0
  399. agent_evolve/session/__init__.py +11 -0
  400. agent_evolve/session/authorship.py +864 -0
  401. agent_evolve/session/evaluate.py +236 -0
  402. agent_evolve/session/fidelity.py +237 -0
  403. agent_evolve/session/genetic_loop.py +742 -0
  404. agent_evolve/session/loop.py +803 -0
  405. agent_evolve/session/screening.py +671 -0
  406. agent_evolve/settings.py +376 -0
  407. agent_evolve/workload_kit.py +368 -0
  408. agent_evolve/workload_prompt.py +398 -0
  409. agentevolve_optimizer-0.5.0.dist-info/METADATA +599 -0
  410. agentevolve_optimizer-0.5.0.dist-info/RECORD +414 -0
  411. agentevolve_optimizer-0.5.0.dist-info/WHEEL +5 -0
  412. agentevolve_optimizer-0.5.0.dist-info/entry_points.txt +2 -0
  413. agentevolve_optimizer-0.5.0.dist-info/licenses/LICENSE +21 -0
  414. agentevolve_optimizer-0.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2257 @@
1
+ """Generic three-generation causal-development screen for AgentEvolve.
2
+
3
+ This module owns no benchmark semantics. A narrow boundary supplies frozen
4
+ parent-relative finite catalogs and authenticated hypothesis compilation. The
5
+ planner composes existing causal-memory, strict-treatment, deterministic
6
+ materialization, recombination, and budgeted-optimizer mechanisms into the
7
+ preregistered G1/G2/G3 screen.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import hashlib
13
+ import json
14
+ import math
15
+ import re
16
+ from dataclasses import dataclass, field, replace
17
+ from typing import Protocol, runtime_checkable
18
+
19
+ from agent_evolve.application.agentic_evolution import (
20
+ AgenticEvolutionEngine,
21
+ EvolutionCandidate,
22
+ InsightAssignmentKind,
23
+ InvocationPlan,
24
+ InvocationOutcome,
25
+ MaterializedInvocation,
26
+ MutationContract,
27
+ MutationResponseMode,
28
+ OperatorKind,
29
+ ProposalAuthority,
30
+ RewardPolicyBinding,
31
+ )
32
+ from agent_evolve.application.budgeted_optimizer import (
33
+ FrozenWaveReward,
34
+ GenerationPlan,
35
+ GenerationReceipt,
36
+ OptimizerBudget,
37
+ OptimizerSlot,
38
+ OptimizerState,
39
+ )
40
+ from agent_evolve.application.executable_hypothesis import (
41
+ CompiledHypothesisTreatment,
42
+ )
43
+ from agent_evolve.application.insight_memory import (
44
+ InsightLifecycleState,
45
+ InsightMemoryBank,
46
+ InsightMemoryEntry,
47
+ context_stratum_hash,
48
+ )
49
+ from agent_evolve.application.materialized_variation import (
50
+ materialized_disjoint_invocation,
51
+ )
52
+ from agent_evolve.application.staged_memory import (
53
+ DiagnosticMemoryCheckpointService,
54
+ )
55
+ from agent_evolve.domain.finite_variation import (
56
+ FiniteVariationContract,
57
+ validate_finite_variation_contract,
58
+ )
59
+ from agent_evolve.domain.ids import CandidateId
60
+ from agent_evolve.domain.insight import InsightRef
61
+ from agent_evolve.domain.patch import (
62
+ ArrayIndex,
63
+ JsonPath,
64
+ ObjectKey,
65
+ canonical_path_bytes,
66
+ require_sha256,
67
+ )
68
+ from agent_evolve.domain.typed_json import (
69
+ FrozenJsonValue,
70
+ freeze_json,
71
+ is_frozen_json_value,
72
+ thaw_json,
73
+ typed_json_equal,
74
+ typed_json_sha256,
75
+ )
76
+ from agent_evolve.policies.memory.prompt_shape import (
77
+ MatchedPromptStructureReceipt,
78
+ seal_matched_prompt_structure,
79
+ )
80
+ from agent_evolve.policies.memory.staged_causal import (
81
+ CausalSearchScorePolicy,
82
+ DeterministicMemoryControlPolicy,
83
+ FrozenDiagnosticMemoryWave,
84
+ MemoryAssignmentArm,
85
+ MemoryCheckpointClosure,
86
+ MemoryCheckpointClosureStatus,
87
+ ResolvedInsightAssignment,
88
+ WaveSealedCheckpointBuilder,
89
+ )
90
+ from agent_evolve.policies.memory.treatment_compliance import (
91
+ InsightTreatmentRequirement,
92
+ TreatmentActionBinding,
93
+ TreatmentAssignmentRole,
94
+ TreatmentClaimMode,
95
+ TreatmentInsightEvidence,
96
+ )
97
+ from agent_evolve.policies.variation.disjoint_recombination import (
98
+ DisjointPatchMaterialization,
99
+ DisjointPatchRecombiner,
100
+ )
101
+ from agent_evolve.policies.variation.typed_patch import derive_patch
102
+ from agent_evolve.ports.agentic_generator import (
103
+ MetricEffectDirection,
104
+ SourceAttribution,
105
+ CandidateDraft,
106
+ )
107
+ from agent_evolve.ports.executable_hypothesis import (
108
+ HypothesisCompilationReceipt,
109
+ HypothesisCompilationRequest,
110
+ validate_hypothesis_compilation,
111
+ )
112
+ from agent_evolve.ports.id_factory import IdFactory
113
+
114
+
115
+ G3_SCREEN_POLICY_ID = "g3_causal_development_screen"
116
+ G3_SCREEN_POLICY_VERSION = 1
117
+ G3_SCREEN_BUDGET = OptimizerBudget(
118
+ max_unique_evaluations=11,
119
+ max_logical_llm_calls=6,
120
+ max_generations=3,
121
+ )
122
+ G1_DIAGNOSTIC_SLOT_IDS = ("g1_diagnostic_0", "g1_diagnostic_1")
123
+ G2_SLOT_IDS = ("g2_adaptive", "g2_score_shuffled", "g2_sham", "g2_mate")
124
+ G3_SLOT_IDS = (
125
+ "g3_reproduction",
126
+ "g3_adaptive_union",
127
+ "g3_score_shuffled_union",
128
+ "g3_sham_union",
129
+ )
130
+
131
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
132
+ _CHOICE_DOMAIN = b"agent-evolve:g3-parent-bound-action-choice:v1\x00"
133
+ _PERMUTATION_DOMAIN = b"agent-evolve:g3-diagnostic-joint-permutation:v1\x00"
134
+ _OCCURRENCE_DOMAIN = b"agent-evolve:g3-seed-occurrence-binding:v1\x00"
135
+ _PROSPECTIVE_DOMAIN = b"agent-evolve:g3-prospective-endpoint-proof:v1\x00"
136
+
137
+
138
+ def _canonical_json(value: object) -> bytes:
139
+ return json.dumps(
140
+ value,
141
+ ensure_ascii=True,
142
+ allow_nan=False,
143
+ separators=(",", ":"),
144
+ sort_keys=True,
145
+ ).encode("ascii")
146
+
147
+
148
+ def _hash(domain: bytes, value: object) -> str:
149
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
150
+
151
+
152
+ def _path_text(path: JsonPath) -> str:
153
+ parts = ["$"]
154
+ for segment in path.segments:
155
+ if type(segment) is ObjectKey:
156
+ parts.append(f".{segment.value}")
157
+ elif type(segment) is ArrayIndex:
158
+ parts.append(f"[{segment.value}]")
159
+ else: # pragma: no cover - JsonPath closes the union.
160
+ raise AssertionError("unsupported path segment")
161
+ return "".join(parts)
162
+
163
+
164
+ @dataclass(frozen=True, slots=True)
165
+ class ParentBoundActionChoice:
166
+ """Outcome-blind exact option commitment made during preparation."""
167
+
168
+ role: str
169
+ catalog_id: str
170
+ parent_configuration_sha256: str
171
+ finite_contract_sha256: str
172
+ option_id: str
173
+ option_identity_sha256: str
174
+ selection_policy_id: str
175
+ selection_policy_version: int
176
+ selection_policy_definition_sha256: str
177
+ choice_sha256: str = field(init=False)
178
+
179
+ def __post_init__(self) -> None:
180
+ for name in ("role", "catalog_id", "selection_policy_id"):
181
+ value = getattr(self, name)
182
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
183
+ raise ValueError(f"{name} must use the canonical token grammar")
184
+ for name in (
185
+ "parent_configuration_sha256",
186
+ "finite_contract_sha256",
187
+ "option_identity_sha256",
188
+ "selection_policy_definition_sha256",
189
+ ):
190
+ require_sha256(getattr(self, name), name)
191
+ if type(self.option_id) is not str or not self.option_id:
192
+ raise ValueError("option_id must be canonical non-empty text")
193
+ if (
194
+ type(self.selection_policy_version) is not int
195
+ or self.selection_policy_version <= 0
196
+ ):
197
+ raise ValueError("selection_policy_version must be positive")
198
+ object.__setattr__(self, "choice_sha256", _hash(_CHOICE_DOMAIN, self.to_record()))
199
+
200
+ def to_record(self) -> dict[str, object]:
201
+ return {
202
+ "schema_version": 1,
203
+ "role": self.role,
204
+ "catalog_id": self.catalog_id,
205
+ "parent_configuration_sha256": self.parent_configuration_sha256,
206
+ "finite_contract_sha256": self.finite_contract_sha256,
207
+ "option_id": self.option_id,
208
+ "option_identity_sha256": self.option_identity_sha256,
209
+ "selection_policy_id": self.selection_policy_id,
210
+ "selection_policy_version": self.selection_policy_version,
211
+ "selection_policy_definition_sha256": (
212
+ self.selection_policy_definition_sha256
213
+ ),
214
+ }
215
+
216
+ @classmethod
217
+ def seal(
218
+ cls,
219
+ *,
220
+ role: str,
221
+ contract: FiniteVariationContract,
222
+ option_id: str,
223
+ selection_policy_id: str,
224
+ selection_policy_version: int,
225
+ selection_policy_definition_sha256: str,
226
+ ) -> "ParentBoundActionChoice":
227
+ validate_finite_variation_contract(contract)
228
+ option = contract.resolve(option_id)
229
+ return cls(
230
+ role=role,
231
+ catalog_id=contract.catalog_id,
232
+ parent_configuration_sha256=contract.parent_configuration_sha256,
233
+ finite_contract_sha256=contract.identity_sha256,
234
+ option_id=option.option_id,
235
+ option_identity_sha256=option.identity_sha256,
236
+ selection_policy_id=selection_policy_id,
237
+ selection_policy_version=selection_policy_version,
238
+ selection_policy_definition_sha256=selection_policy_definition_sha256,
239
+ )
240
+
241
+ def validate_contract(self, contract: FiniteVariationContract) -> None:
242
+ validate_finite_variation_contract(contract)
243
+ observed = (
244
+ contract.catalog_id,
245
+ contract.parent_configuration_sha256,
246
+ contract.identity_sha256,
247
+ )
248
+ expected = (
249
+ self.catalog_id,
250
+ self.parent_configuration_sha256,
251
+ self.finite_contract_sha256,
252
+ )
253
+ if observed != expected:
254
+ raise ValueError("parent-bound action choice differs from finite contract")
255
+ option = contract.resolve(self.option_id)
256
+ if option.identity_sha256 != self.option_identity_sha256:
257
+ raise ValueError("parent-bound action option identity changed")
258
+
259
+
260
+ @dataclass(frozen=True, slots=True)
261
+ class FrozenDiagnosticPermutation:
262
+ """Public randomization realization for the complete two-slot G1 block.
263
+
264
+ Randomness lives outside the planner. Preparation samples one integer
265
+ uniformly from ``[0, 2!)`` and records the sampler identity here; the
266
+ planner performs only the deterministic rank-to-joint-assignment mapping.
267
+ This is a joint receipt, not two independent probability annotations.
268
+ """
269
+
270
+ active_references: tuple[InsightRef, InsightRef]
271
+ permutation_rank: int
272
+ randomization_policy_id: str
273
+ randomization_policy_version: int
274
+ randomization_definition_sha256: str
275
+ receipt_sha256: str = field(init=False)
276
+
277
+ def __post_init__(self) -> None:
278
+ if (
279
+ type(self.active_references) is not tuple
280
+ or len(self.active_references) != 2
281
+ or self.active_references
282
+ != tuple(sorted(set(self.active_references)))
283
+ ):
284
+ raise ValueError(
285
+ "active_references must be two canonical exact references"
286
+ )
287
+ if type(self.permutation_rank) is not int or self.permutation_rank not in {
288
+ 0,
289
+ 1,
290
+ }:
291
+ raise ValueError("two-slot permutation_rank must be exactly 0 or 1")
292
+ if (
293
+ type(self.randomization_policy_id) is not str
294
+ or _TOKEN.fullmatch(self.randomization_policy_id) is None
295
+ ):
296
+ raise ValueError("randomization_policy_id must use the token grammar")
297
+ if (
298
+ type(self.randomization_policy_version) is not int
299
+ or self.randomization_policy_version <= 0
300
+ ):
301
+ raise ValueError("randomization_policy_version must be positive")
302
+ require_sha256(
303
+ self.randomization_definition_sha256,
304
+ "randomization_definition_sha256",
305
+ )
306
+ object.__setattr__(
307
+ self,
308
+ "receipt_sha256",
309
+ _hash(_PERMUTATION_DOMAIN, self.to_record()),
310
+ )
311
+
312
+ @property
313
+ def subset_ranks_by_slot(self) -> tuple[int, int]:
314
+ return (0, 1) if self.permutation_rank == 0 else (1, 0)
315
+
316
+ def to_record(self) -> dict[str, object]:
317
+ return {
318
+ "schema_version": 1,
319
+ "active_references": [
320
+ {
321
+ "insight_id": reference.insight_id.value,
322
+ "version": reference.version,
323
+ }
324
+ for reference in self.active_references
325
+ ],
326
+ "permutation_rank": self.permutation_rank,
327
+ "subset_ranks_by_slot": list(self.subset_ranks_by_slot),
328
+ "randomization_policy_id": self.randomization_policy_id,
329
+ "randomization_policy_version": self.randomization_policy_version,
330
+ "randomization_definition_sha256": (
331
+ self.randomization_definition_sha256
332
+ ),
333
+ }
334
+
335
+
336
+ @dataclass(frozen=True, slots=True)
337
+ class _ProspectiveEndpoint:
338
+ slot_id: str
339
+ reference: InsightRef | None
340
+ option_id: str
341
+ option_identity_sha256: str
342
+ configuration: FrozenJsonValue
343
+ configuration_sha256: str
344
+ phenotype_identity_sha256: str
345
+ changed_paths: tuple[str, ...]
346
+
347
+
348
+ @dataclass(frozen=True, slots=True)
349
+ class _ProspectiveUnion:
350
+ slot_id: str
351
+ configuration: FrozenJsonValue
352
+ configuration_sha256: str
353
+ phenotype_identity_sha256: str
354
+ prospective_receipt_sha256: str
355
+
356
+
357
+ @dataclass(frozen=True, slots=True)
358
+ class G3ExpectedEndpoint:
359
+ """Public immutable authority for one prospectively frozen G1/G2 endpoint."""
360
+
361
+ slot_id: str
362
+ reference: InsightRef | None
363
+ option_id: str
364
+ option_identity_sha256: str
365
+ configuration: FrozenJsonValue
366
+ configuration_sha256: str
367
+ phenotype_identity_sha256: str
368
+ changed_paths: tuple[str, ...]
369
+
370
+ def __post_init__(self) -> None:
371
+ if type(self.slot_id) is not str or not self.slot_id:
372
+ raise ValueError("endpoint slot_id must be non-empty exact text")
373
+ if self.reference is not None:
374
+ if type(self.reference) is not InsightRef:
375
+ raise TypeError("endpoint reference must be an exact InsightRef")
376
+ InsightRef.__post_init__(self.reference)
377
+ if type(self.option_id) is not str or not self.option_id:
378
+ raise ValueError("endpoint option_id must be non-empty exact text")
379
+ require_sha256(
380
+ self.option_identity_sha256,
381
+ "option_identity_sha256",
382
+ )
383
+ if not is_frozen_json_value(self.configuration):
384
+ raise TypeError("endpoint configuration must be frozen typed JSON")
385
+ require_sha256(self.configuration_sha256, "configuration_sha256")
386
+ if typed_json_sha256(self.configuration) != self.configuration_sha256:
387
+ raise ValueError("endpoint configuration hash does not authenticate value")
388
+ require_sha256(
389
+ self.phenotype_identity_sha256,
390
+ "phenotype_identity_sha256",
391
+ )
392
+ if (
393
+ type(self.changed_paths) is not tuple
394
+ or any(type(value) is not str or not value for value in self.changed_paths)
395
+ or self.changed_paths != tuple(sorted(set(self.changed_paths)))
396
+ ):
397
+ raise ValueError("endpoint changed_paths must be canonical and unique")
398
+
399
+ def to_record(self) -> dict[str, object]:
400
+ return {
401
+ "slot_id": self.slot_id,
402
+ "reference": (
403
+ None
404
+ if self.reference is None
405
+ else {
406
+ "insight_id": self.reference.insight_id.value,
407
+ "version": self.reference.version,
408
+ }
409
+ ),
410
+ "option_id": self.option_id,
411
+ "option_identity_sha256": self.option_identity_sha256,
412
+ "configuration_sha256": self.configuration_sha256,
413
+ "phenotype_identity_sha256": self.phenotype_identity_sha256,
414
+ "changed_paths": list(self.changed_paths),
415
+ }
416
+
417
+
418
+ @dataclass(frozen=True, slots=True)
419
+ class G3ExpectedUnion:
420
+ """Public prospective/runtime authority for one zero-call G3 union."""
421
+
422
+ slot_id: str
423
+ configuration: FrozenJsonValue
424
+ configuration_sha256: str
425
+ phenotype_identity_sha256: str
426
+ prospective_materialization_receipt_sha256: str
427
+ runtime_materialization_receipt_sha256: str
428
+
429
+ def __post_init__(self) -> None:
430
+ if type(self.slot_id) is not str or not self.slot_id:
431
+ raise ValueError("union slot_id must be non-empty exact text")
432
+ if not is_frozen_json_value(self.configuration):
433
+ raise TypeError("union configuration must be frozen typed JSON")
434
+ require_sha256(self.configuration_sha256, "configuration_sha256")
435
+ if typed_json_sha256(self.configuration) != self.configuration_sha256:
436
+ raise ValueError("union configuration hash does not authenticate value")
437
+ for name in (
438
+ "phenotype_identity_sha256",
439
+ "prospective_materialization_receipt_sha256",
440
+ "runtime_materialization_receipt_sha256",
441
+ ):
442
+ require_sha256(getattr(self, name), name)
443
+
444
+ def to_record(self) -> dict[str, object]:
445
+ return {
446
+ "slot_id": self.slot_id,
447
+ "configuration_sha256": self.configuration_sha256,
448
+ "phenotype_identity_sha256": self.phenotype_identity_sha256,
449
+ "prospective_materialization_receipt_sha256": (
450
+ self.prospective_materialization_receipt_sha256
451
+ ),
452
+ "runtime_materialization_receipt_sha256": (
453
+ self.runtime_materialization_receipt_sha256
454
+ ),
455
+ }
456
+
457
+
458
+ @dataclass(frozen=True, slots=True)
459
+ class G3TerminalValidationAuthority:
460
+ """Hash-bound expectations consumed by the post-G3 terminal gate.
461
+
462
+ The planner creates this only after it has validated G1/G2 and constructed
463
+ the exact zero-call G3 plan. A feedback interceptor can therefore validate
464
+ actual terminal outcomes without reaching into mutable planner internals.
465
+ """
466
+
467
+ hypothesis_parent_candidate_id: CandidateId
468
+ hypothesis_parent_configuration: FrozenJsonValue
469
+ hypothesis_parent_configuration_sha256: str
470
+ hypothesis_parent_phenotype_identity_sha256: str
471
+ seed_occurrence_binding_sha256: str
472
+ seed_phenotype_identity_sha256s: tuple[str, str]
473
+ g1_expected_endpoints: tuple[G3ExpectedEndpoint, G3ExpectedEndpoint]
474
+ g2_expected_endpoints: tuple[
475
+ G3ExpectedEndpoint,
476
+ G3ExpectedEndpoint,
477
+ G3ExpectedEndpoint,
478
+ G3ExpectedEndpoint,
479
+ ]
480
+ g3_expected_unions: tuple[
481
+ G3ExpectedUnion,
482
+ G3ExpectedUnion,
483
+ G3ExpectedUnion,
484
+ ]
485
+ prospective_proof_sha256: str
486
+ g1_rendered_prompt_receipt_sha256: str
487
+ g2_rendered_prompt_receipt_sha256: str
488
+ genesis_snapshot_sha256: str
489
+ diagnostic_wave_sha256: str
490
+ closure_snapshot_sha256: str
491
+ authority_sha256: str = field(init=False)
492
+
493
+ def __post_init__(self) -> None:
494
+ if type(self.hypothesis_parent_candidate_id) is not CandidateId:
495
+ raise TypeError("hypothesis parent ID must be an exact CandidateId")
496
+ CandidateId.__post_init__(self.hypothesis_parent_candidate_id)
497
+ if not is_frozen_json_value(self.hypothesis_parent_configuration):
498
+ raise TypeError("hypothesis parent configuration must be frozen JSON")
499
+ require_sha256(
500
+ self.hypothesis_parent_configuration_sha256,
501
+ "hypothesis_parent_configuration_sha256",
502
+ )
503
+ if (
504
+ typed_json_sha256(self.hypothesis_parent_configuration)
505
+ != self.hypothesis_parent_configuration_sha256
506
+ ):
507
+ raise ValueError("hypothesis parent hash does not authenticate value")
508
+ for name in (
509
+ "hypothesis_parent_phenotype_identity_sha256",
510
+ "seed_occurrence_binding_sha256",
511
+ "prospective_proof_sha256",
512
+ "g1_rendered_prompt_receipt_sha256",
513
+ "g2_rendered_prompt_receipt_sha256",
514
+ "genesis_snapshot_sha256",
515
+ "diagnostic_wave_sha256",
516
+ "closure_snapshot_sha256",
517
+ ):
518
+ require_sha256(getattr(self, name), name)
519
+ if (
520
+ type(self.seed_phenotype_identity_sha256s) is not tuple
521
+ or len(self.seed_phenotype_identity_sha256s) != 2
522
+ ):
523
+ raise ValueError("terminal authority requires two seed phenotypes")
524
+ for value in self.seed_phenotype_identity_sha256s:
525
+ require_sha256(value, "seed phenotype identity")
526
+ if len(set(self.seed_phenotype_identity_sha256s)) != 2:
527
+ raise ValueError("seed phenotype identities must be distinct")
528
+ endpoint_groups = (
529
+ (self.g1_expected_endpoints, G1_DIAGNOSTIC_SLOT_IDS),
530
+ (self.g2_expected_endpoints, G2_SLOT_IDS),
531
+ )
532
+ for endpoints, slot_ids in endpoint_groups:
533
+ if type(endpoints) is not tuple or any(
534
+ type(value) is not G3ExpectedEndpoint for value in endpoints
535
+ ):
536
+ raise TypeError("endpoint authorities must be exact values")
537
+ if tuple(value.slot_id for value in endpoints) != slot_ids:
538
+ raise ValueError("endpoint authority slot order changed")
539
+ if type(self.g3_expected_unions) is not tuple or any(
540
+ type(value) is not G3ExpectedUnion for value in self.g3_expected_unions
541
+ ):
542
+ raise TypeError("union authorities must be exact values")
543
+ if tuple(value.slot_id for value in self.g3_expected_unions) != G3_SLOT_IDS[1:]:
544
+ raise ValueError("union authority slot order changed")
545
+ object.__setattr__(
546
+ self,
547
+ "authority_sha256",
548
+ _hash(_PROSPECTIVE_DOMAIN, self.to_record()),
549
+ )
550
+
551
+ def to_record(self) -> dict[str, object]:
552
+ return {
553
+ "schema_version": 1,
554
+ "hypothesis_parent_candidate_id": (
555
+ self.hypothesis_parent_candidate_id.value
556
+ ),
557
+ "hypothesis_parent_configuration_sha256": (
558
+ self.hypothesis_parent_configuration_sha256
559
+ ),
560
+ "hypothesis_parent_phenotype_identity_sha256": (
561
+ self.hypothesis_parent_phenotype_identity_sha256
562
+ ),
563
+ "seed_occurrence_binding_sha256": self.seed_occurrence_binding_sha256,
564
+ "seed_phenotype_identity_sha256s": list(
565
+ self.seed_phenotype_identity_sha256s
566
+ ),
567
+ "g1_expected_endpoints": [
568
+ value.to_record() for value in self.g1_expected_endpoints
569
+ ],
570
+ "g2_expected_endpoints": [
571
+ value.to_record() for value in self.g2_expected_endpoints
572
+ ],
573
+ "g3_expected_unions": [
574
+ value.to_record() for value in self.g3_expected_unions
575
+ ],
576
+ "prospective_proof_sha256": self.prospective_proof_sha256,
577
+ "g1_rendered_prompt_receipt_sha256": (
578
+ self.g1_rendered_prompt_receipt_sha256
579
+ ),
580
+ "g2_rendered_prompt_receipt_sha256": (
581
+ self.g2_rendered_prompt_receipt_sha256
582
+ ),
583
+ "genesis_snapshot_sha256": self.genesis_snapshot_sha256,
584
+ "diagnostic_wave_sha256": self.diagnostic_wave_sha256,
585
+ "closure_snapshot_sha256": self.closure_snapshot_sha256,
586
+ }
587
+
588
+
589
+ def _portable_compilation_record(
590
+ request: HypothesisCompilationRequest,
591
+ receipt: HypothesisCompilationReceipt,
592
+ ) -> dict[str, object]:
593
+ """Project a prepared compilation across placeholder occurrence IDs.
594
+
595
+ Offline preparation cannot know the engine-assigned seed occurrence ID.
596
+ Every other semantic input/output remains exact; the full prepared request
597
+ and receipt hashes are retained separately in the matrix commitment.
598
+ """
599
+
600
+ validate_hypothesis_compilation(request, receipt)
601
+ if not receipt.applicable or receipt.spec is None:
602
+ raise ValueError("prepared G3 hypotheses must compile as applicable")
603
+ spec = receipt.spec
604
+ return {
605
+ "reference": {
606
+ "insight_id": request.reference.insight_id.value,
607
+ "version": request.reference.version,
608
+ },
609
+ "insight_content_sha256": request.insight.content_sha256,
610
+ "source_evidence_sha256": request.source_evidence_sha256,
611
+ "requested_operator_kind": request.requested_operator_kind,
612
+ "source_operator_kinds": list(request.source_operator_kinds),
613
+ "parent_configuration_sha256": request.parent_configuration_sha256,
614
+ "finite_contract_sha256": request.finite_contract.identity_sha256,
615
+ "context_projection_sha256": request.context_projection_sha256,
616
+ "endpoint_definition_sha256": request.endpoint_definition_sha256,
617
+ "executable_operator_kinds": list(spec.executable_operator_kinds),
618
+ "allowed_actions": [value.to_record() for value in spec.allowed_actions],
619
+ "recommended_option_families": list(spec.recommended_option_families),
620
+ "affected_paths": list(spec.affected_paths),
621
+ "held_fixed_paths": list(spec.held_fixed_paths),
622
+ "effect_predictions": [
623
+ {
624
+ "metric_id": value.metric_id,
625
+ "direction": value.direction.value,
626
+ }
627
+ for value in spec.effect_predictions
628
+ ],
629
+ "falsification_condition": spec.falsification_condition,
630
+ "compiler_policy_id": receipt.compiler_policy_id,
631
+ "compiler_policy_version": receipt.compiler_policy_version,
632
+ "compiler_definition_sha256": receipt.compiler_definition_sha256,
633
+ }
634
+
635
+
636
+ @dataclass(frozen=True, slots=True)
637
+ class PreparedHypothesisMatrix:
638
+ """Pre-run compiler authority for one parent role and exact card matrix."""
639
+
640
+ parent_role: str
641
+ requests: tuple[HypothesisCompilationRequest, HypothesisCompilationRequest]
642
+ receipts: tuple[HypothesisCompilationReceipt, HypothesisCompilationReceipt]
643
+ portable_matrix_sha256: str = field(init=False)
644
+ commitment_sha256: str = field(init=False)
645
+
646
+ def __post_init__(self) -> None:
647
+ if self.parent_role not in {"diagnostic_parent", "hypothesis_parent"}:
648
+ raise ValueError("parent_role must be a frozen G3 parent role")
649
+ if type(self.requests) is not tuple or len(self.requests) != 2:
650
+ raise ValueError("prepared matrix requires two exact requests")
651
+ if type(self.receipts) is not tuple or len(self.receipts) != 2:
652
+ raise ValueError("prepared matrix requires two exact receipts")
653
+ if any(type(value) is not HypothesisCompilationRequest for value in self.requests):
654
+ raise TypeError("prepared requests must be exact")
655
+ if any(type(value) is not HypothesisCompilationReceipt for value in self.receipts):
656
+ raise TypeError("prepared receipts must be exact")
657
+ portable = tuple(
658
+ _portable_compilation_record(request, receipt)
659
+ for request, receipt in zip(self.requests, self.receipts, strict=True)
660
+ )
661
+ references = tuple(request.reference for request in self.requests)
662
+ if references != tuple(sorted(set(references))):
663
+ raise ValueError("prepared matrix references must be canonical and unique")
664
+ shared = {
665
+ (
666
+ request.parent_configuration_sha256,
667
+ request.finite_contract.identity_sha256,
668
+ request.context_projection_sha256,
669
+ request.endpoint_definition_sha256,
670
+ request.requested_operator_kind,
671
+ )
672
+ for request in self.requests
673
+ }
674
+ if len(shared) != 1:
675
+ raise ValueError("prepared matrix mixes parent execution contexts")
676
+ portable_sha256 = _hash(_PROSPECTIVE_DOMAIN, list(portable))
677
+ object.__setattr__(self, "portable_matrix_sha256", portable_sha256)
678
+ object.__setattr__(
679
+ self,
680
+ "commitment_sha256",
681
+ _hash(
682
+ _PROSPECTIVE_DOMAIN,
683
+ {
684
+ "schema_version": 1,
685
+ "parent_role": self.parent_role,
686
+ "portable_matrix_sha256": portable_sha256,
687
+ "prepared_request_sha256s": [
688
+ request.request_sha256 for request in self.requests
689
+ ],
690
+ "prepared_receipt_sha256s": [
691
+ receipt.receipt_sha256 for receipt in self.receipts
692
+ ],
693
+ },
694
+ ),
695
+ )
696
+
697
+ @property
698
+ def references(self) -> tuple[InsightRef, InsightRef]:
699
+ return self.requests[0].reference, self.requests[1].reference
700
+
701
+ @property
702
+ def parent_configuration_sha256(self) -> str:
703
+ return self.requests[0].parent_configuration_sha256
704
+
705
+ def validate_runtime(
706
+ self,
707
+ matrix: tuple[CompiledHypothesisTreatment, ...],
708
+ ) -> None:
709
+ self.__post_init__()
710
+ if type(matrix) is not tuple or len(matrix) != 2:
711
+ raise ValueError("runtime hypothesis matrix must contain two treatments")
712
+ portable = tuple(
713
+ _portable_compilation_record(value.request, value.receipt)
714
+ for value in matrix
715
+ )
716
+ observed_sha256 = _hash(_PROSPECTIVE_DOMAIN, list(portable))
717
+ if observed_sha256 != self.portable_matrix_sha256:
718
+ raise ValueError(
719
+ "runtime hypothesis compilation differs from pre-run authority"
720
+ )
721
+
722
+
723
+ @runtime_checkable
724
+ class G3BenchmarkBoundary(Protocol):
725
+ """Narrow inverted boundary implemented by the public benchmark bundle."""
726
+
727
+ def bind_finite_variation(
728
+ self,
729
+ catalog_id: str,
730
+ parent_configuration: object,
731
+ ) -> FiniteVariationContract: ...
732
+
733
+ def compile_registered_hypothesis_treatment(
734
+ self,
735
+ *,
736
+ catalog_id: str,
737
+ parent_candidate_id: CandidateId,
738
+ parent_configuration: object,
739
+ entry: InsightMemoryEntry,
740
+ requested_operator_kind: str,
741
+ context_projection_sha256: str,
742
+ endpoint_definition_sha256: str,
743
+ ) -> CompiledHypothesisTreatment: ...
744
+
745
+
746
+ def finite_mutation_boundary(
747
+ *,
748
+ contract: FiniteVariationContract,
749
+ parent_candidate_id: CandidateId,
750
+ ) -> tuple[tuple[str, ...], MutationContract]:
751
+ """Derive the smallest complete machine boundary for a finite palette."""
752
+
753
+ validate_finite_variation_contract(contract)
754
+ probe = CandidateId("candidate_g3_finite_boundary_probe")
755
+ if probe == parent_candidate_id:
756
+ probe = CandidateId("candidate_g3_finite_boundary_probe_alternate")
757
+ paths: dict[bytes, JsonPath] = {}
758
+ max_changed_paths = 0
759
+ max_operations = 0
760
+ for option in contract.options:
761
+ patch = derive_patch(
762
+ contract.parent_configuration,
763
+ option.child_configuration,
764
+ base_candidate_id=parent_candidate_id,
765
+ target_candidate_id=probe,
766
+ )
767
+ changed = {operation.path for operation in patch.operations}
768
+ max_changed_paths = max(max_changed_paths, len(changed))
769
+ max_operations = max(max_operations, len(patch.operations))
770
+ for path in changed:
771
+ paths[canonical_path_bytes(path)] = path
772
+ editable = tuple(paths[key] for key in sorted(paths))
773
+ if not editable or max_changed_paths <= 0 or max_operations <= 0:
774
+ raise ValueError("finite variation palette has no executable mutation")
775
+ allowed = tuple(
776
+ sorted(
777
+ {
778
+ path.segments[0].value
779
+ for path in editable
780
+ if type(path.segments[0]) is ObjectKey
781
+ }
782
+ )
783
+ )
784
+ return allowed, MutationContract(
785
+ editable_paths=editable,
786
+ max_changed_paths=max_changed_paths,
787
+ max_operations=max_operations,
788
+ allow_abstention=False,
789
+ )
790
+
791
+
792
+ def _materialized_finite_choice(
793
+ *,
794
+ ids: IdFactory,
795
+ parent: EvolutionCandidate,
796
+ generation: int,
797
+ label: str,
798
+ contract: FiniteVariationContract,
799
+ choice: ParentBoundActionChoice,
800
+ ) -> MaterializedInvocation:
801
+ choice.validate_contract(contract)
802
+ option = contract.resolve(choice.option_id)
803
+ probe = ids.new_candidate_id()
804
+ patch = derive_patch(
805
+ parent.configuration,
806
+ option.child_configuration,
807
+ base_candidate_id=parent.candidate_id,
808
+ target_candidate_id=probe,
809
+ )
810
+ paths = tuple(sorted({_path_text(operation.path) for operation in patch.operations}))
811
+ top_level = tuple(
812
+ sorted(
813
+ {
814
+ operation.path.segments[0].value
815
+ for operation in patch.operations
816
+ if type(operation.path.segments[0]) is ObjectKey
817
+ }
818
+ )
819
+ )
820
+ plan = InvocationPlan(
821
+ operator_kind=OperatorKind.TYPED_MUTATION,
822
+ parents=(parent,),
823
+ generation=generation,
824
+ label=label,
825
+ allowed_top_level=top_level,
826
+ phase="g3_engine_mate",
827
+ )
828
+ configuration = thaw_json(option.child_configuration)
829
+ if type(configuration) is not dict:
830
+ raise TypeError("finite choice child must be an object")
831
+ return MaterializedInvocation(
832
+ plan=plan,
833
+ draft=CandidateDraft(
834
+ configuration=configuration,
835
+ design_rationale="Engine-owned outcome-blind parent-bound mate action.",
836
+ intended_changes=paths,
837
+ source_attribution=tuple(
838
+ SourceAttribution(path, "mutation") for path in paths
839
+ ),
840
+ ),
841
+ candidate_id=probe,
842
+ materialization_policy_id=choice.selection_policy_id,
843
+ materialization_policy_version=choice.selection_policy_version,
844
+ materialization_receipt_hash=choice.choice_sha256,
845
+ )
846
+
847
+
848
+ def _neutral_sham_requirement(
849
+ *,
850
+ entry: InsightMemoryEntry,
851
+ contract: FiniteVariationContract,
852
+ choice: ParentBoundActionChoice,
853
+ ) -> InsightTreatmentRequirement:
854
+ choice.validate_contract(contract)
855
+ if entry.lifecycle_state is not InsightLifecycleState.QUARANTINED:
856
+ raise ValueError("neutral sham card must remain quarantined")
857
+ if entry.evidence_lineage is not None or entry.draft.evidence_contrast_ids:
858
+ raise ValueError("neutral sham card must be evidence-free")
859
+ if any(
860
+ prediction.direction is not MetricEffectDirection.UNKNOWN
861
+ for prediction in entry.draft.effect_predictions
862
+ ):
863
+ raise ValueError("neutral sham card cannot make a directional prediction")
864
+ option = contract.resolve(choice.option_id)
865
+ if entry.draft.recommended_option_ids != (option.option_id,):
866
+ raise ValueError("neutral sham card must name its exact parent-bound option")
867
+ if entry.draft.recommended_option_families != (option.family,):
868
+ raise ValueError("neutral sham card family differs from its exact option")
869
+ evidence = TreatmentInsightEvidence(
870
+ reference=entry.reference,
871
+ insight_content_sha256=entry.draft.content_sha256,
872
+ applicable_operator_kinds=(OperatorKind.TYPED_MUTATION.value,),
873
+ affected_paths=tuple(sorted(entry.draft.affected_paths)),
874
+ recommended_option_families=entry.draft.recommended_option_families,
875
+ recommended_option_ids=entry.draft.recommended_option_ids,
876
+ )
877
+ return InsightTreatmentRequirement(
878
+ insight_bindings=(evidence.binding(),),
879
+ finite_contract_sha256=contract.identity_sha256,
880
+ allowed_actions=(
881
+ TreatmentActionBinding(option.option_id, option.identity_sha256),
882
+ ),
883
+ claim_mode=TreatmentClaimMode.EXACT_REQUIRED,
884
+ assignment_role=TreatmentAssignmentRole.SHAM_CONTROL,
885
+ require_option_family_match=True,
886
+ require_changed_path_overlap=True,
887
+ )
888
+
889
+
890
+ class G3CausalScreenPlanner:
891
+ """Stateful deterministic planner for the exact three-wave screen."""
892
+
893
+ policy_id = G3_SCREEN_POLICY_ID
894
+ policy_version = G3_SCREEN_POLICY_VERSION
895
+
896
+ def __init__(
897
+ self,
898
+ *,
899
+ benchmark: G3BenchmarkBoundary,
900
+ engine: AgenticEvolutionEngine,
901
+ ids: IdFactory,
902
+ memory: InsightMemoryBank,
903
+ reward_binding: RewardPolicyBinding,
904
+ active_references: tuple[InsightRef, InsightRef],
905
+ neutral_reference: InsightRef,
906
+ diagnostic_permutation: FrozenDiagnosticPermutation,
907
+ prepared_hypothesis_matrices: tuple[
908
+ PreparedHypothesisMatrix,
909
+ PreparedHypothesisMatrix,
910
+ ],
911
+ model_catalog_id: str,
912
+ neutral_choice: ParentBoundActionChoice,
913
+ mate_choice: ParentBoundActionChoice,
914
+ diagnostic_parent_configuration_sha256: str,
915
+ hypothesis_parent_configuration_sha256: str,
916
+ endpoint_definition_sha256: str,
917
+ estimand_stratum_sha256: str,
918
+ phase: str = "g3_causal_screen",
919
+ no_yield_reward: float = -1.0,
920
+ score_policy: CausalSearchScorePolicy | None = None,
921
+ controls: DeterministicMemoryControlPolicy | None = None,
922
+ trace_sink=None,
923
+ ) -> None:
924
+ if not isinstance(benchmark, G3BenchmarkBoundary):
925
+ raise TypeError("benchmark must implement G3BenchmarkBoundary")
926
+ if not isinstance(engine, AgenticEvolutionEngine):
927
+ raise TypeError("engine must be an AgenticEvolutionEngine")
928
+ if not isinstance(ids, IdFactory):
929
+ raise TypeError("ids must implement IdFactory")
930
+ if type(memory) is not InsightMemoryBank:
931
+ raise TypeError("memory must be an exact InsightMemoryBank")
932
+ if type(reward_binding) is not RewardPolicyBinding:
933
+ raise TypeError("reward_binding must be exact")
934
+ RewardPolicyBinding.__post_init__(reward_binding)
935
+ if endpoint_definition_sha256 != reward_binding.definition_hash:
936
+ raise ValueError(
937
+ "endpoint_definition_sha256 must equal the active reward/Q definition"
938
+ )
939
+ if (
940
+ type(active_references) is not tuple
941
+ or len(active_references) != 2
942
+ or active_references != tuple(sorted(set(active_references)))
943
+ ):
944
+ raise ValueError("active_references must be two canonical exact refs")
945
+ if neutral_reference in active_references:
946
+ raise ValueError("neutral sham must be distinct from active hypotheses")
947
+ if type(diagnostic_permutation) is not FrozenDiagnosticPermutation:
948
+ raise TypeError("diagnostic_permutation must be exact")
949
+ FrozenDiagnosticPermutation.__post_init__(diagnostic_permutation)
950
+ if diagnostic_permutation.active_references != active_references:
951
+ raise ValueError("diagnostic permutation differs from active references")
952
+ if (
953
+ type(prepared_hypothesis_matrices) is not tuple
954
+ or len(prepared_hypothesis_matrices) != 2
955
+ or any(
956
+ type(value) is not PreparedHypothesisMatrix
957
+ for value in prepared_hypothesis_matrices
958
+ )
959
+ ):
960
+ raise TypeError("prepared_hypothesis_matrices must contain two matrices")
961
+ for value in prepared_hypothesis_matrices:
962
+ PreparedHypothesisMatrix.__post_init__(value)
963
+ if tuple(value.parent_role for value in prepared_hypothesis_matrices) != (
964
+ "diagnostic_parent",
965
+ "hypothesis_parent",
966
+ ):
967
+ raise ValueError("prepared matrices must use frozen G3 parent order")
968
+ if any(
969
+ value.references != active_references
970
+ for value in prepared_hypothesis_matrices
971
+ ):
972
+ raise ValueError("prepared matrices differ from active references")
973
+ for value in (
974
+ diagnostic_parent_configuration_sha256,
975
+ hypothesis_parent_configuration_sha256,
976
+ endpoint_definition_sha256,
977
+ estimand_stratum_sha256,
978
+ ):
979
+ require_sha256(value, "g3 screen identity")
980
+ prepared_parent_hashes = tuple(
981
+ value.parent_configuration_sha256
982
+ for value in prepared_hypothesis_matrices
983
+ )
984
+ if prepared_parent_hashes != (
985
+ diagnostic_parent_configuration_sha256,
986
+ hypothesis_parent_configuration_sha256,
987
+ ):
988
+ raise ValueError("prepared matrices differ from frozen G3 parents")
989
+ if any(
990
+ request.endpoint_definition_sha256 != endpoint_definition_sha256
991
+ for matrix in prepared_hypothesis_matrices
992
+ for request in matrix.requests
993
+ ):
994
+ raise ValueError("prepared matrices differ from the frozen G3 endpoint")
995
+ if type(model_catalog_id) is not str or _TOKEN.fullmatch(model_catalog_id) is None:
996
+ raise ValueError("model_catalog_id must use the token grammar")
997
+ if neutral_choice.catalog_id != model_catalog_id:
998
+ raise ValueError("neutral action choice must use the model catalog")
999
+ if neutral_choice.role != "neutral_sham" or mate_choice.role != "orthogonal_mate":
1000
+ raise ValueError("action choices have incorrect G3 roles")
1001
+ if type(phase) is not str or not phase.strip():
1002
+ raise ValueError("phase must be non-empty")
1003
+ if type(no_yield_reward) is not float or not math.isfinite(no_yield_reward):
1004
+ raise TypeError("no_yield_reward must be a finite canonical float")
1005
+ if no_yield_reward != reward_binding.failure_score:
1006
+ raise ValueError(
1007
+ "G3 no_yield_reward must equal the active reward failure score"
1008
+ )
1009
+
1010
+ self.benchmark = benchmark
1011
+ self.engine = engine
1012
+ self.ids = ids
1013
+ self.memory = memory
1014
+ self.reward_binding = reward_binding
1015
+ self.active_references = active_references
1016
+ self.neutral_reference = neutral_reference
1017
+ self.diagnostic_permutation = diagnostic_permutation
1018
+ self.prepared_hypothesis_matrices = prepared_hypothesis_matrices
1019
+ self.model_catalog_id = model_catalog_id
1020
+ self.neutral_choice = neutral_choice
1021
+ self.mate_choice = mate_choice
1022
+ self.diagnostic_parent_configuration_sha256 = (
1023
+ diagnostic_parent_configuration_sha256
1024
+ )
1025
+ self.hypothesis_parent_configuration_sha256 = (
1026
+ hypothesis_parent_configuration_sha256
1027
+ )
1028
+ self.endpoint_definition_sha256 = endpoint_definition_sha256
1029
+ self.estimand_stratum_sha256 = estimand_stratum_sha256
1030
+ self.phase = phase
1031
+ self.no_yield_reward = no_yield_reward
1032
+ self.score_policy = score_policy or CausalSearchScorePolicy(
1033
+ prior_effective_sample_size=1.0,
1034
+ uncertainty_scale=0.0,
1035
+ exploration_weight=0.0,
1036
+ )
1037
+ self.controls = controls or DeterministicMemoryControlPolicy()
1038
+ self.checkpoint_service = DiagnosticMemoryCheckpointService(
1039
+ WaveSealedCheckpointBuilder(self.score_policy),
1040
+ trace_sink=trace_sink,
1041
+ )
1042
+ self.trace_sink = trace_sink
1043
+ self.genesis = None
1044
+ self.wave: FrozenDiagnosticMemoryWave | None = None
1045
+ self.closure: MemoryCheckpointClosure | None = None
1046
+ self.g1_prompt_shape_sha256: str | None = None
1047
+ self.g2_prompt_shape_sha256: str | None = None
1048
+ self.g1_rendered_prompt_receipt: MatchedPromptStructureReceipt | None = None
1049
+ self.g2_rendered_prompt_receipt: MatchedPromptStructureReceipt | None = None
1050
+ self.g2_assignments: tuple[ResolvedInsightAssignment, ...] = ()
1051
+ self._diagnostic_parent_id: CandidateId | None = None
1052
+ self._hypothesis_parent_id: CandidateId | None = None
1053
+ self._seed_occurrence_binding_sha256: str | None = None
1054
+ self._seed_phenotype_sha256s: tuple[str, str] | None = None
1055
+ self._runtime_diagnostic_matrix: tuple[
1056
+ CompiledHypothesisTreatment,
1057
+ ...,
1058
+ ] = ()
1059
+ self._runtime_hypothesis_matrix: tuple[
1060
+ CompiledHypothesisTreatment,
1061
+ ...,
1062
+ ] = ()
1063
+ self._g1_expected: tuple[_ProspectiveEndpoint, ...] = ()
1064
+ self._g2_expected: tuple[_ProspectiveEndpoint, ...] = ()
1065
+ self._g2_prospective_unions: tuple[_ProspectiveUnion, ...] = ()
1066
+ self._g2_prospective_proof_sha256: str | None = None
1067
+ self._terminal_validation_authority: (
1068
+ G3TerminalValidationAuthority | None
1069
+ ) = None
1070
+
1071
+ @property
1072
+ def terminal_validation_authority(
1073
+ self,
1074
+ ) -> G3TerminalValidationAuthority | None:
1075
+ """Return the immutable post-G3 authority once the G3 plan is frozen."""
1076
+
1077
+ return self._terminal_validation_authority
1078
+
1079
+ def _reward(self, state: OptimizerState, generation: int) -> FrozenWaveReward:
1080
+ return FrozenWaveReward(
1081
+ binding=self.reward_binding,
1082
+ archive_snapshot_hash=state.archive_snapshot_hash,
1083
+ reward_snapshot_hash=_hash(
1084
+ b"agent-evolve:g3-wave-reward:v1\x00",
1085
+ {
1086
+ "generation": generation,
1087
+ "archive_snapshot_hash": state.archive_snapshot_hash,
1088
+ "endpoint_definition_sha256": self.endpoint_definition_sha256,
1089
+ },
1090
+ ),
1091
+ )
1092
+
1093
+ def plan(self, state: OptimizerState, budget: OptimizerBudget) -> GenerationPlan:
1094
+ if budget != G3_SCREEN_BUDGET:
1095
+ raise ValueError("G3 screen requires the exact 6-call/11-evaluation budget")
1096
+ generation = state.generation + 1
1097
+ if generation == 1:
1098
+ return self._g1(state)
1099
+ if generation == 2:
1100
+ return self._g2(state)
1101
+ if generation == 3:
1102
+ return self._g3(state)
1103
+ raise ValueError("G3 causal screen has exactly three generations")
1104
+
1105
+ @staticmethod
1106
+ def _occurrence_record(candidate: EvolutionCandidate) -> dict[str, object]:
1107
+ occurrence = candidate.occurrence
1108
+ return {
1109
+ "candidate_id": occurrence.candidate_id.value,
1110
+ "configuration_hash": occurrence.configuration_hash,
1111
+ "configuration_artifact_hash": (
1112
+ occurrence.configuration_artifact_hash
1113
+ ),
1114
+ "proposal_sequence": occurrence.proposal_sequence,
1115
+ "operator_invocation_id": (
1116
+ None
1117
+ if occurrence.operator_invocation_id is None
1118
+ else occurrence.operator_invocation_id.value
1119
+ ),
1120
+ }
1121
+
1122
+ def _phenotype_sha256(self, candidate: EvolutionCandidate) -> str:
1123
+ identity = self.engine.identify_phenotype(candidate)
1124
+ detailed = candidate.detailed_evaluation
1125
+ if detailed is not None:
1126
+ if not detailed.success:
1127
+ raise ValueError("G3 endpoint detailed evaluation did not succeed")
1128
+ if detailed.phenotype != identity:
1129
+ raise ValueError(
1130
+ "candidate detailed phenotype differs from engine policy"
1131
+ )
1132
+ return identity.identity_sha256
1133
+
1134
+ def _parents(
1135
+ self,
1136
+ state: OptimizerState,
1137
+ ) -> tuple[EvolutionCandidate, EvolutionCandidate]:
1138
+ diagnostic, hypothesis = state.candidates[:2]
1139
+ if diagnostic.occurrence.configuration_hash != (
1140
+ self.diagnostic_parent_configuration_sha256
1141
+ ):
1142
+ raise ValueError("diagnostic seed differs from frozen G3 parent")
1143
+ if hypothesis.occurrence.configuration_hash != (
1144
+ self.hypothesis_parent_configuration_sha256
1145
+ ):
1146
+ raise ValueError("hypothesis seed differs from frozen G3 parent")
1147
+ if any(
1148
+ not candidate.valid
1149
+ or not candidate.operator_compliant
1150
+ or not candidate.evidence_compliant
1151
+ for candidate in (diagnostic, hypothesis)
1152
+ ):
1153
+ raise ValueError("G3 seeds must be valid and per-protocol")
1154
+ observed_ids = (diagnostic.candidate_id, hypothesis.candidate_id)
1155
+ occurrence_sha256 = _hash(
1156
+ _OCCURRENCE_DOMAIN,
1157
+ [
1158
+ self._occurrence_record(diagnostic),
1159
+ self._occurrence_record(hypothesis),
1160
+ ],
1161
+ )
1162
+ phenotype_sha256s = (
1163
+ self._phenotype_sha256(diagnostic),
1164
+ self._phenotype_sha256(hypothesis),
1165
+ )
1166
+ if len(set(phenotype_sha256s)) != 2:
1167
+ raise ValueError("G3 seeds collide under semantic phenotype identity")
1168
+ if self._diagnostic_parent_id is None:
1169
+ if state.generation != 0:
1170
+ raise RuntimeError("seed occurrences were not frozen before G1")
1171
+ self._diagnostic_parent_id, self._hypothesis_parent_id = observed_ids
1172
+ self._seed_occurrence_binding_sha256 = occurrence_sha256
1173
+ self._seed_phenotype_sha256s = phenotype_sha256s
1174
+ elif (
1175
+ observed_ids
1176
+ != (self._diagnostic_parent_id, self._hypothesis_parent_id)
1177
+ or occurrence_sha256 != self._seed_occurrence_binding_sha256
1178
+ or phenotype_sha256s != self._seed_phenotype_sha256s
1179
+ ):
1180
+ raise ValueError("frozen G3 seed occurrences changed")
1181
+ return diagnostic, hypothesis
1182
+
1183
+ def _require_exact_state(self, state: OptimizerState) -> None:
1184
+ expected = {
1185
+ 0: (2, 0, 0, 2, 0),
1186
+ 1: (4, 1, 1, 4, 2),
1187
+ 2: (8, 2, 2, 8, 5),
1188
+ }.get(state.generation)
1189
+ if expected is None:
1190
+ raise ValueError("G3 planner received an unsupported generation state")
1191
+ (
1192
+ candidate_count,
1193
+ generation_receipt_count,
1194
+ feedback_receipt_count,
1195
+ unique_evaluations,
1196
+ logical_llm_calls,
1197
+ ) = expected
1198
+ observed = (
1199
+ len(state.candidates),
1200
+ len(state.generation_receipts),
1201
+ len(state.feedback_receipts),
1202
+ state.unique_evaluations,
1203
+ state.logical_llm_calls,
1204
+ )
1205
+ if observed != expected:
1206
+ raise ValueError(
1207
+ "G3 state differs from the exact 2-to-4-to-8 causal protocol"
1208
+ )
1209
+ for receipt in state.feedback_receipts:
1210
+ if receipt.used_logical_llm_calls != 0:
1211
+ raise ValueError("G1/G2 feedback must be a zero-call sealed no-op")
1212
+ if state.generation >= 1:
1213
+ first = state.generation_receipts[0]
1214
+ if (
1215
+ first.logical_llm_calls_before,
1216
+ first.logical_llm_calls_after,
1217
+ first.unique_evaluations_before,
1218
+ first.unique_evaluations_after,
1219
+ ) != (0, 2, 2, 4):
1220
+ raise ValueError("G1 counters differ from two calls/two fresh misses")
1221
+ if state.generation >= 2:
1222
+ second = state.generation_receipts[1]
1223
+ if (
1224
+ second.logical_llm_calls_before,
1225
+ second.logical_llm_calls_after,
1226
+ second.unique_evaluations_before,
1227
+ second.unique_evaluations_after,
1228
+ ) != (2, 5, 4, 8):
1229
+ raise ValueError("G2 counters differ from three calls/four fresh misses")
1230
+ self._parents(state)
1231
+
1232
+ @staticmethod
1233
+ def _probe_candidate_id(label: str, forbidden: set[CandidateId]) -> CandidateId:
1234
+ # Slot labels are durable scientific metadata and may intentionally use
1235
+ # words that the identifier policy forbids as embedded content markers.
1236
+ # Keep the prospective lineage identity opaque while deterministically
1237
+ # binding it to the exact slot label.
1238
+ opaque_label = hashlib.sha256(
1239
+ label.encode("utf-8", errors="strict")
1240
+ ).hexdigest()[:16]
1241
+ base = f"candidate_g3_probe_{opaque_label}"
1242
+ for suffix in ("", "_alternate", "_second_alternate"):
1243
+ value = CandidateId(base + suffix)
1244
+ if value not in forbidden:
1245
+ return value
1246
+ raise RuntimeError("cannot allocate a prospective candidate identity")
1247
+
1248
+ def _endpoint(
1249
+ self,
1250
+ *,
1251
+ slot_id: str,
1252
+ reference: InsightRef | None,
1253
+ parent: EvolutionCandidate,
1254
+ contract: FiniteVariationContract,
1255
+ option_id: str,
1256
+ ) -> _ProspectiveEndpoint:
1257
+ option = contract.resolve(option_id)
1258
+ target = self._probe_candidate_id(slot_id, {parent.candidate_id})
1259
+ patch = derive_patch(
1260
+ parent.configuration,
1261
+ option.child_configuration,
1262
+ base_candidate_id=parent.candidate_id,
1263
+ target_candidate_id=target,
1264
+ )
1265
+ if not patch.operations:
1266
+ raise ValueError("G3 treatment option is an empty parent-relative action")
1267
+ paths = tuple(
1268
+ sorted({_path_text(operation.path) for operation in patch.operations})
1269
+ )
1270
+ phenotype = self.engine.identify_phenotype(option.child_configuration)
1271
+ return _ProspectiveEndpoint(
1272
+ slot_id=slot_id,
1273
+ reference=reference,
1274
+ option_id=option.option_id,
1275
+ option_identity_sha256=option.identity_sha256,
1276
+ configuration=option.child_configuration,
1277
+ configuration_sha256=option.child_configuration_sha256,
1278
+ phenotype_identity_sha256=phenotype.identity_sha256,
1279
+ changed_paths=paths,
1280
+ )
1281
+
1282
+ def _base_model_plan(
1283
+ self,
1284
+ *,
1285
+ parent: EvolutionCandidate,
1286
+ generation: int,
1287
+ label: str,
1288
+ contract: FiniteVariationContract,
1289
+ ) -> InvocationPlan:
1290
+ allowed, mutation = finite_mutation_boundary(
1291
+ contract=contract,
1292
+ parent_candidate_id=parent.candidate_id,
1293
+ )
1294
+ return InvocationPlan(
1295
+ operator_kind=OperatorKind.TYPED_MUTATION,
1296
+ parents=(parent,),
1297
+ generation=generation,
1298
+ label=label,
1299
+ allowed_top_level=allowed,
1300
+ mutation_contract=mutation,
1301
+ mutation_response_mode=MutationResponseMode.FINITE_OPTION_SELECTION_V1,
1302
+ finite_variation_contract=contract,
1303
+ phase=self.phase,
1304
+ )
1305
+
1306
+ def _compile_matrix(
1307
+ self,
1308
+ *,
1309
+ parent: EvolutionCandidate,
1310
+ context_sha256: str,
1311
+ prepared: PreparedHypothesisMatrix,
1312
+ ) -> tuple[CompiledHypothesisTreatment, ...]:
1313
+ entries = self.memory.entries_for(self.active_references)
1314
+ if any(
1315
+ entry.lifecycle_state is InsightLifecycleState.DEPRECATED
1316
+ for entry in entries
1317
+ ):
1318
+ raise ValueError("deprecated hypotheses cannot enter a G3 treatment")
1319
+ compiled = tuple(
1320
+ self.benchmark.compile_registered_hypothesis_treatment(
1321
+ catalog_id=self.model_catalog_id,
1322
+ parent_candidate_id=parent.candidate_id,
1323
+ parent_configuration=parent.configuration,
1324
+ entry=entry,
1325
+ requested_operator_kind=OperatorKind.TYPED_MUTATION.value,
1326
+ context_projection_sha256=context_sha256,
1327
+ endpoint_definition_sha256=self.endpoint_definition_sha256,
1328
+ )
1329
+ for entry in entries
1330
+ )
1331
+ if tuple(value.request.reference for value in compiled) != self.active_references:
1332
+ raise RuntimeError("compiled hypothesis matrix changed reference order")
1333
+ if any(len(value.requirement.allowed_actions) != 1 for value in compiled):
1334
+ raise ValueError("G3 hypotheses must compile to exact singleton actions")
1335
+ actions = tuple(
1336
+ value.requirement.allowed_actions[0].option_identity_sha256
1337
+ for value in compiled
1338
+ )
1339
+ if len(set(actions)) != len(actions):
1340
+ raise ValueError("active hypotheses compiled to the same exact action")
1341
+ prepared.validate_runtime(compiled)
1342
+ return compiled
1343
+
1344
+ def _g1(self, state: OptimizerState) -> GenerationPlan:
1345
+ if self.wave is not None:
1346
+ raise RuntimeError("G1 diagnostic wave was already frozen")
1347
+ self._require_exact_state(state)
1348
+ diagnostic, hypothesis = self._parents(state)
1349
+ contract = self.benchmark.bind_finite_variation(
1350
+ self.model_catalog_id,
1351
+ diagnostic.configuration,
1352
+ )
1353
+ hypothesis_contract = self.benchmark.bind_finite_variation(
1354
+ self.model_catalog_id,
1355
+ hypothesis.configuration,
1356
+ )
1357
+ base = self._base_model_plan(
1358
+ parent=diagnostic,
1359
+ generation=1,
1360
+ label="g1_diagnostic",
1361
+ contract=contract,
1362
+ )
1363
+ context_sha256 = context_stratum_hash(
1364
+ problem_id=self.engine.problem_id,
1365
+ operator_kind=OperatorKind.TYPED_MUTATION.value,
1366
+ phase=self.phase,
1367
+ )
1368
+ self._runtime_diagnostic_matrix = self._compile_matrix(
1369
+ parent=diagnostic,
1370
+ context_sha256=context_sha256,
1371
+ prepared=self.prepared_hypothesis_matrices[0],
1372
+ )
1373
+ self._runtime_hypothesis_matrix = self._compile_matrix(
1374
+ parent=hypothesis,
1375
+ context_sha256=context_sha256,
1376
+ prepared=self.prepared_hypothesis_matrices[1],
1377
+ )
1378
+ if any(
1379
+ value.request.finite_contract.identity_sha256 != contract.identity_sha256
1380
+ for value in self._runtime_diagnostic_matrix
1381
+ ) or any(
1382
+ value.request.finite_contract.identity_sha256
1383
+ != hypothesis_contract.identity_sha256
1384
+ for value in self._runtime_hypothesis_matrix
1385
+ ):
1386
+ raise ValueError("compiled runtime matrices differ from bound catalogs")
1387
+ self._g1_expected = tuple(
1388
+ self._endpoint(
1389
+ slot_id=G1_DIAGNOSTIC_SLOT_IDS[index],
1390
+ reference=value.request.reference,
1391
+ parent=diagnostic,
1392
+ contract=contract,
1393
+ option_id=value.requirement.allowed_actions[0].option_id,
1394
+ )
1395
+ for index, value in enumerate(self._runtime_diagnostic_matrix)
1396
+ )
1397
+ g1_phenotypes = tuple(
1398
+ value.phenotype_identity_sha256 for value in self._g1_expected
1399
+ )
1400
+ if len(set(g1_phenotypes)) != 2 or set(g1_phenotypes).intersection(
1401
+ self._seed_phenotype_sha256s or ()
1402
+ ):
1403
+ raise ValueError("G1 hypotheses do not define two fresh phenotypes")
1404
+ entries = self.memory.entries_for(self.active_references)
1405
+ self.genesis = self.score_policy.genesis(
1406
+ exact_context_hash=context_sha256,
1407
+ estimand_stratum_hash=self.estimand_stratum_sha256,
1408
+ priors={entry.reference: entry.initial_score for entry in entries},
1409
+ )
1410
+ self.g1_prompt_shape_sha256 = self.engine.prompt_shape_commitment(
1411
+ base,
1412
+ selected_insight_count=1,
1413
+ reward_definition_hash=self.reward_binding.definition_hash,
1414
+ )
1415
+ assignments = tuple(
1416
+ ResolvedInsightAssignment.resolve(
1417
+ credit_unit_id=self.ids.new_operator_invocation_id(),
1418
+ snapshot=self.genesis,
1419
+ expected_snapshot_sha256=self.genesis.snapshot_sha256,
1420
+ block_id="g1_diagnostic_randomized_block",
1421
+ arm=MemoryAssignmentArm.DIAGNOSTIC,
1422
+ selection_decision=self.controls.uniform(
1423
+ snapshot=self.genesis,
1424
+ subset_size=1,
1425
+ subset_rank=rank,
1426
+ ),
1427
+ prompt_shape_sha256=self.g1_prompt_shape_sha256,
1428
+ )
1429
+ for rank in self.diagnostic_permutation.subset_ranks_by_slot
1430
+ )
1431
+ if tuple(
1432
+ assignment.selection_decision.selected[0]
1433
+ for assignment in assignments
1434
+ ) != tuple(
1435
+ self.active_references[rank]
1436
+ for rank in self.diagnostic_permutation.subset_ranks_by_slot
1437
+ ):
1438
+ raise RuntimeError("joint diagnostic permutation realization drifted")
1439
+ self.wave = FrozenDiagnosticMemoryWave(
1440
+ wave_id="g3_causal_screen_diagnostic_wave",
1441
+ prior_snapshot=self.genesis,
1442
+ assignments=tuple(sorted(assignments, key=lambda value: value.assignment_sha256)),
1443
+ reward_definition_hash=self.reward_binding.definition_hash,
1444
+ no_yield_reward=self.no_yield_reward,
1445
+ )
1446
+ self.checkpoint_service.publish_frozen_wave(self.wave)
1447
+ matrix = self._runtime_diagnostic_matrix
1448
+ by_ref = {value.request.reference: value for value in matrix}
1449
+ expected_by_ref = {value.reference: value for value in self._g1_expected}
1450
+ slots = tuple(
1451
+ OptimizerSlot.model(
1452
+ slot_id=G1_DIAGNOSTIC_SLOT_IDS[index],
1453
+ role="diagnostic_active_hypothesis",
1454
+ plan=replace(
1455
+ base,
1456
+ label=G1_DIAGNOSTIC_SLOT_IDS[index],
1457
+ resolved_insight_assignment=assignment,
1458
+ insight_treatment_requirement=(
1459
+ by_ref[assignment.selection_decision.selected[0]].requirement
1460
+ ),
1461
+ compiled_hypothesis_treatment=(
1462
+ by_ref[assignment.selection_decision.selected[0]]
1463
+ ),
1464
+ compiled_hypothesis_eligibility=matrix,
1465
+ ),
1466
+ )
1467
+ for index, assignment in enumerate(assignments)
1468
+ )
1469
+ for slot, assignment in zip(slots, assignments, strict=True):
1470
+ selected = assignment.selection_decision.selected[0]
1471
+ expected = expected_by_ref[selected]
1472
+ if (
1473
+ slot.plan.insight_treatment_requirement.allowed_actions[0].option_id
1474
+ != expected.option_id
1475
+ ):
1476
+ raise RuntimeError("G1 slot differs from its prospective endpoint")
1477
+ return GenerationPlan(
1478
+ generation=1,
1479
+ slots=slots,
1480
+ reward=self._reward(state, 1),
1481
+ planner_policy_id=self.policy_id,
1482
+ planner_policy_version=self.policy_version,
1483
+ metadata=tuple(
1484
+ sorted(
1485
+ (
1486
+ ("diagnostic_permutation_receipt_sha256", self.diagnostic_permutation.receipt_sha256),
1487
+ ("diagnostic_wave_sha256", self.wave.wave_sha256),
1488
+ ("hypothesis_runtime_matrix_sha256", _hash(_PROSPECTIVE_DOMAIN, [value.binding_sha256 for value in self._runtime_hypothesis_matrix])),
1489
+ ("prepared_diagnostic_matrix_sha256", self.prepared_hypothesis_matrices[0].commitment_sha256),
1490
+ ("prepared_hypothesis_matrix_sha256", self.prepared_hypothesis_matrices[1].commitment_sha256),
1491
+ ("prompt_shape_sha256", self.g1_prompt_shape_sha256),
1492
+ ("seed_occurrence_binding_sha256", self._seed_occurrence_binding_sha256),
1493
+ )
1494
+ )
1495
+ ),
1496
+ )
1497
+
1498
+ def _require_model_endpoint(
1499
+ self,
1500
+ outcome: InvocationOutcome,
1501
+ *,
1502
+ expected: _ProspectiveEndpoint,
1503
+ assignment_role: TreatmentAssignmentRole,
1504
+ assignment_kind: InsightAssignmentKind,
1505
+ generation: int,
1506
+ ) -> EvolutionCandidate:
1507
+ if outcome.failure_stage is not None or outcome.candidate is None:
1508
+ raise ValueError("G3 model treatment did not complete successfully")
1509
+ prepared = outcome.prepared
1510
+ plan = prepared.plan
1511
+ candidate = outcome.candidate
1512
+ if (
1513
+ prepared.proposal_authority is not ProposalAuthority.MODEL
1514
+ or prepared.call_id is None
1515
+ or plan.operator_kind is not OperatorKind.TYPED_MUTATION
1516
+ or candidate.operator_kind is not OperatorKind.TYPED_MUTATION
1517
+ ):
1518
+ raise ValueError("G3 model endpoint has the wrong proposal authority")
1519
+ if candidate.generation != generation:
1520
+ raise ValueError("G3 model endpoint has the wrong generation")
1521
+ if (
1522
+ not candidate.valid
1523
+ or not candidate.operator_compliant
1524
+ or not candidate.evidence_compliant
1525
+ ):
1526
+ raise ValueError("G3 model endpoint is invalid or noncompliant")
1527
+ if candidate.occurrence.operator_invocation_id != prepared.operator_invocation_id:
1528
+ raise ValueError("G3 endpoint occurrence differs from its invocation")
1529
+ requirement = plan.insight_treatment_requirement
1530
+ if requirement is None or requirement.assignment_role is not assignment_role:
1531
+ raise ValueError("G3 endpoint has the wrong treatment role")
1532
+ if len(requirement.allowed_actions) != 1:
1533
+ raise ValueError("G3 endpoint treatment is not an exact singleton")
1534
+ action_binding = requirement.allowed_actions[0]
1535
+ if (
1536
+ action_binding.option_id,
1537
+ action_binding.option_identity_sha256,
1538
+ ) != (expected.option_id, expected.option_identity_sha256):
1539
+ raise ValueError("G3 endpoint differs from its frozen exact action")
1540
+ preflight = prepared.treatment_preflight_receipt
1541
+ if (
1542
+ preflight is None
1543
+ or not preflight.passed
1544
+ or len(preflight.compatible_actions) != 1
1545
+ or preflight.compatible_actions[0].binding() != action_binding
1546
+ ):
1547
+ raise ValueError("G3 treatment preflight did not admit one exact action")
1548
+ admission = outcome.treatment_admission_receipt
1549
+ if (
1550
+ admission is None
1551
+ or not admission.passed
1552
+ or admission.selected_action.binding() != action_binding
1553
+ ):
1554
+ raise ValueError("G3 treatment admission did not pass exactly")
1555
+ reference = expected.reference
1556
+ if reference is None:
1557
+ raise RuntimeError("model endpoint lost its treatment reference")
1558
+ if (
1559
+ candidate.selected_insight_refs != (reference,)
1560
+ or candidate.claimed_insight_ids != (reference.insight_id.value,)
1561
+ or candidate.insight_assignment_kind is not assignment_kind
1562
+ ):
1563
+ raise ValueError("G3 endpoint did not instantiate its assigned card")
1564
+ if candidate.occurrence.configuration_hash != expected.configuration_sha256:
1565
+ raise ValueError("G3 endpoint configuration differs from frozen action")
1566
+ if not typed_json_equal(candidate.configuration, expected.configuration):
1567
+ raise ValueError("G3 endpoint typed configuration changed")
1568
+ if self._phenotype_sha256(candidate) != expected.phenotype_identity_sha256:
1569
+ raise ValueError("G3 endpoint semantic phenotype changed")
1570
+ if assignment_role is TreatmentAssignmentRole.ACTIVE:
1571
+ if (
1572
+ plan.resolved_insight_assignment is None
1573
+ or plan.compiled_hypothesis_treatment is None
1574
+ or not plan.compiled_hypothesis_eligibility
1575
+ ):
1576
+ raise ValueError("active G3 treatment lost compiled causal authority")
1577
+ elif (
1578
+ plan.resolved_insight_assignment is not None
1579
+ or plan.compiled_hypothesis_treatment is not None
1580
+ or plan.compiled_hypothesis_eligibility
1581
+ or plan.quarantine_test_insights != (reference,)
1582
+ ):
1583
+ raise ValueError("sham G3 endpoint acquired causal-memory authority")
1584
+ return candidate
1585
+
1586
+ def _require_engine_endpoint(
1587
+ self,
1588
+ outcome: InvocationOutcome,
1589
+ *,
1590
+ expected: _ProspectiveEndpoint,
1591
+ generation: int,
1592
+ ) -> EvolutionCandidate:
1593
+ if outcome.failure_stage is not None or outcome.candidate is None:
1594
+ raise ValueError("G3 engine endpoint did not complete successfully")
1595
+ prepared = outcome.prepared
1596
+ candidate = outcome.candidate
1597
+ if (
1598
+ prepared.proposal_authority is not ProposalAuthority.ENGINE
1599
+ or prepared.call_id is not None
1600
+ or prepared.plan.operator_kind is not OperatorKind.TYPED_MUTATION
1601
+ or candidate.operator_kind is not OperatorKind.TYPED_MUTATION
1602
+ or outcome.treatment_admission_receipt is not None
1603
+ ):
1604
+ raise ValueError("G3 mate has the wrong engine-only authority")
1605
+ if (
1606
+ candidate.generation != generation
1607
+ or not candidate.valid
1608
+ or not candidate.operator_compliant
1609
+ or not candidate.evidence_compliant
1610
+ ):
1611
+ raise ValueError("G3 mate is invalid or noncompliant")
1612
+ if candidate.occurrence.operator_invocation_id != prepared.operator_invocation_id:
1613
+ raise ValueError("G3 mate occurrence differs from its invocation")
1614
+ if (
1615
+ candidate.occurrence.configuration_hash != expected.configuration_sha256
1616
+ or not typed_json_equal(candidate.configuration, expected.configuration)
1617
+ or self._phenotype_sha256(candidate)
1618
+ != expected.phenotype_identity_sha256
1619
+ ):
1620
+ raise ValueError("G3 mate differs from its frozen prospective endpoint")
1621
+ return candidate
1622
+
1623
+ @staticmethod
1624
+ def _prompt_receipt(
1625
+ receipt: GenerationReceipt,
1626
+ slot_ids: tuple[str, ...],
1627
+ ) -> MatchedPromptStructureReceipt:
1628
+ by_slot = {value.slot.slot_id: value.outcome for value in receipt.slot_results}
1629
+ if tuple(by_slot) != tuple(value.slot.slot_id for value in receipt.slot_results):
1630
+ raise ValueError("generation receipt repeats or reorders slot IDs")
1631
+ return seal_matched_prompt_structure(
1632
+ tuple(by_slot[slot_id].prepared.prompt for slot_id in slot_ids)
1633
+ )
1634
+
1635
+ def _prospective_union(
1636
+ self,
1637
+ *,
1638
+ hypothesis: EvolutionCandidate,
1639
+ model_endpoint: _ProspectiveEndpoint,
1640
+ mate_endpoint: _ProspectiveEndpoint,
1641
+ slot_id: str,
1642
+ ) -> tuple[_ProspectiveUnion, DisjointPatchMaterialization]:
1643
+ forbidden = {hypothesis.candidate_id}
1644
+ left_id = self._probe_candidate_id(f"{slot_id}_left", forbidden)
1645
+ forbidden.add(left_id)
1646
+ right_id = self._probe_candidate_id(f"{slot_id}_right", forbidden)
1647
+ forbidden.add(right_id)
1648
+ target_id = self._probe_candidate_id(f"{slot_id}_target", forbidden)
1649
+ materialization = DisjointPatchRecombiner().materialize(
1650
+ ancestor=hypothesis.configuration,
1651
+ ancestor_candidate_id=hypothesis.candidate_id,
1652
+ left=model_endpoint.configuration,
1653
+ left_candidate_id=left_id,
1654
+ right=mate_endpoint.configuration,
1655
+ right_candidate_id=right_id,
1656
+ target_candidate_id=target_id,
1657
+ )
1658
+ materialization.revalidate()
1659
+ left_paths = tuple(
1660
+ sorted(
1661
+ _path_text(operation.path)
1662
+ for operation in materialization.classification.left_patch.operations
1663
+ )
1664
+ )
1665
+ right_paths = tuple(
1666
+ sorted(
1667
+ _path_text(operation.path)
1668
+ for operation in materialization.classification.right_patch.operations
1669
+ )
1670
+ )
1671
+ if (
1672
+ left_paths != model_endpoint.changed_paths
1673
+ or right_paths != mate_endpoint.changed_paths
1674
+ ):
1675
+ raise ValueError("prospective union did not bind complete branch support")
1676
+ configuration_sha256 = typed_json_sha256(materialization.configuration)
1677
+ phenotype = self.engine.identify_phenotype(materialization.configuration)
1678
+ return (
1679
+ _ProspectiveUnion(
1680
+ slot_id=slot_id,
1681
+ configuration=materialization.configuration,
1682
+ configuration_sha256=configuration_sha256,
1683
+ phenotype_identity_sha256=phenotype.identity_sha256,
1684
+ prospective_receipt_sha256=materialization.receipt_sha256,
1685
+ ),
1686
+ materialization,
1687
+ )
1688
+
1689
+ def _g2(self, state: OptimizerState) -> GenerationPlan:
1690
+ if self.wave is None or self.genesis is None:
1691
+ raise RuntimeError("G1 diagnostic wave is unavailable")
1692
+ self._require_exact_state(state)
1693
+ if not self._g1_expected or not self._runtime_hypothesis_matrix:
1694
+ raise RuntimeError("G1 prospective/runtime authorities are unavailable")
1695
+ g1_receipt = state.generation_receipts[0]
1696
+ if tuple(value.slot.slot_id for value in g1_receipt.slot_results) != (
1697
+ G1_DIAGNOSTIC_SLOT_IDS
1698
+ ):
1699
+ raise ValueError("G1 receipt differs from the frozen slot order")
1700
+ expected_by_ref = {value.reference: value for value in self._g1_expected}
1701
+ g1_children: list[EvolutionCandidate] = []
1702
+ for result in g1_receipt.slot_results:
1703
+ assignment = result.outcome.prepared.plan.resolved_insight_assignment
1704
+ if assignment is None or assignment.arm is not MemoryAssignmentArm.DIAGNOSTIC:
1705
+ raise ValueError("G1 outcome lost its diagnostic assignment")
1706
+ reference = assignment.selection_decision.selected
1707
+ if len(reference) != 1 or reference[0] not in expected_by_ref:
1708
+ raise ValueError("G1 outcome selected a foreign hypothesis")
1709
+ g1_children.append(
1710
+ self._require_model_endpoint(
1711
+ result.outcome,
1712
+ expected=expected_by_ref[reference[0]],
1713
+ assignment_role=TreatmentAssignmentRole.ACTIVE,
1714
+ assignment_kind=InsightAssignmentKind.RESOLVED_CAUSAL,
1715
+ generation=1,
1716
+ )
1717
+ )
1718
+ if len({self._phenotype_sha256(value) for value in g1_children}) != 2:
1719
+ raise ValueError("G1 actual hypothesis phenotypes collided")
1720
+ self.g1_rendered_prompt_receipt = self._prompt_receipt(
1721
+ g1_receipt,
1722
+ G1_DIAGNOSTIC_SLOT_IDS,
1723
+ )
1724
+ self.closure = self.checkpoint_service.close_generation(
1725
+ self.wave,
1726
+ g1_receipt,
1727
+ )
1728
+ if self.closure.status is not MemoryCheckpointClosureStatus.SEALED:
1729
+ raise RuntimeError("G1 causal memory wave did not seal")
1730
+ snapshot = self.closure.snapshot
1731
+ if snapshot is None:
1732
+ raise RuntimeError("sealed G1 wave has no score checkpoint")
1733
+ if any(not entry.identified for entry in snapshot.entries):
1734
+ raise ValueError("G1 did not identify both active hypothesis effects")
1735
+ scores = tuple(entry.retrieval_score for entry in snapshot.entries)
1736
+ if scores[0] == scores[1]:
1737
+ raise ValueError("G1 active hypothesis scores tied")
1738
+
1739
+ _, hypothesis = self._parents(state)
1740
+ contract = self.benchmark.bind_finite_variation(
1741
+ self.model_catalog_id,
1742
+ hypothesis.configuration,
1743
+ )
1744
+ matrix = self._runtime_hypothesis_matrix
1745
+ if any(
1746
+ value.request.finite_contract.identity_sha256 != contract.identity_sha256
1747
+ for value in matrix
1748
+ ):
1749
+ raise ValueError("frozen P_H compilation differs from runtime catalog")
1750
+ base = self._base_model_plan(
1751
+ parent=hypothesis,
1752
+ generation=2,
1753
+ label="g2_model",
1754
+ contract=contract,
1755
+ )
1756
+ self.g2_prompt_shape_sha256 = self.engine.prompt_shape_commitment(
1757
+ base,
1758
+ selected_insight_count=1,
1759
+ reward_definition_hash=self.reward_binding.definition_hash,
1760
+ )
1761
+ assignments = (
1762
+ ResolvedInsightAssignment.resolve(
1763
+ credit_unit_id=self.ids.new_operator_invocation_id(),
1764
+ snapshot=snapshot,
1765
+ expected_snapshot_sha256=snapshot.snapshot_sha256,
1766
+ block_id="g2_matched_block",
1767
+ arm=MemoryAssignmentArm.ADAPTIVE,
1768
+ selection_decision=self.controls.adaptive(
1769
+ snapshot=snapshot,
1770
+ subset_size=1,
1771
+ ),
1772
+ prompt_shape_sha256=self.g2_prompt_shape_sha256,
1773
+ ),
1774
+ ResolvedInsightAssignment.resolve(
1775
+ credit_unit_id=self.ids.new_operator_invocation_id(),
1776
+ snapshot=snapshot,
1777
+ expected_snapshot_sha256=snapshot.snapshot_sha256,
1778
+ block_id="g2_matched_block",
1779
+ arm=MemoryAssignmentArm.SCORE_SHUFFLED_CONTROL,
1780
+ selection_decision=self.controls.score_shuffled(
1781
+ snapshot=snapshot,
1782
+ subset_size=1,
1783
+ permutation_rank=1,
1784
+ ),
1785
+ prompt_shape_sha256=self.g2_prompt_shape_sha256,
1786
+ ),
1787
+ )
1788
+ if assignments[0].selection_decision.selected == (
1789
+ assignments[1].selection_decision.selected
1790
+ ):
1791
+ raise ValueError("score-shuffled G2 control did not derange selection")
1792
+ self.g2_assignments = assignments
1793
+ by_ref = {value.request.reference: value for value in matrix}
1794
+ active_slots = tuple(
1795
+ OptimizerSlot.model(
1796
+ slot_id=G2_SLOT_IDS[index],
1797
+ role=("adaptive_active" if index == 0 else "score_shuffled_active"),
1798
+ plan=replace(
1799
+ base,
1800
+ label=G2_SLOT_IDS[index],
1801
+ resolved_insight_assignment=assignment,
1802
+ insight_treatment_requirement=(
1803
+ by_ref[assignment.selection_decision.selected[0]].requirement
1804
+ ),
1805
+ compiled_hypothesis_treatment=(
1806
+ by_ref[assignment.selection_decision.selected[0]]
1807
+ ),
1808
+ compiled_hypothesis_eligibility=matrix,
1809
+ ),
1810
+ )
1811
+ for index, assignment in enumerate(assignments)
1812
+ )
1813
+
1814
+ neutral_entry = self.memory.entries_for((self.neutral_reference,))[0]
1815
+ neutral_requirement = _neutral_sham_requirement(
1816
+ entry=neutral_entry,
1817
+ contract=contract,
1818
+ choice=self.neutral_choice,
1819
+ )
1820
+ neutral_plan = replace(
1821
+ base,
1822
+ label=G2_SLOT_IDS[2],
1823
+ quarantine_test_insights=(neutral_entry.reference,),
1824
+ insight_treatment_requirement=neutral_requirement,
1825
+ )
1826
+ neutral_shape = self.engine.prompt_shape_commitment(
1827
+ neutral_plan,
1828
+ selected_insight_count=1,
1829
+ reward_definition_hash=self.reward_binding.definition_hash,
1830
+ )
1831
+ if neutral_shape != self.g2_prompt_shape_sha256:
1832
+ raise ValueError("G2 sham prompt-shape commitment is unmatched")
1833
+
1834
+ mate_contract = self.benchmark.bind_finite_variation(
1835
+ self.mate_choice.catalog_id,
1836
+ hypothesis.configuration,
1837
+ )
1838
+ mate = _materialized_finite_choice(
1839
+ ids=self.ids,
1840
+ parent=hypothesis,
1841
+ generation=2,
1842
+ label=G2_SLOT_IDS[3],
1843
+ contract=mate_contract,
1844
+ choice=self.mate_choice,
1845
+ )
1846
+ active_expected = tuple(
1847
+ self._endpoint(
1848
+ slot_id=G2_SLOT_IDS[index],
1849
+ reference=assignment.selection_decision.selected[0],
1850
+ parent=hypothesis,
1851
+ contract=contract,
1852
+ option_id=by_ref[
1853
+ assignment.selection_decision.selected[0]
1854
+ ].requirement.allowed_actions[0].option_id,
1855
+ )
1856
+ for index, assignment in enumerate(assignments)
1857
+ )
1858
+ neutral_expected = self._endpoint(
1859
+ slot_id=G2_SLOT_IDS[2],
1860
+ reference=neutral_entry.reference,
1861
+ parent=hypothesis,
1862
+ contract=contract,
1863
+ option_id=self.neutral_choice.option_id,
1864
+ )
1865
+ mate_expected = self._endpoint(
1866
+ slot_id=G2_SLOT_IDS[3],
1867
+ reference=None,
1868
+ parent=hypothesis,
1869
+ contract=mate_contract,
1870
+ option_id=self.mate_choice.option_id,
1871
+ )
1872
+ if (
1873
+ typed_json_sha256(freeze_json(mate.draft.configuration))
1874
+ != mate_expected.configuration_sha256
1875
+ ):
1876
+ raise RuntimeError("engine mate materialization differs from frozen choice")
1877
+ model_endpoints = (*active_expected, neutral_expected)
1878
+ if len({value.option_identity_sha256 for value in model_endpoints}) != 3:
1879
+ raise ValueError("G2 A/S/N actions are not pairwise distinct")
1880
+ if len({value.phenotype_identity_sha256 for value in model_endpoints}) != 3:
1881
+ raise ValueError("G2 A/S/N treatments do not produce three phenotypes")
1882
+
1883
+ prospective_pairs = tuple(
1884
+ self._prospective_union(
1885
+ hypothesis=hypothesis,
1886
+ model_endpoint=endpoint,
1887
+ mate_endpoint=mate_expected,
1888
+ slot_id=slot_id,
1889
+ )
1890
+ for endpoint, slot_id in zip(
1891
+ model_endpoints,
1892
+ G3_SLOT_IDS[1:],
1893
+ strict=True,
1894
+ )
1895
+ )
1896
+ prospective_unions = tuple(value[0] for value in prospective_pairs)
1897
+ historical_phenotypes = {
1898
+ self._phenotype_sha256(candidate) for candidate in state.candidates
1899
+ }
1900
+ all_new_phenotypes = tuple(
1901
+ value.phenotype_identity_sha256
1902
+ for value in (*model_endpoints, mate_expected, *prospective_unions)
1903
+ )
1904
+ if len(set(all_new_phenotypes)) != 7 or historical_phenotypes.intersection(
1905
+ all_new_phenotypes
1906
+ ):
1907
+ raise ValueError(
1908
+ "prospective G2/G3 endpoints do not prove seven fresh phenotypes"
1909
+ )
1910
+ self._g2_expected = (*model_endpoints, mate_expected)
1911
+ self._g2_prospective_unions = prospective_unions
1912
+ self._g2_prospective_proof_sha256 = _hash(
1913
+ _PROSPECTIVE_DOMAIN,
1914
+ {
1915
+ "historical_phenotype_sha256s": sorted(historical_phenotypes),
1916
+ "endpoints": [
1917
+ {
1918
+ "slot_id": value.slot_id,
1919
+ "configuration_sha256": value.configuration_sha256,
1920
+ "phenotype_identity_sha256": (
1921
+ value.phenotype_identity_sha256
1922
+ ),
1923
+ "changed_paths": list(value.changed_paths),
1924
+ }
1925
+ for value in self._g2_expected
1926
+ ],
1927
+ "unions": [
1928
+ {
1929
+ "slot_id": value.slot_id,
1930
+ "configuration_sha256": value.configuration_sha256,
1931
+ "phenotype_identity_sha256": (
1932
+ value.phenotype_identity_sha256
1933
+ ),
1934
+ "prospective_receipt_sha256": (
1935
+ value.prospective_receipt_sha256
1936
+ ),
1937
+ }
1938
+ for value in prospective_unions
1939
+ ],
1940
+ },
1941
+ )
1942
+
1943
+ return GenerationPlan(
1944
+ generation=2,
1945
+ slots=(
1946
+ *active_slots,
1947
+ OptimizerSlot.model(
1948
+ slot_id=G2_SLOT_IDS[2],
1949
+ role="evidence_free_sham_control",
1950
+ plan=neutral_plan,
1951
+ ),
1952
+ OptimizerSlot.engine(
1953
+ slot_id=G2_SLOT_IDS[3],
1954
+ role="orthogonal_engine_mate",
1955
+ invocation=mate,
1956
+ ),
1957
+ ),
1958
+ reward=self._reward(state, 2),
1959
+ planner_policy_id=self.policy_id,
1960
+ planner_policy_version=self.policy_version,
1961
+ metadata=tuple(
1962
+ sorted(
1963
+ (
1964
+ ("g1_rendered_prompt_receipt_sha256", self.g1_rendered_prompt_receipt.receipt_sha256),
1965
+ ("mate_choice_sha256", self.mate_choice.choice_sha256),
1966
+ ("memory_snapshot_sha256", snapshot.snapshot_sha256),
1967
+ ("neutral_choice_sha256", self.neutral_choice.choice_sha256),
1968
+ ("prompt_shape_sha256", self.g2_prompt_shape_sha256),
1969
+ ("prospective_g2_g3_proof_sha256", self._g2_prospective_proof_sha256),
1970
+ )
1971
+ )
1972
+ ),
1973
+ )
1974
+
1975
+ def _g3(self, state: OptimizerState) -> GenerationPlan:
1976
+ self._require_exact_state(state)
1977
+ if len(self._g2_expected) != 4 or len(self._g2_prospective_unions) != 3:
1978
+ raise RuntimeError("G2 prospective authority is unavailable")
1979
+ _, hypothesis = self._parents(state)
1980
+ g2 = state.generation_receipts[1]
1981
+ if tuple(value.slot.slot_id for value in g2.slot_results) != G2_SLOT_IDS:
1982
+ raise ValueError("G2 receipt slot order differs from frozen contract")
1983
+ active_children = tuple(
1984
+ self._require_model_endpoint(
1985
+ result.outcome,
1986
+ expected=expected,
1987
+ assignment_role=TreatmentAssignmentRole.ACTIVE,
1988
+ assignment_kind=InsightAssignmentKind.RESOLVED_CAUSAL,
1989
+ generation=2,
1990
+ )
1991
+ for result, expected in zip(
1992
+ g2.slot_results[:2],
1993
+ self._g2_expected[:2],
1994
+ strict=True,
1995
+ )
1996
+ )
1997
+ sham = self._require_model_endpoint(
1998
+ g2.slot_results[2].outcome,
1999
+ expected=self._g2_expected[2],
2000
+ assignment_role=TreatmentAssignmentRole.SHAM_CONTROL,
2001
+ assignment_kind=InsightAssignmentKind.QUARANTINE_TEST,
2002
+ generation=2,
2003
+ )
2004
+ mate = self._require_engine_endpoint(
2005
+ g2.slot_results[3].outcome,
2006
+ expected=self._g2_expected[3],
2007
+ generation=2,
2008
+ )
2009
+ adaptive, shuffled = active_children
2010
+ actual_g2_phenotypes = tuple(
2011
+ self._phenotype_sha256(value)
2012
+ for value in (adaptive, shuffled, sham, mate)
2013
+ )
2014
+ if len(set(actual_g2_phenotypes)) != 4:
2015
+ raise ValueError("actual G2 A/S/N/E phenotypes collided")
2016
+ self.g2_rendered_prompt_receipt = self._prompt_receipt(
2017
+ g2,
2018
+ G2_SLOT_IDS[:3],
2019
+ )
2020
+
2021
+ reproduction = InvocationPlan(
2022
+ operator_kind=OperatorKind.REPRODUCTION,
2023
+ parents=(hypothesis,),
2024
+ generation=3,
2025
+ label=G3_SLOT_IDS[0],
2026
+ phase="g3_reproduction_control",
2027
+ )
2028
+
2029
+ def union(
2030
+ model_child: EvolutionCandidate,
2031
+ slot_id: str,
2032
+ ) -> MaterializedInvocation:
2033
+ materialization = DisjointPatchRecombiner().materialize(
2034
+ ancestor=hypothesis.configuration,
2035
+ ancestor_candidate_id=hypothesis.candidate_id,
2036
+ left=model_child.configuration,
2037
+ left_candidate_id=model_child.candidate_id,
2038
+ right=mate.configuration,
2039
+ right_candidate_id=mate.candidate_id,
2040
+ target_candidate_id=self.ids.new_candidate_id(),
2041
+ )
2042
+ plan = InvocationPlan(
2043
+ operator_kind=OperatorKind.THREE_WAY_RECOMBINATION,
2044
+ parents=(model_child, mate),
2045
+ generation=3,
2046
+ label=slot_id,
2047
+ common_ancestor=hypothesis,
2048
+ phase="g3_disjoint_union",
2049
+ )
2050
+ return materialized_disjoint_invocation(
2051
+ plan=plan,
2052
+ materialization=materialization,
2053
+ )
2054
+
2055
+ unions = tuple(
2056
+ union(child, slot_id)
2057
+ for child, slot_id in zip(
2058
+ (adaptive, shuffled, sham),
2059
+ G3_SLOT_IDS[1:],
2060
+ strict=True,
2061
+ )
2062
+ )
2063
+ for invocation, expected in zip(
2064
+ unions,
2065
+ self._g2_prospective_unions,
2066
+ strict=True,
2067
+ ):
2068
+ observed_configuration = freeze_json(invocation.draft.configuration)
2069
+ if (
2070
+ typed_json_sha256(observed_configuration)
2071
+ != expected.configuration_sha256
2072
+ or not typed_json_equal(
2073
+ observed_configuration,
2074
+ expected.configuration,
2075
+ )
2076
+ or self.engine.identify_phenotype(observed_configuration).identity_sha256
2077
+ != expected.phenotype_identity_sha256
2078
+ ):
2079
+ raise ValueError(
2080
+ "actual G3 union differs from prospective disjoint replay"
2081
+ )
2082
+ slots = (
2083
+ OptimizerSlot.reproduction(
2084
+ slot_id=G3_SLOT_IDS[0],
2085
+ role="hypothesis_parent_reproduction",
2086
+ plan=reproduction,
2087
+ ),
2088
+ *(
2089
+ OptimizerSlot.engine(
2090
+ slot_id=slot_id,
2091
+ role="deterministic_disjoint_union",
2092
+ invocation=invocation,
2093
+ )
2094
+ for slot_id, invocation in zip(
2095
+ G3_SLOT_IDS[1:], unions, strict=True
2096
+ )
2097
+ ),
2098
+ )
2099
+ if any(
2100
+ slot.proposal_authority is ProposalAuthority.MODEL for slot in slots
2101
+ ):
2102
+ raise RuntimeError("G3 must contain zero model calls")
2103
+ if (
2104
+ self._seed_occurrence_binding_sha256 is None
2105
+ or self._seed_phenotype_sha256s is None
2106
+ or self._g2_prospective_proof_sha256 is None
2107
+ or self.genesis is None
2108
+ or self.wave is None
2109
+ or self.closure is None
2110
+ or self.closure.snapshot is None
2111
+ or self.g1_rendered_prompt_receipt is None
2112
+ or self.g2_rendered_prompt_receipt is None
2113
+ ):
2114
+ raise RuntimeError("G3 terminal authority prerequisites are unavailable")
2115
+
2116
+ def endpoint_authority(
2117
+ value: _ProspectiveEndpoint,
2118
+ ) -> G3ExpectedEndpoint:
2119
+ return G3ExpectedEndpoint(
2120
+ slot_id=value.slot_id,
2121
+ reference=value.reference,
2122
+ option_id=value.option_id,
2123
+ option_identity_sha256=value.option_identity_sha256,
2124
+ configuration=value.configuration,
2125
+ configuration_sha256=value.configuration_sha256,
2126
+ phenotype_identity_sha256=value.phenotype_identity_sha256,
2127
+ changed_paths=value.changed_paths,
2128
+ )
2129
+
2130
+ g1_expected_by_reference = {
2131
+ value.reference: value for value in self._g1_expected
2132
+ }
2133
+ # The frozen wave canonicalizes assignments by receipt hash. Recover
2134
+ # the actual slot realization from the G1 receipt instead of relying on
2135
+ # that storage order when the public permutation rank is non-zero.
2136
+ g1_receipt = state.generation_receipts[0]
2137
+
2138
+ def realized_g1_endpoint(result) -> _ProspectiveEndpoint:
2139
+ assignment = result.outcome.prepared.plan.resolved_insight_assignment
2140
+ if assignment is None or len(assignment.selection_decision.selected) != 1:
2141
+ raise RuntimeError("G1 terminal authority lost its assignment")
2142
+ return replace(
2143
+ g1_expected_by_reference[
2144
+ assignment.selection_decision.selected[0]
2145
+ ],
2146
+ slot_id=result.slot.slot_id,
2147
+ )
2148
+
2149
+ realized_g1_expected = tuple(
2150
+ realized_g1_endpoint(result) for result in g1_receipt.slot_results
2151
+ )
2152
+ terminal_authority = G3TerminalValidationAuthority(
2153
+ hypothesis_parent_candidate_id=hypothesis.candidate_id,
2154
+ hypothesis_parent_configuration=hypothesis.configuration,
2155
+ hypothesis_parent_configuration_sha256=(
2156
+ hypothesis.occurrence.configuration_hash
2157
+ ),
2158
+ hypothesis_parent_phenotype_identity_sha256=(
2159
+ self._phenotype_sha256(hypothesis)
2160
+ ),
2161
+ seed_occurrence_binding_sha256=self._seed_occurrence_binding_sha256,
2162
+ seed_phenotype_identity_sha256s=self._seed_phenotype_sha256s,
2163
+ g1_expected_endpoints=tuple(
2164
+ endpoint_authority(value) for value in realized_g1_expected
2165
+ ),
2166
+ g2_expected_endpoints=tuple(
2167
+ endpoint_authority(value) for value in self._g2_expected
2168
+ ),
2169
+ g3_expected_unions=tuple(
2170
+ G3ExpectedUnion(
2171
+ slot_id=expected.slot_id,
2172
+ configuration=expected.configuration,
2173
+ configuration_sha256=expected.configuration_sha256,
2174
+ phenotype_identity_sha256=(
2175
+ expected.phenotype_identity_sha256
2176
+ ),
2177
+ prospective_materialization_receipt_sha256=(
2178
+ expected.prospective_receipt_sha256
2179
+ ),
2180
+ runtime_materialization_receipt_sha256=(
2181
+ invocation.materialization_receipt_hash
2182
+ ),
2183
+ )
2184
+ for expected, invocation in zip(
2185
+ self._g2_prospective_unions,
2186
+ unions,
2187
+ strict=True,
2188
+ )
2189
+ ),
2190
+ prospective_proof_sha256=self._g2_prospective_proof_sha256,
2191
+ g1_rendered_prompt_receipt_sha256=(
2192
+ self.g1_rendered_prompt_receipt.receipt_sha256
2193
+ ),
2194
+ g2_rendered_prompt_receipt_sha256=(
2195
+ self.g2_rendered_prompt_receipt.receipt_sha256
2196
+ ),
2197
+ genesis_snapshot_sha256=self.genesis.snapshot_sha256,
2198
+ diagnostic_wave_sha256=self.wave.wave_sha256,
2199
+ closure_snapshot_sha256=self.closure.snapshot.snapshot_sha256,
2200
+ )
2201
+ if self._terminal_validation_authority is not None:
2202
+ if (
2203
+ self._terminal_validation_authority.authority_sha256
2204
+ != terminal_authority.authority_sha256
2205
+ ):
2206
+ raise RuntimeError("G3 terminal authority changed after freezing")
2207
+ else:
2208
+ self._terminal_validation_authority = terminal_authority
2209
+ return GenerationPlan(
2210
+ generation=3,
2211
+ slots=slots,
2212
+ reward=self._reward(state, 3),
2213
+ planner_policy_id=self.policy_id,
2214
+ planner_policy_version=self.policy_version,
2215
+ metadata=tuple(
2216
+ sorted(
2217
+ (
2218
+ ("g2_rendered_prompt_receipt_sha256", self.g2_rendered_prompt_receipt.receipt_sha256),
2219
+ ("prospective_g2_g3_proof_sha256", self._g2_prospective_proof_sha256),
2220
+ (
2221
+ "terminal_validation_authority_sha256",
2222
+ terminal_authority.authority_sha256,
2223
+ ),
2224
+ *(
2225
+ (
2226
+ f"{slot_id}_receipt_sha256",
2227
+ invocation.materialization_receipt_hash,
2228
+ )
2229
+ for slot_id, invocation in zip(
2230
+ G3_SLOT_IDS[1:],
2231
+ unions,
2232
+ strict=True,
2233
+ )
2234
+ ),
2235
+ )
2236
+ )
2237
+ ),
2238
+ )
2239
+
2240
+
2241
+ __all__ = [
2242
+ "G1_DIAGNOSTIC_SLOT_IDS",
2243
+ "G2_SLOT_IDS",
2244
+ "G3_SLOT_IDS",
2245
+ "G3BenchmarkBoundary",
2246
+ "G3CausalScreenPlanner",
2247
+ "G3ExpectedEndpoint",
2248
+ "G3ExpectedUnion",
2249
+ "G3_SCREEN_BUDGET",
2250
+ "G3_SCREEN_POLICY_ID",
2251
+ "G3_SCREEN_POLICY_VERSION",
2252
+ "FrozenDiagnosticPermutation",
2253
+ "G3TerminalValidationAuthority",
2254
+ "ParentBoundActionChoice",
2255
+ "PreparedHypothesisMatrix",
2256
+ "finite_mutation_boundary",
2257
+ ]