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,187 @@
1
+ """Prospective task-keyed uniform comparator for matched finite action sets."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ from dataclasses import dataclass, field
8
+
9
+ from agent_evolve.domain.finite_action_set import FiniteActionSetAuthority
10
+ from agent_evolve.domain.patch import require_sha256
11
+ from agent_evolve.ports.finite_action_selection import (
12
+ EngineFiniteActionRequest,
13
+ FiniteActionDecision,
14
+ FiniteActionSelectorKind,
15
+ ProspectiveUniformRankToken,
16
+ validate_finite_action_decision,
17
+ )
18
+
19
+
20
+ POLICY_ID = "task_keyed_uniform_finite_action"
21
+ POLICY_VERSION = 2
22
+ _DEFINITION_DOMAIN = b"agent-evolve:task-keyed-uniform-finite-action:def:v2\x00"
23
+ _STATE_DOMAIN = b"agent-evolve:task-keyed-uniform-finite-action:state:v2\x00"
24
+ _RANK_DOMAIN = b"agent-evolve:task-keyed-uniform-finite-action:rank:v2\x00"
25
+ _DEFINITION = {
26
+ "rank": (
27
+ "counter-domain-separated SHA-256 rejection sampling followed by "
28
+ "modulo K"
29
+ ),
30
+ "propensity": "1/K under a prospectively randomized uniform seed",
31
+ "resample_on_model_alias": False,
32
+ "current_outcome_access": False,
33
+ }
34
+ POLICY_DEFINITION_SHA256 = hashlib.sha256(
35
+ _DEFINITION_DOMAIN
36
+ + json.dumps(
37
+ _DEFINITION,
38
+ ensure_ascii=True,
39
+ allow_nan=False,
40
+ separators=(",", ":"),
41
+ sort_keys=True,
42
+ ).encode("ascii")
43
+ ).hexdigest()
44
+
45
+
46
+ @dataclass(frozen=True, slots=True)
47
+ class TaskKeyedUniformFiniteActionPolicy:
48
+ """Freeze and replay one uniform ordinal without inspecting outcomes."""
49
+
50
+ schedule_seed_sha256: str
51
+ policy_id: str = field(init=False, default=POLICY_ID)
52
+ policy_version: int = field(init=False, default=POLICY_VERSION)
53
+ definition_sha256: str = field(
54
+ init=False,
55
+ default=POLICY_DEFINITION_SHA256,
56
+ )
57
+ schedule_state_sha256: str = field(init=False)
58
+
59
+ def __post_init__(self) -> None:
60
+ require_sha256(self.schedule_seed_sha256, "schedule_seed_sha256")
61
+ object.__setattr__(
62
+ self,
63
+ "schedule_state_sha256",
64
+ hashlib.sha256(
65
+ _STATE_DOMAIN + bytes.fromhex(self.schedule_seed_sha256)
66
+ ).hexdigest(),
67
+ )
68
+
69
+ def _selected_ordinal(
70
+ self,
71
+ authority: FiniteActionSetAuthority,
72
+ *,
73
+ task_sha256: str,
74
+ ) -> int:
75
+ FiniteActionSetAuthority.__post_init__(authority)
76
+ require_sha256(task_sha256, "task_sha256")
77
+ framing = (
78
+ _RANK_DOMAIN
79
+ + bytes.fromhex(self.schedule_seed_sha256)
80
+ + bytes.fromhex(task_sha256)
81
+ + bytes.fromhex(authority.authority_sha256)
82
+ + bytes.fromhex(authority.support.support_sha256)
83
+ + bytes.fromhex(authority.card.card_content_sha256)
84
+ )
85
+ cardinality = authority.support.cardinality
86
+ sample_space = 1 << 256
87
+ acceptance_limit = sample_space - (sample_space % cardinality)
88
+ # Rejection sampling is required because ``2**256 % K`` is non-zero
89
+ # for K=5, 6, and 7. A direct digest modulo K would therefore make the
90
+ # recorded 1/K propensity false outside the first K=8 release.
91
+ for counter in range(1 << 32):
92
+ digest = hashlib.sha256(
93
+ framing + counter.to_bytes(4, "big", signed=False)
94
+ ).digest()
95
+ sample = int.from_bytes(digest, "big", signed=False)
96
+ if sample < acceptance_limit:
97
+ return sample % cardinality
98
+ raise RuntimeError("uniform finite-action rejection sampler exhausted")
99
+
100
+ def freeze_rank(
101
+ self,
102
+ authority: FiniteActionSetAuthority,
103
+ *,
104
+ task_sha256: str,
105
+ pre_outcome_phase_commit_sha256: str,
106
+ ) -> ProspectiveUniformRankToken:
107
+ if type(authority) is not FiniteActionSetAuthority:
108
+ raise TypeError("authority must be an exact FiniteActionSetAuthority")
109
+ FiniteActionSetAuthority.__post_init__(authority)
110
+ require_sha256(
111
+ pre_outcome_phase_commit_sha256,
112
+ "pre_outcome_phase_commit_sha256",
113
+ )
114
+ return ProspectiveUniformRankToken(
115
+ task_sha256=task_sha256,
116
+ authority_sha256=authority.authority_sha256,
117
+ support_sha256=authority.support.support_sha256,
118
+ card_reference=authority.card.reference,
119
+ card_content_sha256=authority.card.card_content_sha256,
120
+ cardinality=authority.support.cardinality,
121
+ selected_ordinal=self._selected_ordinal(
122
+ authority,
123
+ task_sha256=task_sha256,
124
+ ),
125
+ schedule_policy_id=self.policy_id,
126
+ schedule_policy_version=self.policy_version,
127
+ schedule_definition_sha256=self.definition_sha256,
128
+ schedule_state_sha256=self.schedule_state_sha256,
129
+ pre_outcome_phase_commit_sha256=pre_outcome_phase_commit_sha256,
130
+ current_outcome_access=False,
131
+ )
132
+
133
+ def choose(self, request: EngineFiniteActionRequest) -> FiniteActionDecision:
134
+ if type(request) is not EngineFiniteActionRequest:
135
+ raise TypeError("request must be an exact EngineFiniteActionRequest")
136
+ EngineFiniteActionRequest.__post_init__(request)
137
+ token = request.prospective_rank
138
+ expected_policy = (
139
+ self.policy_id,
140
+ self.policy_version,
141
+ self.definition_sha256,
142
+ self.schedule_state_sha256,
143
+ )
144
+ observed_policy = (
145
+ token.schedule_policy_id,
146
+ token.schedule_policy_version,
147
+ token.schedule_definition_sha256,
148
+ token.schedule_state_sha256,
149
+ )
150
+ if observed_policy != expected_policy:
151
+ raise ValueError("prospective rank token uses a foreign schedule policy")
152
+ if token.selected_ordinal != self._selected_ordinal(
153
+ request.authority,
154
+ task_sha256=token.task_sha256,
155
+ ):
156
+ raise ValueError("prospective rank token does not replay its public rank")
157
+ row = request.authority.support.options[token.selected_ordinal]
158
+ decision = FiniteActionDecision(
159
+ authority_sha256=request.authority.authority_sha256,
160
+ support_sha256=request.authority.support.support_sha256,
161
+ selector_kind=FiniteActionSelectorKind.ENGINE,
162
+ selected_ordinal=token.selected_ordinal,
163
+ option_id=row.option.option_id,
164
+ option_identity_sha256=row.option.identity_sha256,
165
+ child_configuration_sha256=row.option.child_configuration_sha256,
166
+ phenotype_identity_sha256=row.phenotype_identity_sha256,
167
+ selector_policy_id=self.policy_id,
168
+ selector_policy_version=self.policy_version,
169
+ selector_definition_sha256=self.definition_sha256,
170
+ prospective_token_sha256=token.token_sha256,
171
+ model_call_id=None,
172
+ model_prompt_sha256=None,
173
+ model_telemetry_sha256=None,
174
+ propensity_numerator=1,
175
+ propensity_denominator=request.authority.support.cardinality,
176
+ current_outcome_access=False,
177
+ )
178
+ validate_finite_action_decision(request.authority, decision)
179
+ return decision
180
+
181
+
182
+ __all__ = [
183
+ "POLICY_DEFINITION_SHA256",
184
+ "POLICY_ID",
185
+ "POLICY_VERSION",
186
+ "TaskKeyedUniformFiniteActionPolicy",
187
+ ]
@@ -0,0 +1,377 @@
1
+ """Authenticated, workload-neutral projection of finite-option prompt facts.
2
+
3
+ Finite variation options may carry replay and catalog hashes alongside the
4
+ semantic facts a model needs to compare actions. Sending every metadata field
5
+ can dominate the prompt without expanding model authority: trusted code still
6
+ owns the full child configurations and exact option identities. This policy
7
+ lets a benchmark composition root explicitly allowlist prompt-visible metadata
8
+ while retaining an authenticated join to every sealed source option.
9
+
10
+ The legacy ``ALL`` mode reproduces ``FiniteVariationContract.prompt_records``
11
+ exactly. No key is removed by heuristic and no outcome value is consulted.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import hashlib
17
+ import json
18
+ import re
19
+ from dataclasses import dataclass
20
+ from enum import Enum
21
+
22
+ from agent_evolve.domain.finite_variation import (
23
+ FiniteVariationContract,
24
+ validate_finite_variation_contract,
25
+ )
26
+ from agent_evolve.domain.patch import require_sha256
27
+
28
+
29
+ POLICY_ID = "finite_option_prompt_projection"
30
+ POLICY_VERSION = 1
31
+ POLICY_DEFINITION_SHA256 = hashlib.sha256(
32
+ b"agent-evolve:finite-option-prompt-projection:v1\x00"
33
+ b"always=option-id,family,description;metadata=all-or-explicit-allowlist;"
34
+ b"unknown-allowlist-key=fail;source-option-identities=authenticated;"
35
+ b"outcome-access=false;heuristic-key-removal=false"
36
+ ).hexdigest()
37
+
38
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
39
+ _CONFIGURATION_DOMAIN = b"agent-evolve:finite-option-prompt-config:v1\x00"
40
+ _PROMPT_RECORD_DOMAIN = b"agent-evolve:finite-option-prompt-record:v1\x00"
41
+ _PROJECTION_DOMAIN = b"agent-evolve:finite-option-prompt-projection:v1\x00"
42
+
43
+
44
+ def _canonical_json(value: object) -> bytes:
45
+ return json.dumps(
46
+ value,
47
+ allow_nan=False,
48
+ ensure_ascii=True,
49
+ separators=(",", ":"),
50
+ sort_keys=True,
51
+ ).encode("ascii", errors="strict")
52
+
53
+
54
+ class PromptMetadataProjectionMode(str, Enum):
55
+ """Closed choice between legacy-complete and explicit semantic metadata."""
56
+
57
+ ALL = "all"
58
+ ALLOWLIST = "allowlist"
59
+
60
+
61
+ def _validate_metadata_keys(values: tuple[str, ...], *, name: str) -> None:
62
+ if type(values) is not tuple or any(
63
+ type(value) is not str or _TOKEN.fullmatch(value) is None for value in values
64
+ ):
65
+ raise TypeError(f"{name} must be an exact tuple of closed metadata keys")
66
+ if values != tuple(sorted(set(values))):
67
+ raise ValueError(f"{name} must be unique and canonical")
68
+
69
+
70
+ @dataclass(frozen=True, slots=True)
71
+ class FiniteOptionPromptRecord:
72
+ """One projected record plus its hidden exact source-option join."""
73
+
74
+ option_id: str
75
+ family: str
76
+ description: str
77
+ metadata: tuple[tuple[str, str], ...]
78
+ source_option_identity_sha256: str
79
+
80
+ def __post_init__(self) -> None:
81
+ if type(self.option_id) is not str or not self.option_id:
82
+ raise ValueError("option_id must be a non-empty exact string")
83
+ if type(self.family) is not str or not self.family:
84
+ raise ValueError("family must be a non-empty exact string")
85
+ if type(self.description) is not str or not self.description:
86
+ raise ValueError("description must be a non-empty exact string")
87
+ if type(self.metadata) is not tuple or any(
88
+ type(item) is not tuple
89
+ or len(item) != 2
90
+ or type(item[0]) is not str
91
+ or type(item[1]) is not str
92
+ for item in self.metadata
93
+ ):
94
+ raise TypeError("metadata must contain exact key/value string pairs")
95
+ keys = tuple(key for key, _ in self.metadata)
96
+ _validate_metadata_keys(keys, name="metadata keys")
97
+ require_sha256(
98
+ self.source_option_identity_sha256,
99
+ "source_option_identity_sha256",
100
+ )
101
+
102
+ def to_prompt_record(self) -> dict[str, object]:
103
+ """Return only model-visible semantic facts, never hidden identities."""
104
+
105
+ self.__post_init__()
106
+ return {
107
+ "option_id": self.option_id,
108
+ "family": self.family,
109
+ "description": self.description,
110
+ "metadata": dict(self.metadata),
111
+ }
112
+
113
+ @property
114
+ def prompt_record_sha256(self) -> str:
115
+ return hashlib.sha256(
116
+ _PROMPT_RECORD_DOMAIN + _canonical_json(self.to_prompt_record())
117
+ ).hexdigest()
118
+
119
+ def to_binding_record(self) -> dict[str, object]:
120
+ self.__post_init__()
121
+ return {
122
+ "option_id": self.option_id,
123
+ "source_option_identity_sha256": self.source_option_identity_sha256,
124
+ "prompt_record_sha256": self.prompt_record_sha256,
125
+ }
126
+
127
+
128
+ @dataclass(frozen=True, slots=True)
129
+ class FiniteOptionPromptProjection:
130
+ """Immutable projection receipt and ordered model-visible records."""
131
+
132
+ source_contract_sha256: str
133
+ mode: PromptMetadataProjectionMode
134
+ included_metadata_keys: tuple[str, ...]
135
+ available_metadata_keys: tuple[str, ...]
136
+ omitted_metadata_keys: tuple[str, ...]
137
+ records: tuple[FiniteOptionPromptRecord, ...]
138
+ policy_id: str
139
+ policy_version: int
140
+ policy_definition_sha256: str
141
+ policy_configuration_sha256: str
142
+
143
+ def __post_init__(self) -> None:
144
+ require_sha256(self.source_contract_sha256, "source_contract_sha256")
145
+ if type(self.mode) is not PromptMetadataProjectionMode:
146
+ raise TypeError("mode must be exact PromptMetadataProjectionMode")
147
+ for name in (
148
+ "included_metadata_keys",
149
+ "available_metadata_keys",
150
+ "omitted_metadata_keys",
151
+ ):
152
+ _validate_metadata_keys(getattr(self, name), name=name)
153
+ available = set(self.available_metadata_keys)
154
+ included = set(self.included_metadata_keys)
155
+ omitted = set(self.omitted_metadata_keys)
156
+ if not included.issubset(available):
157
+ raise ValueError("included metadata keys escape the available key set")
158
+ if omitted != available - included or omitted & included:
159
+ raise ValueError("omitted metadata keys do not complement included keys")
160
+ if self.mode is PromptMetadataProjectionMode.ALL and omitted:
161
+ raise ValueError("all-metadata projection cannot omit a key")
162
+ if (
163
+ type(self.records) is not tuple
164
+ or not self.records
165
+ or any(
166
+ type(value) is not FiniteOptionPromptRecord for value in self.records
167
+ )
168
+ ):
169
+ raise TypeError("records must contain exact prompt records")
170
+ for value in self.records:
171
+ value.__post_init__()
172
+ record_keys = {key for key, _ in value.metadata}
173
+ if not record_keys.issubset(included):
174
+ raise ValueError("a prompt record escaped the included metadata set")
175
+ option_ids = tuple(value.option_id for value in self.records)
176
+ if len(set(option_ids)) != len(option_ids):
177
+ raise ValueError("prompt records cannot repeat an option ID")
178
+ if self.policy_id != POLICY_ID:
179
+ raise ValueError("policy_id drifted")
180
+ if self.policy_version != POLICY_VERSION:
181
+ raise ValueError("policy_version drifted")
182
+ if self.policy_definition_sha256 != POLICY_DEFINITION_SHA256:
183
+ raise ValueError("policy_definition_sha256 drifted")
184
+ require_sha256(
185
+ self.policy_configuration_sha256,
186
+ "policy_configuration_sha256",
187
+ )
188
+ expected_configuration = FiniteOptionPromptProjectionPolicy(
189
+ metadata_keys=(
190
+ None
191
+ if self.mode is PromptMetadataProjectionMode.ALL
192
+ else self.included_metadata_keys
193
+ )
194
+ ).configuration_sha256
195
+ if self.policy_configuration_sha256 != expected_configuration:
196
+ raise ValueError("policy configuration does not match projection mode")
197
+
198
+ def prompt_records(self) -> tuple[dict[str, object], ...]:
199
+ self.__post_init__()
200
+ return tuple(value.to_prompt_record() for value in self.records)
201
+
202
+ def _unsigned_binding_record(self) -> dict[str, object]:
203
+ self.__post_init__()
204
+ return {
205
+ "schema_version": 1,
206
+ "source_contract_sha256": self.source_contract_sha256,
207
+ "policy": {
208
+ "policy_id": self.policy_id,
209
+ "policy_version": self.policy_version,
210
+ "definition_sha256": self.policy_definition_sha256,
211
+ "configuration_sha256": self.policy_configuration_sha256,
212
+ "mode": self.mode.value,
213
+ },
214
+ "included_metadata_keys": list(self.included_metadata_keys),
215
+ "available_metadata_keys": list(self.available_metadata_keys),
216
+ "omitted_metadata_keys": list(self.omitted_metadata_keys),
217
+ "ordered_records": [value.to_binding_record() for value in self.records],
218
+ "outcome_values_consulted": False,
219
+ }
220
+
221
+ @property
222
+ def projection_sha256(self) -> str:
223
+ return hashlib.sha256(
224
+ _PROJECTION_DOMAIN + _canonical_json(self._unsigned_binding_record())
225
+ ).hexdigest()
226
+
227
+ def to_binding_record(self) -> dict[str, object]:
228
+ return {
229
+ **self._unsigned_binding_record(),
230
+ "projection_sha256": self.projection_sha256,
231
+ }
232
+
233
+ def to_prompt_contract_record(self) -> dict[str, object]:
234
+ """Return the compact receipt rendered beside projected options.
235
+
236
+ The complete per-option source joins remain inside the input binding.
237
+ The prompt needs only their aggregate projection digest plus the closed
238
+ policy/configuration facts: ``input_binding_sha256`` authenticates the
239
+ complete receipt without paying to render hundreds of hidden hashes.
240
+ """
241
+
242
+ self.__post_init__()
243
+ return {
244
+ "schema_version": 1,
245
+ "projection_sha256": self.projection_sha256,
246
+ "source_contract_sha256": self.source_contract_sha256,
247
+ "policy": {
248
+ "policy_id": self.policy_id,
249
+ "policy_version": self.policy_version,
250
+ "definition_sha256": self.policy_definition_sha256,
251
+ "configuration_sha256": self.policy_configuration_sha256,
252
+ "mode": self.mode.value,
253
+ },
254
+ "included_metadata_keys": list(self.included_metadata_keys),
255
+ "available_metadata_keys": list(self.available_metadata_keys),
256
+ "omitted_metadata_keys": list(self.omitted_metadata_keys),
257
+ "ordered_record_count": len(self.records),
258
+ "outcome_values_consulted": False,
259
+ }
260
+
261
+ def require_contract(self, contract: FiniteVariationContract) -> None:
262
+ """Fail closed unless replay from ``contract`` is byte-identical."""
263
+
264
+ if type(contract) is not FiniteVariationContract:
265
+ raise TypeError("contract must be exact FiniteVariationContract")
266
+ validate_finite_variation_contract(contract)
267
+ policy = FiniteOptionPromptProjectionPolicy(
268
+ metadata_keys=(
269
+ None
270
+ if self.mode is PromptMetadataProjectionMode.ALL
271
+ else self.included_metadata_keys
272
+ )
273
+ )
274
+ expected = policy.project(contract)
275
+ if expected.projection_sha256 != self.projection_sha256:
276
+ raise ValueError("prompt projection differs from the sealed contract")
277
+
278
+
279
+ @dataclass(frozen=True, slots=True)
280
+ class FiniteOptionPromptProjectionPolicy:
281
+ """Project all metadata or an explicit composition-root allowlist."""
282
+
283
+ metadata_keys: tuple[str, ...] | None = None
284
+ policy_id: str = POLICY_ID
285
+ policy_version: int = POLICY_VERSION
286
+ definition_sha256: str = POLICY_DEFINITION_SHA256
287
+
288
+ def __post_init__(self) -> None:
289
+ if self.metadata_keys is not None:
290
+ _validate_metadata_keys(self.metadata_keys, name="metadata_keys")
291
+ if self.policy_id != POLICY_ID:
292
+ raise ValueError("policy_id drifted")
293
+ if self.policy_version != POLICY_VERSION:
294
+ raise ValueError("policy_version drifted")
295
+ if self.definition_sha256 != POLICY_DEFINITION_SHA256:
296
+ raise ValueError("definition_sha256 drifted")
297
+
298
+ @property
299
+ def mode(self) -> PromptMetadataProjectionMode:
300
+ return (
301
+ PromptMetadataProjectionMode.ALL
302
+ if self.metadata_keys is None
303
+ else PromptMetadataProjectionMode.ALLOWLIST
304
+ )
305
+
306
+ @property
307
+ def configuration_sha256(self) -> str:
308
+ self.__post_init__()
309
+ return hashlib.sha256(
310
+ _CONFIGURATION_DOMAIN
311
+ + _canonical_json(
312
+ {
313
+ "schema_version": 1,
314
+ "mode": self.mode.value,
315
+ "metadata_keys": (
316
+ None if self.metadata_keys is None else list(self.metadata_keys)
317
+ ),
318
+ }
319
+ )
320
+ ).hexdigest()
321
+
322
+ def project(
323
+ self,
324
+ contract: FiniteVariationContract,
325
+ ) -> FiniteOptionPromptProjection:
326
+ self.__post_init__()
327
+ if type(contract) is not FiniteVariationContract:
328
+ raise TypeError("contract must be exact FiniteVariationContract")
329
+ validate_finite_variation_contract(contract)
330
+ available = tuple(
331
+ sorted({key for option in contract.options for key, _ in option.metadata})
332
+ )
333
+ included = available if self.metadata_keys is None else self.metadata_keys
334
+ unknown = set(included) - set(available)
335
+ if unknown:
336
+ raise ValueError(
337
+ "metadata allowlist names keys absent from the finite contract: "
338
+ + ",".join(sorted(unknown))
339
+ )
340
+ included_set = set(included)
341
+ records = tuple(
342
+ FiniteOptionPromptRecord(
343
+ option_id=option.option_id,
344
+ family=option.family,
345
+ description=option.description,
346
+ metadata=tuple(
347
+ (key, value)
348
+ for key, value in option.metadata
349
+ if key in included_set
350
+ ),
351
+ source_option_identity_sha256=option.identity_sha256,
352
+ )
353
+ for option in contract.options
354
+ )
355
+ return FiniteOptionPromptProjection(
356
+ source_contract_sha256=contract.identity_sha256,
357
+ mode=self.mode,
358
+ included_metadata_keys=included,
359
+ available_metadata_keys=available,
360
+ omitted_metadata_keys=tuple(sorted(set(available) - included_set)),
361
+ records=records,
362
+ policy_id=self.policy_id,
363
+ policy_version=self.policy_version,
364
+ policy_definition_sha256=self.definition_sha256,
365
+ policy_configuration_sha256=self.configuration_sha256,
366
+ )
367
+
368
+
369
+ __all__ = [
370
+ "FiniteOptionPromptProjection",
371
+ "FiniteOptionPromptProjectionPolicy",
372
+ "FiniteOptionPromptRecord",
373
+ "POLICY_DEFINITION_SHA256",
374
+ "POLICY_ID",
375
+ "POLICY_VERSION",
376
+ "PromptMetadataProjectionMode",
377
+ ]