mostlyright-data 0.9.7__tar.gz → 0.9.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.
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/PKG-INFO +8 -4
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/README.md +7 -3
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/pyproject.toml +5 -3
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/cli.py +31 -9
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/download.py +74 -1
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/propose.py +146 -2
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/router.py +453 -50
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/remediation.py +1 -1
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/.gitignore +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/scripts/hatch_build.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/acquisition/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/acquisition/http.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/acquisition/parsing.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/acquisition/ranges.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/acquisition/result_download.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/acquisition/retention_admission.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/acquisition/sandbox.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/acquisition/url_policy.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/agent_runtime.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/assets/logo-ink.svg +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/backends/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/backends/pandas_backend.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/backends/polars_backend.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/backends/protocol.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/backends/reference.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/backends/registry.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/backends/restrictions.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/canonical.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/catalog_job.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/coordinator.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/deploy.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/deploy_target.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/deployment_evidence.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/event_presentation.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/events.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/fast_delimited.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/fleet.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/formats.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/governors.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_bootstrap.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_crawler.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_crawler_container_smoke.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_crawler_fetch.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_crawler_job.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_crawler_protocol.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_dataset.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_deploy.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_handoff.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_ingestion_contract.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_ingestion_job.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_ingestion_job_smoke.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_session_container_smoke.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_session_worker.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_session_worker_job_smoke.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/hosted_worker.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ingestion/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ingestion/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ingestion/faults.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ingestion/gcs_store.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ingestion/spool.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ingestion/store.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/key_seam.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/linux_process_boundary.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/local_contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/local_search/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/local_search/build_index.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/local_search/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/local_search/query_trace.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/local_search/retrieval.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/local_search/sealed.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/local_search/service.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/CONTRACT.md +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/chrome.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/code_body.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/document.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/frame.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/interactive.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/markdown_body.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/mr_components.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/outputs_data.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/outputs_rich.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/outputs_source.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/outputs_stage.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/outputs_text.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/parse.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/status.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/nbrender/tokens.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/notebook.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/offline.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/operation_registry.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/operator_setup.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/pipeline.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/plan_graph.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/engine.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/errors.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/gates.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/joins.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/profile.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/table.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/preparation/transforms.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/progress_events.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/containers.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/delimited.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/grib2/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/grib2/admission.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/grib2/decode.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/grib2/geometry.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/grib2/portable_math.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/json_tabular.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/parquet_tabular.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/registry.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/README.md +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.gzip/1.0.0/cities_one_stream/cities.csv.gz +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.gzip/1.0.0/cities_one_stream/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.gzip/1.1.0/cities_one_stream/cities.csv.gz +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.gzip/1.1.0/cities_one_stream/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.tar/1.0.0/cities_beside_a_directory_entry/cities.tar +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.tar/1.0.0/cities_beside_a_directory_entry/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.tar/1.1.0/cities_beside_a_directory_entry/cities.tar +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.tar/1.1.0/cities_beside_a_directory_entry/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.zip/1.0.0/cities_beside_a_second_member/cities.zip +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.zip/1.0.0/cities_beside_a_second_member/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.zip/1.1.0/dwd_semicolon_station_member/dwd-station.zip +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.zip/1.1.0/dwd_semicolon_station_member/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.zip/1.2.0/dwd_semicolon_station_member/dwd-station.zip +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/archive.zip/1.2.0/dwd_semicolon_station_member/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/delimited_text/1.0.0/an_ordinary_comma_separated_table/cities.csv +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/delimited_text/1.0.0/an_ordinary_comma_separated_table/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/delimited_text/1.0.0/quoted_fields_holding_the_delimiter/cities.tsv +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/delimited_text/1.0.0/quoted_fields_holding_the_delimiter/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/delimited_text/1.1.0/an_hourly_observation_table_served_as_plain_text/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/delimited_text/1.1.0/an_hourly_observation_table_served_as_plain_text/observations.csv +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/json.tabular/1.0.0/nested_hourly_observations/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/json.tabular/1.0.0/nested_hourly_observations/stations.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/json.tabular/1.1.0/an_observation_stream_served_as_plain_text/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/json.tabular/1.1.0/an_observation_stream_served_as_plain_text/observations.ndjson +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/parquet.tabular/1.0.0/two_columns/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/parquet.tabular/1.0.0/two_columns/prices.parquet +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.0.0/an_ordinary_table_beside_a_second_sheet/cities.xlsx +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.0.0/an_ordinary_table_beside_a_second_sheet/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.0.0/shares_the_workbook_had_already_computed/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.0.0/shares_the_workbook_had_already_computed/shares.xlsx +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.1.0/shares_the_workbook_had_already_computed/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/spreadsheet.xlsx/1.1.0/shares_the_workbook_had_already_computed/shares.xlsx +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/README.md +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/gfs_2m_temperature/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/gfs_2m_temperature/gfs-2m-temperature.grib2 +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_2m_temperature/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_2m_temperature/hrrr-2m-temperature.grib2 +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_categorical_rain/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_categorical_rain/hrrr-categorical-rain.grib2 +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/2.0.0/hrrr_2m_temperature/expected.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples/weather.grib2/2.0.0/hrrr_2m_temperature/hrrr-2m-temperature.grib2 +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/samples.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/spreadsheet.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/readers/tabular.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/recipe.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/repair/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/repair/adapters.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/repair/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/repair/coordinator.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/repair/errors.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/review.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/rowset.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/serving.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/serving_edge.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/serving_http.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/session_probes.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/signing.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/source_discovery.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/_adapter_steps.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/adapters.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/authenticated_https.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/authenticated_https_v2.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/cadence.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/cadence_emission.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/cadence_history.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/admission.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/authoring.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/authoring_policy.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/authoring_shards.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/bounded_io.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/channel.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/channel_client.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/coverage.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/delta.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/embedding.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/entry_v2.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/fill.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/fill_partitions.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/fill_staging.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/gating.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/generation_receipt.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/harvest/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/harvest/ckan.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/harvest/datagov_v4.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/harvest/protocol.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/harvest/sdmx.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/harvest/stac.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/health.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/hosted_catalog.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/identity_history.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/neural.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/packed_catalog.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/packed_retrieval.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/packed_writer.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/query_trace.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/recommend.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/retrieval.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/retrieval_manifest.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/rights_decisions.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/sealed.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/search.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/streaming_delta.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/catalog/update.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/collections.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/deletion.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/fitness.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/governance.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/hosted.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/integration.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/range_reader.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/registry.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/rights_rule.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/source_cadence_vectors.v1.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/sports.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream_capture_session.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream_connector.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream_connectors/polymarket.clob-market.v1.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream_recorder.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream_registry.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream_rotation.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream_series.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/sources/stream_transport.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/studio_boundary.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/acquire.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/acquire_cancel.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/approvals.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/commands.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/narrative.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/parity.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/research.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/runs.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/session.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/stream.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/transport.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/vocabulary.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/workers.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ucum/TABLE-PIN.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ucum/ucum-subset.v1.json +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/unit_flow.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/units.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/approve.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/author_yaml.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/cloud_auth.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/approve.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/auth.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/author.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/catalog_author.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/catalog_fill.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/catalog_harvest.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/catalog_publish.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/catalog_search.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/catalog_update.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/deploy.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/deploy_dataset.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/deploy_plan.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/deploy_status.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/diff.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/index.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/inventory.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/list_builds.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/login.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/peek.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/plan_check.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/preflight.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/record.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/review_setup.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/search.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/show.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/commands/whoami.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/credential_native.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/credential_store.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/credentials.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/diffing.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/headline.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/hosted_acquisition.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/hosted_run_status.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/inventory.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/local_review.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/login.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/path_kind.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/peek.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/plain_file.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/plan_check.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/preflight.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/readers.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/render.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/ux/workload.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/viewer.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/__init__.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/authoring.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/contracts.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/materialize.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/observations.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/query.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/reducer.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/sdk.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/store.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/visual_run/transport.py +0 -0
- {mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/watch.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mostlyright-data
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.9
|
|
4
4
|
Summary: Mostly Right CLI for reproducible, reviewed Parquet datasets
|
|
5
5
|
Project-URL: Homepage, https://mostlyright.md/
|
|
6
6
|
Project-URL: Documentation, https://mostlyright.md/docs/guides/cli/
|
|
@@ -126,7 +126,10 @@ The local execution lane runs only on Linux:
|
|
|
126
126
|
python -m pip install "mostlyright-data[local]"
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
It
|
|
129
|
+
It is not required for the hosted client, and it is off by default: `mr-data` sends that work to
|
|
130
|
+
the backend. What still runs on this computer is catalog authoring, the search index, and the
|
|
131
|
+
commands that check a document or a run folder. A command with no backend lane refuses by name and
|
|
132
|
+
says why.
|
|
130
133
|
|
|
131
134
|
## Documentation
|
|
132
135
|
|
|
@@ -138,11 +141,12 @@ It builds and checks worker inputs. It is not required for the hosted client.
|
|
|
138
141
|
Use `mr-data --help` for the full command list and options. Commands that support
|
|
139
142
|
`--json` write one JSON object.
|
|
140
143
|
|
|
141
|
-
|
|
144
|
+
`--input-root` and `--output` may use relative paths.
|
|
142
145
|
|
|
143
146
|
## Behavior and limits
|
|
144
147
|
|
|
145
|
-
- `mr-data review --local
|
|
148
|
+
- `mr-data review RUN_DIR --local` runs the deterministic checks and writes no review decision. It exits 1 when a check fails. Write the flag after the command name; before it, `--local` is the lane selector.
|
|
149
|
+
- `mr-data review RUN_DIR --report REPORT` seals a review decision from signed reviewer reports.
|
|
146
150
|
- The weather reader accepts one extracted GRIB2 record. It refuses a multi-record GFS or HRRR file.
|
|
147
151
|
- Hosted credential-free acquisition supports one single-address public HTTPS object. Bounded collections require both local attestations.
|
|
148
152
|
|
|
@@ -45,7 +45,10 @@ The local execution lane runs only on Linux:
|
|
|
45
45
|
python -m pip install "mostlyright-data[local]"
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
It
|
|
48
|
+
It is not required for the hosted client, and it is off by default: `mr-data` sends that work to
|
|
49
|
+
the backend. What still runs on this computer is catalog authoring, the search index, and the
|
|
50
|
+
commands that check a document or a run folder. A command with no backend lane refuses by name and
|
|
51
|
+
says why.
|
|
49
52
|
|
|
50
53
|
## Documentation
|
|
51
54
|
|
|
@@ -57,11 +60,12 @@ It builds and checks worker inputs. It is not required for the hosted client.
|
|
|
57
60
|
Use `mr-data --help` for the full command list and options. Commands that support
|
|
58
61
|
`--json` write one JSON object.
|
|
59
62
|
|
|
60
|
-
|
|
63
|
+
`--input-root` and `--output` may use relative paths.
|
|
61
64
|
|
|
62
65
|
## Behavior and limits
|
|
63
66
|
|
|
64
|
-
- `mr-data review --local
|
|
67
|
+
- `mr-data review RUN_DIR --local` runs the deterministic checks and writes no review decision. It exits 1 when a check fails. Write the flag after the command name; before it, `--local` is the lane selector.
|
|
68
|
+
- `mr-data review RUN_DIR --report REPORT` seals a review decision from signed reviewer reports.
|
|
65
69
|
- The weather reader accepts one extracted GRIB2 record. It refuses a multi-record GFS or HRRR file.
|
|
66
70
|
- Hosted credential-free acquisition supports one single-address public HTTPS object. Bounded collections require both local attestations.
|
|
67
71
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mostlyright-data"
|
|
3
|
-
version = "0.9.
|
|
3
|
+
version = "0.9.9"
|
|
4
4
|
description = "Mostly Right CLI for reproducible, reviewed Parquet datasets"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13,<3.14"
|
|
@@ -54,8 +54,10 @@ mostlyright-studio-client-v3 = { path = "vendor/wheels/mostlyright_studio_client
|
|
|
54
54
|
[project.scripts]
|
|
55
55
|
# ⚠ NOT `cli:main`. `cli` imports `hosted_worker`, which imports pyarrow and cryptography at module
|
|
56
56
|
# scope, so `cli` cannot even be IMPORTED on a thin install. The router is the one module that can
|
|
57
|
-
# run on a bare interpreter and decide which lane this invocation belongs to
|
|
58
|
-
# extra present it hands
|
|
57
|
+
# run on a bare interpreter and decide which lane this invocation belongs to. The local product
|
|
58
|
+
# lanes are off by default, so with the `local` extra present it hands the names that still run on
|
|
59
|
+
# this computer to `cli.main` unchanged, and every other name is answered by the hosted lane or
|
|
60
|
+
# told, by name, that this computer no longer runs it.
|
|
59
61
|
mr-data = "mostlyright.data_harness.thin.router:main"
|
|
60
62
|
# ⚠ AND NOT THE MODULES THEMSELVES, for the same reason. Each of these seven is defined in a
|
|
61
63
|
# module that imports pyarrow or cryptography at module scope -- or, for the catalogue job, reaches
|
|
@@ -2260,7 +2260,29 @@ def _require_verify_url(value: str) -> str:
|
|
|
2260
2260
|
|
|
2261
2261
|
|
|
2262
2262
|
def _agent_workflow_surface() -> dict[str, Any]:
|
|
2263
|
-
"""Return the versioned discovery surface for external data agents.
|
|
2263
|
+
"""Return the versioned discovery surface for external data agents.
|
|
2264
|
+
|
|
2265
|
+
``implementation_status`` says where a stage runs, and the three values partition the stages
|
|
2266
|
+
rather than describing them: exactly one is true of any stage, and which one is decided by the
|
|
2267
|
+
surface beside it rather than by how the stage feels.
|
|
2268
|
+
|
|
2269
|
+
* ``available`` -- every command the surface names runs from this command line, with no
|
|
2270
|
+
backend: the kept lane-``local`` names and the portable ones.
|
|
2271
|
+
* ``hosted_only`` -- the surface names only hosted-lane commands. The stage still happens, and
|
|
2272
|
+
the named commands are how it is asked for and reported on; what is not true of it is that
|
|
2273
|
+
this computer performs it. A hosted-lane command is not a skipped stage.
|
|
2274
|
+
* ``backend_internal`` -- a backend operator step: it has a name, and nobody runs it from here.
|
|
2275
|
+
|
|
2276
|
+
⚠ THE STATUS IS THE PROMISE, SO IT IS NOT DECORATION. An agent chooses its route from this
|
|
2277
|
+
payload, and a stage that says ``available`` about a command which exits 2 sends the agent to
|
|
2278
|
+
a refusal it will read as a defect and retry. The word has to be the answer the command would
|
|
2279
|
+
actually give.
|
|
2280
|
+
|
|
2281
|
+
⚠ AND A SURFACE NAMED TWICE IS CLASSIFIED ONCE. ``view`` appears under two stages; both say
|
|
2282
|
+
``hosted_only``, because the same command cannot run here in one row and on the backend in the
|
|
2283
|
+
next. ``tests/test_agent_workflow_cli.py`` derives both halves of the partition from the live
|
|
2284
|
+
lane table, so a command that changes lane fails there rather than drifting.
|
|
2285
|
+
"""
|
|
2264
2286
|
|
|
2265
2287
|
return {
|
|
2266
2288
|
"schema_version": "mr-data-agent-workflow.v4",
|
|
@@ -2269,9 +2291,9 @@ def _agent_workflow_surface() -> dict[str, Any]:
|
|
|
2269
2291
|
"stages": [
|
|
2270
2292
|
{
|
|
2271
2293
|
"stage": "viewer_observability",
|
|
2272
|
-
"implementation_status": "
|
|
2294
|
+
"implementation_status": "hosted_only",
|
|
2273
2295
|
"judgment_owner": "external_agent",
|
|
2274
|
-
"deterministic_surface": "mr-data view",
|
|
2296
|
+
"deterministic_surface": "mr-data watch/view",
|
|
2275
2297
|
},
|
|
2276
2298
|
{
|
|
2277
2299
|
"stage": "question_and_requirements",
|
|
@@ -2299,15 +2321,15 @@ def _agent_workflow_surface() -> dict[str, Any]:
|
|
|
2299
2321
|
},
|
|
2300
2322
|
{
|
|
2301
2323
|
"stage": "recipe_approval",
|
|
2302
|
-
"implementation_status": "
|
|
2324
|
+
"implementation_status": "hosted_only",
|
|
2303
2325
|
"judgment_owner": "human",
|
|
2304
2326
|
"deterministic_surface": "mr-data recipe-approve",
|
|
2305
2327
|
},
|
|
2306
2328
|
{
|
|
2307
2329
|
"stage": "acquire_clean_join_validate_package",
|
|
2308
|
-
"implementation_status": "
|
|
2330
|
+
"implementation_status": "hosted_only",
|
|
2309
2331
|
"judgment_owner": "deterministic_worker",
|
|
2310
|
-
"deterministic_surface": "mr-data
|
|
2332
|
+
"deterministic_surface": "mr-data run/status",
|
|
2311
2333
|
},
|
|
2312
2334
|
{
|
|
2313
2335
|
"stage": "independent_review",
|
|
@@ -2317,19 +2339,19 @@ def _agent_workflow_surface() -> dict[str, Any]:
|
|
|
2317
2339
|
},
|
|
2318
2340
|
{
|
|
2319
2341
|
"stage": "independent_verification",
|
|
2320
|
-
"implementation_status": "
|
|
2342
|
+
"implementation_status": "hosted_only",
|
|
2321
2343
|
"judgment_owner": "deterministic_verifier",
|
|
2322
2344
|
"deterministic_surface": "mr-data verify/status/inspect",
|
|
2323
2345
|
},
|
|
2324
2346
|
{
|
|
2325
2347
|
"stage": "handoff",
|
|
2326
|
-
"implementation_status": "
|
|
2348
|
+
"implementation_status": "hosted_only",
|
|
2327
2349
|
"judgment_owner": "external_agent",
|
|
2328
2350
|
"deterministic_surface": "mr-data notebook/view",
|
|
2329
2351
|
},
|
|
2330
2352
|
{
|
|
2331
2353
|
"stage": "hosted_export",
|
|
2332
|
-
"implementation_status": "
|
|
2354
|
+
"implementation_status": "backend_internal",
|
|
2333
2355
|
"judgment_owner": "external_agent",
|
|
2334
2356
|
"deterministic_surface": "mr-data export-hosted-candidate",
|
|
2335
2357
|
},
|
{mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/download.py
RENAMED
|
@@ -70,6 +70,11 @@ class DownloadedArtifact:
|
|
|
70
70
|
media_type: str
|
|
71
71
|
size_bytes: int
|
|
72
72
|
content_digest: str
|
|
73
|
+
#: False when the bytes were already on disk, carried the digest the signed session declared,
|
|
74
|
+
#: and were adopted rather than fetched again. Reported so that "it was already here" can
|
|
75
|
+
#: never be read as "it was fetched and checked just now" -- the same reason ``verify`` prints
|
|
76
|
+
#: ``checked_by`` and ``acquire`` prints ``reader_binding``.
|
|
77
|
+
transferred: bool = True
|
|
73
78
|
|
|
74
79
|
def to_receipt(self) -> dict[str, Any]:
|
|
75
80
|
return {
|
|
@@ -78,6 +83,7 @@ class DownloadedArtifact:
|
|
|
78
83
|
"media_type": self.media_type,
|
|
79
84
|
"size_bytes": self.size_bytes,
|
|
80
85
|
"content_digest": self.content_digest,
|
|
86
|
+
"transferred": self.transferred,
|
|
81
87
|
}
|
|
82
88
|
|
|
83
89
|
|
|
@@ -103,6 +109,48 @@ def _required_headers(session: Mapping[str, Any]) -> dict[str, str]:
|
|
|
103
109
|
return headers
|
|
104
110
|
|
|
105
111
|
|
|
112
|
+
def _adopted(
|
|
113
|
+
destination: Path,
|
|
114
|
+
*,
|
|
115
|
+
expected_digest: Any,
|
|
116
|
+
expected_preimage: ExpectedPreimage | None,
|
|
117
|
+
) -> tuple[bool, str, int]:
|
|
118
|
+
"""Whether the file already on disk IS this artifact, by the digest the session declared.
|
|
119
|
+
|
|
120
|
+
⚠ A DIGEST SKIP, NOT AN OVERWRITE. `deploy-dataset` fetches one artifact per kind in a loop,
|
|
121
|
+
and every one was created ``O_EXCL``, so a transfer interrupted after the first of two left a
|
|
122
|
+
folder holding one complete, verified artifact and no way to finish the job except a fresh
|
|
123
|
+
folder that re-downloaded the first as well. On a released dataset of several gigabytes the
|
|
124
|
+
cost of a dropped connection was paid twice (#438).
|
|
125
|
+
|
|
126
|
+
The skip is decided by the SAME fact the download would be verified against, so adopting
|
|
127
|
+
cannot be weaker than fetching: the bytes on disk must hash to the digest the signed session
|
|
128
|
+
declares, in whichever of the two authorities this download uses. Anything present that does
|
|
129
|
+
not match stays ``THIN_DESTINATION_EXISTS``: that file is not this artifact, and replacing it
|
|
130
|
+
silently is exactly what that refusal exists to prevent.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
size = destination.stat().st_size
|
|
134
|
+
if size > MAX_ARTIFACT_BYTES:
|
|
135
|
+
return False, "", size
|
|
136
|
+
raw = bytearray()
|
|
137
|
+
observed = hashlib.sha256()
|
|
138
|
+
with destination.open("rb") as handle:
|
|
139
|
+
while chunk := handle.read(DOWNLOAD_CHUNK_BYTES):
|
|
140
|
+
observed.update(chunk)
|
|
141
|
+
if expected_preimage is not None:
|
|
142
|
+
raw.extend(chunk)
|
|
143
|
+
digest = observed.hexdigest()
|
|
144
|
+
if expected_preimage is None:
|
|
145
|
+
return f"sha256:{digest}" == expected_digest, f"sha256:{digest}", size
|
|
146
|
+
# The bundle seals its own preimage, so the authority is the excised hash, not the raw one.
|
|
147
|
+
body = bytes(raw)
|
|
148
|
+
if body.count(expected_preimage.excised_field) != 1:
|
|
149
|
+
return False, "", size
|
|
150
|
+
preimage = hashlib.sha256(body.replace(expected_preimage.excised_field, b"", 1)).hexdigest()
|
|
151
|
+
return preimage == expected_preimage.digest, f"sha256:{digest}", size
|
|
152
|
+
|
|
153
|
+
|
|
106
154
|
def download_signed_artifact(
|
|
107
155
|
session: Mapping[str, Any],
|
|
108
156
|
destination: Path,
|
|
@@ -153,6 +201,30 @@ def download_signed_artifact(
|
|
|
153
201
|
|
|
154
202
|
selected = transport or UrlLibTransport()
|
|
155
203
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
204
|
+
# ⚠ A SYMLINK IS NEVER ADOPTED. The write path opens with ``O_NOFOLLOW`` precisely so a
|
|
205
|
+
# symlinked destination is refused rather than followed, and adopting through one would walk
|
|
206
|
+
# around that. Only a regular file in the place the artifact belongs can stand in for it; a
|
|
207
|
+
# symlink falls through to the open below and is refused there, as before.
|
|
208
|
+
#
|
|
209
|
+
# The remaining race is benign: a file swapped between this check and the read would have to
|
|
210
|
+
# hash to the sealed digest to be adopted, and a file that does is the artifact.
|
|
211
|
+
if destination.is_file() and not destination.is_symlink():
|
|
212
|
+
matched, observed_digest, size = _adopted(
|
|
213
|
+
destination, expected_digest=expected_digest, expected_preimage=expected_preimage
|
|
214
|
+
)
|
|
215
|
+
if matched:
|
|
216
|
+
media_type = session.get("media_type")
|
|
217
|
+
artifact_id = session.get("artifact_id")
|
|
218
|
+
return DownloadedArtifact(
|
|
219
|
+
path=destination,
|
|
220
|
+
artifact_id=artifact_id if isinstance(artifact_id, str) else "",
|
|
221
|
+
media_type=(
|
|
222
|
+
media_type if isinstance(media_type, str) else "application/octet-stream"
|
|
223
|
+
),
|
|
224
|
+
size_bytes=size,
|
|
225
|
+
content_digest=(expected_digest if expected_preimage is None else observed_digest),
|
|
226
|
+
transferred=False,
|
|
227
|
+
)
|
|
156
228
|
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
|
|
157
229
|
if hasattr(os, "O_NOFOLLOW"):
|
|
158
230
|
flags |= os.O_NOFOLLOW
|
|
@@ -165,7 +237,8 @@ def download_signed_artifact(
|
|
|
165
237
|
except FileExistsError as error:
|
|
166
238
|
raise ThinLaneError(
|
|
167
239
|
"THIN_DESTINATION_EXISTS",
|
|
168
|
-
f"{destination} already exists
|
|
240
|
+
f"{destination} already exists and does not carry this artifact's sealed digest, so "
|
|
241
|
+
"it is a different file; a hosted download never overwrites a local file",
|
|
169
242
|
) from error
|
|
170
243
|
|
|
171
244
|
try:
|
{mostlyright_data-0.9.7 → mostlyright_data-0.9.9}/src/mostlyright/data_harness/thin/propose.py
RENAMED
|
@@ -2099,6 +2099,7 @@ def propose(
|
|
|
2099
2099
|
recipe = bundle.recipe
|
|
2100
2100
|
assert recipe is not None
|
|
2101
2101
|
_check_recipe_sources(recipe, source_ids=source_ids, configurations=configurations)
|
|
2102
|
+
_check_recipe_query_templates(recipe, configurations=configurations)
|
|
2102
2103
|
research_run_id: str | None = None
|
|
2103
2104
|
if research_session_id is not None:
|
|
2104
2105
|
record = _lookup_session(
|
|
@@ -2359,6 +2360,149 @@ def _refuse_a_registered_source_the_bundle_no_longer_names(
|
|
|
2359
2360
|
)
|
|
2360
2361
|
|
|
2361
2362
|
|
|
2363
|
+
#: The Reader families a thin install can canonicalize in process. The other five certified
|
|
2364
|
+
#: coordinates -- ``spreadsheet.xlsx`` (two), ``parquet.tabular``, ``weather.grib2`` (two) --
|
|
2365
|
+
#: import openpyxl, pyarrow or mostlyright-grib at module scope, which the thin profile does not
|
|
2366
|
+
#: install. ``propose`` therefore refuses such a pin by name rather than sealing one it cannot
|
|
2367
|
+
#: check; see :func:`_admitted_reader_pin`.
|
|
2368
|
+
_READER_CANONICALIZATION_UNAVAILABLE = (
|
|
2369
|
+
"this Reader family needs a native wheel the hosted profile does not install, so propose "
|
|
2370
|
+
"cannot admit its options here; author the Recipe from an install that has it "
|
|
2371
|
+
'(pip install "mostlyright-data[local]") so the sealed pin is the admitted one'
|
|
2372
|
+
)
|
|
2373
|
+
|
|
2374
|
+
|
|
2375
|
+
def _admitted_reader_pin(pin: Any, *, name: str, path: str) -> Any:
|
|
2376
|
+
"""One Reader pin in the form the CRAWLER will recompute, or a refusal naming why not.
|
|
2377
|
+
|
|
2378
|
+
⚠ WHY AUTHORING HAS TO DO THIS. A pin is digested, and the digest is over the ADMITTED options
|
|
2379
|
+
-- ``family.validate_options`` with every family-defaulted key filled in. An author who writes
|
|
2380
|
+
``{"delimiter": ","}`` and omits ``encoding``, ``header``, ``expand`` or ``required`` seals a
|
|
2381
|
+
document that digests differently from the one the crawler will reconstruct, and every crawl
|
|
2382
|
+
then fails ``reader_identity`` with nothing naming the cause. That is what killed r13 and r14
|
|
2383
|
+
(#411). Every gate accepted those Recipes -- propose, Studio admission, approval -- and only
|
|
2384
|
+
the crawl refused, unnamed.
|
|
2385
|
+
|
|
2386
|
+
The principle the issue states is the one applied here: an agent authors against ``propose``,
|
|
2387
|
+
so anything Studio or the crawler will refuse at run time must be refused HERE, by name,
|
|
2388
|
+
before a person is asked to approve it.
|
|
2389
|
+
|
|
2390
|
+
⚠ THE THIN PROFILE CAN DO THIS FOR MOST FAMILIES, AND SAYS SO WHEN IT CANNOT. Importing
|
|
2391
|
+
``readers.registry`` is stdlib-only, and the registry loads a family lazily, so the ten
|
|
2392
|
+
delimited/JSON/archive coordinates -- ``delimited_text`` among them, which is the family the
|
|
2393
|
+
failing Recipes used -- canonicalize on a bare interpreter. The five that need a native wheel
|
|
2394
|
+
are refused rather than passed through unchecked.
|
|
2395
|
+
"""
|
|
2396
|
+
|
|
2397
|
+
if pin is None:
|
|
2398
|
+
return None
|
|
2399
|
+
if not isinstance(pin, dict):
|
|
2400
|
+
raise _invalid(name, path, "must be null or a Reader pin object")
|
|
2401
|
+
_keys(pin, name, path, ("family_id", "family_version", "decode_options"))
|
|
2402
|
+
family_id = pin["family_id"]
|
|
2403
|
+
family_version = pin["family_version"]
|
|
2404
|
+
options = pin["decode_options"]
|
|
2405
|
+
if not isinstance(family_id, str) or not isinstance(family_version, str):
|
|
2406
|
+
raise _invalid(name, path, "family_id and family_version must be strings")
|
|
2407
|
+
if not isinstance(options, dict):
|
|
2408
|
+
raise _invalid(name, f"{path}.decode_options", "must be an object")
|
|
2409
|
+
|
|
2410
|
+
# Imported here rather than at module scope: `propose` is reached on a bare interpreter, and
|
|
2411
|
+
# the registry is only needed when a Recipe actually pins a Reader.
|
|
2412
|
+
from mostlyright.data_harness.readers.registry import TOOLBOX
|
|
2413
|
+
|
|
2414
|
+
try:
|
|
2415
|
+
family = TOOLBOX.resolve(family_id, family_version)
|
|
2416
|
+
except ImportError as error: # the family's native wheel is absent on this install
|
|
2417
|
+
raise ProposeError(
|
|
2418
|
+
"THIN_PROPOSE_READER_PIN",
|
|
2419
|
+
f"{name} {path} pins {family_id}@{family_version}: "
|
|
2420
|
+
f"{_READER_CANONICALIZATION_UNAVAILABLE} ({error})",
|
|
2421
|
+
) from error
|
|
2422
|
+
except Exception as error: # unknown family, unknown version, or a dependency refusal
|
|
2423
|
+
raise ProposeError(
|
|
2424
|
+
"THIN_PROPOSE_READER_PIN",
|
|
2425
|
+
f"{name} {path} pins {family_id}@{family_version}, which is not a certified Reader "
|
|
2426
|
+
f"coordinate this Harness can admit: {error}",
|
|
2427
|
+
) from error
|
|
2428
|
+
try:
|
|
2429
|
+
admitted = dict(family.validate_options(options))
|
|
2430
|
+
except Exception as error:
|
|
2431
|
+
raise ProposeError(
|
|
2432
|
+
"THIN_PROPOSE_READER_PIN",
|
|
2433
|
+
f"{name} {path} pins Reader options {family_id}@{family_version} refuses: {error}",
|
|
2434
|
+
) from error
|
|
2435
|
+
return {
|
|
2436
|
+
"family_id": family_id,
|
|
2437
|
+
"family_version": family_version,
|
|
2438
|
+
"decode_options": admitted,
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
|
|
2442
|
+
def _reader_pin_of(query: Any) -> Any:
|
|
2443
|
+
return query.get("reader_pin") if isinstance(query, dict) else None
|
|
2444
|
+
|
|
2445
|
+
|
|
2446
|
+
def _check_recipe_query_templates(
|
|
2447
|
+
recipe: Mapping[str, Any],
|
|
2448
|
+
*,
|
|
2449
|
+
configurations: Mapping[str, Mapping[str, Any]],
|
|
2450
|
+
) -> None:
|
|
2451
|
+
"""Every recipe query is the query its registered connector holds, in the admitted form.
|
|
2452
|
+
|
|
2453
|
+
⚠ TWO REFUSALS, BECAUSE THEY ARE TWO MISTAKES. Studio binds ``query_template`` byte-for-byte
|
|
2454
|
+
to the registered connector configuration, so a Recipe whose query has drifted from its source
|
|
2455
|
+
is refused at run time with nothing naming the field. And a raw (non-admitted) Reader pin
|
|
2456
|
+
digests differently from the one the crawler rebuilds, failing ``reader_identity`` on every
|
|
2457
|
+
crawl. Both were accepted by every authoring gate before this (#411); both are named here,
|
|
2458
|
+
with the exact value to write.
|
|
2459
|
+
|
|
2460
|
+
Sources whose adapter carries no connector query -- ``user.file`` snapshots -- are skipped:
|
|
2461
|
+
there is nothing registered to compare against.
|
|
2462
|
+
"""
|
|
2463
|
+
|
|
2464
|
+
for source in recipe["sources"]:
|
|
2465
|
+
source_id = source["source_id"]
|
|
2466
|
+
template = source.get("query_template")
|
|
2467
|
+
registered = configurations.get(source_id, {}).get("query")
|
|
2468
|
+
if template is None or registered is None:
|
|
2469
|
+
continue
|
|
2470
|
+
if not isinstance(template, dict):
|
|
2471
|
+
raise _invalid("recipe.json", f"sources[{source_id}].query_template", "must be object")
|
|
2472
|
+
|
|
2473
|
+
admitted_pin = _admitted_reader_pin(
|
|
2474
|
+
_reader_pin_of(template),
|
|
2475
|
+
name="recipe.json",
|
|
2476
|
+
path=f"sources[{source_id}].query_template.reader_pin",
|
|
2477
|
+
)
|
|
2478
|
+
if admitted_pin != _reader_pin_of(template):
|
|
2479
|
+
raise ProposeError(
|
|
2480
|
+
"THIN_PROPOSE_READER_PIN",
|
|
2481
|
+
f"recipe.json source {source_id} pins Reader options that are not the admitted "
|
|
2482
|
+
"form, so its sealed digest is not the one every crawl will recompute and "
|
|
2483
|
+
"reader_identity would fail on each run; write the pin exactly as: "
|
|
2484
|
+
f"{json.dumps(admitted_pin, sort_keys=True)}",
|
|
2485
|
+
)
|
|
2486
|
+
|
|
2487
|
+
differing = sorted(
|
|
2488
|
+
key
|
|
2489
|
+
for key in set(template) | set(registered)
|
|
2490
|
+
if canonical_json_bytes(template.get(key)) != canonical_json_bytes(registered.get(key))
|
|
2491
|
+
)
|
|
2492
|
+
if differing:
|
|
2493
|
+
detail = "; ".join(
|
|
2494
|
+
f"{key}: recipe.json has {json.dumps(template.get(key), sort_keys=True)}, "
|
|
2495
|
+
f"the registered connector has {json.dumps(registered.get(key), sort_keys=True)}"
|
|
2496
|
+
for key in differing
|
|
2497
|
+
)
|
|
2498
|
+
raise ProposeError(
|
|
2499
|
+
"THIN_PROPOSE_SOURCE_QUERY",
|
|
2500
|
+
f"recipe.json source {source_id} carries a query its registered connector "
|
|
2501
|
+
f"configuration does not hold, and Studio binds the two byte-for-byte, so this "
|
|
2502
|
+
f"Recipe would be refused when it ran -- {detail}",
|
|
2503
|
+
)
|
|
2504
|
+
|
|
2505
|
+
|
|
2362
2506
|
def _check_recipe_sources(
|
|
2363
2507
|
recipe: Mapping[str, Any],
|
|
2364
2508
|
*,
|
|
@@ -2560,8 +2704,8 @@ def _proposal_receipt(
|
|
|
2560
2704
|
and ``mr-data build --hosted`` queues one; it is approved and the confirmation STARTED the
|
|
2561
2705
|
Build in the same act -- Studio #124 -- and the run is named here because ``mr-data build``
|
|
2562
2706
|
would refuse it rather than replay it; or it was declined (exit 2). Both commands carry
|
|
2563
|
-
``--hosted
|
|
2564
|
-
decides anything.
|
|
2707
|
+
``--hosted`` because it names the lane explicitly and remains valid: the bare names reach the
|
|
2708
|
+
backend on every install. Nothing here decides anything.
|
|
2565
2709
|
"""
|
|
2566
2710
|
|
|
2567
2711
|
payload = _common(client, journal, stage=stage)
|