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.
- agent_evolve/__init__.py +722 -0
- agent_evolve/agentic.py +2800 -0
- agent_evolve/api.py +767 -0
- agent_evolve/application/__init__.py +1580 -0
- agent_evolve/application/action_allocation.py +744 -0
- agent_evolve/application/action_allocation_frame.py +347 -0
- agent_evolve/application/action_allocation_frame_commit.py +185 -0
- agent_evolve/application/action_allocation_frame_commit_v3.py +184 -0
- agent_evolve/application/action_allocation_frame_v3.py +338 -0
- agent_evolve/application/action_archive_value.py +497 -0
- agent_evolve/application/action_evidence_consistency.py +455 -0
- agent_evolve/application/action_forecast_partitioning.py +1471 -0
- agent_evolve/application/action_metric_projection.py +211 -0
- agent_evolve/application/action_role_value.py +680 -0
- agent_evolve/application/action_score_authorities.py +363 -0
- agent_evolve/application/action_structural_signature.py +116 -0
- agent_evolve/application/action_target_realization.py +402 -0
- agent_evolve/application/agentic_evolution.py +7734 -0
- agent_evolve/application/agentic_portfolio_residual_expert.py +835 -0
- agent_evolve/application/anchor_residual_identification.py +463 -0
- agent_evolve/application/archive_conditioned_action_target.py +208 -0
- agent_evolve/application/artifact_journal.py +246 -0
- agent_evolve/application/artifact_replay.py +347 -0
- agent_evolve/application/budgeted_optimizer.py +1828 -0
- agent_evolve/application/calibrated_campaign.py +485 -0
- agent_evolve/application/calibrated_current_prefix_forecast_opportunity.py +322 -0
- agent_evolve/application/calibrated_positive_gain_opportunity.py +1581 -0
- agent_evolve/application/campaign_capacity_recourse.py +254 -0
- agent_evolve/application/campaign_contextual_outcomes.py +119 -0
- agent_evolve/application/campaign_diagnostic_blocks.py +930 -0
- agent_evolve/application/campaign_evidence_registry.py +262 -0
- agent_evolve/application/campaign_execution.py +2537 -0
- agent_evolve/application/campaign_generation_audit.py +942 -0
- agent_evolve/application/campaign_learning.py +1812 -0
- agent_evolve/application/campaign_learning_runtime.py +1977 -0
- agent_evolve/application/campaign_search_phase.py +227 -0
- agent_evolve/application/campaign_selector_context_extension.py +220 -0
- agent_evolve/application/campaign_variation_envelope.py +649 -0
- agent_evolve/application/campaign_variation_trace.py +451 -0
- agent_evolve/application/candidate_archive_consequence.py +128 -0
- agent_evolve/application/causal_opportunity_portfolio_gate.py +385 -0
- agent_evolve/application/composite_outcome_updater.py +145 -0
- agent_evolve/application/composition_portfolio_selection.py +363 -0
- agent_evolve/application/concurrent_stage.py +144 -0
- agent_evolve/application/contextual_action_allocation.py +181 -0
- agent_evolve/application/contextual_campaign_outcomes.py +267 -0
- agent_evolve/application/contextual_campaign_planning.py +1366 -0
- agent_evolve/application/contextual_delayed_credit.py +651 -0
- agent_evolve/application/contextual_search_controller.py +2374 -0
- agent_evolve/application/current_prefix_forecast_opportunity.py +714 -0
- agent_evolve/application/decision_metric_projection.py +112 -0
- agent_evolve/application/derived_action_semantics.py +129 -0
- agent_evolve/application/detailed_evaluation.py +449 -0
- agent_evolve/application/earned_lineage.py +1011 -0
- agent_evolve/application/effective_choice_audit.py +484 -0
- agent_evolve/application/empirical_consequence_calibration.py +908 -0
- agent_evolve/application/evaluation_accounting.py +325 -0
- agent_evolve/application/evaluation_cache.py +199 -0
- agent_evolve/application/evaluation_escrow.py +547 -0
- agent_evolve/application/evaluation_recourse.py +253 -0
- agent_evolve/application/event_recorder.py +151 -0
- agent_evolve/application/evolution_campaign.py +1840 -0
- agent_evolve/application/executable_hypothesis.py +323 -0
- agent_evolve/application/factorial_branch_pilot.py +772 -0
- agent_evolve/application/finite_acquisition_capacity_recourse.py +672 -0
- agent_evolve/application/finite_acquisition_residual_expert.py +373 -0
- agent_evolve/application/finite_acquisition_variation_envelope.py +802 -0
- agent_evolve/application/finite_action_hypothesis_semantics.py +446 -0
- agent_evolve/application/finite_action_selection.py +188 -0
- agent_evolve/application/finite_action_set.py +306 -0
- agent_evolve/application/finite_action_transition.py +537 -0
- agent_evolve/application/finite_variation_eligibility.py +296 -0
- agent_evolve/application/forecast_geometry_portfolio.py +799 -0
- agent_evolve/application/forecast_opportunity_shadow_calibration.py +316 -0
- agent_evolve/application/front_proximity_admission.py +311 -0
- agent_evolve/application/front_proximity_parent_basis.py +458 -0
- agent_evolve/application/frozen_hurdle_score.py +659 -0
- agent_evolve/application/g3_causal_screen.py +2257 -0
- agent_evolve/application/g3_causal_validation.py +1046 -0
- agent_evolve/application/g3_postseal_curation.py +818 -0
- agent_evolve/application/gated_agentic_generator.py +205 -0
- agent_evolve/application/generation_feedback.py +293 -0
- agent_evolve/application/generative_proposal_journal.py +185 -0
- agent_evolve/application/geometry_conditional_elasticity.py +453 -0
- agent_evolve/application/global_wave_action_allocation.py +1151 -0
- agent_evolve/application/head_mass_conditional_seat.py +268 -0
- agent_evolve/application/identifiable_reflection_evidence.py +1147 -0
- agent_evolve/application/identifiable_reflection_learning.py +395 -0
- agent_evolve/application/identifiable_reflection_request.py +364 -0
- agent_evolve/application/in_memory_residual_archive.py +341 -0
- agent_evolve/application/insight_memory.py +1804 -0
- agent_evolve/application/live_runtime_manifest.py +758 -0
- agent_evolve/application/llm_task_queue.py +769 -0
- agent_evolve/application/matched_finite_action_block.py +409 -0
- agent_evolve/application/materialized_action_broker.py +2328 -0
- agent_evolve/application/materialized_action_constraints.py +83 -0
- agent_evolve/application/materialized_variation.py +211 -0
- agent_evolve/application/multi_option_evolution.py +1536 -0
- agent_evolve/application/outcome_adaptive_action_racing.py +2827 -0
- agent_evolve/application/outcome_adaptive_residual_campaign_runtime.py +580 -0
- agent_evolve/application/outcome_adaptive_residual_portfolio_evolution.py +3671 -0
- agent_evolve/application/outcome_conditioned_portfolio_selection.py +1374 -0
- agent_evolve/application/outcome_relation.py +193 -0
- agent_evolve/application/paired_allocation_comparison.py +241 -0
- agent_evolve/application/paired_block_schedule.py +127 -0
- agent_evolve/application/parent_measurement.py +226 -0
- agent_evolve/application/pareto_archive.py +811 -0
- agent_evolve/application/portfolio_campaign_runtime.py +4739 -0
- agent_evolve/application/portfolio_evolution.py +2950 -0
- agent_evolve/application/portfolio_hypothesis_observations.py +814 -0
- agent_evolve/application/portfolio_memory_attribution.py +581 -0
- agent_evolve/application/portfolio_memory_dose.py +788 -0
- agent_evolve/application/portfolio_memory_matched_control.py +938 -0
- agent_evolve/application/portfolio_memory_transfer.py +297 -0
- agent_evolve/application/portfolio_optimization_memory.py +363 -0
- agent_evolve/application/portfolio_outcome_feedback.py +1613 -0
- agent_evolve/application/portfolio_projection.py +335 -0
- agent_evolve/application/portfolio_recombination.py +2032 -0
- agent_evolve/application/post_evolution_reflection.py +834 -0
- agent_evolve/application/postcommit_rank_authority.py +245 -0
- agent_evolve/application/precommitted_portfolio_racing.py +2762 -0
- agent_evolve/application/prequential_archive_opportunity_calibration.py +1154 -0
- agent_evolve/application/prequential_residual_exploration.py +343 -0
- agent_evolve/application/prequential_score_portfolio.py +954 -0
- agent_evolve/application/projections.py +292 -0
- agent_evolve/application/protected_action_committee.py +1027 -0
- agent_evolve/application/protected_branch_pilot.py +376 -0
- agent_evolve/application/protected_current_prefix_forecast_opportunity.py +552 -0
- agent_evolve/application/provider_replay.py +910 -0
- agent_evolve/application/rank_balanced_causal_pilot.py +1372 -0
- agent_evolve/application/recombination_residual_expert.py +403 -0
- agent_evolve/application/reflection_workflow.py +571 -0
- agent_evolve/application/region_conditional_credit.py +911 -0
- agent_evolve/application/residual_campaign_runtime.py +531 -0
- agent_evolve/application/residual_headroom_campaign_runtime.py +459 -0
- agent_evolve/application/residual_headroom_ledger.py +1544 -0
- agent_evolve/application/residual_learning_transaction.py +396 -0
- agent_evolve/application/residual_portfolio_evolution.py +1228 -0
- agent_evolve/application/residual_reachability.py +749 -0
- agent_evolve/application/residual_stage_credit.py +499 -0
- agent_evolve/application/same_prefix_paired_audit.py +1580 -0
- agent_evolve/application/semantic_coverage_score_portfolio.py +838 -0
- agent_evolve/application/sequential_lineage_allocation.py +1017 -0
- agent_evolve/application/sequential_market_replay.py +1395 -0
- agent_evolve/application/sequential_residual_campaign_runtime.py +305 -0
- agent_evolve/application/sequential_residual_portfolio_evolution.py +940 -0
- agent_evolve/application/single_score_action_allocation.py +299 -0
- agent_evolve/application/source_exposure_allocation.py +906 -0
- agent_evolve/application/staged_memory.py +210 -0
- agent_evolve/application/stratified_cold_start_allocation.py +732 -0
- agent_evolve/application/support_guarded_hurdle_score.py +549 -0
- agent_evolve/application/target_conditioned_action_forecast.py +595 -0
- agent_evolve/application/target_conditioned_campaign.py +566 -0
- agent_evolve/application/treatment_assignment.py +201 -0
- agent_evolve/application/trusted_objective_evidence.py +217 -0
- agent_evolve/application/two_stage_action_evolution.py +1131 -0
- agent_evolve/application/v8lite_allocation_policy.py +1083 -0
- agent_evolve/application/v9_candidate_policy.py +1303 -0
- agent_evolve/bootstrap.py +108 -0
- agent_evolve/campaign_presets.py +517 -0
- agent_evolve/campaign_profiles.py +452 -0
- agent_evolve/campaign_variation_topology.py +288 -0
- agent_evolve/campaign_workload.py +950 -0
- agent_evolve/cli.py +797 -0
- agent_evolve/contract.py +241 -0
- agent_evolve/core/__init__.py +91 -0
- agent_evolve/core/action_semantics.py +411 -0
- agent_evolve/core/authored.py +105 -0
- agent_evolve/core/formatting.py +286 -0
- agent_evolve/core/optimization_semantics.py +324 -0
- agent_evolve/core/problem.py +167 -0
- agent_evolve/core/results.py +323 -0
- agent_evolve/core/stats.py +70 -0
- agent_evolve/core/telemetry.py +100 -0
- agent_evolve/domain/__init__.py +89 -0
- agent_evolve/domain/artifact.py +162 -0
- agent_evolve/domain/durable_text.py +68 -0
- agent_evolve/domain/event.py +1454 -0
- agent_evolve/domain/finite_action_set.py +426 -0
- agent_evolve/domain/finite_variation.py +526 -0
- agent_evolve/domain/generative_emission.py +559 -0
- agent_evolve/domain/ids.py +163 -0
- agent_evolve/domain/inline_text.py +106 -0
- agent_evolve/domain/insight.py +27 -0
- agent_evolve/domain/lineage.py +737 -0
- agent_evolve/domain/llm_task_queue.py +960 -0
- agent_evolve/domain/outcome.py +96 -0
- agent_evolve/domain/patch.py +854 -0
- agent_evolve/domain/typed_json.py +542 -0
- agent_evolve/domain/variation_space.py +158 -0
- agent_evolve/driver.py +1014 -0
- agent_evolve/harness/__init__.py +29 -0
- agent_evolve/harness/base.py +242 -0
- agent_evolve/harness/directives.py +163 -0
- agent_evolve/harness/generative_seal.py +479 -0
- agent_evolve/harness/registry.py +41 -0
- agent_evolve/infrastructure/__init__.py +39 -0
- agent_evolve/infrastructure/artifacts/__init__.py +6 -0
- agent_evolve/infrastructure/artifacts/_verification.py +67 -0
- agent_evolve/infrastructure/artifacts/filesystem.py +343 -0
- agent_evolve/infrastructure/artifacts/in_memory.py +73 -0
- agent_evolve/infrastructure/asyncio_runtime.py +109 -0
- agent_evolve/infrastructure/authored_runtime.py +188 -0
- agent_evolve/infrastructure/authored_worker.py +171 -0
- agent_evolve/infrastructure/clock.py +53 -0
- agent_evolve/infrastructure/events/__init__.py +6 -0
- agent_evolve/infrastructure/events/_validation.py +89 -0
- agent_evolve/infrastructure/events/in_memory.py +56 -0
- agent_evolve/infrastructure/events/jsonl.py +193 -0
- agent_evolve/infrastructure/exception_provenance.py +215 -0
- agent_evolve/infrastructure/ids.py +118 -0
- agent_evolve/infrastructure/lineage_codec.py +1836 -0
- agent_evolve/infrastructure/outcome_adaptive_phase_journal.py +170 -0
- agent_evolve/infrastructure/residual_headroom_journal.py +221 -0
- agent_evolve/infrastructure/resource_lease.py +370 -0
- agent_evolve/infrastructure/sanitization/__init__.py +8 -0
- agent_evolve/infrastructure/sanitization/strict_json.py +484 -0
- agent_evolve/infrastructure/sequential_phase_journal.py +170 -0
- agent_evolve/infrastructure/stream_liveness.py +383 -0
- agent_evolve/infrastructure/subprocess_boundary.py +136 -0
- agent_evolve/integrations/__init__.py +1 -0
- agent_evolve/integrations/botorch/__init__.py +28 -0
- agent_evolve/integrations/botorch/finite_qlognehvi.py +190 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch.py +155 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch_identity.py +20 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_batch_worker.py +55 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_identity.py +22 -0
- agent_evolve/integrations/botorch/finite_qlognehvi_worker.py +55 -0
- agent_evolve/integrations/botorch/subprocess_qlognehvi.py +261 -0
- agent_evolve/integrations/botorch/subprocess_qlognehvi_batch.py +273 -0
- agent_evolve/integrations/completion.py +242 -0
- agent_evolve/integrations/pydantic_ai/__init__.py +441 -0
- agent_evolve/integrations/pydantic_ai/action_forecast.py +1068 -0
- agent_evolve/integrations/pydantic_ai/agentic_generator.py +2308 -0
- agent_evolve/integrations/pydantic_ai/async_generator.py +1604 -0
- agent_evolve/integrations/pydantic_ai/boundary_codec.py +1526 -0
- agent_evolve/integrations/pydantic_ai/calibrated_portfolio_campaign.py +756 -0
- agent_evolve/integrations/pydantic_ai/calibrated_portfolio_selection.py +7537 -0
- agent_evolve/integrations/pydantic_ai/campaign_acquisition.py +609 -0
- agent_evolve/integrations/pydantic_ai/execution_binding.py +138 -0
- agent_evolve/integrations/pydantic_ai/forecast_geometry_action_committee.py +217 -0
- agent_evolve/integrations/pydantic_ai/harness.py +159 -0
- agent_evolve/integrations/pydantic_ai/heterogeneous_model_execution.py +306 -0
- agent_evolve/integrations/pydantic_ai/hierarchical_residual_adaptive_semantic_view.py +179 -0
- agent_evolve/integrations/pydantic_ai/json_schema_dialect.py +108 -0
- agent_evolve/integrations/pydantic_ai/materialized_hierarchical_residual_expert.py +952 -0
- agent_evolve/integrations/pydantic_ai/materialized_portfolio_judge.py +520 -0
- agent_evolve/integrations/pydantic_ai/model_execution_profile.py +659 -0
- agent_evolve/integrations/pydantic_ai/outbound_request_manifest.py +1170 -0
- agent_evolve/integrations/pydantic_ai/portable_residual_consequence_features.py +575 -0
- agent_evolve/integrations/pydantic_ai/portfolio_selection.py +422 -0
- agent_evolve/integrations/pydantic_ai/progress_aware_openrouter.py +416 -0
- agent_evolve/integrations/pydantic_ai/provider_attempt_join.py +1523 -0
- agent_evolve/integrations/pydantic_ai/provider_free_calibrated_runner.py +607 -0
- agent_evolve/integrations/pydantic_ai/queued_runner.py +2634 -0
- agent_evolve/integrations/pydantic_ai/reconciled_residual_reachability.py +1417 -0
- agent_evolve/integrations/pydantic_ai/residual_forecast_geometry.py +445 -0
- agent_evolve/integrations/pydantic_ai/residual_reachability.py +674 -0
- agent_evolve/integrations/pydantic_ai/residual_semantic_cells.py +239 -0
- agent_evolve/integrations/pydantic_ai/sealed_output_replay.py +1068 -0
- agent_evolve/integrations/pydantic_ai/semantic_coverage_residual_portfolio.py +770 -0
- agent_evolve/integrations/pydantic_ai/semantic_decision_replay.py +383 -0
- agent_evolve/integrations/pydantic_ai/support_adaptive_residual_portfolio.py +135 -0
- agent_evolve/integrations/pydantic_ai/trusted_residual_prompt_context.py +143 -0
- agent_evolve/integrations/pydantic_ai/validated_openrouter_model.py +107 -0
- agent_evolve/integrations/pymoo_adapter.py +242 -0
- agent_evolve/policies/__init__.py +17 -0
- agent_evolve/policies/check.py +469 -0
- agent_evolve/policies/emit_scaffold.py +451 -0
- agent_evolve/policies/feedback/__init__.py +37 -0
- agent_evolve/policies/feedback/held_out_asn.py +1325 -0
- agent_evolve/policies/genetic.py +607 -0
- agent_evolve/policies/llm_backoff.py +183 -0
- agent_evolve/policies/llm_chooser.py +226 -0
- agent_evolve/policies/llm_generator.py +1760 -0
- agent_evolve/policies/llm_init.py +267 -0
- agent_evolve/policies/llm_operator.py +109 -0
- agent_evolve/policies/llm_prior.py +194 -0
- agent_evolve/policies/llm_surrogate.py +334 -0
- agent_evolve/policies/measurement_evidence.py +704 -0
- agent_evolve/policies/memory/__init__.py +223 -0
- agent_evolve/policies/memory/balanced_subset_blocks.py +707 -0
- agent_evolve/policies/memory/compatibility_matching.py +593 -0
- agent_evolve/policies/memory/global_falsification.py +1841 -0
- agent_evolve/policies/memory/prompt_shape.py +503 -0
- agent_evolve/policies/memory/randomized_subset.py +714 -0
- agent_evolve/policies/memory/staged_causal.py +1270 -0
- agent_evolve/policies/memory/treatment_compliance.py +759 -0
- agent_evolve/policies/objective_resolution/__init__.py +17 -0
- agent_evolve/policies/objective_resolution/fixed_grid.py +364 -0
- agent_evolve/policies/operator_portfolio.py +407 -0
- agent_evolve/policies/reguidance.py +1133 -0
- agent_evolve/policies/reward/__init__.py +83 -0
- agent_evolve/policies/reward/affine_candidate_consequence.py +156 -0
- agent_evolve/policies/reward/affine_candidate_consequence_3d.py +159 -0
- agent_evolve/policies/reward/affine_hypervolume.py +490 -0
- agent_evolve/policies/reward/affine_hypervolume_3d.py +567 -0
- agent_evolve/policies/reward/contextual_marginal_utility.py +318 -0
- agent_evolve/policies/reward/frozen_archive.py +360 -0
- agent_evolve/policies/reward/frozen_wave_archive.py +368 -0
- agent_evolve/policies/search_state.py +208 -0
- agent_evolve/policies/selection/__init__.py +345 -0
- agent_evolve/policies/selection/acquisition_certified_slate.py +684 -0
- agent_evolve/policies/selection/affine_frontier_context.py +330 -0
- agent_evolve/policies/selection/affine_frontier_target.py +473 -0
- agent_evolve/policies/selection/archive_elite.py +1346 -0
- agent_evolve/policies/selection/calibrated_portfolio_binding.py +640 -0
- agent_evolve/policies/selection/calibrated_slate.py +1394 -0
- agent_evolve/policies/selection/calibrated_slate_codec.py +579 -0
- agent_evolve/policies/selection/common_candidate_pool.py +685 -0
- agent_evolve/policies/selection/diagnostic_sampling.py +319 -0
- agent_evolve/policies/selection/disjoint_pairs.py +479 -0
- agent_evolve/policies/selection/elite_explorer.py +719 -0
- agent_evolve/policies/selection/finite_action.py +187 -0
- agent_evolve/policies/selection/finite_option_prompt_projection.py +377 -0
- agent_evolve/policies/selection/finite_palette_evidence.py +247 -0
- agent_evolve/policies/selection/forecast_calibration.py +922 -0
- agent_evolve/policies/selection/frontier_probe_slate.py +814 -0
- agent_evolve/policies/selection/frozen_archive_pairs.py +762 -0
- agent_evolve/policies/selection/full_support_slate.py +91 -0
- agent_evolve/policies/selection/meaningful_direction.py +240 -0
- agent_evolve/policies/selection/memory_dose_feasibility.py +259 -0
- agent_evolve/policies/selection/model_anchored_slate.py +826 -0
- agent_evolve/policies/selection/phenotype_recourse.py +979 -0
- agent_evolve/policies/selection/proposal_support.py +368 -0
- agent_evolve/policies/selection/random_portfolio.py +254 -0
- agent_evolve/policies/selection/regret_bounded_slate.py +1084 -0
- agent_evolve/policies/selection/residual_frontier.py +463 -0
- agent_evolve/policies/selection/residual_frontier_target.py +605 -0
- agent_evolve/policies/selection/structural_posterior_slate.py +1571 -0
- agent_evolve/policies/selection/target_conditioned_allocator.py +648 -0
- agent_evolve/policies/selection/target_conditioned_features.py +812 -0
- agent_evolve/policies/selection/target_conditioned_prequential.py +1527 -0
- agent_evolve/policies/selection/task_keyed_palette.py +906 -0
- agent_evolve/policies/semantics.py +147 -0
- agent_evolve/policies/structure.py +362 -0
- agent_evolve/policies/structured_output_budget.py +62 -0
- agent_evolve/policies/surrogate.py +696 -0
- agent_evolve/policies/variation/__init__.py +1 -0
- agent_evolve/policies/variation/compositional_finite_catalog.py +426 -0
- agent_evolve/policies/variation/crossover_inheritance.py +575 -0
- agent_evolve/policies/variation/disjoint_recombination.py +611 -0
- agent_evolve/policies/variation/exact_composition_capacity.py +214 -0
- agent_evolve/policies/variation/exact_parent_crossover.py +950 -0
- agent_evolve/policies/variation/multiscale_restart_catalog.py +372 -0
- agent_evolve/policies/variation/source_union_finite_catalog.py +403 -0
- agent_evolve/policies/variation/typed_patch.py +1981 -0
- agent_evolve/policies/weighted_prior.py +394 -0
- agent_evolve/ports/__init__.py +383 -0
- agent_evolve/ports/action_allocation.py +733 -0
- agent_evolve/ports/action_allocation_frame.py +1153 -0
- agent_evolve/ports/action_allocation_frame_commit.py +294 -0
- agent_evolve/ports/action_allocation_frame_commit_v3.py +432 -0
- agent_evolve/ports/action_allocation_frame_v3.py +995 -0
- agent_evolve/ports/action_forecast.py +1568 -0
- agent_evolve/ports/action_metric_projection.py +165 -0
- agent_evolve/ports/agentic_generator.py +1561 -0
- agent_evolve/ports/archive_context.py +136 -0
- agent_evolve/ports/artifact_sanitizer.py +44 -0
- agent_evolve/ports/artifact_store.py +225 -0
- agent_evolve/ports/clock.py +13 -0
- agent_evolve/ports/contextual_search_allocation.py +827 -0
- agent_evolve/ports/decision_metric_projection.py +258 -0
- agent_evolve/ports/event_store.py +55 -0
- agent_evolve/ports/executable_hypothesis.py +557 -0
- agent_evolve/ports/finite_acquisition.py +377 -0
- agent_evolve/ports/finite_acquisition_batch.py +296 -0
- agent_evolve/ports/finite_acquisition_batch_json.py +164 -0
- agent_evolve/ports/finite_acquisition_json.py +247 -0
- agent_evolve/ports/finite_acquisition_space.py +168 -0
- agent_evolve/ports/finite_action_selection.py +348 -0
- agent_evolve/ports/finite_action_set.py +256 -0
- agent_evolve/ports/frontier_target.py +396 -0
- agent_evolve/ports/generation_failure.py +43 -0
- agent_evolve/ports/hard_feasibility.py +233 -0
- agent_evolve/ports/id_factory.py +34 -0
- agent_evolve/ports/llm_task_queue.py +93 -0
- agent_evolve/ports/objective_resolution.py +419 -0
- agent_evolve/ports/paired_allocation_comparison.py +401 -0
- agent_evolve/ports/paired_block_schedule.py +475 -0
- agent_evolve/ports/parent_measurement.py +336 -0
- agent_evolve/ports/portfolio_memory_dose.py +643 -0
- agent_evolve/ports/portfolio_selection.py +3169 -0
- agent_evolve/ports/postcommit_rank_authority.py +467 -0
- agent_evolve/ports/presented_action_evidence.py +794 -0
- agent_evolve/ports/resource_lease.py +162 -0
- agent_evolve/ports/structured_generator.py +734 -0
- agent_evolve/ports/structured_output_budget.py +120 -0
- agent_evolve/ports/subprocess_boundary.py +138 -0
- agent_evolve/ports/treatment_assignment.py +466 -0
- agent_evolve/ports/variation_catalog.py +76 -0
- agent_evolve/ports/variation_source.py +226 -0
- agent_evolve/proposal_mode.py +157 -0
- agent_evolve/proposers/__init__.py +10 -0
- agent_evolve/proposers/random_proposer.py +188 -0
- agent_evolve/provider_accounting.py +163 -0
- agent_evolve/py.typed +0 -0
- agent_evolve/reference_method.py +1570 -0
- agent_evolve/session/__init__.py +11 -0
- agent_evolve/session/authorship.py +864 -0
- agent_evolve/session/evaluate.py +236 -0
- agent_evolve/session/fidelity.py +237 -0
- agent_evolve/session/genetic_loop.py +742 -0
- agent_evolve/session/loop.py +803 -0
- agent_evolve/session/screening.py +671 -0
- agent_evolve/settings.py +376 -0
- agent_evolve/workload_kit.py +368 -0
- agent_evolve/workload_prompt.py +398 -0
- agentevolve_optimizer-0.5.0.dist-info/METADATA +599 -0
- agentevolve_optimizer-0.5.0.dist-info/RECORD +414 -0
- agentevolve_optimizer-0.5.0.dist-info/WHEEL +5 -0
- agentevolve_optimizer-0.5.0.dist-info/entry_points.txt +2 -0
- agentevolve_optimizer-0.5.0.dist-info/licenses/LICENSE +21 -0
- agentevolve_optimizer-0.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,942 @@
|
|
|
1
|
+
"""Transactional production audit of finite-action campaign generations.
|
|
2
|
+
|
|
3
|
+
Every ranked portfolio action is first projected into an authenticated metric
|
|
4
|
+
observation or a typed candidate-infeasibility exclusion. Observations enter
|
|
5
|
+
the append-only evidence registry; exclusions remain in the generation audit
|
|
6
|
+
without resampling. If the same pre-outcome waves contain an
|
|
7
|
+
admitted diagnostic memory assignment, registered semantic plans are sealed
|
|
8
|
+
against that one prospective registry snapshot and adjudicated by the global
|
|
9
|
+
falsification gate. The workload seams are deliberately narrow: raw metric
|
|
10
|
+
effects, finite-action semantics, and hypothesis matching.
|
|
11
|
+
|
|
12
|
+
Randomized card exposure is *not* randomized action administration. The
|
|
13
|
+
candidate observations produced here retain ``DIRECT_MUTATION`` provenance;
|
|
14
|
+
the separate memory-credit transaction owns causal card usefulness.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import hashlib
|
|
20
|
+
import json
|
|
21
|
+
import re
|
|
22
|
+
from dataclasses import dataclass, field
|
|
23
|
+
|
|
24
|
+
from agent_evolve.application.campaign_evidence_registry import (
|
|
25
|
+
CampaignEvidenceAppendPreparation,
|
|
26
|
+
CampaignEvidenceRegistry,
|
|
27
|
+
)
|
|
28
|
+
from agent_evolve.application.campaign_execution import CampaignStageRequest
|
|
29
|
+
from agent_evolve.application.campaign_learning import (
|
|
30
|
+
CampaignInsightAuditBinding,
|
|
31
|
+
CampaignSemanticAuditPlan,
|
|
32
|
+
)
|
|
33
|
+
from agent_evolve.application.evolution_campaign import CampaignGenerationKind
|
|
34
|
+
from agent_evolve.application.insight_memory import InsightMemoryEntry
|
|
35
|
+
from agent_evolve.application.portfolio_evolution import (
|
|
36
|
+
PortfolioMemoryCreditBatchPreparation,
|
|
37
|
+
PortfolioMemoryMatchedControlWavePlan,
|
|
38
|
+
PortfolioVariationWaveRequest,
|
|
39
|
+
PortfolioVariationWaveResult,
|
|
40
|
+
)
|
|
41
|
+
from agent_evolve.application.portfolio_hypothesis_observations import (
|
|
42
|
+
CampaignActionSemanticsCompiler,
|
|
43
|
+
CampaignHypothesisObservationExclusion,
|
|
44
|
+
CampaignMetricEffectProjector,
|
|
45
|
+
CampaignPortfolioHypothesisEvidenceProjection,
|
|
46
|
+
project_portfolio_hypothesis_evidence,
|
|
47
|
+
)
|
|
48
|
+
from agent_evolve.application.portfolio_memory_attribution import (
|
|
49
|
+
PortfolioMemoryAttributionAudit,
|
|
50
|
+
audit_portfolio_memory_attribution,
|
|
51
|
+
)
|
|
52
|
+
from agent_evolve.application.portfolio_memory_matched_control import (
|
|
53
|
+
PortfolioMemoryMatchedControlOutcome,
|
|
54
|
+
)
|
|
55
|
+
from agent_evolve.domain.insight import InsightRef
|
|
56
|
+
from agent_evolve.domain.patch import require_sha256
|
|
57
|
+
from agent_evolve.policies.memory.global_falsification import (
|
|
58
|
+
AuthenticatedHypothesisObservation,
|
|
59
|
+
EvidenceProvenance,
|
|
60
|
+
GlobalHypothesisAuditRequest,
|
|
61
|
+
GlobalHypothesisEvidenceMatcher,
|
|
62
|
+
GlobalHypothesisFalsificationGate,
|
|
63
|
+
)
|
|
64
|
+
from agent_evolve.policies.memory.staged_causal import MemoryAssignmentArm
|
|
65
|
+
from agent_evolve.ports.agentic_generator import MetricComparisonAnchorKind
|
|
66
|
+
from agent_evolve.ports.portfolio_selection import PortfolioExperimentalArm
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
_TOKEN = re.compile(r"^[a-z][a-z0-9_.-]{0,95}$")
|
|
70
|
+
_PROJECTION_DOMAIN = b"agent-evolve:campaign-generation-audit-projection:v2\x00"
|
|
71
|
+
_PREPARATION_DOMAIN = b"agent-evolve:campaign-generation-audit-preparation:v2\x00"
|
|
72
|
+
_CONTEXT_DOMAIN = b"agent-evolve:campaign-diagnostic-context-binding:v1\x00"
|
|
73
|
+
|
|
74
|
+
PRODUCTION_GENERATION_AUDITOR_ID = "authenticated_portfolio_generation_audit"
|
|
75
|
+
PRODUCTION_GENERATION_AUDITOR_VERSION = 3
|
|
76
|
+
PRODUCTION_GENERATION_AUDITOR_DEFINITION_SHA256 = hashlib.sha256(
|
|
77
|
+
b"agent-evolve:authenticated-portfolio-generation-audit:v3:"
|
|
78
|
+
b"all-ranked-itt-actions-accounted:scored-actions-appended:"
|
|
79
|
+
b"candidate-infeasibility-explicitly-excluded:no-resampling:"
|
|
80
|
+
b"one-prospective-snapshot:real-global-gate:"
|
|
81
|
+
b"diagnostic-assignment-context:typed-mutation-current-parent-only:"
|
|
82
|
+
b"post-barrier-randomized-active-neutral-pair-outcomes:"
|
|
83
|
+
b"no-single-block-causal-claim:no-online-score-update"
|
|
84
|
+
).hexdigest()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def resolve_portfolio_memory_matched_control_outcomes(
|
|
88
|
+
*,
|
|
89
|
+
waves: tuple[PortfolioVariationWaveRequest, ...],
|
|
90
|
+
results: tuple[PortfolioVariationWaveResult, ...],
|
|
91
|
+
) -> tuple[PortfolioMemoryMatchedControlOutcome, ...]:
|
|
92
|
+
"""Join complete precommitted M/N pairs after the generation barrier.
|
|
93
|
+
|
|
94
|
+
This is an append-only experimental observation. The function neither
|
|
95
|
+
mutates memory scores nor labels one realized pair as an identified effect.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
if type(waves) is not tuple or type(results) is not tuple:
|
|
99
|
+
raise TypeError("waves/results must be exact tuples")
|
|
100
|
+
if len(waves) != len(results):
|
|
101
|
+
raise ValueError("matched outcome join requires one result per wave")
|
|
102
|
+
result_by_request: dict[str, PortfolioVariationWaveResult] = {}
|
|
103
|
+
for result in results:
|
|
104
|
+
if type(result) is not PortfolioVariationWaveResult:
|
|
105
|
+
raise TypeError("results must contain exact wave results")
|
|
106
|
+
PortfolioVariationWaveResult.__post_init__(result)
|
|
107
|
+
request_sha256 = result.receipt.request_sha256
|
|
108
|
+
if request_sha256 in result_by_request:
|
|
109
|
+
raise ValueError("matched outcome results repeat a request identity")
|
|
110
|
+
result_by_request[request_sha256] = result
|
|
111
|
+
|
|
112
|
+
grouped: dict[
|
|
113
|
+
str,
|
|
114
|
+
list[
|
|
115
|
+
tuple[
|
|
116
|
+
PortfolioMemoryMatchedControlWavePlan,
|
|
117
|
+
PortfolioVariationWaveResult,
|
|
118
|
+
]
|
|
119
|
+
],
|
|
120
|
+
] = {}
|
|
121
|
+
for wave in waves:
|
|
122
|
+
if type(wave) is not PortfolioVariationWaveRequest:
|
|
123
|
+
raise TypeError("waves must contain exact wave requests")
|
|
124
|
+
PortfolioVariationWaveRequest.__post_init__(wave)
|
|
125
|
+
matched = wave.matched_memory_control
|
|
126
|
+
if matched is None:
|
|
127
|
+
continue
|
|
128
|
+
request_sha256 = wave.selection_request.request_sha256
|
|
129
|
+
result = result_by_request.get(request_sha256)
|
|
130
|
+
if result is None:
|
|
131
|
+
raise ValueError("matched arm has no joined wave result")
|
|
132
|
+
if (
|
|
133
|
+
result.receipt.request_sha256 != request_sha256
|
|
134
|
+
or result.receipt.generation != wave.generation
|
|
135
|
+
):
|
|
136
|
+
raise ValueError("matched arm result differs from its wave")
|
|
137
|
+
grouped.setdefault(matched.plan.plan_sha256, []).append((matched, result))
|
|
138
|
+
|
|
139
|
+
outcomes: list[PortfolioMemoryMatchedControlOutcome] = []
|
|
140
|
+
for plan_sha256 in sorted(grouped):
|
|
141
|
+
members = grouped[plan_sha256]
|
|
142
|
+
if len(members) != 2:
|
|
143
|
+
raise ValueError("matched control plan requires exactly two realized arms")
|
|
144
|
+
plan = members[0][0].plan
|
|
145
|
+
if any(value[0].plan != plan for value in members):
|
|
146
|
+
raise ValueError("matched arms disagree on their precommitted plan")
|
|
147
|
+
aggregation_sha256s = {
|
|
148
|
+
value[0].aggregation.binding_sha256 for value in members
|
|
149
|
+
}
|
|
150
|
+
if len(aggregation_sha256s) != 1:
|
|
151
|
+
raise ValueError("matched arms use different reward aggregations")
|
|
152
|
+
by_arm = {value[0].assignment.arm: value for value in members}
|
|
153
|
+
if set(by_arm) != {
|
|
154
|
+
PortfolioExperimentalArm.MEMORY,
|
|
155
|
+
PortfolioExperimentalArm.NEUTRAL,
|
|
156
|
+
}:
|
|
157
|
+
raise ValueError("matched plan must realize one M and one N arm")
|
|
158
|
+
active, active_result = by_arm[PortfolioExperimentalArm.MEMORY]
|
|
159
|
+
neutral, neutral_result = by_arm[PortfolioExperimentalArm.NEUTRAL]
|
|
160
|
+
active_reward = float(active.aggregation.aggregate(active_result.outcomes))
|
|
161
|
+
neutral_reward = float(
|
|
162
|
+
neutral.aggregation.aggregate(neutral_result.outcomes)
|
|
163
|
+
)
|
|
164
|
+
outcomes.append(
|
|
165
|
+
PortfolioMemoryMatchedControlOutcome(
|
|
166
|
+
plan_sha256=plan_sha256,
|
|
167
|
+
generation=plan.generation,
|
|
168
|
+
reference=plan.reference,
|
|
169
|
+
aggregation_binding_sha256=active.aggregation.binding_sha256,
|
|
170
|
+
active_view_sha256=active.arm_view.view_sha256,
|
|
171
|
+
neutral_view_sha256=neutral.arm_view.view_sha256,
|
|
172
|
+
active_result_receipt_sha256=(
|
|
173
|
+
active_result.receipt.receipt_sha256
|
|
174
|
+
),
|
|
175
|
+
neutral_result_receipt_sha256=(
|
|
176
|
+
neutral_result.receipt.receipt_sha256
|
|
177
|
+
),
|
|
178
|
+
active_wave_reward=active_reward,
|
|
179
|
+
neutral_wave_reward=neutral_reward,
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
return tuple(outcomes)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _canonical_json(value: object) -> bytes:
|
|
186
|
+
return json.dumps(
|
|
187
|
+
value,
|
|
188
|
+
allow_nan=False,
|
|
189
|
+
ensure_ascii=True,
|
|
190
|
+
separators=(",", ":"),
|
|
191
|
+
sort_keys=True,
|
|
192
|
+
).encode("ascii", errors="strict")
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _hash(domain: bytes, value: object) -> str:
|
|
196
|
+
return hashlib.sha256(domain + _canonical_json(value)).hexdigest()
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def _reference_record(reference: InsightRef) -> dict[str, object]:
|
|
200
|
+
return {
|
|
201
|
+
"insight_id": reference.insight_id.value,
|
|
202
|
+
"version": reference.version,
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
@dataclass(frozen=True, slots=True)
|
|
207
|
+
class CampaignDiagnosticContextBinding:
|
|
208
|
+
"""One audit context authenticated only by pre-outcome assignments."""
|
|
209
|
+
|
|
210
|
+
reference: InsightRef
|
|
211
|
+
exact_context_sha256: str
|
|
212
|
+
assignment_sha256s: tuple[str, ...]
|
|
213
|
+
binding_sha256: str = field(init=False)
|
|
214
|
+
|
|
215
|
+
def __post_init__(self) -> None:
|
|
216
|
+
if type(self.reference) is not InsightRef:
|
|
217
|
+
raise TypeError("reference must be exact InsightRef")
|
|
218
|
+
InsightRef.__post_init__(self.reference)
|
|
219
|
+
require_sha256(self.exact_context_sha256, "exact_context_sha256")
|
|
220
|
+
if type(self.assignment_sha256s) is not tuple or not self.assignment_sha256s:
|
|
221
|
+
raise ValueError("assignment_sha256s must be a non-empty exact tuple")
|
|
222
|
+
for value in self.assignment_sha256s:
|
|
223
|
+
require_sha256(value, "assignment_sha256s")
|
|
224
|
+
if self.assignment_sha256s != tuple(sorted(set(self.assignment_sha256s))):
|
|
225
|
+
raise ValueError("assignment_sha256s must be unique and canonical")
|
|
226
|
+
object.__setattr__(
|
|
227
|
+
self,
|
|
228
|
+
"binding_sha256",
|
|
229
|
+
_hash(_CONTEXT_DOMAIN, self._unsigned_record()),
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
233
|
+
return {
|
|
234
|
+
"schema_version": 1,
|
|
235
|
+
"reference": _reference_record(self.reference),
|
|
236
|
+
"exact_context_sha256": self.exact_context_sha256,
|
|
237
|
+
"assignment_sha256s": list(self.assignment_sha256s),
|
|
238
|
+
"context_authority": "pre_outcome_resolved_diagnostic_assignment",
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
def to_record(self) -> dict[str, object]:
|
|
242
|
+
self.__post_init__()
|
|
243
|
+
return {**self._unsigned_record(), "binding_sha256": self.binding_sha256}
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
@dataclass(frozen=True, slots=True)
|
|
247
|
+
class CampaignGenerationAuditProjection:
|
|
248
|
+
"""Real-gate audit family over one shared prospective registry snapshot."""
|
|
249
|
+
|
|
250
|
+
stage_request_sha256: str
|
|
251
|
+
generation: int
|
|
252
|
+
wave_request_sha256s: tuple[str, ...]
|
|
253
|
+
wave_result_receipt_sha256s: tuple[str, ...]
|
|
254
|
+
memory_credit_batch_receipt_sha256: str
|
|
255
|
+
registry_snapshot_sha256: str
|
|
256
|
+
evidence_append_preparation_sha256: str
|
|
257
|
+
context_bindings: tuple[CampaignDiagnosticContextBinding, ...]
|
|
258
|
+
audits: tuple[CampaignInsightAuditBinding, ...]
|
|
259
|
+
projection_policy_id: str = field(
|
|
260
|
+
init=False,
|
|
261
|
+
default=PRODUCTION_GENERATION_AUDITOR_ID,
|
|
262
|
+
)
|
|
263
|
+
projection_policy_version: int = field(
|
|
264
|
+
init=False,
|
|
265
|
+
default=PRODUCTION_GENERATION_AUDITOR_VERSION,
|
|
266
|
+
)
|
|
267
|
+
projection_policy_definition_sha256: str = field(
|
|
268
|
+
init=False,
|
|
269
|
+
default=PRODUCTION_GENERATION_AUDITOR_DEFINITION_SHA256,
|
|
270
|
+
)
|
|
271
|
+
projection_sha256: str = field(init=False)
|
|
272
|
+
|
|
273
|
+
def __post_init__(self) -> None:
|
|
274
|
+
require_sha256(self.stage_request_sha256, "stage_request_sha256")
|
|
275
|
+
if type(self.generation) is not int or self.generation <= 0:
|
|
276
|
+
raise ValueError("generation must be positive")
|
|
277
|
+
for name in ("wave_request_sha256s", "wave_result_receipt_sha256s"):
|
|
278
|
+
values = getattr(self, name)
|
|
279
|
+
if type(values) is not tuple or not values:
|
|
280
|
+
raise ValueError(f"{name} must be non-empty")
|
|
281
|
+
for value in values:
|
|
282
|
+
require_sha256(value, name)
|
|
283
|
+
if values != tuple(sorted(set(values))):
|
|
284
|
+
raise ValueError(f"{name} must be unique and canonical")
|
|
285
|
+
for name in (
|
|
286
|
+
"memory_credit_batch_receipt_sha256",
|
|
287
|
+
"registry_snapshot_sha256",
|
|
288
|
+
"evidence_append_preparation_sha256",
|
|
289
|
+
"projection_policy_definition_sha256",
|
|
290
|
+
):
|
|
291
|
+
require_sha256(getattr(self, name), name)
|
|
292
|
+
if (
|
|
293
|
+
type(self.context_bindings) is not tuple
|
|
294
|
+
or not self.context_bindings
|
|
295
|
+
or any(
|
|
296
|
+
type(value) is not CampaignDiagnosticContextBinding
|
|
297
|
+
for value in self.context_bindings
|
|
298
|
+
)
|
|
299
|
+
):
|
|
300
|
+
raise ValueError("context_bindings must contain exact bindings")
|
|
301
|
+
for value in self.context_bindings:
|
|
302
|
+
CampaignDiagnosticContextBinding.__post_init__(value)
|
|
303
|
+
references = tuple(value.reference for value in self.context_bindings)
|
|
304
|
+
if references != tuple(sorted(set(references))):
|
|
305
|
+
raise ValueError("context bindings must use canonical unique references")
|
|
306
|
+
if (
|
|
307
|
+
type(self.audits) is not tuple
|
|
308
|
+
or not self.audits
|
|
309
|
+
or any(
|
|
310
|
+
type(value) is not CampaignInsightAuditBinding for value in self.audits
|
|
311
|
+
)
|
|
312
|
+
):
|
|
313
|
+
raise ValueError("audits must contain exact bindings")
|
|
314
|
+
for value in self.audits:
|
|
315
|
+
CampaignInsightAuditBinding.__post_init__(value)
|
|
316
|
+
if tuple(value.request.reference for value in self.audits) != references:
|
|
317
|
+
raise ValueError("audits must exactly cover context-bound references")
|
|
318
|
+
if any(
|
|
319
|
+
value.request.registry_snapshot_sha256 != self.registry_snapshot_sha256
|
|
320
|
+
or value.receipt.registry_snapshot_sha256 != self.registry_snapshot_sha256
|
|
321
|
+
for value in self.audits
|
|
322
|
+
):
|
|
323
|
+
raise ValueError("audit family does not share the sealed registry snapshot")
|
|
324
|
+
if (
|
|
325
|
+
type(self.projection_policy_id) is not str
|
|
326
|
+
or _TOKEN.fullmatch(self.projection_policy_id) is None
|
|
327
|
+
or self.projection_policy_version != PRODUCTION_GENERATION_AUDITOR_VERSION
|
|
328
|
+
or self.projection_policy_definition_sha256
|
|
329
|
+
!= PRODUCTION_GENERATION_AUDITOR_DEFINITION_SHA256
|
|
330
|
+
):
|
|
331
|
+
raise ValueError("unsupported production generation auditor identity")
|
|
332
|
+
object.__setattr__(
|
|
333
|
+
self,
|
|
334
|
+
"projection_sha256",
|
|
335
|
+
_hash(_PROJECTION_DOMAIN, self._unsigned_record()),
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def references(self) -> tuple[InsightRef, ...]:
|
|
340
|
+
return tuple(value.reference for value in self.context_bindings)
|
|
341
|
+
|
|
342
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
343
|
+
return {
|
|
344
|
+
"schema_version": 2,
|
|
345
|
+
"stage_request_sha256": self.stage_request_sha256,
|
|
346
|
+
"generation": self.generation,
|
|
347
|
+
"wave_request_sha256s": list(self.wave_request_sha256s),
|
|
348
|
+
"wave_result_receipt_sha256s": list(self.wave_result_receipt_sha256s),
|
|
349
|
+
"memory_credit_batch_receipt_sha256": (
|
|
350
|
+
self.memory_credit_batch_receipt_sha256
|
|
351
|
+
),
|
|
352
|
+
"registry_snapshot_sha256": self.registry_snapshot_sha256,
|
|
353
|
+
"evidence_append_preparation_sha256": (
|
|
354
|
+
self.evidence_append_preparation_sha256
|
|
355
|
+
),
|
|
356
|
+
"context_binding_sha256s": [
|
|
357
|
+
value.binding_sha256 for value in self.context_bindings
|
|
358
|
+
],
|
|
359
|
+
"audit_request_sha256s": [
|
|
360
|
+
value.request.request_sha256 for value in self.audits
|
|
361
|
+
],
|
|
362
|
+
"audit_receipt_sha256s": [
|
|
363
|
+
value.receipt.audit_receipt_sha256 for value in self.audits
|
|
364
|
+
],
|
|
365
|
+
"projection_policy": {
|
|
366
|
+
"policy_id": self.projection_policy_id,
|
|
367
|
+
"policy_version": self.projection_policy_version,
|
|
368
|
+
"definition_sha256": self.projection_policy_definition_sha256,
|
|
369
|
+
},
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
def to_record(self) -> dict[str, object]:
|
|
373
|
+
self.__post_init__()
|
|
374
|
+
return {
|
|
375
|
+
**self._unsigned_record(),
|
|
376
|
+
"context_bindings": [value.to_record() for value in self.context_bindings],
|
|
377
|
+
"audits": [
|
|
378
|
+
{
|
|
379
|
+
"request": value.request.to_record(),
|
|
380
|
+
"receipt": value.receipt.to_record(),
|
|
381
|
+
"exact_context_sha256": value.exact_context_sha256,
|
|
382
|
+
}
|
|
383
|
+
for value in self.audits
|
|
384
|
+
],
|
|
385
|
+
"projection_sha256": self.projection_sha256,
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
@dataclass(frozen=True, slots=True)
|
|
390
|
+
class CampaignGenerationAuditPreparation:
|
|
391
|
+
"""Evidence append plus optional real-gate lifecycle projection."""
|
|
392
|
+
|
|
393
|
+
stage_request_sha256: str
|
|
394
|
+
generation: int
|
|
395
|
+
wave_request_sha256s: tuple[str, ...]
|
|
396
|
+
wave_result_receipt_sha256s: tuple[str, ...]
|
|
397
|
+
memory_credit_preparation_sha256: str
|
|
398
|
+
observations: tuple[AuthenticatedHypothesisObservation, ...]
|
|
399
|
+
observation_exclusions: tuple[CampaignHypothesisObservationExclusion, ...]
|
|
400
|
+
hypothesis_evidence_projection: CampaignPortfolioHypothesisEvidenceProjection
|
|
401
|
+
evidence_append: CampaignEvidenceAppendPreparation
|
|
402
|
+
memory_attribution_audit: PortfolioMemoryAttributionAudit | None
|
|
403
|
+
matched_memory_control_outcomes: tuple[
|
|
404
|
+
PortfolioMemoryMatchedControlOutcome, ...
|
|
405
|
+
]
|
|
406
|
+
projection: CampaignGenerationAuditProjection | None
|
|
407
|
+
preparation_sha256: str = field(init=False)
|
|
408
|
+
|
|
409
|
+
def __post_init__(self) -> None:
|
|
410
|
+
require_sha256(self.stage_request_sha256, "stage_request_sha256")
|
|
411
|
+
if type(self.generation) is not int or self.generation <= 0:
|
|
412
|
+
raise ValueError("generation must be positive")
|
|
413
|
+
for name in ("wave_request_sha256s", "wave_result_receipt_sha256s"):
|
|
414
|
+
values = getattr(self, name)
|
|
415
|
+
if type(values) is not tuple or not values:
|
|
416
|
+
raise ValueError(f"{name} must be non-empty")
|
|
417
|
+
for value in values:
|
|
418
|
+
require_sha256(value, name)
|
|
419
|
+
if values != tuple(sorted(set(values))):
|
|
420
|
+
raise ValueError(f"{name} must be unique and canonical")
|
|
421
|
+
require_sha256(
|
|
422
|
+
self.memory_credit_preparation_sha256,
|
|
423
|
+
"memory_credit_preparation_sha256",
|
|
424
|
+
)
|
|
425
|
+
if type(self.observations) is not tuple or any(
|
|
426
|
+
type(value) is not AuthenticatedHypothesisObservation
|
|
427
|
+
for value in self.observations
|
|
428
|
+
):
|
|
429
|
+
raise TypeError("observations must contain exact authenticated evidence")
|
|
430
|
+
for value in self.observations:
|
|
431
|
+
AuthenticatedHypothesisObservation.__post_init__(value)
|
|
432
|
+
if (
|
|
433
|
+
value.event_index != self.generation
|
|
434
|
+
or value.provenance is not EvidenceProvenance.DIRECT_MUTATION
|
|
435
|
+
or value.operator_family != "typed_mutation"
|
|
436
|
+
):
|
|
437
|
+
raise ValueError(
|
|
438
|
+
"production MVP accepts current-generation direct mutations only"
|
|
439
|
+
)
|
|
440
|
+
if type(self.observation_exclusions) is not tuple or any(
|
|
441
|
+
type(value) is not CampaignHypothesisObservationExclusion
|
|
442
|
+
for value in self.observation_exclusions
|
|
443
|
+
):
|
|
444
|
+
raise TypeError("observation_exclusions must contain exact receipts")
|
|
445
|
+
for value in self.observation_exclusions:
|
|
446
|
+
CampaignHypothesisObservationExclusion.__post_init__(value)
|
|
447
|
+
if not self.observations and not self.observation_exclusions:
|
|
448
|
+
raise ValueError("generation audit cannot omit every ranked ITT member")
|
|
449
|
+
if type(self.hypothesis_evidence_projection) is not (
|
|
450
|
+
CampaignPortfolioHypothesisEvidenceProjection
|
|
451
|
+
):
|
|
452
|
+
raise TypeError("hypothesis_evidence_projection must be exact")
|
|
453
|
+
CampaignPortfolioHypothesisEvidenceProjection.__post_init__(
|
|
454
|
+
self.hypothesis_evidence_projection
|
|
455
|
+
)
|
|
456
|
+
if (
|
|
457
|
+
self.hypothesis_evidence_projection.observations != self.observations
|
|
458
|
+
or self.hypothesis_evidence_projection.exclusions
|
|
459
|
+
!= self.observation_exclusions
|
|
460
|
+
or self.hypothesis_evidence_projection.wave_receipt_sha256s
|
|
461
|
+
!= self.wave_result_receipt_sha256s
|
|
462
|
+
):
|
|
463
|
+
raise ValueError("hypothesis evidence projection differs from audit inputs")
|
|
464
|
+
if type(self.evidence_append) is not CampaignEvidenceAppendPreparation:
|
|
465
|
+
raise TypeError("evidence_append must be exact")
|
|
466
|
+
CampaignEvidenceAppendPreparation.__post_init__(self.evidence_append)
|
|
467
|
+
if self.evidence_append.observations != self.observations:
|
|
468
|
+
raise ValueError("evidence append differs from projected observations")
|
|
469
|
+
attribution = self.memory_attribution_audit
|
|
470
|
+
if attribution is not None:
|
|
471
|
+
if type(attribution) is not PortfolioMemoryAttributionAudit:
|
|
472
|
+
raise TypeError("memory_attribution_audit must be exact or None")
|
|
473
|
+
PortfolioMemoryAttributionAudit.__post_init__(attribution)
|
|
474
|
+
if (
|
|
475
|
+
attribution.generation != self.generation
|
|
476
|
+
or attribution.wave_request_sha256s != self.wave_request_sha256s
|
|
477
|
+
or attribution.wave_result_receipt_sha256s
|
|
478
|
+
!= self.wave_result_receipt_sha256s
|
|
479
|
+
):
|
|
480
|
+
raise ValueError(
|
|
481
|
+
"memory attribution audit differs from generation inputs"
|
|
482
|
+
)
|
|
483
|
+
matched_outcomes = self.matched_memory_control_outcomes
|
|
484
|
+
if type(matched_outcomes) is not tuple or any(
|
|
485
|
+
type(value) is not PortfolioMemoryMatchedControlOutcome
|
|
486
|
+
for value in matched_outcomes
|
|
487
|
+
):
|
|
488
|
+
raise TypeError(
|
|
489
|
+
"matched_memory_control_outcomes must contain exact outcomes"
|
|
490
|
+
)
|
|
491
|
+
result_receipts = set(self.wave_result_receipt_sha256s)
|
|
492
|
+
plan_sha256s: list[str] = []
|
|
493
|
+
for value in matched_outcomes:
|
|
494
|
+
PortfolioMemoryMatchedControlOutcome.__post_init__(value)
|
|
495
|
+
if value.generation != self.generation:
|
|
496
|
+
raise ValueError("matched outcome differs from audit generation")
|
|
497
|
+
if {
|
|
498
|
+
value.active_result_receipt_sha256,
|
|
499
|
+
value.neutral_result_receipt_sha256,
|
|
500
|
+
} - result_receipts:
|
|
501
|
+
raise ValueError("matched outcome names a foreign wave result")
|
|
502
|
+
plan_sha256s.append(value.plan_sha256)
|
|
503
|
+
if tuple(plan_sha256s) != tuple(sorted(set(plan_sha256s))):
|
|
504
|
+
raise ValueError("matched outcomes require canonical unique plans")
|
|
505
|
+
projection = self.projection
|
|
506
|
+
if projection is not None:
|
|
507
|
+
if type(projection) is not CampaignGenerationAuditProjection:
|
|
508
|
+
raise TypeError("projection must be exact or None")
|
|
509
|
+
CampaignGenerationAuditProjection.__post_init__(projection)
|
|
510
|
+
expected = (
|
|
511
|
+
self.stage_request_sha256,
|
|
512
|
+
self.generation,
|
|
513
|
+
self.wave_request_sha256s,
|
|
514
|
+
self.wave_result_receipt_sha256s,
|
|
515
|
+
self.evidence_append.prospective_snapshot.snapshot_sha256,
|
|
516
|
+
self.evidence_append.preparation_sha256,
|
|
517
|
+
)
|
|
518
|
+
observed = (
|
|
519
|
+
projection.stage_request_sha256,
|
|
520
|
+
projection.generation,
|
|
521
|
+
projection.wave_request_sha256s,
|
|
522
|
+
projection.wave_result_receipt_sha256s,
|
|
523
|
+
projection.registry_snapshot_sha256,
|
|
524
|
+
projection.evidence_append_preparation_sha256,
|
|
525
|
+
)
|
|
526
|
+
if observed != expected:
|
|
527
|
+
raise ValueError("generation projection differs from evidence append")
|
|
528
|
+
object.__setattr__(
|
|
529
|
+
self,
|
|
530
|
+
"preparation_sha256",
|
|
531
|
+
_hash(_PREPARATION_DOMAIN, self._unsigned_record()),
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
def _unsigned_record(self) -> dict[str, object]:
|
|
535
|
+
return {
|
|
536
|
+
"schema_version": 4,
|
|
537
|
+
"stage_request_sha256": self.stage_request_sha256,
|
|
538
|
+
"generation": self.generation,
|
|
539
|
+
"wave_request_sha256s": list(self.wave_request_sha256s),
|
|
540
|
+
"wave_result_receipt_sha256s": list(self.wave_result_receipt_sha256s),
|
|
541
|
+
"memory_credit_preparation_sha256": (self.memory_credit_preparation_sha256),
|
|
542
|
+
"observation_sha256s": [
|
|
543
|
+
value.observation_sha256 for value in self.observations
|
|
544
|
+
],
|
|
545
|
+
"observation_exclusion_sha256s": [
|
|
546
|
+
value.exclusion_sha256 for value in self.observation_exclusions
|
|
547
|
+
],
|
|
548
|
+
"hypothesis_evidence_projection_sha256": (
|
|
549
|
+
self.hypothesis_evidence_projection.projection_sha256
|
|
550
|
+
),
|
|
551
|
+
"evidence_append_preparation_sha256": (
|
|
552
|
+
self.evidence_append.preparation_sha256
|
|
553
|
+
),
|
|
554
|
+
"prospective_registry_snapshot_sha256": (
|
|
555
|
+
self.evidence_append.prospective_snapshot.snapshot_sha256
|
|
556
|
+
),
|
|
557
|
+
"memory_attribution_audit_sha256": (
|
|
558
|
+
None
|
|
559
|
+
if self.memory_attribution_audit is None
|
|
560
|
+
else self.memory_attribution_audit.audit_sha256
|
|
561
|
+
),
|
|
562
|
+
"matched_memory_control_outcome_sha256s": [
|
|
563
|
+
value.outcome_sha256
|
|
564
|
+
for value in self.matched_memory_control_outcomes
|
|
565
|
+
],
|
|
566
|
+
"projection_sha256": (
|
|
567
|
+
None if self.projection is None else self.projection.projection_sha256
|
|
568
|
+
),
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
def to_record(self) -> dict[str, object]:
|
|
572
|
+
self.__post_init__()
|
|
573
|
+
return {
|
|
574
|
+
**self._unsigned_record(),
|
|
575
|
+
"status": (
|
|
576
|
+
"evidence_append_and_real_gate_prepared"
|
|
577
|
+
if self.projection is not None
|
|
578
|
+
else "evidence_append_prepared_no_diagnostic_assignment"
|
|
579
|
+
),
|
|
580
|
+
"hypothesis_evidence_projection": (
|
|
581
|
+
self.hypothesis_evidence_projection.to_record()
|
|
582
|
+
),
|
|
583
|
+
"evidence_append": self.evidence_append.to_record(),
|
|
584
|
+
"memory_attribution_audit": (
|
|
585
|
+
None
|
|
586
|
+
if self.memory_attribution_audit is None
|
|
587
|
+
else self.memory_attribution_audit.to_record()
|
|
588
|
+
),
|
|
589
|
+
"matched_memory_control_outcomes": [
|
|
590
|
+
value.to_record()
|
|
591
|
+
for value in self.matched_memory_control_outcomes
|
|
592
|
+
],
|
|
593
|
+
"projection": (
|
|
594
|
+
None if self.projection is None else self.projection.to_record()
|
|
595
|
+
),
|
|
596
|
+
"preparation_sha256": self.preparation_sha256,
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
@dataclass(slots=True)
|
|
601
|
+
class TransactionalPortfolioGenerationAuditor:
|
|
602
|
+
"""Concrete prepare/commit/abort path for production campaign evidence."""
|
|
603
|
+
|
|
604
|
+
evidence_registry: CampaignEvidenceRegistry
|
|
605
|
+
campaign_sha256: str
|
|
606
|
+
workload_instance_sha256: str
|
|
607
|
+
evaluator_contract_sha256: str
|
|
608
|
+
metric_projector: CampaignMetricEffectProjector
|
|
609
|
+
action_semantics_compiler: CampaignActionSemanticsCompiler
|
|
610
|
+
hypothesis_matcher: GlobalHypothesisEvidenceMatcher
|
|
611
|
+
falsification_gate: GlobalHypothesisFalsificationGate = field(
|
|
612
|
+
default_factory=GlobalHypothesisFalsificationGate
|
|
613
|
+
)
|
|
614
|
+
_prepared: dict[str, CampaignGenerationAuditPreparation] = field(
|
|
615
|
+
init=False,
|
|
616
|
+
default_factory=dict,
|
|
617
|
+
)
|
|
618
|
+
|
|
619
|
+
@property
|
|
620
|
+
def policy_id(self) -> str:
|
|
621
|
+
return PRODUCTION_GENERATION_AUDITOR_ID
|
|
622
|
+
|
|
623
|
+
@property
|
|
624
|
+
def policy_version(self) -> int:
|
|
625
|
+
return PRODUCTION_GENERATION_AUDITOR_VERSION
|
|
626
|
+
|
|
627
|
+
@property
|
|
628
|
+
def definition_sha256(self) -> str:
|
|
629
|
+
return PRODUCTION_GENERATION_AUDITOR_DEFINITION_SHA256
|
|
630
|
+
|
|
631
|
+
def __post_init__(self) -> None:
|
|
632
|
+
if type(self.evidence_registry) is not CampaignEvidenceRegistry:
|
|
633
|
+
raise TypeError("evidence_registry must be exact CampaignEvidenceRegistry")
|
|
634
|
+
for name in (
|
|
635
|
+
"campaign_sha256",
|
|
636
|
+
"workload_instance_sha256",
|
|
637
|
+
"evaluator_contract_sha256",
|
|
638
|
+
):
|
|
639
|
+
require_sha256(getattr(self, name), name)
|
|
640
|
+
if not isinstance(self.metric_projector, CampaignMetricEffectProjector):
|
|
641
|
+
raise TypeError("metric_projector must implement its narrow port")
|
|
642
|
+
if not isinstance(
|
|
643
|
+
self.action_semantics_compiler,
|
|
644
|
+
CampaignActionSemanticsCompiler,
|
|
645
|
+
):
|
|
646
|
+
raise TypeError("action_semantics_compiler must implement its narrow port")
|
|
647
|
+
if not isinstance(
|
|
648
|
+
self.hypothesis_matcher,
|
|
649
|
+
GlobalHypothesisEvidenceMatcher,
|
|
650
|
+
):
|
|
651
|
+
raise TypeError("hypothesis_matcher must implement its narrow port")
|
|
652
|
+
if type(self.falsification_gate) is not GlobalHypothesisFalsificationGate:
|
|
653
|
+
raise TypeError("falsification_gate must be exact")
|
|
654
|
+
GlobalHypothesisFalsificationGate.__post_init__(self.falsification_gate)
|
|
655
|
+
|
|
656
|
+
@staticmethod
|
|
657
|
+
def _validate_plans(
|
|
658
|
+
entries: tuple[InsightMemoryEntry, ...],
|
|
659
|
+
plans: tuple[CampaignSemanticAuditPlan, ...],
|
|
660
|
+
) -> None:
|
|
661
|
+
if type(entries) is not tuple or type(plans) is not tuple:
|
|
662
|
+
raise TypeError("entries/plans must be exact tuples")
|
|
663
|
+
if len(entries) != len(plans):
|
|
664
|
+
raise ValueError("entries and registered plans differ")
|
|
665
|
+
for entry, plan in zip(entries, plans, strict=True):
|
|
666
|
+
if type(entry) is not InsightMemoryEntry:
|
|
667
|
+
raise TypeError("entries must contain exact InsightMemoryEntry values")
|
|
668
|
+
if type(plan) is not CampaignSemanticAuditPlan:
|
|
669
|
+
raise TypeError(
|
|
670
|
+
"plans must contain exact CampaignSemanticAuditPlan values"
|
|
671
|
+
)
|
|
672
|
+
InsightMemoryEntry.__post_init__(entry)
|
|
673
|
+
CampaignSemanticAuditPlan.__post_init__(plan)
|
|
674
|
+
if entry.reference != plan.reference:
|
|
675
|
+
raise ValueError("registered plan belongs to a different entry")
|
|
676
|
+
if plan.intervention.admissible_operator_families != ("typed_mutation",):
|
|
677
|
+
raise ValueError("production audit MVP supports typed mutation only")
|
|
678
|
+
if any(
|
|
679
|
+
value.comparison_anchor is None
|
|
680
|
+
or value.comparison_anchor.kind
|
|
681
|
+
is not MetricComparisonAnchorKind.CURRENT_PARENT
|
|
682
|
+
for value in entry.draft.effect_predictions
|
|
683
|
+
):
|
|
684
|
+
raise ValueError("production audit MVP requires current-parent anchors")
|
|
685
|
+
|
|
686
|
+
@staticmethod
|
|
687
|
+
def _diagnostic_context_bindings(
|
|
688
|
+
*,
|
|
689
|
+
waves: tuple[PortfolioVariationWaveRequest, ...],
|
|
690
|
+
planned_references: tuple[InsightRef, ...],
|
|
691
|
+
) -> tuple[CampaignDiagnosticContextBinding, ...]:
|
|
692
|
+
planned = set(planned_references)
|
|
693
|
+
contexts: dict[InsightRef, set[str]] = {}
|
|
694
|
+
assignments: dict[InsightRef, set[str]] = {}
|
|
695
|
+
for wave in waves:
|
|
696
|
+
credit = wave.memory_credit
|
|
697
|
+
if (
|
|
698
|
+
credit is None
|
|
699
|
+
or credit.assignment.arm is not MemoryAssignmentArm.DIAGNOSTIC
|
|
700
|
+
):
|
|
701
|
+
continue
|
|
702
|
+
# A generic diagnostic assignment that does not carry a bank-issued
|
|
703
|
+
# quarantine admission is not semantic-card lifecycle evidence.
|
|
704
|
+
if credit.quarantine_admission is None:
|
|
705
|
+
continue
|
|
706
|
+
assignment = credit.assignment
|
|
707
|
+
eligible = set(assignment.selection_decision.eligible)
|
|
708
|
+
admitted = set(credit.quarantine_admission.references)
|
|
709
|
+
if credit.quarantine_admission_subset_authorization_sha256 is None:
|
|
710
|
+
planned_admitted = admitted.intersection(planned)
|
|
711
|
+
else:
|
|
712
|
+
# The credit binding carries an explicit prospective cohort-
|
|
713
|
+
# selection receipt. Only its assignment-eligible subset was
|
|
714
|
+
# exposed, so unselected admitted cards are not semantic-audit
|
|
715
|
+
# subjects for this generation.
|
|
716
|
+
planned_admitted = admitted.intersection(planned, eligible)
|
|
717
|
+
if not planned_admitted:
|
|
718
|
+
raise ValueError(
|
|
719
|
+
"authorized quarantine subset has no planned audit subject"
|
|
720
|
+
)
|
|
721
|
+
if not planned_admitted.issubset(eligible):
|
|
722
|
+
raise ValueError(
|
|
723
|
+
"planned quarantine admission differs from assignment eligibility"
|
|
724
|
+
)
|
|
725
|
+
# Normal seed/promoted controls can intentionally share the eligible
|
|
726
|
+
# assignment slate. Only bank-admitted quarantine references are
|
|
727
|
+
# lifecycle audit subjects; admission authenticity was already
|
|
728
|
+
# replayed by PortfolioEvolution against the memory bank.
|
|
729
|
+
for reference in planned_admitted:
|
|
730
|
+
contexts.setdefault(reference, set()).add(assignment.exact_context_hash)
|
|
731
|
+
assignments.setdefault(reference, set()).add(
|
|
732
|
+
assignment.assignment_sha256
|
|
733
|
+
)
|
|
734
|
+
bindings = []
|
|
735
|
+
for reference in sorted(contexts):
|
|
736
|
+
values = contexts[reference]
|
|
737
|
+
if len(values) != 1:
|
|
738
|
+
raise ValueError(
|
|
739
|
+
"one diagnostic insight cannot mix exact estimand contexts"
|
|
740
|
+
)
|
|
741
|
+
bindings.append(
|
|
742
|
+
CampaignDiagnosticContextBinding(
|
|
743
|
+
reference=reference,
|
|
744
|
+
exact_context_sha256=next(iter(values)),
|
|
745
|
+
assignment_sha256s=tuple(sorted(assignments[reference])),
|
|
746
|
+
)
|
|
747
|
+
)
|
|
748
|
+
return tuple(bindings)
|
|
749
|
+
|
|
750
|
+
@staticmethod
|
|
751
|
+
def _request_from_plan(
|
|
752
|
+
plan: CampaignSemanticAuditPlan,
|
|
753
|
+
*,
|
|
754
|
+
audit_cutoff_event_index: int,
|
|
755
|
+
registry_snapshot_sha256: str,
|
|
756
|
+
) -> GlobalHypothesisAuditRequest:
|
|
757
|
+
return GlobalHypothesisAuditRequest(
|
|
758
|
+
reference=plan.reference,
|
|
759
|
+
draft_content_sha256=plan.draft_content_sha256,
|
|
760
|
+
trigger=plan.trigger,
|
|
761
|
+
intervention=plan.intervention,
|
|
762
|
+
predictions=plan.predictions,
|
|
763
|
+
claim_strength=plan.claim_strength,
|
|
764
|
+
scope=plan.scope,
|
|
765
|
+
matcher_definition_sha256=plan.matcher_definition_sha256,
|
|
766
|
+
origin_cutoff_event_index=plan.origin_cutoff_event_index,
|
|
767
|
+
audit_cutoff_event_index=audit_cutoff_event_index,
|
|
768
|
+
registry_snapshot_sha256=registry_snapshot_sha256,
|
|
769
|
+
minimum_support_clusters=plan.minimum_support_clusters,
|
|
770
|
+
minimum_support_instances=plan.minimum_support_instances,
|
|
771
|
+
audit_policy_definition_sha256=plan.audit_policy_definition_sha256,
|
|
772
|
+
)
|
|
773
|
+
|
|
774
|
+
def prepare_generation_audit(
|
|
775
|
+
self,
|
|
776
|
+
*,
|
|
777
|
+
request: CampaignStageRequest,
|
|
778
|
+
waves: tuple[PortfolioVariationWaveRequest, ...],
|
|
779
|
+
results: tuple[PortfolioVariationWaveResult, ...],
|
|
780
|
+
memory_credit_preparation: PortfolioMemoryCreditBatchPreparation,
|
|
781
|
+
entries: tuple[InsightMemoryEntry, ...] = (),
|
|
782
|
+
plans: tuple[CampaignSemanticAuditPlan, ...] = (),
|
|
783
|
+
) -> CampaignGenerationAuditPreparation:
|
|
784
|
+
"""Prepare evidence for every stage and real audits when assigned."""
|
|
785
|
+
|
|
786
|
+
self.__post_init__()
|
|
787
|
+
if type(request) is not CampaignStageRequest:
|
|
788
|
+
raise TypeError("request must be exact CampaignStageRequest")
|
|
789
|
+
CampaignStageRequest.__post_init__(request)
|
|
790
|
+
if request.step.kind is not CampaignGenerationKind.PORTFOLIO:
|
|
791
|
+
raise ValueError(
|
|
792
|
+
"production generation audit accepts portfolio stages only"
|
|
793
|
+
)
|
|
794
|
+
if type(memory_credit_preparation) is not PortfolioMemoryCreditBatchPreparation:
|
|
795
|
+
raise TypeError("memory_credit_preparation must be exact")
|
|
796
|
+
PortfolioMemoryCreditBatchPreparation.__post_init__(memory_credit_preparation)
|
|
797
|
+
if memory_credit_preparation.prepared_results != results:
|
|
798
|
+
raise ValueError("audit results differ from memory preparation")
|
|
799
|
+
self._validate_plans(entries, plans)
|
|
800
|
+
planned_references = tuple(plan.reference for plan in plans)
|
|
801
|
+
if planned_references != tuple(sorted(set(planned_references))):
|
|
802
|
+
raise ValueError("registered audit plans must be canonical and unique")
|
|
803
|
+
hypothesis_evidence = project_portfolio_hypothesis_evidence(
|
|
804
|
+
campaign_sha256=self.campaign_sha256,
|
|
805
|
+
event_index=request.step.generation,
|
|
806
|
+
workload_instance_sha256=self.workload_instance_sha256,
|
|
807
|
+
evaluator_contract_sha256=self.evaluator_contract_sha256,
|
|
808
|
+
waves=waves,
|
|
809
|
+
results=results,
|
|
810
|
+
metric_projector=self.metric_projector,
|
|
811
|
+
semantics_compiler=self.action_semantics_compiler,
|
|
812
|
+
)
|
|
813
|
+
memory_attribution = audit_portfolio_memory_attribution(
|
|
814
|
+
waves=waves,
|
|
815
|
+
results=results,
|
|
816
|
+
)
|
|
817
|
+
matched_outcomes = resolve_portfolio_memory_matched_control_outcomes(
|
|
818
|
+
waves=waves,
|
|
819
|
+
results=results,
|
|
820
|
+
)
|
|
821
|
+
observations = hypothesis_evidence.observations
|
|
822
|
+
append = self.evidence_registry.prepare_append(
|
|
823
|
+
observations,
|
|
824
|
+
captured_through_event_index=request.step.generation,
|
|
825
|
+
)
|
|
826
|
+
try:
|
|
827
|
+
context_bindings = self._diagnostic_context_bindings(
|
|
828
|
+
waves=waves,
|
|
829
|
+
planned_references=planned_references,
|
|
830
|
+
)
|
|
831
|
+
projection = None
|
|
832
|
+
if context_bindings:
|
|
833
|
+
batch = memory_credit_preparation.batch_receipt
|
|
834
|
+
if batch is None:
|
|
835
|
+
raise ValueError(
|
|
836
|
+
"diagnostic assignments require a prospective memory batch"
|
|
837
|
+
)
|
|
838
|
+
plan_by_reference = {value.reference: value for value in plans}
|
|
839
|
+
snapshot = append.prospective_snapshot
|
|
840
|
+
audits = []
|
|
841
|
+
for binding in context_bindings:
|
|
842
|
+
plan = plan_by_reference[binding.reference]
|
|
843
|
+
audit_request = self._request_from_plan(
|
|
844
|
+
plan,
|
|
845
|
+
audit_cutoff_event_index=request.step.generation,
|
|
846
|
+
registry_snapshot_sha256=snapshot.snapshot_sha256,
|
|
847
|
+
)
|
|
848
|
+
if not plan.admits(audit_request):
|
|
849
|
+
raise ValueError(
|
|
850
|
+
"sealed audit request differs from its registered plan"
|
|
851
|
+
)
|
|
852
|
+
audit_receipt = self.falsification_gate.audit(
|
|
853
|
+
request=audit_request,
|
|
854
|
+
registry=snapshot,
|
|
855
|
+
matcher=self.hypothesis_matcher,
|
|
856
|
+
)
|
|
857
|
+
audits.append(
|
|
858
|
+
CampaignInsightAuditBinding(
|
|
859
|
+
request=audit_request,
|
|
860
|
+
receipt=audit_receipt,
|
|
861
|
+
exact_context_sha256=binding.exact_context_sha256,
|
|
862
|
+
)
|
|
863
|
+
)
|
|
864
|
+
projection = CampaignGenerationAuditProjection(
|
|
865
|
+
stage_request_sha256=request.request_sha256,
|
|
866
|
+
generation=request.step.generation,
|
|
867
|
+
wave_request_sha256s=tuple(
|
|
868
|
+
sorted(
|
|
869
|
+
value.selection_request.request_sha256 for value in waves
|
|
870
|
+
)
|
|
871
|
+
),
|
|
872
|
+
wave_result_receipt_sha256s=tuple(
|
|
873
|
+
sorted(value.receipt.receipt_sha256 for value in results)
|
|
874
|
+
),
|
|
875
|
+
memory_credit_batch_receipt_sha256=batch.receipt_sha256,
|
|
876
|
+
registry_snapshot_sha256=snapshot.snapshot_sha256,
|
|
877
|
+
evidence_append_preparation_sha256=append.preparation_sha256,
|
|
878
|
+
context_bindings=context_bindings,
|
|
879
|
+
audits=tuple(audits),
|
|
880
|
+
)
|
|
881
|
+
preparation = CampaignGenerationAuditPreparation(
|
|
882
|
+
stage_request_sha256=request.request_sha256,
|
|
883
|
+
generation=request.step.generation,
|
|
884
|
+
wave_request_sha256s=tuple(
|
|
885
|
+
sorted(value.selection_request.request_sha256 for value in waves)
|
|
886
|
+
),
|
|
887
|
+
wave_result_receipt_sha256s=tuple(
|
|
888
|
+
sorted(value.receipt.receipt_sha256 for value in results)
|
|
889
|
+
),
|
|
890
|
+
memory_credit_preparation_sha256=(
|
|
891
|
+
memory_credit_preparation.preparation_sha256
|
|
892
|
+
),
|
|
893
|
+
observations=observations,
|
|
894
|
+
observation_exclusions=hypothesis_evidence.exclusions,
|
|
895
|
+
hypothesis_evidence_projection=hypothesis_evidence,
|
|
896
|
+
evidence_append=append,
|
|
897
|
+
memory_attribution_audit=memory_attribution,
|
|
898
|
+
matched_memory_control_outcomes=matched_outcomes,
|
|
899
|
+
projection=projection,
|
|
900
|
+
)
|
|
901
|
+
except BaseException:
|
|
902
|
+
self.evidence_registry.abort_append(append)
|
|
903
|
+
raise
|
|
904
|
+
if preparation.preparation_sha256 in self._prepared:
|
|
905
|
+
self.evidence_registry.abort_append(append)
|
|
906
|
+
raise ValueError("generation audit preparation identity collided")
|
|
907
|
+
self._prepared[preparation.preparation_sha256] = preparation
|
|
908
|
+
return preparation
|
|
909
|
+
|
|
910
|
+
def commit_generation_audit(
|
|
911
|
+
self,
|
|
912
|
+
preparation: CampaignGenerationAuditPreparation,
|
|
913
|
+
) -> None:
|
|
914
|
+
if type(preparation) is not CampaignGenerationAuditPreparation:
|
|
915
|
+
raise TypeError("preparation must be exact")
|
|
916
|
+
CampaignGenerationAuditPreparation.__post_init__(preparation)
|
|
917
|
+
stored = self._prepared.get(preparation.preparation_sha256)
|
|
918
|
+
if stored is not preparation:
|
|
919
|
+
raise ValueError("generation audit preparation is unavailable")
|
|
920
|
+
self.evidence_registry.commit_append(preparation.evidence_append)
|
|
921
|
+
del self._prepared[preparation.preparation_sha256]
|
|
922
|
+
|
|
923
|
+
def abort_generation_audit(
|
|
924
|
+
self,
|
|
925
|
+
preparation: CampaignGenerationAuditPreparation,
|
|
926
|
+
) -> None:
|
|
927
|
+
if type(preparation) is not CampaignGenerationAuditPreparation:
|
|
928
|
+
raise TypeError("preparation must be exact")
|
|
929
|
+
self.evidence_registry.abort_append(preparation.evidence_append)
|
|
930
|
+
self._prepared.pop(preparation.preparation_sha256, None)
|
|
931
|
+
|
|
932
|
+
|
|
933
|
+
__all__ = [
|
|
934
|
+
"CampaignDiagnosticContextBinding",
|
|
935
|
+
"CampaignGenerationAuditPreparation",
|
|
936
|
+
"CampaignGenerationAuditProjection",
|
|
937
|
+
"PRODUCTION_GENERATION_AUDITOR_DEFINITION_SHA256",
|
|
938
|
+
"PRODUCTION_GENERATION_AUDITOR_ID",
|
|
939
|
+
"PRODUCTION_GENERATION_AUDITOR_VERSION",
|
|
940
|
+
"TransactionalPortfolioGenerationAuditor",
|
|
941
|
+
"resolve_portfolio_memory_matched_control_outcomes",
|
|
942
|
+
]
|