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,758 @@
1
+ """Content-addressed, provider-free live-runtime provenance manifests.
2
+
3
+ The application layer owns the immutable record and its validation rules. It
4
+ does not know any benchmark, provider SDK, credential source, or evaluator.
5
+ Composition roots supply closed JSON sections and an explicit role-indexed
6
+ source closure. Local probes are deliberately content-blind: git diffs and
7
+ status are hashed but never embedded, so a manifest cannot leak source or
8
+ secrets through provenance metadata.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import hashlib
14
+ import importlib.metadata
15
+ import json
16
+ import os
17
+ import platform
18
+ import re
19
+ import subprocess
20
+ import sys
21
+ from dataclasses import dataclass, field
22
+ from datetime import datetime
23
+ from pathlib import Path
24
+ from typing import Mapping, Sequence
25
+
26
+ from agent_evolve.domain.typed_json import (
27
+ FrozenJsonObject,
28
+ freeze_json,
29
+ thaw_json,
30
+ )
31
+ from agent_evolve.ports.artifact_store import decode_json_bytes
32
+
33
+
34
+ _SHA256 = re.compile(r"^[0-9a-f]{64}$")
35
+ _TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
36
+ _UTC_SECONDS = re.compile(r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$")
37
+ _FILE_DOMAIN = b"agent-evolve:live-runtime-file:v1\x00"
38
+ _SOURCE_DOMAIN = b"agent-evolve:live-runtime-source-closure:v1\x00"
39
+ _SECTION_DOMAIN = b"agent-evolve:live-runtime-section:v1\x00"
40
+ _MANIFEST_DOMAIN = b"agent-evolve:live-runtime-manifest:v1\x00"
41
+
42
+
43
+ class LiveRuntimeManifestError(RuntimeError):
44
+ """A prospective runtime commitment is missing or has drifted."""
45
+
46
+
47
+ def _canonical_bytes(value: object) -> bytes:
48
+ return json.dumps(
49
+ value,
50
+ ensure_ascii=True,
51
+ allow_nan=False,
52
+ separators=(",", ":"),
53
+ sort_keys=True,
54
+ ).encode("ascii")
55
+
56
+
57
+ def _hash(domain: bytes, value: object) -> str:
58
+ return hashlib.sha256(domain + _canonical_bytes(value)).hexdigest()
59
+
60
+
61
+ def _sha256_bytes(value: bytes) -> str:
62
+ return hashlib.sha256(value).hexdigest()
63
+
64
+
65
+ def _exact_json_equal(left: object, right: object) -> bool:
66
+ """JSON equality that does not conflate bool with integer values."""
67
+
68
+ if type(left) is not type(right):
69
+ return False
70
+ if type(left) is dict:
71
+ assert type(right) is dict
72
+ return left.keys() == right.keys() and all(
73
+ _exact_json_equal(left[key], right[key]) for key in left
74
+ )
75
+ if type(left) is list:
76
+ assert type(right) is list
77
+ return len(left) == len(right) and all(
78
+ _exact_json_equal(a, b) for a, b in zip(left, right, strict=True)
79
+ )
80
+ return left == right
81
+
82
+
83
+ def _validate_token(value: str, *, name: str) -> None:
84
+ if type(value) is not str or _TOKEN.fullmatch(value) is None:
85
+ raise ValueError(f"{name} must use the closed lowercase token grammar")
86
+
87
+
88
+ def _validate_logical_path(value: str) -> None:
89
+ if type(value) is not str or not value or "\\" in value:
90
+ raise ValueError("logical_path must be non-empty canonical POSIX text")
91
+ parsed = Path(value)
92
+ if parsed.is_absolute() or value != parsed.as_posix() or ".." in parsed.parts:
93
+ raise ValueError("logical_path must be relative canonical POSIX text")
94
+
95
+
96
+ @dataclass(frozen=True, slots=True)
97
+ class RuntimeFileBinding:
98
+ """Exact bytes for one source, lock, route, or evaluator dependency."""
99
+
100
+ logical_path: str
101
+ resolved_path: str
102
+ size_bytes: int
103
+ sha256: str
104
+ binding_sha256: str = field(init=False)
105
+
106
+ def __post_init__(self) -> None:
107
+ _validate_logical_path(self.logical_path)
108
+ resolved = Path(self.resolved_path)
109
+ if (
110
+ type(self.resolved_path) is not str
111
+ or not resolved.is_absolute()
112
+ or self.resolved_path != str(resolved)
113
+ ):
114
+ raise ValueError("resolved_path must be an absolute normalized path")
115
+ if type(self.size_bytes) is not int or self.size_bytes < 0:
116
+ raise ValueError("size_bytes must be a non-negative exact integer")
117
+ if type(self.sha256) is not str or _SHA256.fullmatch(self.sha256) is None:
118
+ raise ValueError("sha256 must be a lowercase SHA-256 digest")
119
+ object.__setattr__(
120
+ self,
121
+ "binding_sha256",
122
+ _hash(_FILE_DOMAIN, self._identity_record()),
123
+ )
124
+
125
+ def _identity_record(self) -> dict[str, object]:
126
+ return {
127
+ "logical_path": self.logical_path,
128
+ "resolved_path": self.resolved_path,
129
+ "size_bytes": self.size_bytes,
130
+ "sha256": self.sha256,
131
+ }
132
+
133
+ def to_record(self) -> dict[str, object]:
134
+ self.__post_init__()
135
+ return {**self._identity_record(), "binding_sha256": self.binding_sha256}
136
+
137
+
138
+ def capture_runtime_file(path: Path, *, logical_path: str) -> RuntimeFileBinding:
139
+ """Hash one exact file without interpreting or publishing its contents."""
140
+
141
+ _validate_logical_path(logical_path)
142
+ resolved = path.expanduser().resolve(strict=True)
143
+ if not resolved.is_file():
144
+ raise LiveRuntimeManifestError(f"runtime dependency is not a file: {resolved}")
145
+ content = resolved.read_bytes()
146
+ return RuntimeFileBinding(
147
+ logical_path=logical_path,
148
+ resolved_path=str(resolved),
149
+ size_bytes=len(content),
150
+ sha256=_sha256_bytes(content),
151
+ )
152
+
153
+
154
+ @dataclass(frozen=True, slots=True)
155
+ class RuntimeSourceClosure:
156
+ """Role-indexed conservative closure over every live execution byte."""
157
+
158
+ files: tuple[RuntimeFileBinding, ...]
159
+ role_paths: tuple[tuple[str, tuple[str, ...]], ...]
160
+ source_sha256: str = field(init=False)
161
+
162
+ def __post_init__(self) -> None:
163
+ if (
164
+ type(self.files) is not tuple
165
+ or not self.files
166
+ or any(type(value) is not RuntimeFileBinding for value in self.files)
167
+ ):
168
+ raise TypeError("files must be a non-empty exact tuple of bindings")
169
+ for value in self.files:
170
+ value.__post_init__()
171
+ if self.files != tuple(sorted(self.files, key=lambda value: value.logical_path)):
172
+ raise ValueError("source files must be ordered by logical_path")
173
+ logical_paths = tuple(value.logical_path for value in self.files)
174
+ if len(set(logical_paths)) != len(logical_paths):
175
+ raise ValueError("source closure cannot repeat a logical path")
176
+ if type(self.role_paths) is not tuple or not self.role_paths:
177
+ raise TypeError("role_paths must be a non-empty exact tuple")
178
+ if self.role_paths != tuple(sorted(self.role_paths, key=lambda value: value[0])):
179
+ raise ValueError("source roles must be canonically ordered")
180
+ observed_roles: set[str] = set()
181
+ covered: set[str] = set()
182
+ for item in self.role_paths:
183
+ if type(item) is not tuple or len(item) != 2:
184
+ raise TypeError("each source role must be an exact pair")
185
+ role, paths = item
186
+ _validate_token(role, name="source role")
187
+ if role in observed_roles:
188
+ raise ValueError("source roles cannot repeat")
189
+ observed_roles.add(role)
190
+ if (
191
+ type(paths) is not tuple
192
+ or not paths
193
+ or paths != tuple(sorted(set(paths)))
194
+ or any(path not in logical_paths for path in paths)
195
+ ):
196
+ raise ValueError("source role paths must be non-empty and canonical")
197
+ covered.update(paths)
198
+ if covered != set(logical_paths):
199
+ raise ValueError("every source file must belong to at least one role")
200
+ object.__setattr__(
201
+ self,
202
+ "source_sha256",
203
+ _hash(_SOURCE_DOMAIN, self._identity_record()),
204
+ )
205
+
206
+ def _identity_record(self) -> dict[str, object]:
207
+ return {
208
+ "schema_version": 1,
209
+ "files": [value.to_record() for value in self.files],
210
+ "roles": {
211
+ role: list(paths) for role, paths in self.role_paths
212
+ },
213
+ }
214
+
215
+ def to_record(self) -> dict[str, object]:
216
+ self.__post_init__()
217
+ return {**self._identity_record(), "source_sha256": self.source_sha256}
218
+
219
+
220
+ def capture_runtime_source_closure(
221
+ files_by_role: Mapping[str, Mapping[str, Path]],
222
+ ) -> RuntimeSourceClosure:
223
+ """Capture a deduplicated closure from benchmark-owned semantic roles."""
224
+
225
+ if not isinstance(files_by_role, Mapping) or not files_by_role:
226
+ raise TypeError("files_by_role must be a non-empty mapping")
227
+ bindings: dict[str, RuntimeFileBinding] = {}
228
+ roles: list[tuple[str, tuple[str, ...]]] = []
229
+ for role in sorted(files_by_role):
230
+ _validate_token(role, name="source role")
231
+ sources = files_by_role[role]
232
+ if not isinstance(sources, Mapping) or not sources:
233
+ raise ValueError(f"source role {role} must contain at least one file")
234
+ paths: list[str] = []
235
+ for logical_path in sorted(sources):
236
+ captured = capture_runtime_file(
237
+ Path(sources[logical_path]),
238
+ logical_path=logical_path,
239
+ )
240
+ prior = bindings.get(logical_path)
241
+ if prior is not None and prior != captured:
242
+ raise ValueError(f"logical source path {logical_path} is ambiguous")
243
+ bindings[logical_path] = captured
244
+ paths.append(logical_path)
245
+ roles.append((role, tuple(paths)))
246
+ return RuntimeSourceClosure(
247
+ files=tuple(bindings[key] for key in sorted(bindings)),
248
+ role_paths=tuple(roles),
249
+ )
250
+
251
+
252
+ @dataclass(frozen=True, slots=True)
253
+ class RuntimeManifestSection:
254
+ """One immutable benchmark- or infrastructure-owned manifest section."""
255
+
256
+ section_id: str
257
+ payload: FrozenJsonObject
258
+ section_sha256: str = field(init=False)
259
+
260
+ def __post_init__(self) -> None:
261
+ _validate_token(self.section_id, name="section_id")
262
+ if type(self.payload) is not FrozenJsonObject:
263
+ raise TypeError("section payload must be an exact FrozenJsonObject")
264
+ self.payload.__post_init__()
265
+ object.__setattr__(
266
+ self,
267
+ "section_sha256",
268
+ _hash(
269
+ _SECTION_DOMAIN,
270
+ {
271
+ "section_id": self.section_id,
272
+ "payload": thaw_json(self.payload),
273
+ },
274
+ ),
275
+ )
276
+
277
+ @classmethod
278
+ def seal(
279
+ cls,
280
+ section_id: str,
281
+ payload: Mapping[str, object],
282
+ ) -> "RuntimeManifestSection":
283
+ if not isinstance(payload, Mapping):
284
+ raise TypeError("section payload must be a mapping")
285
+ frozen = freeze_json(dict(payload))
286
+ if type(frozen) is not FrozenJsonObject:
287
+ raise TypeError("section payload did not freeze as an object")
288
+ return cls(section_id=section_id, payload=frozen)
289
+
290
+ def to_record(self) -> dict[str, object]:
291
+ self.__post_init__()
292
+ return {
293
+ "section_id": self.section_id,
294
+ "payload": thaw_json(self.payload),
295
+ "section_sha256": self.section_sha256,
296
+ }
297
+
298
+
299
+ def _run_git(root: Path, *args: str) -> bytes:
300
+ try:
301
+ completed = subprocess.run(
302
+ ("git", *args),
303
+ cwd=root,
304
+ check=True,
305
+ capture_output=True,
306
+ )
307
+ except (OSError, subprocess.CalledProcessError) as exc:
308
+ raise LiveRuntimeManifestError(
309
+ f"git provenance probe failed: {' '.join(args)}"
310
+ ) from exc
311
+ return completed.stdout
312
+
313
+
314
+ def capture_git_worktree_section(
315
+ repo_root: Path,
316
+ *,
317
+ source_closure: RuntimeSourceClosure,
318
+ ) -> RuntimeManifestSection:
319
+ """Bind HEAD and dirty state while retaining only content-blind digests."""
320
+
321
+ source_closure.__post_init__()
322
+ root = repo_root.expanduser().resolve(strict=True)
323
+ observed_root = Path(
324
+ _run_git(root, "rev-parse", "--show-toplevel").decode("utf-8").strip()
325
+ ).resolve(strict=True)
326
+ if observed_root != root:
327
+ raise LiveRuntimeManifestError("repo_root is not the git worktree root")
328
+ head = _run_git(root, "rev-parse", "HEAD").decode("ascii").strip()
329
+ head_tree = _run_git(root, "rev-parse", "HEAD^{tree}").decode("ascii").strip()
330
+ if _SHA256.fullmatch(head) is None and re.fullmatch(r"[0-9a-f]{40}", head) is None:
331
+ raise LiveRuntimeManifestError("git HEAD is not a supported object identity")
332
+ if _SHA256.fullmatch(head_tree) is None and re.fullmatch(r"[0-9a-f]{40}", head_tree) is None:
333
+ raise LiveRuntimeManifestError("git HEAD tree is not a supported identity")
334
+ try:
335
+ branch_probe = subprocess.run(
336
+ ("git", "symbolic-ref", "--quiet", "--short", "HEAD"),
337
+ cwd=root,
338
+ check=False,
339
+ capture_output=True,
340
+ )
341
+ except OSError as exc:
342
+ raise LiveRuntimeManifestError("git branch provenance probe failed") from exc
343
+ if branch_probe.returncode not in (0, 1):
344
+ raise LiveRuntimeManifestError("git branch provenance probe failed")
345
+ branch = (
346
+ branch_probe.stdout.decode("utf-8").strip()
347
+ if branch_probe.returncode == 0
348
+ else None
349
+ )
350
+ # Restrict every dirty-state probe to the bound closure. A live run writes
351
+ # journals and evaluator receipts after the prospective manifest is built;
352
+ # hashing full-worktree state would therefore make the gate invalidate
353
+ # itself even though no executable input changed.
354
+ repo_paths = tuple(
355
+ sorted(
356
+ {
357
+ Path(binding.resolved_path).relative_to(root).as_posix()
358
+ for binding in source_closure.files
359
+ if Path(binding.resolved_path).is_relative_to(root)
360
+ }
361
+ )
362
+ )
363
+ if repo_paths:
364
+ pathspec = ("--", *repo_paths)
365
+ status = _run_git(
366
+ root,
367
+ "status",
368
+ "--porcelain=v2",
369
+ "-z",
370
+ "--untracked-files=all",
371
+ *pathspec,
372
+ )
373
+ staged = _run_git(
374
+ root,
375
+ "diff",
376
+ "--cached",
377
+ "--binary",
378
+ "--no-ext-diff",
379
+ *pathspec,
380
+ )
381
+ unstaged = _run_git(
382
+ root,
383
+ "diff",
384
+ "--binary",
385
+ "--no-ext-diff",
386
+ *pathspec,
387
+ )
388
+ tracked = set(
389
+ item.decode("utf-8")
390
+ for item in _run_git(
391
+ root,
392
+ "ls-files",
393
+ "-z",
394
+ *pathspec,
395
+ ).split(b"\x00")
396
+ if item
397
+ )
398
+ untracked = set(
399
+ item.decode("utf-8")
400
+ for item in _run_git(
401
+ root,
402
+ "ls-files",
403
+ "--others",
404
+ "--exclude-standard",
405
+ "-z",
406
+ *pathspec,
407
+ ).split(b"\x00")
408
+ if item
409
+ )
410
+ else:
411
+ status = staged = unstaged = b""
412
+ tracked: set[str] = set()
413
+ untracked: set[str] = set()
414
+ relevant_states: list[dict[str, str]] = []
415
+ for binding in source_closure.files:
416
+ path = Path(binding.resolved_path)
417
+ if not path.is_relative_to(root):
418
+ state = "external"
419
+ else:
420
+ relative = path.relative_to(root).as_posix()
421
+ if relative in tracked:
422
+ state = "tracked"
423
+ elif relative in untracked:
424
+ state = "untracked"
425
+ else:
426
+ state = "ignored_or_unindexed"
427
+ relevant_states.append(
428
+ {"logical_path": binding.logical_path, "git_state": state}
429
+ )
430
+ return RuntimeManifestSection.seal(
431
+ "git_worktree",
432
+ {
433
+ "schema_version": 1,
434
+ "repo_root": str(root),
435
+ "head_commit": head,
436
+ "head_tree": head_tree,
437
+ "branch": branch,
438
+ "head_mode": "attached" if branch is not None else "detached",
439
+ "dirty": bool(status),
440
+ "dirty_scope": "runtime_source_closure_repo_files_only",
441
+ "repo_relative_source_file_count": len(repo_paths),
442
+ "porcelain_v2_bytes": len(status),
443
+ "porcelain_v2_sha256": _sha256_bytes(status),
444
+ "staged_binary_diff_bytes": len(staged),
445
+ "staged_binary_diff_sha256": _sha256_bytes(staged),
446
+ "unstaged_binary_diff_bytes": len(unstaged),
447
+ "unstaged_binary_diff_sha256": _sha256_bytes(unstaged),
448
+ "relevant_source_manifest_sha256": source_closure.source_sha256,
449
+ "relevant_source_git_states": relevant_states,
450
+ "content_disclosure": "hashes_only_no_patch_or_source_text",
451
+ },
452
+ )
453
+
454
+
455
+ def capture_runtime_environment_section(
456
+ *,
457
+ distribution_names: Sequence[str],
458
+ dependency_locks: Sequence[RuntimeFileBinding],
459
+ ) -> RuntimeManifestSection:
460
+ """Bind the interpreter, host ABI, installed transports, and lock bytes."""
461
+
462
+ if (
463
+ not isinstance(distribution_names, Sequence)
464
+ or isinstance(distribution_names, (str, bytes))
465
+ or not distribution_names
466
+ ):
467
+ raise TypeError("distribution_names must be a non-empty sequence")
468
+ names = tuple(distribution_names)
469
+ if (
470
+ any(type(value) is not str or not value for value in names)
471
+ or names != tuple(sorted(set(names)))
472
+ ):
473
+ raise ValueError("distribution_names must be unique and ordered")
474
+ locks = tuple(dependency_locks)
475
+ if not locks or any(type(value) is not RuntimeFileBinding for value in locks):
476
+ raise TypeError("dependency_locks must contain exact file bindings")
477
+ for value in locks:
478
+ value.__post_init__()
479
+ packages: dict[str, str] = {}
480
+ for name in names:
481
+ try:
482
+ packages[name] = importlib.metadata.version(name)
483
+ except importlib.metadata.PackageNotFoundError as exc:
484
+ raise LiveRuntimeManifestError(
485
+ f"required runtime distribution is unavailable: {name}"
486
+ ) from exc
487
+ executable = Path(os.path.abspath(sys.executable))
488
+ if not executable.is_file():
489
+ raise LiveRuntimeManifestError("invocation Python executable is unavailable")
490
+ return RuntimeManifestSection.seal(
491
+ "runtime_environment",
492
+ {
493
+ "schema_version": 1,
494
+ "python_executable": str(executable),
495
+ "python_executable_resolved": str(executable.resolve(strict=True)),
496
+ "python_prefix": os.path.abspath(sys.prefix),
497
+ "python_base_prefix": os.path.abspath(sys.base_prefix),
498
+ "python_version": platform.python_version(),
499
+ "python_implementation": platform.python_implementation(),
500
+ "python_compiler": platform.python_compiler(),
501
+ "platform": platform.platform(),
502
+ "system": platform.system(),
503
+ "release": platform.release(),
504
+ "machine": platform.machine(),
505
+ "installed_distributions": packages,
506
+ "dependency_locks": [value.to_record() for value in locks],
507
+ },
508
+ )
509
+
510
+
511
+ @dataclass(frozen=True, slots=True)
512
+ class LiveRuntimeManifest:
513
+ """Prospective full-stack commitment produced before credentials or work."""
514
+
515
+ manifest_id: str
516
+ manifest_version: int
517
+ built_at_utc: str
518
+ source_closure: RuntimeSourceClosure
519
+ sections: tuple[RuntimeManifestSection, ...]
520
+ required_section_ids: tuple[str, ...]
521
+ manifest_sha256: str = field(init=False)
522
+
523
+ def __post_init__(self) -> None:
524
+ _validate_token(self.manifest_id, name="manifest_id")
525
+ if type(self.manifest_version) is not int or self.manifest_version <= 0:
526
+ raise ValueError("manifest_version must be a positive exact integer")
527
+ if type(self.built_at_utc) is not str or _UTC_SECONDS.fullmatch(
528
+ self.built_at_utc
529
+ ) is None:
530
+ raise ValueError("built_at_utc must be UTC RFC3339 at whole seconds")
531
+ try:
532
+ datetime.strptime(self.built_at_utc, "%Y-%m-%dT%H:%M:%SZ")
533
+ except ValueError as exc:
534
+ raise ValueError("built_at_utc is not a real UTC instant") from exc
535
+ self.source_closure.__post_init__()
536
+ if (
537
+ type(self.sections) is not tuple
538
+ or not self.sections
539
+ or any(type(value) is not RuntimeManifestSection for value in self.sections)
540
+ ):
541
+ raise TypeError("sections must be a non-empty exact tuple")
542
+ for value in self.sections:
543
+ value.__post_init__()
544
+ if self.sections != tuple(sorted(self.sections, key=lambda value: value.section_id)):
545
+ raise ValueError("manifest sections must be canonically ordered")
546
+ ids = tuple(value.section_id for value in self.sections)
547
+ if len(set(ids)) != len(ids):
548
+ raise ValueError("manifest section IDs cannot repeat")
549
+ if (
550
+ type(self.required_section_ids) is not tuple
551
+ or not self.required_section_ids
552
+ or self.required_section_ids != tuple(sorted(set(self.required_section_ids)))
553
+ ):
554
+ raise ValueError("required_section_ids must be unique and ordered")
555
+ for value in self.required_section_ids:
556
+ _validate_token(value, name="required section ID")
557
+ if not set(self.required_section_ids).issubset(ids):
558
+ raise ValueError("one or more required manifest sections are missing")
559
+ object.__setattr__(
560
+ self,
561
+ "manifest_sha256",
562
+ _hash(_MANIFEST_DOMAIN, self._identity_record()),
563
+ )
564
+
565
+ def _identity_record(self) -> dict[str, object]:
566
+ return {
567
+ "schema_version": 1,
568
+ "manifest_id": self.manifest_id,
569
+ "manifest_version": self.manifest_version,
570
+ "built_at_utc": self.built_at_utc,
571
+ "claim_boundary": {
572
+ "credentials_read": False,
573
+ "provider_called": False,
574
+ "physical_evaluator_called": False,
575
+ "current_run_outcomes_observed": False,
576
+ "meaning": "prospective provider-free runtime commitment only",
577
+ },
578
+ "source_closure": self.source_closure.to_record(),
579
+ "required_section_ids": list(self.required_section_ids),
580
+ "sections": [value.to_record() for value in self.sections],
581
+ }
582
+
583
+ def to_record(self) -> dict[str, object]:
584
+ self.__post_init__()
585
+ return {**self._identity_record(), "manifest_sha256": self.manifest_sha256}
586
+
587
+
588
+ def build_live_runtime_manifest(
589
+ *,
590
+ manifest_id: str,
591
+ manifest_version: int,
592
+ built_at_utc: str,
593
+ source_closure: RuntimeSourceClosure,
594
+ sections: Sequence[RuntimeManifestSection],
595
+ required_section_ids: Sequence[str],
596
+ ) -> LiveRuntimeManifest:
597
+ """Canonicalize injected sections into one self-authenticating manifest."""
598
+
599
+ return LiveRuntimeManifest(
600
+ manifest_id=manifest_id,
601
+ manifest_version=manifest_version,
602
+ built_at_utc=built_at_utc,
603
+ source_closure=source_closure,
604
+ sections=tuple(sorted(sections, key=lambda value: value.section_id)),
605
+ required_section_ids=tuple(sorted(required_section_ids)),
606
+ )
607
+
608
+
609
+ def verify_runtime_source_closure(source: RuntimeSourceClosure) -> None:
610
+ """Fail closed if any currently installed source byte differs."""
611
+
612
+ source.__post_init__()
613
+ observed = tuple(
614
+ capture_runtime_file(
615
+ Path(value.resolved_path),
616
+ logical_path=value.logical_path,
617
+ )
618
+ for value in source.files
619
+ )
620
+ if observed != source.files:
621
+ raise LiveRuntimeManifestError("live runtime source closure drifted")
622
+
623
+
624
+ def runtime_file_binding_from_record(value: Mapping[str, object]) -> RuntimeFileBinding:
625
+ """Reconstruct and authenticate one serialized file binding."""
626
+
627
+ try:
628
+ binding = RuntimeFileBinding(
629
+ logical_path=str(value["logical_path"]),
630
+ resolved_path=str(value["resolved_path"]),
631
+ size_bytes=int(value["size_bytes"]),
632
+ sha256=str(value["sha256"]),
633
+ )
634
+ except (KeyError, TypeError, ValueError) as exc:
635
+ raise LiveRuntimeManifestError("runtime file binding is malformed") from exc
636
+ if not _exact_json_equal(dict(value), binding.to_record()):
637
+ raise LiveRuntimeManifestError("runtime file binding identity changed")
638
+ return binding
639
+
640
+
641
+ def runtime_source_closure_from_record(
642
+ value: Mapping[str, object],
643
+ ) -> RuntimeSourceClosure:
644
+ """Reconstruct and authenticate a serialized role-indexed source closure."""
645
+
646
+ try:
647
+ raw_files = value["files"]
648
+ raw_roles = value["roles"]
649
+ if type(raw_files) is not list or type(raw_roles) is not dict:
650
+ raise TypeError("source closure files/roles have wrong types")
651
+ files = tuple(
652
+ runtime_file_binding_from_record(item)
653
+ for item in raw_files
654
+ if type(item) is dict
655
+ )
656
+ if len(files) != len(raw_files):
657
+ raise TypeError("one source file binding is not an object")
658
+ role_paths = tuple(
659
+ (role, tuple(paths))
660
+ for role, paths in sorted(raw_roles.items())
661
+ if type(role) is str and type(paths) is list
662
+ )
663
+ if len(role_paths) != len(raw_roles):
664
+ raise TypeError("one source role is malformed")
665
+ closure = RuntimeSourceClosure(files=files, role_paths=role_paths)
666
+ except (KeyError, TypeError, ValueError) as exc:
667
+ raise LiveRuntimeManifestError("runtime source closure is malformed") from exc
668
+ if not _exact_json_equal(dict(value), closure.to_record()):
669
+ raise LiveRuntimeManifestError("runtime source closure identity changed")
670
+ return closure
671
+
672
+
673
+ def runtime_manifest_section_from_record(
674
+ value: Mapping[str, object],
675
+ ) -> RuntimeManifestSection:
676
+ """Reconstruct and authenticate one serialized manifest section."""
677
+
678
+ try:
679
+ payload = value["payload"]
680
+ if type(payload) is not dict:
681
+ raise TypeError("section payload must be an object")
682
+ section = RuntimeManifestSection.seal(str(value["section_id"]), payload)
683
+ except (KeyError, TypeError, ValueError) as exc:
684
+ raise LiveRuntimeManifestError("runtime manifest section is malformed") from exc
685
+ if not _exact_json_equal(dict(value), section.to_record()):
686
+ raise LiveRuntimeManifestError("runtime manifest section identity changed")
687
+ return section
688
+
689
+
690
+ def live_runtime_manifest_from_record(
691
+ value: Mapping[str, object],
692
+ ) -> LiveRuntimeManifest:
693
+ """Reconstruct a complete manifest and reject any forged self-hash."""
694
+
695
+ try:
696
+ raw_source = value["source_closure"]
697
+ raw_sections = value["sections"]
698
+ raw_required = value["required_section_ids"]
699
+ if (
700
+ type(raw_source) is not dict
701
+ or type(raw_sections) is not list
702
+ or type(raw_required) is not list
703
+ ):
704
+ raise TypeError("manifest containers have wrong types")
705
+ source = runtime_source_closure_from_record(raw_source)
706
+ sections = tuple(
707
+ runtime_manifest_section_from_record(item)
708
+ for item in raw_sections
709
+ if type(item) is dict
710
+ )
711
+ if len(sections) != len(raw_sections):
712
+ raise TypeError("one manifest section is not an object")
713
+ manifest = LiveRuntimeManifest(
714
+ manifest_id=str(value["manifest_id"]),
715
+ manifest_version=int(value["manifest_version"]),
716
+ built_at_utc=str(value["built_at_utc"]),
717
+ source_closure=source,
718
+ sections=sections,
719
+ required_section_ids=tuple(str(item) for item in raw_required),
720
+ )
721
+ except (KeyError, TypeError, ValueError) as exc:
722
+ raise LiveRuntimeManifestError("live runtime manifest is malformed") from exc
723
+ if not _exact_json_equal(dict(value), manifest.to_record()):
724
+ raise LiveRuntimeManifestError("live runtime manifest identity changed")
725
+ return manifest
726
+
727
+
728
+ def load_live_runtime_manifest(path: Path) -> LiveRuntimeManifest:
729
+ """Load strict JSON and authenticate every nested manifest commitment."""
730
+
731
+ resolved = path.expanduser().resolve(strict=True)
732
+ try:
733
+ value = decode_json_bytes(resolved.read_bytes())
734
+ except Exception as exc:
735
+ raise LiveRuntimeManifestError("live runtime manifest is unreadable") from exc
736
+ if type(value) is not dict:
737
+ raise LiveRuntimeManifestError("live runtime manifest root is not an object")
738
+ return live_runtime_manifest_from_record(value)
739
+
740
+
741
+ __all__ = [
742
+ "LiveRuntimeManifest",
743
+ "LiveRuntimeManifestError",
744
+ "RuntimeFileBinding",
745
+ "RuntimeManifestSection",
746
+ "RuntimeSourceClosure",
747
+ "build_live_runtime_manifest",
748
+ "capture_git_worktree_section",
749
+ "capture_runtime_environment_section",
750
+ "capture_runtime_file",
751
+ "capture_runtime_source_closure",
752
+ "live_runtime_manifest_from_record",
753
+ "load_live_runtime_manifest",
754
+ "runtime_file_binding_from_record",
755
+ "runtime_manifest_section_from_record",
756
+ "runtime_source_closure_from_record",
757
+ "verify_runtime_source_closure",
758
+ ]