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