cognite-data-quality 0.0.1b1__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.
- cognite_data_quality-0.0.1b1/.cursor/skills/merge-ready-pr-gate/SKILL.md +79 -0
- cognite_data_quality-0.0.1b1/.cursor/skills/pydantic-first-coding/SKILL.md +63 -0
- cognite_data_quality-0.0.1b1/.cursor/skills/rule-engine-focus-node-filtering/SKILL.md +105 -0
- cognite_data_quality-0.0.1b1/.cursor/skills/rule-engine-listener-blueprint/SKILL.md +167 -0
- cognite_data_quality-0.0.1b1/.cursor/skills/rule-engine-sync-state-watermarks/SKILL.md +283 -0
- cognite_data_quality-0.0.1b1/.cursor/skills/ruleset-lifecycle-state/SKILL.md +319 -0
- cognite_data_quality-0.0.1b1/.cursor/skills/sdk-contract-verification/SKILL.md +50 -0
- cognite_data_quality-0.0.1b1/.cursor/skills/shacl-extension-dispatch/SKILL.md +64 -0
- cognite_data_quality-0.0.1b1/.cursor/skills/validation-lifecycle-baseline-incremental/SKILL.md +169 -0
- cognite_data_quality-0.0.1b1/.gitattributes +1 -0
- cognite_data_quality-0.0.1b1/.github/CODEOWNERS +1 -0
- cognite_data_quality-0.0.1b1/.github/workflows/build.yml +26 -0
- cognite_data_quality-0.0.1b1/.github/workflows/release.yaml +116 -0
- cognite_data_quality-0.0.1b1/.gitignore +113 -0
- cognite_data_quality-0.0.1b1/.pre-commit-config.yaml +20 -0
- cognite_data_quality-0.0.1b1/.readthedocs.yaml +15 -0
- cognite_data_quality-0.0.1b1/AGENTS.md +54 -0
- cognite_data_quality-0.0.1b1/ARCHITECTURE.md +1425 -0
- cognite_data_quality-0.0.1b1/CLAUDE.md +980 -0
- cognite_data_quality-0.0.1b1/CODE_OF_CONDUCT.md +129 -0
- cognite_data_quality-0.0.1b1/LICENSE +202 -0
- cognite_data_quality-0.0.1b1/PKG-INFO +70 -0
- cognite_data_quality-0.0.1b1/README.md +907 -0
- cognite_data_quality-0.0.1b1/README_PYPI.md +40 -0
- cognite_data_quality-0.0.1b1/add_dimensions_to_shacl.py +251 -0
- cognite_data_quality-0.0.1b1/add_remaining_dimensions.py +210 -0
- cognite_data_quality-0.0.1b1/adr/ADR_0005_rule_engine_result_sync_chaining.md +57 -0
- cognite_data_quality-0.0.1b1/adr/ADR_0006_dataproduct_scoped_validation_workflows.md +300 -0
- cognite_data_quality-0.0.1b1/adr/ADR_0007_per_view_sync_execution_lease.md +196 -0
- cognite_data_quality-0.0.1b1/adr/ADR_0008_edge_existence_production_orchestration.md +724 -0
- cognite_data_quality-0.0.1b1/adr/ADR_0009_mutable_immutable_records_streams.md +161 -0
- cognite_data_quality-0.0.1b1/adr/ADR_0010_dual_write_records_streams.md +97 -0
- cognite_data_quality-0.0.1b1/adr/ARCHITECTURE_DEEP_DIVE.md +1222 -0
- cognite_data_quality-0.0.1b1/adr/PRD_chained_conditional_logic.md +57 -0
- cognite_data_quality-0.0.1b1/adr/SPEC_rule_engine_result_chaining.md +72 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/__init__.py +83 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_client_name.py +37 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_config.py +123 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_containers.py +772 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_credentials.py +42 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_dataproduct_client.py +259 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_dataproduct_loader.py +439 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_dataproduct_publisher.py +712 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/__init__.py +1 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/__init__.py +1 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/cursor_state.py +829 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/edge_existence_baseline_state.py +112 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/edge_existence_constraints.py +130 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/edge_existence_records.py +177 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/records_api.py +489 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/rule_engine_records.py +184 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/rule_engine_result_sync.py +265 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/shacl_classifier.py +269 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/shacl_utils.py +41 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/time_window.py +70 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/timeseries_config_state.py +96 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/timestamp_collection_state.py +236 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/common/view_config_state.py +73 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handler.py +157 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/__init__.py +1 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/aggregate_uniqueness_validation.py +841 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/data_product_sync.py +568 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/edge_existence_baseline.py +348 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/edge_existence_evaluator.py +277 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/edge_existence_event.py +152 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/historic_queue_manager.py +381 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/instance_sync_cursor_validation.py +652 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/instance_validation.py +325 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/orchestration_status.py +303 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/orchestrator.py +2626 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/partitioned_validation.py +668 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/raw_validation.py +741 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/rule_engine_result_sync.py +99 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/shacl_validation.py +298 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/test_rule.py +313 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/handlers/timeseries_validation.py +786 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_function_code/requirements.txt +10 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/__init__.py +49 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_client.py +73 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_constants.py +40 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_extractors/__init__.py +11 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_extractors/_base.py +10 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_extractors/_dict.py +106 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_extractors/_dms.py +474 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_extractors/_raw.py +148 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_shared.py +5 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_sparql_functions/__init__.py +68 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_sparql_functions/_helpers.py +536 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_sparql_functions/_indsl_wrappers.py +460 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_sparql_functions/_registry.py +322 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_sparql_functions/_sdk_wrappers.py +718 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_utils.py +32 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_neat/_validate_instances.py +1859 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_records.py +553 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_rules.py +162 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_validation.py +294 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_version.py +1 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/_workflow_deployer.py +1732 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/deploy.py +2441 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/invoke.py +574 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/runner.py +320 -0
- cognite_data_quality-0.0.1b1/cognite_data_quality/template_generator.py +917 -0
- cognite_data_quality-0.0.1b1/dev.py +293 -0
- cognite_data_quality-0.0.1b1/docs/api/config.md +13 -0
- cognite_data_quality-0.0.1b1/docs/api/deploy.md +234 -0
- cognite_data_quality-0.0.1b1/docs/api/invoke.md +15 -0
- cognite_data_quality-0.0.1b1/docs/api/records.md +20 -0
- cognite_data_quality-0.0.1b1/docs/api/runner.md +9 -0
- cognite_data_quality-0.0.1b1/docs/index.md +107 -0
- cognite_data_quality-0.0.1b1/docs/installation.md +42 -0
- cognite_data_quality-0.0.1b1/docs/quickstart/config.md +199 -0
- cognite_data_quality-0.0.1b1/docs/quickstart/notebook.md +131 -0
- cognite_data_quality-0.0.1b1/docs/quickstart/where_to_start.md +154 -0
- cognite_data_quality-0.0.1b1/docs/requirements.txt +9 -0
- cognite_data_quality-0.0.1b1/docs/troubleshooting.md +195 -0
- cognite_data_quality-0.0.1b1/docs/usage/chained_conditional_logic.md +325 -0
- cognite_data_quality-0.0.1b1/docs/usage/chained_conditional_logic_mode/index.md +87 -0
- cognite_data_quality-0.0.1b1/docs/usage/conditional_logic_mode/index.md +61 -0
- cognite_data_quality-0.0.1b1/docs/usage/deploy.md +539 -0
- cognite_data_quality-0.0.1b1/docs/usage/dqs_system_decomposition_overview.md +91 -0
- cognite_data_quality-0.0.1b1/docs/usage/dqs_use_case_and_dimensions.md +139 -0
- cognite_data_quality-0.0.1b1/docs/usage/graph_consistency/index.md +57 -0
- cognite_data_quality-0.0.1b1/docs/usage/index.md +44 -0
- cognite_data_quality-0.0.1b1/docs/usage/infrastructure/index.md +17 -0
- cognite_data_quality-0.0.1b1/docs/usage/invoke.md +303 -0
- cognite_data_quality-0.0.1b1/docs/usage/lifecycle/index.md +16 -0
- cognite_data_quality-0.0.1b1/docs/usage/migration_0.4.0.md +77 -0
- cognite_data_quality-0.0.1b1/docs/usage/operator_workspace/index.md +16 -0
- cognite_data_quality-0.0.1b1/docs/usage/overview/index.md +16 -0
- cognite_data_quality-0.0.1b1/docs/usage/records_output.md +351 -0
- cognite_data_quality-0.0.1b1/docs/usage/rule_definition/index.md +122 -0
- cognite_data_quality-0.0.1b1/docs/usage/rule_engine.md +283 -0
- cognite_data_quality-0.0.1b1/docs/usage/rule_sources.md +270 -0
- cognite_data_quality-0.0.1b1/docs/usage/run_validation.md +148 -0
- cognite_data_quality-0.0.1b1/docs/usage/runtime_options.md +136 -0
- cognite_data_quality-0.0.1b1/docs/usage/shacl_cdf_data_models.md +98 -0
- cognite_data_quality-0.0.1b1/docs/usage/single_instance/index.md +61 -0
- cognite_data_quality-0.0.1b1/docs/usage/time_series_mode/index.md +55 -0
- cognite_data_quality-0.0.1b1/docs/usage/timeseries_datapoints_examples.md +168 -0
- cognite_data_quality-0.0.1b1/docs/usage/uniqueness.md +281 -0
- cognite_data_quality-0.0.1b1/docs/usage/uniqueness_mode/index.md +48 -0
- cognite_data_quality-0.0.1b1/generate_demo_data/handler.py +521 -0
- cognite_data_quality-0.0.1b1/generate_demo_data/requirements.txt +5 -0
- cognite_data_quality-0.0.1b1/ila.preproc.yml +3565 -0
- cognite_data_quality-0.0.1b1/last_changelog_entry.md +7 -0
- cognite_data_quality-0.0.1b1/last_git_message.txt +16 -0
- cognite_data_quality-0.0.1b1/last_version.txt +1 -0
- cognite_data_quality-0.0.1b1/mkdocs.yml +80 -0
- cognite_data_quality-0.0.1b1/pyproject.toml +94 -0
- cognite_data_quality-0.0.1b1/release.md +286 -0
- cognite_data_quality-0.0.1b1/release_outcome.txt +1 -0
- cognite_data_quality-0.0.1b1/renovate.json +6 -0
- cognite_data_quality-0.0.1b1/scripts/run_instance_handler_test.py +205 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/_live_common.py +297 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/apply_maintenance_name_uniqueness_to_dataproduct.py +176 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/batch_dashboard.py +302 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/dashboard_requirements.txt +4 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/deploy_workorder_uniqueness_rule.py +352 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/ensure_scheduled_workorder_trigger.py +76 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/equipment_shacl_instances.json +336 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/historic_data_validation.ipynb +479 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/maintenance_order_instances.json +158 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/operation_shacl_instances.json +295 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/publish_cog_ai_asset_edge_ruleset.py +157 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/rule_engine_result_sync_run_report.md +55 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/run_cog_ai_live_validation.py +587 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/run_edge_existence_baseline_live.py +232 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/run_edge_existence_sdk_contract_live.py +146 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/run_uniqueness_workflows_from_dataproduct.py +213 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/sensor_readings_shacl_template.ttl +86 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_dataproduct_read.py +207 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_dataproduct_ruleset_migration.ipynb +947 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_dataproduct_version_preflight_live.py +289 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_raw_shacl_validation.ipynb +1012 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_rule_engine_result_sync_cascade_from_recent.py +205 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_rule_engine_result_sync_chaining.py +340 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_ruleset_lifecycle_state_data_product_sync_live.py +324 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_ruleset_lifecycle_state_live.py +381 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_uniqueness_handler_live.py +649 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_workorder_uniqueness_records.py +411 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/test_yourorg_timeseries_example_rules.py +490 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/validation_dashboard.py +1666 -0
- cognite_data_quality-0.0.1b1/test_and_deploy/verify_yourorg_timeseries_example_records.py +109 -0
- cognite_data_quality-0.0.1b1/tests/conftest.py +31 -0
- cognite_data_quality-0.0.1b1/tests/shacl_rules/compressor_shacl_rules.ttl +370 -0
- cognite_data_quality-0.0.1b1/tests/shacl_rules/heatexchanger_shacl_rules.ttl +527 -0
- cognite_data_quality-0.0.1b1/tests/shacl_rules/pump_shacl_rules.ttl +493 -0
- cognite_data_quality-0.0.1b1/tests/shacl_rules/tag_shacl_rules.ttl +467 -0
- cognite_data_quality-0.0.1b1/tests/test_aggregate_uniqueness_validation.py +608 -0
- cognite_data_quality-0.0.1b1/tests/test_cdf_sdk_in_construct.py +126 -0
- cognite_data_quality-0.0.1b1/tests/test_client_name.py +42 -0
- cognite_data_quality-0.0.1b1/tests/test_credentials.py +29 -0
- cognite_data_quality-0.0.1b1/tests/test_data_product_sync_consolidated.py +50 -0
- cognite_data_quality-0.0.1b1/tests/test_data_product_sync_filter.py +38 -0
- cognite_data_quality-0.0.1b1/tests/test_data_product_sync_historic.py +204 -0
- cognite_data_quality-0.0.1b1/tests/test_dataproduct_publisher.py +879 -0
- cognite_data_quality-0.0.1b1/tests/test_dataproduct_view_resolve.py +163 -0
- cognite_data_quality-0.0.1b1/tests/test_dependsOn_publish_guard.py +67 -0
- cognite_data_quality-0.0.1b1/tests/test_deploy.py +385 -0
- cognite_data_quality-0.0.1b1/tests/test_deploy_dataproduct_workflows.py +200 -0
- cognite_data_quality-0.0.1b1/tests/test_deploy_runtime_credentials.py +132 -0
- cognite_data_quality-0.0.1b1/tests/test_dev_bump.py +122 -0
- cognite_data_quality-0.0.1b1/tests/test_edge_existence_baseline.py +455 -0
- cognite_data_quality-0.0.1b1/tests/test_edge_existence_constraints.py +8 -0
- cognite_data_quality-0.0.1b1/tests/test_edge_existence_deploy.py +231 -0
- cognite_data_quality-0.0.1b1/tests/test_edge_existence_evaluator.py +129 -0
- cognite_data_quality-0.0.1b1/tests/test_edge_existence_event.py +154 -0
- cognite_data_quality-0.0.1b1/tests/test_edge_existence_records.py +47 -0
- cognite_data_quality-0.0.1b1/tests/test_external_dp_view_merge.py +82 -0
- cognite_data_quality-0.0.1b1/tests/test_function_code_imports.py +39 -0
- cognite_data_quality-0.0.1b1/tests/test_function_code_records_api.py +48 -0
- cognite_data_quality-0.0.1b1/tests/test_handler_routing.py +267 -0
- cognite_data_quality-0.0.1b1/tests/test_historic_queue_orphan_detection.py +45 -0
- cognite_data_quality-0.0.1b1/tests/test_historic_queue_supersession.py +193 -0
- cognite_data_quality-0.0.1b1/tests/test_instance_sync_cursor.py +457 -0
- cognite_data_quality-0.0.1b1/tests/test_instance_validation_extensions.py +95 -0
- cognite_data_quality-0.0.1b1/tests/test_managed_dp_ids.py +97 -0
- cognite_data_quality-0.0.1b1/tests/test_orchestrator_edge_baseline.py +167 -0
- cognite_data_quality-0.0.1b1/tests/test_orchestrator_sync_trigger.py +384 -0
- cognite_data_quality-0.0.1b1/tests/test_partition_range_bounds.py +90 -0
- cognite_data_quality-0.0.1b1/tests/test_raw_validation.py +669 -0
- cognite_data_quality-0.0.1b1/tests/test_records.py +249 -0
- cognite_data_quality-0.0.1b1/tests/test_reset_sync_cursor.py +51 -0
- cognite_data_quality-0.0.1b1/tests/test_rule_dependency_validator.py +231 -0
- cognite_data_quality-0.0.1b1/tests/test_rule_engine_extraction.py +157 -0
- cognite_data_quality-0.0.1b1/tests/test_rule_engine_records.py +183 -0
- cognite_data_quality-0.0.1b1/tests/test_rule_engine_result_sync.py +928 -0
- cognite_data_quality-0.0.1b1/tests/test_rule_engine_result_sync_deploy.py +124 -0
- cognite_data_quality-0.0.1b1/tests/test_rules.py +79 -0
- cognite_data_quality-0.0.1b1/tests/test_shacl_classifier.py +85 -0
- cognite_data_quality-0.0.1b1/tests/test_shacl_equipment.py +493 -0
- cognite_data_quality-0.0.1b1/tests/test_shacl_validation_extensions.py +489 -0
- cognite_data_quality-0.0.1b1/tests/test_stream_mutability.py +212 -0
- cognite_data_quality-0.0.1b1/tests/test_sync_view_lock.py +132 -0
- cognite_data_quality-0.0.1b1/tests/test_template_generator.py +128 -0
- cognite_data_quality-0.0.1b1/tests/test_timeseries_dataproduct.py +355 -0
- cognite_data_quality-0.0.1b1/tests/test_timeseries_sdk_wrappers.py +57 -0
- cognite_data_quality-0.0.1b1/tests/test_timeseries_validation.py +245 -0
- cognite_data_quality-0.0.1b1/tests/test_validation.py +64 -0
- cognite_data_quality-0.0.1b1/tests/test_view_config_external_dp.py +629 -0
- cognite_data_quality-0.0.1b1/uv.lock +2011 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: merge-ready-pr-gate
|
|
3
|
+
description: >-
|
|
4
|
+
Mandatory pre-push checklist for data-quality-validation PRs to avoid CI and
|
|
5
|
+
Gemini review failures. Use before opening or updating any pull request, after
|
|
6
|
+
feature work on handlers, orchestrator, deploy, ADRs, or skills.
|
|
7
|
+
disable-model-invocation: true
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Merge-Ready PR Gate
|
|
11
|
+
|
|
12
|
+
## See also
|
|
13
|
+
|
|
14
|
+
- CI parity: `release.md` — run `uv run pre-commit run --all-files` before push
|
|
15
|
+
- Lifecycle semantics: `../validation-lifecycle-baseline-incremental/SKILL.md`
|
|
16
|
+
- Pagination invariants: `../rule-engine-sync-state-watermarks/SKILL.md`
|
|
17
|
+
|
|
18
|
+
## Purpose
|
|
19
|
+
|
|
20
|
+
Run this gate **before every push** that opens or updates a PR. Gemini and CI catch the same classes of issues; fixing after review wastes time.
|
|
21
|
+
|
|
22
|
+
## Required commands (same as CI)
|
|
23
|
+
|
|
24
|
+
From repo root:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
uv run pre-commit run --all-files
|
|
28
|
+
uv run pytest tests/ -v --no-cov
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
For focused changes, at minimum:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv run pytest tests/test_<touched_module>.py -v --no-cov
|
|
35
|
+
uv run mypy cognite_data_quality/_function_code/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Do not push** if pre-commit or mypy fails.
|
|
39
|
+
|
|
40
|
+
## Code checklist (handlers / orchestrator)
|
|
41
|
+
|
|
42
|
+
- [ ] **Mypy clean** on all touched files under `cognite_data_quality/_function_code/`
|
|
43
|
+
- [ ] **Pagination resume:** mid-batch timeout must **not** advance cursor/processed count (no silent skip)
|
|
44
|
+
- [ ] **Idempotent re-invoke:** completed stateful runs return early unless `force_rerun: true`
|
|
45
|
+
- [ ] **CDF string parsing:** `space/externalId` uses `split("/", 1)` not `rsplit` (external IDs may contain `/`)
|
|
46
|
+
- [ ] **Regression tests** for every Gemini/ review edge case (timeout, resume, early return)
|
|
47
|
+
- [ ] **Deploy bundle:** new handler modules added to `deploy.py` `include_files` / embedded file list
|
|
48
|
+
- [ ] **Handler dispatch:** `validation_type` in `handler.py` + `tests/test_handler_routing.py`
|
|
49
|
+
|
|
50
|
+
## ADR / docs checklist
|
|
51
|
+
|
|
52
|
+
- [ ] ADR status matches reality (Open PR vs Merged)
|
|
53
|
+
- [ ] No stale "interim / planned / remaining work" sections after implementation
|
|
54
|
+
- [ ] Broken anchor links removed or updated
|
|
55
|
+
- [ ] Delivery plan references correct PR numbers
|
|
56
|
+
|
|
57
|
+
## Review self-pass (Gemini-class questions)
|
|
58
|
+
|
|
59
|
+
Ask before push:
|
|
60
|
+
|
|
61
|
+
1. What happens on **Function timeout mid-page**?
|
|
62
|
+
2. What happens on **duplicate invoke** with same `job_run_id`?
|
|
63
|
+
3. Does **mypy** accept all SDK calls (especially `instances.list` kwargs)?
|
|
64
|
+
4. Are **Records** posted with the same contract as steady-state?
|
|
65
|
+
5. Did I run **pre-commit**, not just pytest?
|
|
66
|
+
|
|
67
|
+
## Anti-patterns that caused PR #290 review pain
|
|
68
|
+
|
|
69
|
+
| Mistake | Prevention |
|
|
70
|
+
|---------|------------|
|
|
71
|
+
| Pushed without `pre-commit` | Run full pre-commit before every push |
|
|
72
|
+
| Mid-page timeout advanced cursor | Break before `processed_total` / `list_cursor` update |
|
|
73
|
+
| `rsplit` on edge type URI | `split("/", 1)` at first slash |
|
|
74
|
+
| ADR marked "Merged" before merge | Match delivery plan to PR state |
|
|
75
|
+
| No test for review finding | Add test in same commit as fix |
|
|
76
|
+
|
|
77
|
+
## When updating skills or ADRs
|
|
78
|
+
|
|
79
|
+
Skills and ADRs are part of the PR — run the same gate. Cross-link new skills from related skills (`See also`).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pydantic-first-coding
|
|
3
|
+
description: Enforce Pydantic-first implementation patterns across the repository. Use when adding or modifying Python code, handler payload contracts, helper data structures, or validation logic.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Pydantic-First Coding
|
|
8
|
+
|
|
9
|
+
## Core rule
|
|
10
|
+
|
|
11
|
+
Treat Pydantic as the default contract layer for all Python code in this repository.
|
|
12
|
+
|
|
13
|
+
- Use `BaseModel` for request/response payloads, config objects, derived results, and nested structures.
|
|
14
|
+
- Prefer typed models over raw dictionaries and untyped containers.
|
|
15
|
+
- Use `Field(...)` aliases/defaults/constraints to encode contract details.
|
|
16
|
+
|
|
17
|
+
## Required patterns
|
|
18
|
+
|
|
19
|
+
- Add type hints to all function parameters and return values.
|
|
20
|
+
- Use concrete types (`str`, `int`, `list[MyModel]`, `dict[str, int]`) instead of `Any` unless unavoidable.
|
|
21
|
+
- Model nested payloads as nested Pydantic models.
|
|
22
|
+
- Validate inputs at boundaries with `MyModel.model_validate(...)`.
|
|
23
|
+
- Return serialized model payloads with `model_dump(mode="json", by_alias=True)` when producing JSON-like responses.
|
|
24
|
+
|
|
25
|
+
## Avoid
|
|
26
|
+
|
|
27
|
+
- `dict[str, Any]` for complex payload contracts.
|
|
28
|
+
- `list[dict[str, Any]]` for structured collections.
|
|
29
|
+
- Ad-hoc key probing when a model can represent the structure.
|
|
30
|
+
- Duplicated validation logic that can be expressed as model field constraints.
|
|
31
|
+
|
|
32
|
+
## Preferred workflow
|
|
33
|
+
|
|
34
|
+
1. Define/extend the relevant Pydantic model(s).
|
|
35
|
+
2. Parse raw input once at boundary (`model_validate`).
|
|
36
|
+
3. Use typed attributes in logic.
|
|
37
|
+
4. Build outputs as models.
|
|
38
|
+
5. Serialize at the final boundary only.
|
|
39
|
+
|
|
40
|
+
## Example direction
|
|
41
|
+
|
|
42
|
+
Prefer this:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
class ViewRef(BaseModel):
|
|
46
|
+
space: str
|
|
47
|
+
external_id: str = Field(alias="externalId")
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Instead of this:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
view: dict[str, str]
|
|
54
|
+
space = view.get("space")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Review checklist
|
|
58
|
+
|
|
59
|
+
- [ ] Is every complex payload represented by a `BaseModel`?
|
|
60
|
+
- [ ] Are nested objects typed as models instead of nested dicts?
|
|
61
|
+
- [ ] Are aliases/constraints/defaults expressed with `Field(...)`?
|
|
62
|
+
- [ ] Is `Any` minimized and justified?
|
|
63
|
+
- [ ] Are outputs serialized from models at boundaries?
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rule-engine-focus-node-filtering
|
|
3
|
+
description: Build RuleEngineResult filters for focusNode and focusNodeInstance safely, including direct-relation normalization for CDF Records API queries. Use when implementing or reviewing rule_engine_result_sync filters, focus node criteria, or focus node instance matching.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rule Engine Focus Node Filtering
|
|
8
|
+
|
|
9
|
+
## See also
|
|
10
|
+
|
|
11
|
+
- For lifecycle-level idempotent publish semantics (RuleSet/DataProduct), deploy preflight checks, and resolved-version logging patterns, see `../ruleset-lifecycle-state/SKILL.md` (including `## Recent changes`).
|
|
12
|
+
|
|
13
|
+
## Purpose
|
|
14
|
+
|
|
15
|
+
Use this skill when changing filter logic for `RuleEngineResult` reads in:
|
|
16
|
+
|
|
17
|
+
- `cognite_data_quality/_function_code/common/rule_engine_result_sync.py`
|
|
18
|
+
- deploy/config surfaces that feed `filter.focus_node_instances`
|
|
19
|
+
|
|
20
|
+
Goal: always generate CDF-valid filter payloads for both scalar and list input, including direct-relation values.
|
|
21
|
+
|
|
22
|
+
## Canonical filter fields
|
|
23
|
+
|
|
24
|
+
For `RuleEngineResult` listener filters, map config keys to container properties:
|
|
25
|
+
|
|
26
|
+
- `focus_nodes` -> `focusNode`
|
|
27
|
+
- `focus_node_instances` -> `focusNodeInstance`
|
|
28
|
+
|
|
29
|
+
Always include `hasData` for the configured records container.
|
|
30
|
+
|
|
31
|
+
## Required focusNodeInstance normalization
|
|
32
|
+
|
|
33
|
+
`focusNodeInstance` is a direct relation. Normalize values before building `in` filters:
|
|
34
|
+
|
|
35
|
+
1. Accept scalar or list input.
|
|
36
|
+
2. Accept either string refs (`space:externalId`) or object refs.
|
|
37
|
+
3. Accept object refs with either key style:
|
|
38
|
+
- `externalId` (preferred)
|
|
39
|
+
- `external_id` (normalize to `externalId`)
|
|
40
|
+
4. Emit normalized values as node refs:
|
|
41
|
+
- `{ "space": "...", "externalId": "..." }`
|
|
42
|
+
|
|
43
|
+
If a string value is not parseable as `space:externalId`, pass it through unchanged and let higher-level validation/tests catch it.
|
|
44
|
+
|
|
45
|
+
## Implementation checklist
|
|
46
|
+
|
|
47
|
+
- [ ] `_append_in_filter(...)` wraps scalar values into lists.
|
|
48
|
+
- [ ] `focusNodeInstance` path calls normalization helper.
|
|
49
|
+
- [ ] Normalizer handles:
|
|
50
|
+
- [ ] `"space:externalId"` string
|
|
51
|
+
- [ ] `{"space": "...", "externalId": "..."}`
|
|
52
|
+
- [ ] `{"space": "...", "external_id": "..."}`
|
|
53
|
+
- [ ] Generated filter uses `in.property = [records_space, records_container, "focusNodeInstance"]`
|
|
54
|
+
|
|
55
|
+
## Test checklist
|
|
56
|
+
|
|
57
|
+
In `tests/test_rule_engine_result_sync.py`, ensure coverage for:
|
|
58
|
+
|
|
59
|
+
- scalar-to-list behavior
|
|
60
|
+
- string direct-relation normalization
|
|
61
|
+
- dict alias normalization (`external_id` -> `externalId`)
|
|
62
|
+
- mixed value lists (string + dict) normalize consistently
|
|
63
|
+
|
|
64
|
+
Use mock `client.post` assertions against final request body:
|
|
65
|
+
|
|
66
|
+
- `json["filter"]["and"][...]["in"]["values"]` contains normalized node refs.
|
|
67
|
+
|
|
68
|
+
Also verify when combined with incremental sync:
|
|
69
|
+
|
|
70
|
+
- focus-node filters remain structurally stable across cursor pages within a run
|
|
71
|
+
- only allowed dynamic fields change between pages (`cursor`, response-derived state), not filter criteria
|
|
72
|
+
- when no cursor is returned, watermark-only pagination may advance `lastUpdatedTime.gt` between pages
|
|
73
|
+
|
|
74
|
+
## Review checklist for filter changes
|
|
75
|
+
|
|
76
|
+
- Confirm output uses only canonical relation object keys (`space`, `externalId`).
|
|
77
|
+
- Confirm snake_case aliases are accepted on input but never emitted.
|
|
78
|
+
- Confirm direct relation values are normalized before request body construction.
|
|
79
|
+
- Add a regression test whenever a new accepted input shape is introduced.
|
|
80
|
+
|
|
81
|
+
## Do and don't
|
|
82
|
+
|
|
83
|
+
- Do keep behavior backward compatible for existing YAML patterns.
|
|
84
|
+
- Do keep naming consistent with deploy/config model fields (`focus_node_instances`).
|
|
85
|
+
- Don't send raw non-normalized direct-relation strings to CDF when they can be normalized.
|
|
86
|
+
- Don't introduce alternative key names in output; always emit `externalId`.
|
|
87
|
+
|
|
88
|
+
## Recurring failure patterns (must not regress)
|
|
89
|
+
|
|
90
|
+
- **Direct relation sent as raw string**:
|
|
91
|
+
- `focusNodeInstance` requires node refs, not plain strings
|
|
92
|
+
- fix: normalize `space:externalId` and dict inputs before request assembly
|
|
93
|
+
- **Input shape drift between deploy config and runtime filter builder**:
|
|
94
|
+
- fix: keep deploy field typing and runtime normalization intentionally aligned
|
|
95
|
+
- **Falsy scalar values skipped by generic truthiness checks**:
|
|
96
|
+
- fix: use explicit emptiness checks so valid values are not dropped
|
|
97
|
+
- **Cursor pagination mutating filter boundaries**:
|
|
98
|
+
- fix: keep filter criteria stable across cursor pages within a run
|
|
99
|
+
|
|
100
|
+
## Gate before merge
|
|
101
|
+
|
|
102
|
+
- [ ] Direct relation filters serialize to canonical node refs only
|
|
103
|
+
- [ ] `external_id` accepted on input and normalized to `externalId`
|
|
104
|
+
- [ ] Scalar, list, mixed-shape inputs tested
|
|
105
|
+
- [ ] Falsy-but-valid scalar handling tested where relevant
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rule-engine-listener-blueprint
|
|
3
|
+
description: Design, implement, and review robust incremental RuleEngineResult listeners end-to-end, including payload parsing, filter construction, state persistence, pagination invariants, runtime safety, testing, and live probe behavior.
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rule Engine Listener Blueprint
|
|
8
|
+
|
|
9
|
+
## See also
|
|
10
|
+
|
|
11
|
+
- For lifecycle-level idempotent publish semantics (RuleSet/DataProduct), deploy preflight checks, and resolved-version logging patterns, see `../ruleset-lifecycle-state/SKILL.md` (including `## Recent changes`).
|
|
12
|
+
- For `test_and_deploy` expectations around resolved RuleSet/DataProduct version propagation, see `../ruleset-lifecycle-state/SKILL.md` (`## test_and_deploy alignment requirements`).
|
|
13
|
+
|
|
14
|
+
## Purpose
|
|
15
|
+
|
|
16
|
+
Use this skill when creating or modifying listeners based on incremental RuleEngineResult consumption, especially in:
|
|
17
|
+
|
|
18
|
+
- `cognite_data_quality/_function_code/handlers/rule_engine_result_sync.py`
|
|
19
|
+
- `cognite_data_quality/_function_code/common/rule_engine_result_sync.py`
|
|
20
|
+
- `tests/test_rule_engine_result_sync.py`
|
|
21
|
+
- `test_and_deploy/test_rule_engine_result_sync_chaining.py`
|
|
22
|
+
|
|
23
|
+
Goal: build listeners that are deterministic, safe across retries, and production-ready.
|
|
24
|
+
|
|
25
|
+
## Design contract
|
|
26
|
+
|
|
27
|
+
A good listener has:
|
|
28
|
+
|
|
29
|
+
1. **Stable input contract**: robust payload parsing and clear errors.
|
|
30
|
+
2. **Correct incremental semantics**: cursor/watermark progression without data loss or duplicates.
|
|
31
|
+
3. **Safe state persistence**: backward-compatible read/write behavior.
|
|
32
|
+
4. **Runtime control**: bounded pagination and timeout headroom.
|
|
33
|
+
5. **Operational confidence**: targeted tests plus live probe guidance.
|
|
34
|
+
|
|
35
|
+
## Handler contract (input and validation)
|
|
36
|
+
|
|
37
|
+
In handler entrypoints:
|
|
38
|
+
|
|
39
|
+
- Accept both modern and compatibility fields where needed:
|
|
40
|
+
- `max_records` and fallback `limit`
|
|
41
|
+
- `source_mode` (`sync` or `filter`)
|
|
42
|
+
- `initialize_cursor` for first sync page
|
|
43
|
+
- Parse integer-like values defensively:
|
|
44
|
+
- `page_limit`, `max_records`, initial watermark values
|
|
45
|
+
- return explicit error payload on invalid input (do not crash)
|
|
46
|
+
- Keep defaults explicit and conservative:
|
|
47
|
+
- deterministic default page size
|
|
48
|
+
- deterministic default max records
|
|
49
|
+
|
|
50
|
+
## Filter construction contract
|
|
51
|
+
|
|
52
|
+
- Always include `hasData` for the source container.
|
|
53
|
+
- Keep filter-generation centralized in common module helpers.
|
|
54
|
+
- Normalize direct relation fields before request construction:
|
|
55
|
+
- for `focusNodeInstance`, emit canonical node refs with `space` + `externalId`
|
|
56
|
+
- accept common input variants (`space:externalId`, `external_id` alias), but normalize output
|
|
57
|
+
|
|
58
|
+
## Stateful incremental contract
|
|
59
|
+
|
|
60
|
+
`RuleEngineSyncState`:
|
|
61
|
+
|
|
62
|
+
- `sync_cursor`: opaque cursor from API
|
|
63
|
+
- `watermark_ms`: logical last-processed timestamp in ms
|
|
64
|
+
|
|
65
|
+
State persistence in `FunctionValidationState`:
|
|
66
|
+
|
|
67
|
+
- persist cursor in `syncCursor`
|
|
68
|
+
- persist watermark using overflow-safe encoding in `processedCount` (seconds)
|
|
69
|
+
- decode legacy ms values with backward compatibility
|
|
70
|
+
- treat missing/invalid persisted values as zero
|
|
71
|
+
|
|
72
|
+
## Pagination invariants (critical)
|
|
73
|
+
|
|
74
|
+
Within a single paginated run:
|
|
75
|
+
|
|
76
|
+
1. Append fetched items before stop checks.
|
|
77
|
+
2. Stop only when no progression (cursor unchanged and no watermark advance in watermark-only mode).
|
|
78
|
+
3. Allow empty pages when progression exists.
|
|
79
|
+
4. Preserve query invariants with cursor:
|
|
80
|
+
- while paging with cursor in `filter` mode, keep `lastUpdatedTime.gt` anchored to run-start watermark.
|
|
81
|
+
5. Support watermark-only progression:
|
|
82
|
+
- when no cursor is returned, advance query watermark between loop iterations.
|
|
83
|
+
6. Never regress accumulated watermark.
|
|
84
|
+
|
|
85
|
+
## Runtime and failure handling
|
|
86
|
+
|
|
87
|
+
- Enforce runtime headroom in loops (leave time for teardown/state save).
|
|
88
|
+
- Use specific exceptions or controlled error returns.
|
|
89
|
+
- Keep behavior idempotent on re-runs.
|
|
90
|
+
- Avoid hidden mutable global state.
|
|
91
|
+
|
|
92
|
+
## Known Environment Constraints
|
|
93
|
+
|
|
94
|
+
Known constraints observed in live environments should be treated as first-class listener requirements:
|
|
95
|
+
|
|
96
|
+
- Filter endpoint may require `lastUpdatedTime` in every `/records/filter` request.
|
|
97
|
+
- Some environments enforce max filter interval windows (for example, 7 days).
|
|
98
|
+
- Unbounded first-run filter bootstrap (watermark `0`) can fail with API `400`.
|
|
99
|
+
|
|
100
|
+
Implementation guidance:
|
|
101
|
+
|
|
102
|
+
- In `filter` mode, always send `lastUpdatedTime`.
|
|
103
|
+
- Use bounded bootstrap watermark defaults for first run when no persisted state exists.
|
|
104
|
+
- Keep bootstrap windows explicit in handler and `test_and_deploy` scripts so local/live behavior matches.
|
|
105
|
+
|
|
106
|
+
## Live probe and retry rules
|
|
107
|
+
|
|
108
|
+
For `test_and_deploy` scripts invoking stateful listeners:
|
|
109
|
+
|
|
110
|
+
- Do **not** retry stateful listener consumption in tight loops.
|
|
111
|
+
- Add short indexing delay after ingestion before first listener call.
|
|
112
|
+
- If retries are needed, retry read-only verification queries, not listener state advancement.
|
|
113
|
+
|
|
114
|
+
## Test checklist (required)
|
|
115
|
+
|
|
116
|
+
Ensure targeted tests cover:
|
|
117
|
+
|
|
118
|
+
- input parsing robustness for integer-like fields and watermark initialization
|
|
119
|
+
- watermark monotonicity and no-regression behavior
|
|
120
|
+
- cursor paging progression and terminal no-progress stop
|
|
121
|
+
- empty-page-with-progress continuation
|
|
122
|
+
- cursor-mode anchored query watermark in `filter` pagination
|
|
123
|
+
- watermark-only pagination updates query watermark between pages
|
|
124
|
+
- direct relation filter normalization (`focusNodeInstance`) for string and dict forms
|
|
125
|
+
- persisted state encode/decode compatibility (seconds + legacy ms)
|
|
126
|
+
|
|
127
|
+
## Review checklist before merge
|
|
128
|
+
|
|
129
|
+
- [ ] Query invariants preserved across cursor pages
|
|
130
|
+
- [ ] Watermark accumulation still advances correctly
|
|
131
|
+
- [ ] No stateful retry anti-patterns in live scripts
|
|
132
|
+
- [ ] Regression tests added for each fixed edge case
|
|
133
|
+
- [ ] Lint/type checks pass for changed files
|
|
134
|
+
- [ ] Naming and structure align with existing Rule Engine modules
|
|
135
|
+
|
|
136
|
+
## Implementation do and don't
|
|
137
|
+
|
|
138
|
+
- Do keep state transition logic explicit and localized.
|
|
139
|
+
- Do separate request-query state from accumulated returned state where needed.
|
|
140
|
+
- Do write tests that assert exact outgoing request bodies for filter correctness.
|
|
141
|
+
- Don't mutate query boundaries mid-cursor page sequence.
|
|
142
|
+
- Don't rely on eventual consistency without explicit indexing delay in live probes.
|
|
143
|
+
- Don't resolve review comments without locking the behavior with regression tests.
|
|
144
|
+
|
|
145
|
+
## Prevent recurrence checklist
|
|
146
|
+
|
|
147
|
+
Before closing review threads on listeners, confirm all of these:
|
|
148
|
+
|
|
149
|
+
- **Cursor lifecycle**
|
|
150
|
+
- terminal response without cursor clears persisted cursor
|
|
151
|
+
- cursor->none transition does not count as progression
|
|
152
|
+
- **Mode-aware progression**
|
|
153
|
+
- `sync` mode progression is cursor-only
|
|
154
|
+
- `filter` mode progression can use watermark in no-cursor path
|
|
155
|
+
- **Filter request validity**
|
|
156
|
+
- `lastUpdatedTime` always present for filter requests
|
|
157
|
+
- first-run filter bootstrap is bounded for environment constraints
|
|
158
|
+
- **Input parsing correctness**
|
|
159
|
+
- numeric defaults use `is None`, not `or`
|
|
160
|
+
- explicit `0` survives parsing and reaches validation
|
|
161
|
+
- **Filter value handling**
|
|
162
|
+
- explicit empty checks in filter helpers (avoid dropping falsy valid values)
|
|
163
|
+
- direct relation normalization is validated by request-body assertions
|
|
164
|
+
- **Live script alignment**
|
|
165
|
+
- `test_and_deploy` payload semantics match handler semantics
|
|
166
|
+
- stateful listener calls are not retried in tight loops
|
|
167
|
+
- mode-specific options are applied conditionally (`initialize_cursor` for sync only)
|