arbiter-engine 0.2.8__tar.gz → 0.2.9__tar.gz
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.
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/CHANGELOG.md +20 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/CITATION.cff +1 -1
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/PKG-INFO +1 -1
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/api.py +11 -2
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/calendar.py +5 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/sqlite_store.py +18 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/residual/predict_vs_mirror.py +42 -13
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/pyproject.toml +1 -1
- arbiter_engine-0.2.9/tests/test_every_history_the_engine_ships_can_be_described.py +260 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/.gitattributes +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/.github/workflows/release.yml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/.github/workflows/tests.yml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/.github/workflows/verify-published.yml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/.github/workflows/verify-tag-artifact.yml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/.gitignore +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/AI_ATTRIBUTION.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/AUTHORS.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/BRIDGES.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/CODE_OF_CONDUCT.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/COMPATIBILITY.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/CONTRIBUTING.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/LICENSE +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/MODELING.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/NOTICE +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/PRIVACY.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/README.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/ROADMAP.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/SECURITY.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/STANCE.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/SUPPORT.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/TRADEMARK.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/assumptions.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/axiom_thresholds.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/causal/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/causal/discovery.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/causal/granger.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/causal/leadlag.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/clock.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/derived/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/derived/indicator.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/derived/parser.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/envelope.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/battery_pack.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/factory_line.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/kubernetes_node.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/margin_book.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/pump_tank_dynamics.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/pump_tank_planning.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/substation_feeder.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/substation_feeder_surprises.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/water_tank.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/fire_frequency.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/forecast/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/forecast/contract.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/forecast/envelope.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/forecast/ingest.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/forecast/monitor.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/forecast/shadow.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/observation.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/observation_production.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/observation_source_wiring.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/readiness.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/inference/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/inference/causal.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/inference/hypothesis.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/inference/runner.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/inference/ve.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/interfaces.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/mcp/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/mcp/server.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axiom_verdicts_production.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/boundedness.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/connectivity.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/conservation.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/consistency.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/extensions.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/homeostasis.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/monotonicity.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/peers.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/responsiveness.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/roles.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axioms/stability.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/domain_loader.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/entail.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/loader.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/prediction_production.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/reasoner.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/schemas/health_meta_ontology.ttl +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/producers/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/producers/baseline_learner.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/projection/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/projection/projector.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/projection/runner.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/propagation/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/propagation/impact_estimator.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/propagation/lp_confidence.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/propagation/mcts_root_cause.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/propagation/root_cause.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/propagation/weight_learner.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/rca/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/rca/greedy_set_cover.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/replay.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/residual/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/residual/sqlite_ledger.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/schema/envelope.schema.json +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/scripts/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/scripts/benchmark_check.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/scripts/surprise_benchmark.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/subenvelope.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/surprises.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/temporal/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/temporal/temporal_edge.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/temporal/trend_projection.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/__init__.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/action_clears_problem.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/actions.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/builder.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/gap.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/hypothesis_generator.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/hypothesis_production.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/kernel_pipeline_executor.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/monte_carlo_predictor.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/optimization_production.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/pipeline_production.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/planner.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/rollout.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/topology.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/topology_optimizer.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/transition_learner.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/traverser.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/twin/traverser_production.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/types.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/evidence/README.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/evidence/alpha1_evidence_pack.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/evidence/customer_deployment_runbook.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/evidence/extended_fault_scenarios.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/evidence/l5_surprise_synthesis.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/evidence/observability_handoff_guide.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/evidence/tech_brief.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/evidence/use-case-catalogue.md +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/battery_pack.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/factory_line.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/kubernetes_node.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/margin_book.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/pump_tank_dynamics.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/pump_tank_planning.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/substation_feeder.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/substation_feeder_surprises.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/examples/water_tank.yaml +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/schema/envelope.schema.json +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/conftest.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_balance_may_cross_an_entity_boundary.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_bound_can_belong_to_one_instance.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_calibration_figure_names_its_population.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_calibration_says_how_many_trajectories_it_saw.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_chain_of_lags_says_how_it_was_composed.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_changelog_section_says_whether_you_can_install_it.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_check_that_cannot_run_says_so.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_check_that_declines_is_heard.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_checker_asks_no_entity_type.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_clean_rollout_still_counts_what_it_evaluated.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_companion_beside_the_models_is_not_one.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_correct_gain_is_not_contradicted_by_a_lagged_series.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_coupling_block_is_checked_too.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_coupling_is_graded_on_its_own_projections.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_coupling_learns_how_its_projections_fared.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_bad_state_is_not_silent.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_calendar_is_actually_read.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_edge_reaches_the_published_surface.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_floor_is_checked_on_every_path.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_gain_moves_the_downstream_value.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_number_is_the_first_breach.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_offset_waits_for_the_delay.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_source_matches_the_guide.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_declared_spread_reaches_the_value.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_decline_states_the_number_it_computed.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_derived_indicator_is_computed_not_fed.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_discipline_reports_its_own_denominator.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_dropped_declaration_is_not_silent.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_filed_source_says_who_is_not_a_producer.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_finding_says_where_to_look_next.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_batch_is_filed_or_accounted_for.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_check_that_refused_says_so_out_loud.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_is_graded_at_its_horizon.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_is_measured_against_a_random_walk.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_is_scored_not_just_stored.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_keeps_its_doubt.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_keeps_its_doubt_when_its_median_stands_still.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_states_its_own_distribution.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecast_widens_and_says_what_it_assumed.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_forecaster_is_judged_by_the_same_eight_axioms.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_freeze_is_found_inside_its_window.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_latency_without_a_threshold_says_so.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_lazy_import_did_not_move_a_name.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_lead_lag_p_value_means_what_it_says.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_learned_gain_is_a_proposal.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_margin_is_measured_against_every_line.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_nested_block_is_checked_too.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_pair_can_beat_the_best_single_action.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_per_instance_bound_reaches_every_reader.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_plan_files_the_row_that_is_a_forecast.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_plan_ranks_only_when_told_how.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_posterior_is_arithmetic_not_assumption.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_posterior_says_which_reading_it_left_out.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_prediction_ledger_outlives_the_process.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_projection_declines_rather_than_guessing.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_proposal_says_what_adopting_it_would_have_caught.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_proposed_spread_says_what_it_assumed.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_ranking_says_how_close_the_call_was.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_reading_can_be_impossible_without_being_extreme.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_refused_block_says_which_rule_it_was_on.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_refused_coupling_is_a_question_not_a_silence.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_response_model_nobody_recognises_is_not_exponential.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_rollout_can_be_graded_later.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_rollout_carries_a_transient_past_the_action_step.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_rollout_steps_the_model_forward.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_second_action_on_a_moved_property_superposes.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_sentence_the_changelog_closed_is_gone.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_set_aside_forecast_says_who_set_it_aside.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_source_pinned_at_zero_passes_no_doubt_on.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_spread_nobody_declared_is_not_a_declared_zero.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_starved_join_says_which_operand_starved.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_surprise_the_store_never_saw_is_not_a_miss.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_tie_break_knows_which_side_of_the_line.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_tie_is_broken_by_the_declared_margin.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_transition_into_an_acted_property_still_arrives.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_two_stage_chain_composes_exactly.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_value_is_final_before_anything_reads_it.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_vertical_may_adopt_and_this_engine_may_not.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_warning_is_a_finding_on_every_surface.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_what_if_is_evaluated_at_the_horizon_it_asked_for.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_window_cannot_see_past_the_frozen_clock.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_withdrawn_check_is_not_silent.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_a_zero_allowance_still_reports.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_absent_data_regressions.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_agreement_declines_what_it_used_to_guess.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_an_action_may_arrive_as_a_mapping.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_an_action_on_a_coupled_property_reads_the_value_it_has.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_an_action_outlives_the_forecast_it_overrides.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_an_action_that_never_runs_says_so.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_an_imagined_breach_is_not_a_live_one_in_the_telemetry.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_an_imagined_finding_is_not_a_live_one.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_an_invented_time_course_says_so.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_an_undeclared_transition_projects_nothing.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_closed_reader.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_connectivity_required_property.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_conservation_absent_output.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_cross_signal_consistency.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_decline_contract.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_did_you_mean_is_case_insensitive.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_discovery_proposes_and_never_promotes.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_documented_paths_the_suite_never_ran.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_entailment_derives_and_refuses.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_envelope_schema.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_every_assumption_stamp_has_one_name.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_every_declared_tool_has_a_wrapper.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_every_decline_reason_has_a_producer.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_every_discipline_decline_has_one_name.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_every_forecast_gets_a_yardstick.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_every_reader_takes_the_same_history.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_every_shipped_example_actually_runs.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_every_simulation_decline_has_an_input.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_gated_cell_declines.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_history_outlives_the_process_and_the_weekend.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_homeostasis_setpoint.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_importing_the_package_does_not_pull_an_optional_extra.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_lower_bounds.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_mcp_feeders.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_mcp_roundtrip.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_monotonicity_reversals.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_no_axiom_retires_a_check.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_no_cell_is_judged_twice.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_no_identifier_names_a_private_record.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_no_test_anchors_time_at_import.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_one_declared_spread_is_counted_once.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_one_question_gets_one_projection.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_one_set_of_names_the_model_reads.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_role_comes_from_the_model.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_slow_oscillation.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_alpha_figure_comes_from_the_record.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_axioms_run_over_the_forecast_itself.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_causal_verb_has_a_model_to_run_against.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_clock_can_be_moved.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_config_blocks_are_documented.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_documented_priorities_are_the_computed_ones.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_engine_declares_no_domain_it_does_not_serve.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_engine_invents_no_indicators.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_engine_races_its_own_forecasts.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_engine_says_what_its_approximation_cost.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_engine_scores_its_own_declared_spread.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_engine_ships_an_opponent_worth_beating.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_engines_own_forecast_is_not_a_producers.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_envelope_legs_are_documented.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_evidence_floor_is_declared_or_disclosed.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_forecasts_leg_says_how_many_were_expected.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_indicator_keys_are_documented.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_ingest_tag_names_the_caller_not_the_funnel.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_lane_cleans_up_after_itself.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_ledger_is_reachable_without_a_deep_import.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_legal_files_ship_together.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_namespaces_point_at_a_graph_that_ships.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_policy_document_and_the_changelog_agree.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_published_cascade_formula_is_the_one_that_runs.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_question_ranking_is_one_scale.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_rate_arm_declines_what_it_used_to_guess.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_readme_decline_count_is_derived.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_readme_name_count_is_derived.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_readme_names_the_forms_load_model_takes.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_rename_table_names_real_things.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_sample_floor_says_whether_it_is_reachable.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_schema_names_every_sub_envelope.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_schema_names_what_a_sub_envelope_carries.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_session_keeps_its_own_ledger.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_stance_page_says_what_no_other_page_says.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_verb_that_used_the_number_names_it.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_the_world_model_can_be_exercised_over_mcp.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_threshold_overrides.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_timestamped_ingestion.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_traverse_vocabularies.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_trend_widens_and_does_not_point.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_two_actions_at_two_instants_are_not_one.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_two_bare_series_are_joinable.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_two_claims_on_one_edge_are_two_questions.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_two_offset_couplings_from_one_source_are_both_charged.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_two_plans_that_cost_the_same_compare_equal.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_two_rules_can_close_a_loop_neither_closes_alone.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_two_settings_of_one_property_do_not_add.py +0 -0
- {arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/tests/test_unread_properties.py +0 -0
|
@@ -34,6 +34,26 @@ useful-looking document and the less trustworthy one.
|
|
|
34
34
|
|
|
35
35
|
## [Unreleased]
|
|
36
36
|
|
|
37
|
+
## [0.2.9] — 2026-09-25
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- **`model_describe` and `gaps` work over every history this package ships.**
|
|
42
|
+
Both asked the session's history for `series_keys()`, which only the
|
|
43
|
+
in-memory store implemented, so a session built over
|
|
44
|
+
`SqliteObservationHistory` or `CalendarHistory` raised `AttributeError`, and
|
|
45
|
+
`rollout` ran with no seeded past (`precondition_unmet`). Both stores now list
|
|
46
|
+
their series. A history of the caller's own that implements only the five
|
|
47
|
+
`ObservationHistory` methods gets `unconsumed_observations: None` -- the report
|
|
48
|
+
could not be made -- rather than a crash or an empty list.
|
|
49
|
+
- **A forecast is graded through whatever history the session reads.** The
|
|
50
|
+
ledger read the in-memory store's private series and skipped any other, so
|
|
51
|
+
a forecast made over `SqliteObservationHistory`, in a model declaring a
|
|
52
|
+
`calendar:`, or in a model with any derived indicator matured `ungradeable`
|
|
53
|
+
every time: measured, none of twelve graded in each case, against twelve of
|
|
54
|
+
twelve on the plain store. It reads through `get_values` now, and all four
|
|
55
|
+
grade alike. No calibration figure moves for a session that graded before.
|
|
56
|
+
|
|
37
57
|
## [0.2.8] — 2026-09-25
|
|
38
58
|
|
|
39
59
|
### Added
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
alias: "james-sheen"
|
|
10
10
|
- name: "The Arbiter Project Authors"
|
|
11
11
|
license: Apache-2.0
|
|
12
|
-
version: "0.2.
|
|
12
|
+
version: "0.2.9"
|
|
13
13
|
date-released: "2026-09-25"
|
|
14
14
|
repository-code: "https://github.com/james-sheen/arbiter"
|
|
15
15
|
url: "https://github.com/james-sheen/arbiter"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: arbiter-engine
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary: A detection engine that reports what it did not check.
|
|
5
5
|
Project-URL: Homepage, https://github.com/james-sheen/arbiter
|
|
6
6
|
Project-URL: Source, https://github.com/james-sheen/arbiter
|
|
@@ -536,7 +536,7 @@ class EngineSession:
|
|
|
536
536
|
})
|
|
537
537
|
return records
|
|
538
538
|
|
|
539
|
-
def unconsumed_observations(self) -> List[Dict[str, Any]]:
|
|
539
|
+
def unconsumed_observations(self) -> Optional[List[Dict[str, Any]]]:
|
|
540
540
|
"""Series this session holds that no declared indicator will ever read.
|
|
541
541
|
|
|
542
542
|
This rules the second half of issue #1. ``add_observations``
|
|
@@ -564,9 +564,18 @@ class EngineSession:
|
|
|
564
564
|
# report on the other input surface counted them as read. One
|
|
565
565
|
# declaration, two verdicts, and the only way to silence the wrong one
|
|
566
566
|
# was to declare the property a second time.
|
|
567
|
+
# A HISTORY THAT CANNOT LIST ITS SERIES CANNOT BE ASKED
|
|
568
|
+
# THIS, and the answer says so rather than crashing or claiming the
|
|
569
|
+
# empty list. `series_keys` is not one of the ABC's five methods; both
|
|
570
|
+
# stores this engine ships implement it, and a caller's own need not.
|
|
571
|
+
# `None` is the engine's convention for *not measured*, and every
|
|
572
|
+
# consumer in the family already reads this key through `or []`.
|
|
573
|
+
keys = getattr(self.history, "series_keys", None)
|
|
574
|
+
if keys is None:
|
|
575
|
+
return None
|
|
567
576
|
declared: Dict[str, set] = self.readable_properties()
|
|
568
577
|
records: List[Dict[str, Any]] = []
|
|
569
|
-
for entity_id, prop in
|
|
578
|
+
for entity_id, prop in keys():
|
|
570
579
|
entity = self.entities.get(entity_id)
|
|
571
580
|
if entity is None:
|
|
572
581
|
reason = "unknown_entity"
|
|
@@ -226,3 +226,8 @@ class CalendarHistory(ObservationHistory):
|
|
|
226
226
|
|
|
227
227
|
def get_observation_count(self, entity_id: str, property_name: str) -> int:
|
|
228
228
|
return self.inner.get_observation_count(entity_id, property_name)
|
|
229
|
+
|
|
230
|
+
def series_keys(self):
|
|
231
|
+
"""The series the history underneath holds -- a calendar changes which
|
|
232
|
+
instants count, never which series exist."""
|
|
233
|
+
return self.inner.series_keys()
|
|
@@ -135,6 +135,24 @@ class SqliteObservationHistory(ObservationHistory):
|
|
|
135
135
|
return [(_from_seconds(ts), text if text is not None else str(number))
|
|
136
136
|
for ts, number, text in rows]
|
|
137
137
|
|
|
138
|
+
def series_keys(self) -> List[Tuple[str, str]]:
|
|
139
|
+
"""Every ``(entity_id, property_name)`` this store holds a series for.
|
|
140
|
+
|
|
141
|
+
Not one of the ABC's five, and the in-memory store had it
|
|
142
|
+
from on -- so every reader that enumerates a history was
|
|
143
|
+
written against the default and this class was never asked. Two of
|
|
144
|
+
them crashed on it: `model_describe` and `gaps` raised AttributeError
|
|
145
|
+
for any session built over this store, and `rollout` ran with no
|
|
146
|
+
imagined past behind it, declining `precondition_unmet`. Nothing
|
|
147
|
+
downstream had constructed one until a vertical kept its readings
|
|
148
|
+
across runs, which is the one use this class exists for.
|
|
149
|
+
"""
|
|
150
|
+
with self._lock:
|
|
151
|
+
rows = self._connection.execute(
|
|
152
|
+
"SELECT DISTINCT entity_id, property FROM obs"
|
|
153
|
+
" ORDER BY entity_id, property").fetchall()
|
|
154
|
+
return [(str(entity_id), str(prop)) for entity_id, prop in rows]
|
|
155
|
+
|
|
138
156
|
def get_observations(self, entity_id: str, start: datetime,
|
|
139
157
|
end: datetime) -> List[Observation]:
|
|
140
158
|
with self._lock:
|
|
@@ -48,7 +48,7 @@ import uuid
|
|
|
48
48
|
from collections import deque
|
|
49
49
|
from dataclasses import dataclass, field
|
|
50
50
|
from datetime import datetime, timedelta
|
|
51
|
-
from ..clock import as_naive_utc, now_utc
|
|
51
|
+
from ..clock import as_naive_utc, as_of, now_utc
|
|
52
52
|
# the id the yardstick is filed under, read from the module that
|
|
53
53
|
# owns it rather than re-spelled here. Two spellings of one literal is how
|
|
54
54
|
# the exclusion below would silently stop excluding anything.
|
|
@@ -698,18 +698,47 @@ class PredictionLedger:
|
|
|
698
698
|
property_name: str,
|
|
699
699
|
start: datetime,
|
|
700
700
|
end: datetime,
|
|
701
|
+
now: Optional[datetime] = None,
|
|
701
702
|
) -> List[Tuple[datetime, float]]:
|
|
702
|
-
"""Numeric observations for (entity, property) in [start, end],
|
|
703
|
-
|
|
703
|
+
"""Numeric observations for (entity, property) in [start, end], read
|
|
704
|
+
through each history's own `get_values` -- never its internals.
|
|
705
|
+
|
|
706
|
+
This read the in-memory store's private `_history` dict and
|
|
707
|
+
SKIPPED any history without one. `check` hands the ledger the session's
|
|
708
|
+
READING history, which is the raw store only when the model declares
|
|
709
|
+
neither a calendar nor a derived indicator; otherwise it is a view, and
|
|
710
|
+
so is the durable store. Measured, the same twenty minutes of one tank
|
|
711
|
+
filing a forecast a minute: the in-memory store graded 12 of 12; the
|
|
712
|
+
durable store, a declared calendar and a model with one derived
|
|
713
|
+
indicator graded NONE, all twelve `ungradeable`. A calibration figure
|
|
714
|
+
that could never be anything but empty, reported without an error --
|
|
715
|
+
beside a comment in `check` saying the view was passed so that a
|
|
716
|
+
derived forecast WOULD have something to score against.
|
|
717
|
+
|
|
718
|
+
`get_values` is the one reader every history implements, and it ends
|
|
719
|
+
at the engine's clock -- so the read is pinned to the GRADING instant,
|
|
720
|
+
`now`, which a caller may pass explicitly and which the private dict
|
|
721
|
+
never consulted. The window reaches back to `start`, a microsecond
|
|
722
|
+
wider because the stores bound it exclusively, and is then cut to
|
|
723
|
+
exactly `[start, end]`. A calendar view answers a window in OPEN time,
|
|
724
|
+
which reaches further back in wall time, and the cut is what makes
|
|
725
|
+
that harmless.
|
|
726
|
+
"""
|
|
704
727
|
out: List[Tuple[datetime, float]] = []
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
728
|
+
at = as_naive_utc(now) if now is not None else now_utc()
|
|
729
|
+
span = at - start + timedelta(microseconds=1)
|
|
730
|
+
if span.total_seconds() <= 0:
|
|
731
|
+
return out
|
|
732
|
+
with as_of(at):
|
|
733
|
+
for history in histories or []:
|
|
734
|
+
reader = getattr(history, "get_values", None)
|
|
735
|
+
if reader is None:
|
|
736
|
+
continue
|
|
737
|
+
for ts, value in reader(entity_id, property_name, span) or []:
|
|
738
|
+
if (isinstance(ts, datetime)
|
|
739
|
+
and isinstance(value, (int, float))
|
|
740
|
+
and start <= ts <= end):
|
|
741
|
+
out.append((ts, float(value)))
|
|
713
742
|
return out
|
|
714
743
|
|
|
715
744
|
def _grade_distribution_record(
|
|
@@ -743,7 +772,7 @@ class PredictionLedger:
|
|
|
743
772
|
return None
|
|
744
773
|
observations = self._observations_for(
|
|
745
774
|
list(histories), record.entity_id, record.indicator or "",
|
|
746
|
-
record.predicted_at, window_end)
|
|
775
|
+
record.predicted_at, window_end, now)
|
|
747
776
|
if not observations:
|
|
748
777
|
record.verdict = GRADE_UNGRADEABLE
|
|
749
778
|
record.graded_at = now
|
|
@@ -779,7 +808,7 @@ class PredictionLedger:
|
|
|
779
808
|
return None
|
|
780
809
|
observations = self._observations_for(
|
|
781
810
|
list(histories), record.entity_id, record.indicator or "",
|
|
782
|
-
record.predicted_at, window_end)
|
|
811
|
+
record.predicted_at, window_end, now)
|
|
783
812
|
target = record.predicted_at + timedelta(seconds=record.horizon_s)
|
|
784
813
|
# AND EACH READING GRADES ONE HORIZON, not every horizon
|
|
785
814
|
# whose window contains it. This took the observation closest to the
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
"""Every history this engine ships can be described, gapped and rolled from.
|
|
2
|
+
|
|
3
|
+
`SqliteObservationHistory` and `CalendarHistory` have been supported names since
|
|
4
|
+
0.2.3. `model_describe` and `gaps` both asked the session's history for
|
|
5
|
+
`series_keys()` -- a method the in-memory store has and the ABC does not
|
|
6
|
+
require -- and so both RAISED AttributeError for any session built over either
|
|
7
|
+
of the other two. `rollout` checked for the method and, finding none, ran with
|
|
8
|
+
no imagined past, declining `precondition_unmet`.
|
|
9
|
+
|
|
10
|
+
NOTHING DOWNSTREAM HAD EVER CONSTRUCTED ONE, which is how it survived. The first
|
|
11
|
+
caller was a vertical keeping its readings across separate runs -- the one use
|
|
12
|
+
the durable store exists for -- and its first `detect` died in the describe
|
|
13
|
+
call. Every test of the durable store here fed it and read it back through
|
|
14
|
+
`get_values`, which is the half that worked.
|
|
15
|
+
|
|
16
|
+
So this is asked of EVERY history the engine ships, through the verbs a caller
|
|
17
|
+
actually uses, rather than of one method on one class.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import pathlib
|
|
23
|
+
from datetime import datetime, timedelta
|
|
24
|
+
|
|
25
|
+
import pytest
|
|
26
|
+
|
|
27
|
+
from arbiter_engine import api
|
|
28
|
+
from arbiter_engine.history.calendar import (CalendarHistory,
|
|
29
|
+
SessionCalendar)
|
|
30
|
+
from arbiter_engine.history.observation import \
|
|
31
|
+
InMemoryObservationHistory
|
|
32
|
+
from arbiter_engine.history.sqlite_store import \
|
|
33
|
+
SqliteObservationHistory
|
|
34
|
+
from arbiter_engine.interfaces import ObservationHistory
|
|
35
|
+
|
|
36
|
+
MODEL = """
|
|
37
|
+
domain:
|
|
38
|
+
id: histories
|
|
39
|
+
name: every shipped history
|
|
40
|
+
entity_types: [Tank]
|
|
41
|
+
indicators:
|
|
42
|
+
Tank:
|
|
43
|
+
- name: level
|
|
44
|
+
type: NUMERIC
|
|
45
|
+
axioms: [BOUNDEDNESS]
|
|
46
|
+
warning: 80
|
|
47
|
+
critical: 90
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
AT = datetime(2026, 9, 25, 12, 0)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _always_open():
|
|
54
|
+
"""A calendar with no sessions, which counts every instant -- the history
|
|
55
|
+
underneath is what is under test, not the calendar."""
|
|
56
|
+
return SessionCalendar()
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
HISTORIES = {
|
|
60
|
+
"in_memory": lambda: InMemoryObservationHistory(),
|
|
61
|
+
"sqlite": lambda: SqliteObservationHistory(":memory:"),
|
|
62
|
+
"calendar_over_memory": lambda: CalendarHistory(
|
|
63
|
+
InMemoryObservationHistory(), _always_open()),
|
|
64
|
+
"calendar_over_sqlite": lambda: CalendarHistory(
|
|
65
|
+
SqliteObservationHistory(":memory:"), _always_open()),
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _session(history, tmp_path):
|
|
70
|
+
path = tmp_path / "model.yaml"
|
|
71
|
+
path.write_text(MODEL)
|
|
72
|
+
session = api.EngineSession(history=history)
|
|
73
|
+
session.load_model(str(path))
|
|
74
|
+
session.add_entity("tank-1", "Tank", {"level": 50.0})
|
|
75
|
+
with api.as_of(AT):
|
|
76
|
+
session.add_observations("tank-1", "level",
|
|
77
|
+
[(AT - timedelta(minutes=5 - i), 50.0 + i)
|
|
78
|
+
for i in range(5)])
|
|
79
|
+
# A series no indicator reads -- the report this breaks exists for it.
|
|
80
|
+
session.add_observations("tank-1", "levle",
|
|
81
|
+
[(AT - timedelta(minutes=1), 1.0)])
|
|
82
|
+
return session
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@pytest.fixture(params=sorted(HISTORIES))
|
|
86
|
+
def shipped(request, tmp_path):
|
|
87
|
+
return request.param, _session(HISTORIES[request.param](), tmp_path)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class TestTheVerbsThatEnumerateAHistory:
|
|
91
|
+
|
|
92
|
+
def test_model_describe_answers(self, shipped):
|
|
93
|
+
name, session = shipped
|
|
94
|
+
with api.as_of(AT):
|
|
95
|
+
payload = api.model_describe(session).to_dict()
|
|
96
|
+
assert "unconsumed_observations" in payload, name
|
|
97
|
+
|
|
98
|
+
def test_gaps_answers(self, shipped):
|
|
99
|
+
name, session = shipped
|
|
100
|
+
with api.as_of(AT):
|
|
101
|
+
api.check(session)
|
|
102
|
+
api.gaps(session).to_dict()
|
|
103
|
+
|
|
104
|
+
def test_the_unread_series_is_reported_the_same_way_by_all_of_them(
|
|
105
|
+
self, shipped):
|
|
106
|
+
"""Same feed, same report, whichever store holds it -- the store is a
|
|
107
|
+
durability choice and must not change what the engine says."""
|
|
108
|
+
name, session = shipped
|
|
109
|
+
records = session.unconsumed_observations()
|
|
110
|
+
assert [(r["entity_id"], r["property"], r["reason"]) for r in records] == [
|
|
111
|
+
("tank-1", "levle", "undeclared_property")], name
|
|
112
|
+
|
|
113
|
+
def test_a_rollout_is_seeded_from_it(self, shipped):
|
|
114
|
+
"""`precondition_unmet` is what a rollout says when it could not read
|
|
115
|
+
the past; on a store the engine ships, it must never say it."""
|
|
116
|
+
name, session = shipped
|
|
117
|
+
with api.as_of(AT):
|
|
118
|
+
payload = api.rollout(session, horizon_s=120.0,
|
|
119
|
+
step_s=60.0).to_dict()["simulation"]
|
|
120
|
+
reasons = {d["reason"] for d in payload.get("not_checked", [])}
|
|
121
|
+
assert "precondition_unmet" not in reasons, (name, reasons)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class TestTheDurableStoreListsItsSeries:
|
|
125
|
+
|
|
126
|
+
def test_distinct_and_ordered(self):
|
|
127
|
+
store = SqliteObservationHistory(":memory:")
|
|
128
|
+
for entity, prop in (("b", "x"), ("a", "y"), ("a", "x"), ("a", "x")):
|
|
129
|
+
store.add(entity, prop, 1.0, AT)
|
|
130
|
+
assert store.series_keys() == [("a", "x"), ("a", "y"), ("b", "x")]
|
|
131
|
+
|
|
132
|
+
def test_it_survives_the_process(self, tmp_path):
|
|
133
|
+
path = str(tmp_path / "h.sqlite")
|
|
134
|
+
SqliteObservationHistory(path).add("tank-1", "level", 1.0, AT)
|
|
135
|
+
assert SqliteObservationHistory(path).series_keys() == [("tank-1", "level")]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class _OnlyTheAbc(ObservationHistory):
|
|
139
|
+
"""A caller's own history, implementing exactly the five methods required."""
|
|
140
|
+
|
|
141
|
+
def __init__(self):
|
|
142
|
+
self._inner = InMemoryObservationHistory()
|
|
143
|
+
|
|
144
|
+
def add(self, *args, **kwargs):
|
|
145
|
+
return self._inner.add(*args, **kwargs)
|
|
146
|
+
|
|
147
|
+
def get_values(self, *args, **kwargs):
|
|
148
|
+
return self._inner.get_values(*args, **kwargs)
|
|
149
|
+
|
|
150
|
+
def get_states(self, *args, **kwargs):
|
|
151
|
+
return self._inner.get_states(*args, **kwargs)
|
|
152
|
+
|
|
153
|
+
def get_observations(self, *args, **kwargs):
|
|
154
|
+
return self._inner.get_observations(*args, **kwargs)
|
|
155
|
+
|
|
156
|
+
def get_observation_count(self, *args, **kwargs):
|
|
157
|
+
return self._inner.get_observation_count(*args, **kwargs)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
class TestAHistoryThatCannotListItsSeriesSaysSo:
|
|
161
|
+
"""The ABC does not require `series_keys`, so a caller's history may lack it.
|
|
162
|
+
The report it feeds cannot be made then -- and `[]` would say it was made
|
|
163
|
+
and found nothing."""
|
|
164
|
+
|
|
165
|
+
def test_the_report_is_none_not_empty(self, tmp_path):
|
|
166
|
+
session = _session(_OnlyTheAbc(), tmp_path)
|
|
167
|
+
assert session.unconsumed_observations() is None
|
|
168
|
+
|
|
169
|
+
def test_describe_still_answers(self, tmp_path):
|
|
170
|
+
session = _session(_OnlyTheAbc(), tmp_path)
|
|
171
|
+
with api.as_of(AT):
|
|
172
|
+
payload = api.model_describe(session).to_dict()
|
|
173
|
+
assert payload["unconsumed_observations"] is None
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
FORECAST_MODEL = """
|
|
177
|
+
domain:
|
|
178
|
+
id: graded
|
|
179
|
+
name: a forecast graded through every view
|
|
180
|
+
entity_types: [Tank]
|
|
181
|
+
indicators:
|
|
182
|
+
Tank:
|
|
183
|
+
- name: level
|
|
184
|
+
type: NUMERIC
|
|
185
|
+
axioms: [BOUNDEDNESS]
|
|
186
|
+
warning: 1000
|
|
187
|
+
critical: 2000
|
|
188
|
+
window: 1h
|
|
189
|
+
dynamics: {model: random_walk}
|
|
190
|
+
"""
|
|
191
|
+
|
|
192
|
+
#: A calendar open around the clock is still a declared calendar, so the view
|
|
193
|
+
#: `check` hands the ledger is the calendar wrapper -- which is the point.
|
|
194
|
+
CALENDAR = (" calendar:\n sessions:\n - {days: [mon, tue, wed, thu, fri, "
|
|
195
|
+
"sat, sun], open: '00:00', close: '23:59'}\n")
|
|
196
|
+
|
|
197
|
+
#: One derived indicator anywhere in the model wraps the whole reading history.
|
|
198
|
+
DERIVED = (" - name: double\n type: NUMERIC\n axioms: [BOUNDEDNESS]\n"
|
|
199
|
+
" warning: 1000\n critical: 2000\n"
|
|
200
|
+
" derived: {expression: \"level + level\"}\n")
|
|
201
|
+
|
|
202
|
+
VIEWS = {
|
|
203
|
+
"in_memory": (FORECAST_MODEL, InMemoryObservationHistory),
|
|
204
|
+
"sqlite": (FORECAST_MODEL, lambda: SqliteObservationHistory(":memory:")),
|
|
205
|
+
"calendar": (FORECAST_MODEL.replace(" entity_types:", CALENDAR + " entity_types:"),
|
|
206
|
+
InMemoryObservationHistory),
|
|
207
|
+
"derived": (FORECAST_MODEL + DERIVED, InMemoryObservationHistory),
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _graded(model_text, history, tmp_path):
|
|
212
|
+
"""Twenty minutes of one tank, a forecast filed each minute from the
|
|
213
|
+
seventh, one fresh session per minute over the same two stores."""
|
|
214
|
+
import random
|
|
215
|
+
|
|
216
|
+
tmp_path.mkdir(parents=True, exist_ok=True)
|
|
217
|
+
path = tmp_path / "m.yaml"
|
|
218
|
+
path.write_text(model_text)
|
|
219
|
+
rng, level, ledger = random.Random(1), 100.0, None
|
|
220
|
+
for minute in range(20):
|
|
221
|
+
at = AT + timedelta(minutes=minute)
|
|
222
|
+
level += rng.gauss(0.0, 1.0)
|
|
223
|
+
with api.as_of(at):
|
|
224
|
+
session = api.EngineSession(history=history, ledger=ledger)
|
|
225
|
+
session.load_model(str(path))
|
|
226
|
+
session.add_entity("t1", "Tank", {"level": level})
|
|
227
|
+
session.add_observations("t1", "level", [(at, level)])
|
|
228
|
+
ledger = session.ledger
|
|
229
|
+
api.check(session)
|
|
230
|
+
if minute >= 6:
|
|
231
|
+
api.project(session, horizon_s=60.0)
|
|
232
|
+
return ledger.calibration(), type(session.reading_history()).__name__
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class TestAForecastIsGradedThroughEveryView:
|
|
236
|
+
"""The ledger read the in-memory store's private dict and skipped anything
|
|
237
|
+
else, so the durable store, a declared calendar and one derived indicator
|
|
238
|
+
each graded NONE of twelve forecasts -- every one `ungradeable`."""
|
|
239
|
+
|
|
240
|
+
@pytest.mark.parametrize("view", sorted(VIEWS))
|
|
241
|
+
def test_it_grades_what_the_plain_store_grades(self, view, tmp_path):
|
|
242
|
+
text, make = VIEWS[view]
|
|
243
|
+
cal, name = _graded(text, make(), tmp_path / view)
|
|
244
|
+
plain_text, plain_store = VIEWS["in_memory"]
|
|
245
|
+
control, _ = _graded(plain_text, plain_store(), tmp_path / "control")
|
|
246
|
+
assert control["confirmed"] + control["falsified"] > 0, (
|
|
247
|
+
"the control graded nothing, so parity with it would be free")
|
|
248
|
+
assert cal["ungradeable"] == 0, (view, name, cal["ungradeable"])
|
|
249
|
+
assert (cal["confirmed"], cal["falsified"]) == (
|
|
250
|
+
control["confirmed"], control["falsified"]), (view, name)
|
|
251
|
+
|
|
252
|
+
def test_the_views_are_really_different_objects(self, tmp_path):
|
|
253
|
+
"""Non-vacuity: if every case were the plain store underneath, the
|
|
254
|
+
parity above would be free."""
|
|
255
|
+
names = {view: _graded(text, make(), tmp_path / view)[1]
|
|
256
|
+
for view, (text, make) in VIEWS.items()}
|
|
257
|
+
assert names == {"in_memory": "InMemoryObservationHistory",
|
|
258
|
+
"sqlite": "SqliteObservationHistory",
|
|
259
|
+
"calendar": "CalendarHistory",
|
|
260
|
+
"derived": "DerivedHistoryView"}, names
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/pump_tank_dynamics.yaml
RENAMED
|
File without changes
|
{arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/pump_tank_planning.yaml
RENAMED
|
File without changes
|
{arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/examples/substation_feeder.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/observation_production.py
RENAMED
|
File without changes
|
{arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/history/observation_source_wiring.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{arbiter_engine-0.2.8 → arbiter_engine-0.2.9}/arbiter_engine/ontology/axiom_verdicts_production.py
RENAMED
|
File without changes
|
|
File without changes
|