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,1147 @@
1
+ """Evidence-identifiable, mutation-only inputs for prospective reflection.
2
+
3
+ The production campaign already records authenticated parent-to-child mutation
4
+ observations. Reflection should consume those exact single-intervention facts
5
+ instead of assigning a recombination result to one arbitrarily chosen
6
+ coordinate. This module is a pure projection over sealed observations. It
7
+ does not call a provider, interpret benchmark prose, mutate memory, or decide
8
+ when a reflected card becomes eligible for use.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import hashlib
14
+ import json
15
+ import re
16
+ from dataclasses import dataclass, field
17
+ from enum import Enum
18
+
19
+ from agent_evolve.domain.ids import CandidateId, OperatorInvocationId
20
+ from agent_evolve.domain.patch import require_sha256
21
+ from agent_evolve.domain.typed_json import (
22
+ FrozenJsonValue,
23
+ canonical_typed_json_bytes,
24
+ freeze_json,
25
+ is_frozen_json_value,
26
+ thaw_json,
27
+ typed_json_equal,
28
+ typed_json_sha256,
29
+ )
30
+ from agent_evolve.policies.memory.global_falsification import (
31
+ AuthenticatedHypothesisObservation,
32
+ EvidenceProvenance,
33
+ InterventionIdentifiability,
34
+ ObservedMetricEffect,
35
+ )
36
+ from agent_evolve.ports.agentic_generator import (
37
+ MetricEffectDirection,
38
+ ReflectionInsightKind,
39
+ )
40
+
41
+
42
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.:-]{0,255}$")
43
+ _OPTION_ID = re.compile(r"^[a-z][a-z0-9_.-]{0,255}$")
44
+ _PATH = re.compile(r"^\$\.[^.\[\]\s]+(?:\.[^.\[\]\s]+|\[(?:0|[1-9][0-9]*)\])*$")
45
+ _CONTRAST_DOMAIN = b"agent-evolve:identifiable-reflection-contrast:v3\x00"
46
+ _HYPOTHESIS_CLUSTER_DOMAIN = (
47
+ b"agent-evolve:identifiable-reflection-hypothesis-cluster:v1\x00"
48
+ )
49
+ _SNAPSHOT_DOMAIN = b"agent-evolve:identifiable-reflection-snapshot:v3\x00"
50
+ _FEEDBACK_DOMAIN = b"agent-evolve:reflection-falsification-feedback:v1\x00"
51
+ MAX_REFLECTION_LOCAL_INTERVENTION_VALUE_BYTES = 4_096
52
+
53
+ IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_ID = (
54
+ "sealed_direct_single_mutation_reflection_evidence"
55
+ )
56
+ IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_VERSION = 3
57
+ IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_DEFINITION_SHA256 = hashlib.sha256(
58
+ b"agent-evolve:sealed-direct-single-mutation-reflection-evidence:v3;"
59
+ b"direct-mutation-only;exact-single-intervention;one-affected-path;"
60
+ b"observed-action-path-option-family-and-finite-contract-join;sealed-event-cutoff;"
61
+ b"authenticated-action-semantics-compiler-id-version-definition-join;"
62
+ b"exact-parent-child-candidate-and-operator-invocation-lineage;"
63
+ b"bounded-exact-parent-child-local-values;"
64
+ b"empirical-rule-only-without-mechanism-identifying-design"
65
+ ).hexdigest()
66
+
67
+
68
+ class NoIdentifiableMutationEvidenceError(ValueError):
69
+ """Typed E0 result for a sealed cutoff with no admissible contrast.
70
+
71
+ Absence of an exact single-intervention contrast is an expected scientific
72
+ outcome, not a provider or campaign failure. The pure projector retains a
73
+ ``ValueError`` compatibility boundary for callers that require a snapshot,
74
+ while publishing the complete exclusion partition so the campaign runtime
75
+ can convert this condition into an authenticated zero-provider-call
76
+ abstention.
77
+ """
78
+
79
+ def __init__(
80
+ self,
81
+ *,
82
+ observation_count: int,
83
+ exclusions: tuple[tuple["ReflectionEvidenceExclusionReason", int], ...],
84
+ ) -> None:
85
+ if type(observation_count) is not int or observation_count < 0:
86
+ raise ValueError("observation_count must be non-negative")
87
+ if type(exclusions) is not tuple or any(
88
+ type(item) is not tuple
89
+ or len(item) != 2
90
+ or type(item[0]) is not ReflectionEvidenceExclusionReason
91
+ or type(item[1]) is not int
92
+ or item[1] <= 0
93
+ for item in exclusions
94
+ ):
95
+ raise TypeError("exclusions must contain typed positive counts")
96
+ if tuple(reason.value for reason, _ in exclusions) != tuple(
97
+ sorted({reason.value for reason, _ in exclusions})
98
+ ):
99
+ raise ValueError("exclusions must be unique and canonical")
100
+ if sum(count for _, count in exclusions) != observation_count:
101
+ raise ValueError("E0 exclusions must partition all observations")
102
+ super().__init__("sealed cutoff contains no identifiable mutation evidence")
103
+ self.observation_count = observation_count
104
+ self.exclusions = exclusions
105
+
106
+ def to_record(self) -> dict[str, object]:
107
+ return {
108
+ "schema_version": 1,
109
+ "evidence_tier": "e0",
110
+ "status": "abstained_no_identifiable_mutation_evidence",
111
+ "observation_count": self.observation_count,
112
+ "identifiable_contrast_count": 0,
113
+ "exclusions": [
114
+ {"reason": reason.value, "count": count}
115
+ for reason, count in self.exclusions
116
+ ],
117
+ "provider_calls": 0,
118
+ "publishable_reflection_content": False,
119
+ }
120
+
121
+
122
+ def _canonical_json(value: object) -> bytes:
123
+ return json.dumps(
124
+ value,
125
+ allow_nan=False,
126
+ ensure_ascii=True,
127
+ separators=(",", ":"),
128
+ sort_keys=True,
129
+ ).encode("ascii", errors="strict")
130
+
131
+
132
+ def _hash(domain: bytes, value: object) -> str:
133
+ return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
134
+
135
+
136
+ def _require_token(value: str, *, name: str) -> None:
137
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
138
+ raise ValueError(f"{name} must use the closed token grammar")
139
+
140
+
141
+ def _require_paths(values: tuple[str, ...], *, name: str) -> None:
142
+ if type(values) is not tuple or any(
143
+ type(value) is not str or _PATH.fullmatch(value) is None for value in values
144
+ ):
145
+ raise ValueError(f"{name} must be an exact tuple of canonical JSON paths")
146
+ if values != tuple(sorted(set(values))):
147
+ raise ValueError(f"{name} must be unique and canonical")
148
+
149
+
150
+ def _require_sha_tuple(
151
+ values: tuple[str, ...],
152
+ *,
153
+ name: str,
154
+ allow_empty: bool,
155
+ ) -> None:
156
+ if type(values) is not tuple or (not allow_empty and not values):
157
+ raise ValueError(f"{name} must be a canonical SHA-256 tuple")
158
+ for value in values:
159
+ require_sha256(value, name)
160
+ if values != tuple(sorted(set(values))):
161
+ raise ValueError(f"{name} must be unique and canonical")
162
+
163
+
164
+ class ReflectionEvidenceExclusionReason(str, Enum):
165
+ """Why an authenticated observation cannot identify a reflection claim."""
166
+
167
+ BEFORE_OR_AT_PRIOR_CUTOFF = "before_or_at_prior_cutoff"
168
+ AFTER_SEALED_CUTOFF = "after_sealed_cutoff"
169
+ FOREIGN_SCOPE = "foreign_scope"
170
+ NON_MUTATION_PROVENANCE = "non_mutation_provenance"
171
+ NON_SINGLE_INTERVENTION = "non_single_intervention"
172
+ MULTI_PATH_INTERVENTION = "multi_path_intervention"
173
+ MALFORMED_ACTION_SEMANTICS = "malformed_action_semantics"
174
+ LOCAL_INTERVENTION_UNAVAILABLE = "local_intervention_unavailable"
175
+ LOCAL_INTERVENTION_TOO_LARGE = "local_intervention_too_large"
176
+ NON_CHANGING_LOCAL_INTERVENTION = "non_changing_local_intervention"
177
+
178
+
179
+ @dataclass(frozen=True, slots=True)
180
+ class IdentifiableMutationReflectionContrast:
181
+ """One direct, single-path mutation fact suitable for reflection."""
182
+
183
+ contrast_id: str
184
+ source_observation_sha256: str
185
+ source_evidence_id: str
186
+ event_index: int
187
+ workload_instance_sha256: str
188
+ evaluator_contract_sha256: str
189
+ campaign_sha256: str
190
+ parent_candidate_id: CandidateId
191
+ child_candidate_id: CandidateId
192
+ operator_invocation_id: OperatorInvocationId
193
+ finite_contract_identity_sha256: str
194
+ action_semantics_compiler_id: str
195
+ action_semantics_compiler_version: int
196
+ action_semantics_definition_sha256: str
197
+ option_id: str
198
+ option_identity_sha256: str
199
+ option_family: str
200
+ affected_path: str
201
+ parent_local_value: FrozenJsonValue
202
+ child_local_value: FrozenJsonValue
203
+ parent_configuration_sha256: str
204
+ child_configuration_sha256: str
205
+ parent_outcome_sha256: str
206
+ child_outcome_sha256: str
207
+ metrics: tuple[ObservedMetricEffect, ...]
208
+ mechanism_identifying_design: bool
209
+ permitted_insight_kinds: tuple[ReflectionInsightKind, ...]
210
+ contrast_sha256: str = field(init=False)
211
+
212
+ def __post_init__(self) -> None:
213
+ for name in (
214
+ "contrast_id",
215
+ "source_observation_sha256",
216
+ "source_evidence_id",
217
+ "workload_instance_sha256",
218
+ "evaluator_contract_sha256",
219
+ "campaign_sha256",
220
+ "option_identity_sha256",
221
+ "finite_contract_identity_sha256",
222
+ "action_semantics_definition_sha256",
223
+ "parent_configuration_sha256",
224
+ "child_configuration_sha256",
225
+ "parent_outcome_sha256",
226
+ "child_outcome_sha256",
227
+ ):
228
+ require_sha256(getattr(self, name), name)
229
+ if self.contrast_id != self.source_observation_sha256:
230
+ raise ValueError("contrast_id must be the authenticated observation hash")
231
+ if type(self.parent_candidate_id) is not CandidateId:
232
+ raise TypeError("parent_candidate_id must be an exact CandidateId")
233
+ if type(self.child_candidate_id) is not CandidateId:
234
+ raise TypeError("child_candidate_id must be an exact CandidateId")
235
+ if type(self.operator_invocation_id) is not OperatorInvocationId:
236
+ raise TypeError(
237
+ "operator_invocation_id must be an exact OperatorInvocationId"
238
+ )
239
+ CandidateId.__post_init__(self.parent_candidate_id)
240
+ CandidateId.__post_init__(self.child_candidate_id)
241
+ OperatorInvocationId.__post_init__(self.operator_invocation_id)
242
+ if self.parent_candidate_id == self.child_candidate_id:
243
+ raise ValueError("reflection child occurrence cannot reuse its parent ID")
244
+ _require_token(
245
+ self.action_semantics_compiler_id,
246
+ name="action_semantics_compiler_id",
247
+ )
248
+ if (
249
+ type(self.action_semantics_compiler_version) is not int
250
+ or self.action_semantics_compiler_version <= 0
251
+ ):
252
+ raise ValueError("action_semantics_compiler_version must be positive")
253
+ if type(self.event_index) is not int or self.event_index <= 0:
254
+ raise ValueError("event_index must be positive")
255
+ if type(self.option_id) is not str or _OPTION_ID.fullmatch(self.option_id) is None:
256
+ raise ValueError("option_id must use the closed option grammar")
257
+ _require_token(self.option_family, name="option_family")
258
+ _require_paths((self.affected_path,), name="affected_path")
259
+ for name in ("parent_local_value", "child_local_value"):
260
+ value = getattr(self, name)
261
+ if not is_frozen_json_value(value):
262
+ raise TypeError(f"{name} must be exact frozen typed JSON")
263
+ if (
264
+ len(canonical_typed_json_bytes(value))
265
+ > MAX_REFLECTION_LOCAL_INTERVENTION_VALUE_BYTES
266
+ ):
267
+ raise ValueError(f"{name} exceeds the local intervention bound")
268
+ if typed_json_equal(self.parent_local_value, self.child_local_value):
269
+ raise ValueError("local intervention must change its affected value")
270
+ if (
271
+ type(self.metrics) is not tuple
272
+ or not self.metrics
273
+ or any(type(value) is not ObservedMetricEffect for value in self.metrics)
274
+ ):
275
+ raise ValueError("metrics must contain exact observed effects")
276
+ for value in self.metrics:
277
+ ObservedMetricEffect.__post_init__(value)
278
+ if tuple(value.metric_id for value in self.metrics) != tuple(
279
+ sorted({value.metric_id for value in self.metrics})
280
+ ):
281
+ raise ValueError("metrics must use unique canonical metric order")
282
+ if type(self.mechanism_identifying_design) is not bool:
283
+ raise TypeError("mechanism_identifying_design must be exact bool")
284
+ if self.mechanism_identifying_design:
285
+ raise ValueError(
286
+ "direct single-mutation contrasts cannot identify mechanisms"
287
+ )
288
+ if (
289
+ type(self.permitted_insight_kinds) is not tuple
290
+ or not self.permitted_insight_kinds
291
+ or any(
292
+ type(value) is not ReflectionInsightKind
293
+ for value in self.permitted_insight_kinds
294
+ )
295
+ ):
296
+ raise ValueError("permitted_insight_kinds must contain exact kinds")
297
+ if self.permitted_insight_kinds != tuple(
298
+ sorted(set(self.permitted_insight_kinds), key=lambda value: value.value)
299
+ ):
300
+ raise ValueError("permitted_insight_kinds must be unique and canonical")
301
+ expected_kinds = (ReflectionInsightKind.EMPIRICAL_PREDICTIVE_RULE,)
302
+ if self.permitted_insight_kinds != expected_kinds:
303
+ raise ValueError("permitted insight kinds overstate evidence design")
304
+ object.__setattr__(
305
+ self,
306
+ "contrast_sha256",
307
+ _hash(_CONTRAST_DOMAIN, self._unsigned_record()),
308
+ )
309
+
310
+ def _unsigned_record(self) -> dict[str, object]:
311
+ return {
312
+ "schema_version": 3,
313
+ "contrast_id": self.contrast_id,
314
+ "source_observation_sha256": self.source_observation_sha256,
315
+ "source_evidence_id": self.source_evidence_id,
316
+ "event_index": self.event_index,
317
+ "workload_instance_sha256": self.workload_instance_sha256,
318
+ "evaluator_contract_sha256": self.evaluator_contract_sha256,
319
+ "campaign_sha256": self.campaign_sha256,
320
+ "parent_candidate_id": self.parent_candidate_id.value,
321
+ "child_candidate_id": self.child_candidate_id.value,
322
+ "operator_invocation_id": self.operator_invocation_id.value,
323
+ "finite_contract_identity_sha256": (
324
+ self.finite_contract_identity_sha256
325
+ ),
326
+ "action_semantics_compiler": {
327
+ "compiler_id": self.action_semantics_compiler_id,
328
+ "compiler_version": self.action_semantics_compiler_version,
329
+ "definition_sha256": self.action_semantics_definition_sha256,
330
+ },
331
+ "option_id": self.option_id,
332
+ "option_identity_sha256": self.option_identity_sha256,
333
+ "option_family": self.option_family,
334
+ "affected_path": self.affected_path,
335
+ "parent_local_value": thaw_json(self.parent_local_value),
336
+ "parent_local_value_sha256": typed_json_sha256(
337
+ self.parent_local_value
338
+ ),
339
+ "child_local_value": thaw_json(self.child_local_value),
340
+ "child_local_value_sha256": typed_json_sha256(
341
+ self.child_local_value
342
+ ),
343
+ "parent_configuration_sha256": self.parent_configuration_sha256,
344
+ "child_configuration_sha256": self.child_configuration_sha256,
345
+ "parent_outcome_sha256": self.parent_outcome_sha256,
346
+ "child_outcome_sha256": self.child_outcome_sha256,
347
+ "metrics": [value.to_record() for value in self.metrics],
348
+ "mechanism_identifying_design": self.mechanism_identifying_design,
349
+ "permitted_insight_kinds": [
350
+ value.value for value in self.permitted_insight_kinds
351
+ ],
352
+ }
353
+
354
+ def to_record(self) -> dict[str, object]:
355
+ self.__post_init__()
356
+ return {**self._unsigned_record(), "contrast_sha256": self.contrast_sha256}
357
+
358
+ def to_prompt_record(self, *, evidence_citation_key: str) -> dict[str, object]:
359
+ """Return bounded scientific facts without raw candidate configurations."""
360
+
361
+ self.__post_init__()
362
+ _require_token(evidence_citation_key, name="evidence_citation_key")
363
+ return {
364
+ "evidence_citation_key": evidence_citation_key,
365
+ "event_index": self.event_index,
366
+ "option_id": self.option_id,
367
+ "option_family": self.option_family,
368
+ "affected_path": self.affected_path,
369
+ "local_intervention": {
370
+ "parent_value": thaw_json(self.parent_local_value),
371
+ "child_value": thaw_json(self.child_local_value),
372
+ },
373
+ "metric_effects": [
374
+ {
375
+ "metric_id": value.metric_id,
376
+ "direction": value.direction.value,
377
+ # Keep the hexadecimal form for exact replay, but also
378
+ # expose Python's shortest round-trippable decimal text.
379
+ # Several otherwise-conformant models read the binary
380
+ # exponent in ``float.hex`` as a base-10 exponent, which
381
+ # changes an authenticated measurement by many orders of
382
+ # magnitude inside the learned prose rule.
383
+ "delta_decimal": repr(value.delta),
384
+ "delta_hex": value.delta.hex(),
385
+ }
386
+ for value in self.metrics
387
+ ],
388
+ "permitted_insight_kinds": [
389
+ value.value for value in self.permitted_insight_kinds
390
+ ],
391
+ "comparison_anchor": "current_parent",
392
+ }
393
+
394
+
395
+ def _hypothesis_signature(
396
+ contrast: IdentifiableMutationReflectionContrast,
397
+ ) -> dict[str, object]:
398
+ """Return the parent-relative empirical hypothesis represented by a fact."""
399
+
400
+ if type(contrast) is not IdentifiableMutationReflectionContrast:
401
+ raise TypeError("contrast must be exact")
402
+ IdentifiableMutationReflectionContrast.__post_init__(contrast)
403
+ # Finite-contract and option-identity hashes authenticate one parent-bound
404
+ # occurrence. They intentionally remain on each contrast rather than in
405
+ # the semantic key, so the same local action observed under two parents can
406
+ # accumulate evidence instead of becoming duplicate prose claims.
407
+ return {
408
+ "schema_version": 1,
409
+ "scope": {
410
+ "campaign_sha256": contrast.campaign_sha256,
411
+ "workload_instance_sha256": contrast.workload_instance_sha256,
412
+ "evaluator_contract_sha256": contrast.evaluator_contract_sha256,
413
+ },
414
+ "finite_action": {
415
+ "option_id": contrast.option_id,
416
+ "option_family": contrast.option_family,
417
+ "affected_path": contrast.affected_path,
418
+ "action_semantics_compiler_id": (
419
+ contrast.action_semantics_compiler_id
420
+ ),
421
+ "action_semantics_compiler_version": (
422
+ contrast.action_semantics_compiler_version
423
+ ),
424
+ "action_semantics_definition_sha256": (
425
+ contrast.action_semantics_definition_sha256
426
+ ),
427
+ },
428
+ "local_intervention": {
429
+ "parent_value_sha256": typed_json_sha256(
430
+ contrast.parent_local_value
431
+ ),
432
+ "child_value_sha256": typed_json_sha256(
433
+ contrast.child_local_value
434
+ ),
435
+ },
436
+ "metric_direction_signature": [
437
+ {
438
+ "metric_id": value.metric_id,
439
+ "direction": value.direction.value,
440
+ }
441
+ for value in contrast.metrics
442
+ ],
443
+ "mechanism_identifying_design": contrast.mechanism_identifying_design,
444
+ "permitted_insight_kinds": [
445
+ value.value for value in contrast.permitted_insight_kinds
446
+ ],
447
+ "comparison_anchor": "current_parent",
448
+ }
449
+
450
+
451
+ @dataclass(frozen=True, slots=True)
452
+ class IdentifiableMutationReflectionHypothesisCluster:
453
+ """Repeated direct observations supporting one unique empirical claim."""
454
+
455
+ contrasts: tuple[IdentifiableMutationReflectionContrast, ...]
456
+ hypothesis_sha256: str = field(init=False)
457
+ cluster_sha256: str = field(init=False)
458
+
459
+ def __post_init__(self) -> None:
460
+ if (
461
+ type(self.contrasts) is not tuple
462
+ or not self.contrasts
463
+ or any(
464
+ type(value) is not IdentifiableMutationReflectionContrast
465
+ for value in self.contrasts
466
+ )
467
+ ):
468
+ raise ValueError("hypothesis cluster must contain exact contrasts")
469
+ for value in self.contrasts:
470
+ IdentifiableMutationReflectionContrast.__post_init__(value)
471
+ contrast_ids = tuple(value.contrast_id for value in self.contrasts)
472
+ if contrast_ids != tuple(sorted(set(contrast_ids))):
473
+ raise ValueError(
474
+ "hypothesis-cluster contrasts must be unique and canonical"
475
+ )
476
+ signature = _hypothesis_signature(self.contrasts[0])
477
+ if any(
478
+ _hypothesis_signature(value) != signature
479
+ for value in self.contrasts[1:]
480
+ ):
481
+ raise ValueError("hypothesis cluster mixed distinct empirical claims")
482
+ hypothesis_sha256 = _hash(_HYPOTHESIS_CLUSTER_DOMAIN, signature)
483
+ object.__setattr__(self, "hypothesis_sha256", hypothesis_sha256)
484
+ object.__setattr__(
485
+ self,
486
+ "cluster_sha256",
487
+ _hash(
488
+ _HYPOTHESIS_CLUSTER_DOMAIN,
489
+ {
490
+ "schema_version": 1,
491
+ "hypothesis_sha256": hypothesis_sha256,
492
+ "contrast_ids": list(contrast_ids),
493
+ },
494
+ ),
495
+ )
496
+
497
+ @property
498
+ def representative(self) -> IdentifiableMutationReflectionContrast:
499
+ self.__post_init__()
500
+ return self.contrasts[0]
501
+
502
+ @property
503
+ def contrast_ids(self) -> tuple[str, ...]:
504
+ self.__post_init__()
505
+ return tuple(value.contrast_id for value in self.contrasts)
506
+
507
+ def to_record(self) -> dict[str, object]:
508
+ self.__post_init__()
509
+ return {
510
+ "schema_version": 1,
511
+ "hypothesis_sha256": self.hypothesis_sha256,
512
+ "cluster_sha256": self.cluster_sha256,
513
+ "hypothesis_signature": _hypothesis_signature(self.contrasts[0]),
514
+ "contrast_ids": list(self.contrast_ids),
515
+ "observation_count": len(self.contrasts),
516
+ }
517
+
518
+
519
+ def cluster_identifiable_mutation_reflection_hypotheses(
520
+ contrasts: tuple[IdentifiableMutationReflectionContrast, ...],
521
+ ) -> tuple[IdentifiableMutationReflectionHypothesisCluster, ...]:
522
+ """Aggregate repeated interventions without collapsing conflicting effects."""
523
+
524
+ if (
525
+ type(contrasts) is not tuple
526
+ or not contrasts
527
+ or any(
528
+ type(value) is not IdentifiableMutationReflectionContrast
529
+ for value in contrasts
530
+ )
531
+ ):
532
+ raise ValueError("contrasts must contain exact identifiable evidence")
533
+ for value in contrasts:
534
+ IdentifiableMutationReflectionContrast.__post_init__(value)
535
+ contrast_ids = tuple(value.contrast_id for value in contrasts)
536
+ if contrast_ids != tuple(sorted(set(contrast_ids))):
537
+ raise ValueError("contrasts must use unique canonical contrast order")
538
+
539
+ grouped: dict[str, list[IdentifiableMutationReflectionContrast]] = {}
540
+ for contrast in contrasts:
541
+ hypothesis_sha256 = _hash(
542
+ _HYPOTHESIS_CLUSTER_DOMAIN,
543
+ _hypothesis_signature(contrast),
544
+ )
545
+ grouped.setdefault(hypothesis_sha256, []).append(contrast)
546
+ return tuple(
547
+ IdentifiableMutationReflectionHypothesisCluster(contrasts=tuple(values))
548
+ for values in grouped.values()
549
+ )
550
+
551
+
552
+ @dataclass(frozen=True, slots=True)
553
+ class ReflectionFalsificationFeedback:
554
+ """A prior card's authenticated counterexample, safe for later prompts."""
555
+
556
+ insight_content_sha256: str
557
+ applicable_workload_instance_sha256s: tuple[str, ...]
558
+ evaluator_contract_sha256: str
559
+ applicable_campaign_sha256s: tuple[str, ...]
560
+ audit_scope_sha256: str
561
+ available_event_index: int
562
+ affected_paths: tuple[str, ...]
563
+ predictions: tuple[tuple[str, MetricEffectDirection], ...]
564
+ counterexample_source_evidence_ids: tuple[str, ...]
565
+ semantic_audit_receipt_sha256: str
566
+ lifecycle_decision_receipt_sha256: str
567
+ deprecation_reason: str
568
+ feedback_sha256: str = field(init=False)
569
+
570
+ def __post_init__(self) -> None:
571
+ for name in (
572
+ "insight_content_sha256",
573
+ "evaluator_contract_sha256",
574
+ "audit_scope_sha256",
575
+ "semantic_audit_receipt_sha256",
576
+ "lifecycle_decision_receipt_sha256",
577
+ ):
578
+ require_sha256(getattr(self, name), name)
579
+ _require_sha_tuple(
580
+ self.applicable_workload_instance_sha256s,
581
+ name="applicable_workload_instance_sha256s",
582
+ allow_empty=False,
583
+ )
584
+ _require_sha_tuple(
585
+ self.applicable_campaign_sha256s,
586
+ name="applicable_campaign_sha256s",
587
+ allow_empty=True,
588
+ )
589
+ if type(self.available_event_index) is not int or (
590
+ self.available_event_index <= 0
591
+ ):
592
+ raise ValueError("available_event_index must be positive")
593
+ _require_paths(self.affected_paths, name="affected_paths")
594
+ if type(self.predictions) is not tuple or not self.predictions:
595
+ raise ValueError("predictions must be a non-empty exact tuple")
596
+ metric_ids: list[str] = []
597
+ for item in self.predictions:
598
+ if type(item) is not tuple or len(item) != 2:
599
+ raise TypeError("predictions must contain exact metric/direction pairs")
600
+ metric_id, direction = item
601
+ _require_token(metric_id, name="metric_id")
602
+ if (
603
+ type(direction) is not MetricEffectDirection
604
+ or direction is MetricEffectDirection.UNKNOWN
605
+ ):
606
+ raise ValueError("prior predictions must use known directions")
607
+ metric_ids.append(metric_id)
608
+ if metric_ids != sorted(set(metric_ids)):
609
+ raise ValueError("predictions must use unique canonical metric order")
610
+ if (
611
+ type(self.counterexample_source_evidence_ids) is not tuple
612
+ or not self.counterexample_source_evidence_ids
613
+ ):
614
+ raise ValueError("counterexample IDs must be a non-empty exact tuple")
615
+ for value in self.counterexample_source_evidence_ids:
616
+ require_sha256(value, "counterexample source evidence ID")
617
+ if self.counterexample_source_evidence_ids != tuple(
618
+ sorted(set(self.counterexample_source_evidence_ids))
619
+ ):
620
+ raise ValueError("counterexample IDs must be unique and canonical")
621
+ if (
622
+ type(self.deprecation_reason) is not str
623
+ or not self.deprecation_reason.strip()
624
+ or self.deprecation_reason != self.deprecation_reason.strip()
625
+ ):
626
+ raise ValueError("deprecation_reason must be canonical non-empty text")
627
+ object.__setattr__(
628
+ self,
629
+ "feedback_sha256",
630
+ _hash(_FEEDBACK_DOMAIN, self._unsigned_record()),
631
+ )
632
+
633
+ def _unsigned_record(self) -> dict[str, object]:
634
+ return {
635
+ "schema_version": 1,
636
+ "insight_content_sha256": self.insight_content_sha256,
637
+ "applicable_workload_instance_sha256s": list(
638
+ self.applicable_workload_instance_sha256s
639
+ ),
640
+ "evaluator_contract_sha256": self.evaluator_contract_sha256,
641
+ "applicable_campaign_sha256s": list(
642
+ self.applicable_campaign_sha256s
643
+ ),
644
+ "audit_scope_sha256": self.audit_scope_sha256,
645
+ "available_event_index": self.available_event_index,
646
+ "affected_paths": list(self.affected_paths),
647
+ "predictions": [
648
+ {"metric_id": metric_id, "direction": direction.value}
649
+ for metric_id, direction in self.predictions
650
+ ],
651
+ "counterexample_source_evidence_ids": list(
652
+ self.counterexample_source_evidence_ids
653
+ ),
654
+ "semantic_audit_receipt_sha256": self.semantic_audit_receipt_sha256,
655
+ "lifecycle_decision_receipt_sha256": (
656
+ self.lifecycle_decision_receipt_sha256
657
+ ),
658
+ "deprecation_reason": self.deprecation_reason,
659
+ "instruction": (
660
+ "do_not_repeat_without_new_identifiable_counterevidence"
661
+ ),
662
+ }
663
+
664
+ def to_record(self) -> dict[str, object]:
665
+ self.__post_init__()
666
+ return {**self._unsigned_record(), "feedback_sha256": self.feedback_sha256}
667
+
668
+ def to_prompt_record(self) -> dict[str, object]:
669
+ self.__post_init__()
670
+ return {
671
+ "available_event_index": self.available_event_index,
672
+ "affected_paths": list(self.affected_paths),
673
+ "predictions": [
674
+ {"metric_id": metric_id, "direction": direction.value}
675
+ for metric_id, direction in self.predictions
676
+ ],
677
+ "counterexample_count": len(self.counterexample_source_evidence_ids),
678
+ "deprecation_reason": self.deprecation_reason,
679
+ "instruction": (
680
+ "Do not repeat this claim unless the new single-intervention "
681
+ "evidence directly resolves its counterexample."
682
+ ),
683
+ }
684
+
685
+
686
+ @dataclass(frozen=True, slots=True)
687
+ class IdentifiableReflectionEvidenceSnapshot:
688
+ """Sealed mutation evidence and prior falsifications for one LLM call."""
689
+
690
+ campaign_sha256: str
691
+ workload_instance_sha256: str
692
+ evaluator_contract_sha256: str
693
+ prior_cutoff_event_index_exclusive: int
694
+ sealed_cutoff_event_index_inclusive: int
695
+ contrasts: tuple[IdentifiableMutationReflectionContrast, ...]
696
+ exclusions: tuple[tuple[ReflectionEvidenceExclusionReason, int], ...]
697
+ prior_falsifications: tuple[ReflectionFalsificationFeedback, ...] = ()
698
+ policy_id: str = IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_ID
699
+ policy_version: int = IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_VERSION
700
+ policy_definition_sha256: str = (
701
+ IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_DEFINITION_SHA256
702
+ )
703
+ snapshot_sha256: str = field(init=False)
704
+
705
+ def __post_init__(self) -> None:
706
+ for name in (
707
+ "campaign_sha256",
708
+ "workload_instance_sha256",
709
+ "evaluator_contract_sha256",
710
+ "policy_definition_sha256",
711
+ ):
712
+ require_sha256(getattr(self, name), name)
713
+ for name in (
714
+ "prior_cutoff_event_index_exclusive",
715
+ "sealed_cutoff_event_index_inclusive",
716
+ ):
717
+ value = getattr(self, name)
718
+ if type(value) is not int or value < 0:
719
+ raise ValueError(f"{name} must be a non-negative exact integer")
720
+ if (
721
+ self.sealed_cutoff_event_index_inclusive
722
+ <= self.prior_cutoff_event_index_exclusive
723
+ ):
724
+ raise ValueError("sealed cutoff must advance beyond the prior cutoff")
725
+ if (
726
+ type(self.contrasts) is not tuple
727
+ or not self.contrasts
728
+ or any(
729
+ type(value) is not IdentifiableMutationReflectionContrast
730
+ for value in self.contrasts
731
+ )
732
+ ):
733
+ raise ValueError("contrasts must contain exact eligible evidence")
734
+ for value in self.contrasts:
735
+ IdentifiableMutationReflectionContrast.__post_init__(value)
736
+ contrast_ids = tuple(value.contrast_id for value in self.contrasts)
737
+ if contrast_ids != tuple(sorted(set(contrast_ids))):
738
+ raise ValueError("contrasts must use unique canonical contrast order")
739
+ if any(
740
+ value.campaign_sha256 != self.campaign_sha256
741
+ or value.workload_instance_sha256 != self.workload_instance_sha256
742
+ or value.evaluator_contract_sha256 != self.evaluator_contract_sha256
743
+ or not (
744
+ self.prior_cutoff_event_index_exclusive
745
+ < value.event_index
746
+ <= self.sealed_cutoff_event_index_inclusive
747
+ )
748
+ for value in self.contrasts
749
+ ):
750
+ raise ValueError("contrast escapes the sealed reflection scope")
751
+ if type(self.exclusions) is not tuple:
752
+ raise TypeError("exclusions must be an exact tuple")
753
+ reasons: list[str] = []
754
+ for reason, count in self.exclusions:
755
+ if type(reason) is not ReflectionEvidenceExclusionReason:
756
+ raise TypeError("exclusion reason must be exact")
757
+ if type(count) is not int or count <= 0:
758
+ raise ValueError("exclusion count must be positive")
759
+ reasons.append(reason.value)
760
+ if reasons != sorted(set(reasons)):
761
+ raise ValueError("exclusions must use canonical unique reason order")
762
+ if type(self.prior_falsifications) is not tuple or any(
763
+ type(value) is not ReflectionFalsificationFeedback
764
+ for value in self.prior_falsifications
765
+ ):
766
+ raise TypeError("prior_falsifications must contain exact feedback")
767
+ for value in self.prior_falsifications:
768
+ ReflectionFalsificationFeedback.__post_init__(value)
769
+ if (
770
+ self.workload_instance_sha256
771
+ not in value.applicable_workload_instance_sha256s
772
+ or value.evaluator_contract_sha256
773
+ != self.evaluator_contract_sha256
774
+ or (
775
+ value.applicable_campaign_sha256s
776
+ and self.campaign_sha256
777
+ not in value.applicable_campaign_sha256s
778
+ )
779
+ or value.available_event_index
780
+ > self.sealed_cutoff_event_index_inclusive
781
+ ):
782
+ raise ValueError(
783
+ "prior falsification escapes the sealed reflection scope"
784
+ )
785
+ if tuple(value.feedback_sha256 for value in self.prior_falsifications) != tuple(
786
+ sorted({value.feedback_sha256 for value in self.prior_falsifications})
787
+ ):
788
+ raise ValueError("prior falsifications must be unique and canonical")
789
+ if (
790
+ self.policy_id != IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_ID
791
+ or self.policy_version != IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_VERSION
792
+ or self.policy_definition_sha256
793
+ != IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_DEFINITION_SHA256
794
+ ):
795
+ raise ValueError("unsupported identifiable reflection evidence policy")
796
+ object.__setattr__(
797
+ self,
798
+ "snapshot_sha256",
799
+ _hash(_SNAPSHOT_DOMAIN, self._unsigned_record()),
800
+ )
801
+
802
+ def _unsigned_record(self) -> dict[str, object]:
803
+ return {
804
+ "schema_version": 2,
805
+ "campaign_sha256": self.campaign_sha256,
806
+ "workload_instance_sha256": self.workload_instance_sha256,
807
+ "evaluator_contract_sha256": self.evaluator_contract_sha256,
808
+ "prior_cutoff_event_index_exclusive": (
809
+ self.prior_cutoff_event_index_exclusive
810
+ ),
811
+ "sealed_cutoff_event_index_inclusive": (
812
+ self.sealed_cutoff_event_index_inclusive
813
+ ),
814
+ "contrast_sha256s": [value.contrast_sha256 for value in self.contrasts],
815
+ "exclusions": [
816
+ {"reason": reason.value, "count": count}
817
+ for reason, count in self.exclusions
818
+ ],
819
+ "prior_falsification_sha256s": [
820
+ value.feedback_sha256 for value in self.prior_falsifications
821
+ ],
822
+ "policy": {
823
+ "policy_id": self.policy_id,
824
+ "policy_version": self.policy_version,
825
+ "definition_sha256": self.policy_definition_sha256,
826
+ },
827
+ }
828
+
829
+ def to_record(self) -> dict[str, object]:
830
+ self.__post_init__()
831
+ return {
832
+ **self._unsigned_record(),
833
+ "contrasts": [value.to_record() for value in self.contrasts],
834
+ "prior_falsifications": [
835
+ value.to_record() for value in self.prior_falsifications
836
+ ],
837
+ "snapshot_sha256": self.snapshot_sha256,
838
+ }
839
+
840
+
841
+ @dataclass(frozen=True, slots=True)
842
+ class _AuthenticatedActionFields:
843
+ option_id: str
844
+ option_identity_sha256: str
845
+ finite_contract_identity_sha256: str
846
+ option_family: str
847
+ changed_paths: tuple[str, ...]
848
+ compiler_id: str
849
+ compiler_version: int
850
+ compiler_definition_sha256: str
851
+
852
+
853
+ def _action_fields(
854
+ observation: AuthenticatedHypothesisObservation,
855
+ ) -> _AuthenticatedActionFields | None:
856
+ raw = thaw_json(observation.observed_action)
857
+ if type(raw) is not dict or raw.get("schema_version") != 2:
858
+ return None
859
+ option_id = raw.get("option_id")
860
+ option_identity = raw.get("option_identity_sha256")
861
+ contract_identity = raw.get("finite_contract_identity_sha256")
862
+ family = raw.get("option_family")
863
+ operator_family = raw.get("operator_family")
864
+ changed_paths = raw.get("changed_paths")
865
+ compiler = raw.get("compiler")
866
+ if (
867
+ type(option_id) is not str
868
+ or _OPTION_ID.fullmatch(option_id) is None
869
+ or type(option_identity) is not str
870
+ or type(contract_identity) is not str
871
+ or type(family) is not str
872
+ or _TOKEN.fullmatch(family) is None
873
+ or operator_family != observation.operator_family
874
+ or type(changed_paths) is not list
875
+ or any(type(value) is not str for value in changed_paths)
876
+ or type(compiler) is not dict
877
+ or set(compiler)
878
+ != {"compiler_id", "compiler_version", "definition_sha256"}
879
+ ):
880
+ return None
881
+ compiler_id = compiler.get("compiler_id")
882
+ compiler_version = compiler.get("compiler_version")
883
+ compiler_definition = compiler.get("definition_sha256")
884
+ if (
885
+ type(compiler_id) is not str
886
+ or _TOKEN.fullmatch(compiler_id) is None
887
+ or type(compiler_version) is not int
888
+ or compiler_version <= 0
889
+ or type(compiler_definition) is not str
890
+ ):
891
+ return None
892
+ try:
893
+ require_sha256(option_identity, "observed option identity")
894
+ require_sha256(contract_identity, "observed finite contract identity")
895
+ require_sha256(
896
+ compiler_definition,
897
+ "observed action semantics definition",
898
+ )
899
+ paths = tuple(changed_paths)
900
+ _require_paths(paths, name="observed changed_paths")
901
+ except (TypeError, ValueError):
902
+ return None
903
+ if paths != observation.affected_paths:
904
+ return None
905
+ if contract_identity != observation.finite_contract_identity_sha256:
906
+ return None
907
+ if (
908
+ compiler_id != observation.action_semantics_compiler_id
909
+ or compiler_version != observation.action_semantics_compiler_version
910
+ or compiler_definition != observation.action_semantics_definition_sha256
911
+ ):
912
+ return None
913
+ return _AuthenticatedActionFields(
914
+ option_id=option_id,
915
+ option_identity_sha256=option_identity,
916
+ finite_contract_identity_sha256=contract_identity,
917
+ option_family=family,
918
+ changed_paths=paths,
919
+ compiler_id=compiler_id,
920
+ compiler_version=compiler_version,
921
+ compiler_definition_sha256=compiler_definition,
922
+ )
923
+
924
+
925
+ def _path_parts(path: str) -> tuple[str | int, ...]:
926
+ _require_paths((path,), name="local intervention path")
927
+ parts: list[str | int] = []
928
+ index = 2
929
+ while index < len(path):
930
+ start = index
931
+ while index < len(path) and path[index] not in ".[":
932
+ index += 1
933
+ if start == index:
934
+ raise ValueError("local intervention path has an empty object key")
935
+ parts.append(path[start:index])
936
+ while index < len(path) and path[index] == "[":
937
+ end = path.index("]", index)
938
+ parts.append(int(path[index + 1 : end]))
939
+ index = end + 1
940
+ if index < len(path):
941
+ if path[index] != ".":
942
+ raise ValueError("local intervention path is malformed")
943
+ index += 1
944
+ return tuple(parts)
945
+
946
+
947
+ def _value_at_path(root: object, parts: tuple[str | int, ...]) -> object:
948
+ value = root
949
+ for part in parts:
950
+ if type(part) is str:
951
+ if type(value) is not dict or part not in value:
952
+ raise KeyError(part)
953
+ value = value[part]
954
+ else:
955
+ if (
956
+ type(value) is not list
957
+ or part < 0
958
+ or part >= len(value)
959
+ ):
960
+ raise IndexError(part)
961
+ value = value[part]
962
+ return value
963
+
964
+
965
+ def _local_intervention_values(
966
+ observation: AuthenticatedHypothesisObservation,
967
+ path: str,
968
+ ) -> (
969
+ tuple[FrozenJsonValue, FrozenJsonValue]
970
+ | ReflectionEvidenceExclusionReason
971
+ ):
972
+ try:
973
+ parts = _path_parts(path)
974
+ parent = freeze_json(
975
+ _value_at_path(thaw_json(observation.parent_configuration), parts)
976
+ )
977
+ child = freeze_json(
978
+ _value_at_path(thaw_json(observation.child_configuration), parts)
979
+ )
980
+ except (IndexError, KeyError, TypeError, ValueError):
981
+ return ReflectionEvidenceExclusionReason.LOCAL_INTERVENTION_UNAVAILABLE
982
+ if (
983
+ len(canonical_typed_json_bytes(parent))
984
+ > MAX_REFLECTION_LOCAL_INTERVENTION_VALUE_BYTES
985
+ or len(canonical_typed_json_bytes(child))
986
+ > MAX_REFLECTION_LOCAL_INTERVENTION_VALUE_BYTES
987
+ ):
988
+ return ReflectionEvidenceExclusionReason.LOCAL_INTERVENTION_TOO_LARGE
989
+ if typed_json_equal(parent, child):
990
+ return ReflectionEvidenceExclusionReason.NON_CHANGING_LOCAL_INTERVENTION
991
+ return parent, child
992
+
993
+
994
+ def project_identifiable_reflection_evidence(
995
+ observations: tuple[AuthenticatedHypothesisObservation, ...],
996
+ *,
997
+ campaign_sha256: str,
998
+ workload_instance_sha256: str,
999
+ evaluator_contract_sha256: str,
1000
+ prior_cutoff_event_index_exclusive: int,
1001
+ sealed_cutoff_event_index_inclusive: int,
1002
+ prior_falsifications: tuple[ReflectionFalsificationFeedback, ...] = (),
1003
+ ) -> IdentifiableReflectionEvidenceSnapshot:
1004
+ """Select only direct, one-path mutations inside an immutable cutoff."""
1005
+
1006
+ for name in (
1007
+ "campaign_sha256",
1008
+ "workload_instance_sha256",
1009
+ "evaluator_contract_sha256",
1010
+ ):
1011
+ require_sha256(locals()[name], name)
1012
+ if type(prior_cutoff_event_index_exclusive) is not int or (
1013
+ prior_cutoff_event_index_exclusive < 0
1014
+ ):
1015
+ raise ValueError("prior cutoff must be a non-negative exact integer")
1016
+ if type(sealed_cutoff_event_index_inclusive) is not int or (
1017
+ sealed_cutoff_event_index_inclusive <= prior_cutoff_event_index_exclusive
1018
+ ):
1019
+ raise ValueError("sealed cutoff must advance beyond the prior cutoff")
1020
+ if type(observations) is not tuple or any(
1021
+ type(value) is not AuthenticatedHypothesisObservation
1022
+ for value in observations
1023
+ ):
1024
+ raise TypeError("observations must contain exact authenticated evidence")
1025
+ exclusions: dict[ReflectionEvidenceExclusionReason, int] = {}
1026
+ contrasts: list[IdentifiableMutationReflectionContrast] = []
1027
+
1028
+ def exclude(reason: ReflectionEvidenceExclusionReason) -> None:
1029
+ exclusions[reason] = exclusions.get(reason, 0) + 1
1030
+
1031
+ for observation in observations:
1032
+ AuthenticatedHypothesisObservation.__post_init__(observation)
1033
+ if observation.event_index <= prior_cutoff_event_index_exclusive:
1034
+ exclude(ReflectionEvidenceExclusionReason.BEFORE_OR_AT_PRIOR_CUTOFF)
1035
+ continue
1036
+ if observation.event_index > sealed_cutoff_event_index_inclusive:
1037
+ exclude(ReflectionEvidenceExclusionReason.AFTER_SEALED_CUTOFF)
1038
+ continue
1039
+ if (
1040
+ observation.campaign_sha256 != campaign_sha256
1041
+ or observation.workload_instance_sha256 != workload_instance_sha256
1042
+ or observation.evaluator_contract_sha256 != evaluator_contract_sha256
1043
+ ):
1044
+ exclude(ReflectionEvidenceExclusionReason.FOREIGN_SCOPE)
1045
+ continue
1046
+ if observation.provenance is not EvidenceProvenance.DIRECT_MUTATION:
1047
+ exclude(ReflectionEvidenceExclusionReason.NON_MUTATION_PROVENANCE)
1048
+ continue
1049
+ if observation.intervention_identifiability is not (
1050
+ InterventionIdentifiability.EXACT_SINGLE
1051
+ ):
1052
+ exclude(ReflectionEvidenceExclusionReason.NON_SINGLE_INTERVENTION)
1053
+ continue
1054
+ if len(observation.affected_paths) != 1:
1055
+ exclude(ReflectionEvidenceExclusionReason.MULTI_PATH_INTERVENTION)
1056
+ continue
1057
+ action = _action_fields(observation)
1058
+ if action is None:
1059
+ exclude(ReflectionEvidenceExclusionReason.MALFORMED_ACTION_SEMANTICS)
1060
+ continue
1061
+ local_values = _local_intervention_values(
1062
+ observation,
1063
+ action.changed_paths[0],
1064
+ )
1065
+ if type(local_values) is ReflectionEvidenceExclusionReason:
1066
+ exclude(local_values)
1067
+ continue
1068
+ parent_local_value, child_local_value = local_values
1069
+ kinds = (ReflectionInsightKind.EMPIRICAL_PREDICTIVE_RULE,)
1070
+ contrasts.append(
1071
+ IdentifiableMutationReflectionContrast(
1072
+ contrast_id=observation.observation_sha256,
1073
+ source_observation_sha256=observation.observation_sha256,
1074
+ source_evidence_id=observation.source_evidence_id,
1075
+ event_index=observation.event_index,
1076
+ workload_instance_sha256=observation.workload_instance_sha256,
1077
+ evaluator_contract_sha256=observation.evaluator_contract_sha256,
1078
+ campaign_sha256=observation.campaign_sha256,
1079
+ parent_candidate_id=observation.parent_candidate_id,
1080
+ child_candidate_id=observation.child_candidate_id,
1081
+ operator_invocation_id=observation.operator_invocation_id,
1082
+ finite_contract_identity_sha256=(
1083
+ action.finite_contract_identity_sha256
1084
+ ),
1085
+ action_semantics_compiler_id=action.compiler_id,
1086
+ action_semantics_compiler_version=action.compiler_version,
1087
+ action_semantics_definition_sha256=(
1088
+ action.compiler_definition_sha256
1089
+ ),
1090
+ option_id=action.option_id,
1091
+ option_identity_sha256=action.option_identity_sha256,
1092
+ option_family=action.option_family,
1093
+ affected_path=action.changed_paths[0],
1094
+ parent_local_value=parent_local_value,
1095
+ child_local_value=child_local_value,
1096
+ parent_configuration_sha256=(
1097
+ observation.parent_configuration_sha256
1098
+ ),
1099
+ child_configuration_sha256=(
1100
+ observation.child_configuration_sha256
1101
+ ),
1102
+ parent_outcome_sha256=observation.parent_outcome_sha256,
1103
+ child_outcome_sha256=observation.child_outcome_sha256,
1104
+ metrics=observation.metrics,
1105
+ mechanism_identifying_design=(
1106
+ observation.mechanism_identifying_design
1107
+ ),
1108
+ permitted_insight_kinds=tuple(
1109
+ sorted(kinds, key=lambda value: value.value)
1110
+ ),
1111
+ )
1112
+ )
1113
+ if not contrasts:
1114
+ raise NoIdentifiableMutationEvidenceError(
1115
+ observation_count=len(observations),
1116
+ exclusions=tuple(
1117
+ sorted(exclusions.items(), key=lambda value: value[0].value)
1118
+ ),
1119
+ )
1120
+ return IdentifiableReflectionEvidenceSnapshot(
1121
+ campaign_sha256=campaign_sha256,
1122
+ workload_instance_sha256=workload_instance_sha256,
1123
+ evaluator_contract_sha256=evaluator_contract_sha256,
1124
+ prior_cutoff_event_index_exclusive=prior_cutoff_event_index_exclusive,
1125
+ sealed_cutoff_event_index_inclusive=sealed_cutoff_event_index_inclusive,
1126
+ contrasts=tuple(sorted(contrasts, key=lambda value: value.contrast_id)),
1127
+ exclusions=tuple(
1128
+ sorted(exclusions.items(), key=lambda value: value[0].value)
1129
+ ),
1130
+ prior_falsifications=prior_falsifications,
1131
+ )
1132
+
1133
+
1134
+ __all__ = [
1135
+ "IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_DEFINITION_SHA256",
1136
+ "IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_ID",
1137
+ "IDENTIFIABLE_REFLECTION_EVIDENCE_POLICY_VERSION",
1138
+ "MAX_REFLECTION_LOCAL_INTERVENTION_VALUE_BYTES",
1139
+ "NoIdentifiableMutationEvidenceError",
1140
+ "IdentifiableMutationReflectionContrast",
1141
+ "IdentifiableMutationReflectionHypothesisCluster",
1142
+ "IdentifiableReflectionEvidenceSnapshot",
1143
+ "ReflectionEvidenceExclusionReason",
1144
+ "ReflectionFalsificationFeedback",
1145
+ "cluster_identifiable_mutation_reflection_hypotheses",
1146
+ "project_identifiable_reflection_evidence",
1147
+ ]