mostlyright-data 0.9.6__tar.gz → 0.9.7__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.6 → mostlyright_data-0.9.7}/PKG-INFO +1 -1
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/pyproject.toml +1 -1
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/acquisition/sandbox.py +5 -1
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/acquisition/url_policy.py +27 -1
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_bootstrap.py +166 -25
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_crawler_fetch.py +9 -1
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_worker.py +511 -9
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/studio_boundary.py +1 -1
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/router.py +41 -1
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/hosted_acquisition.py +29 -4
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/remediation.py +1 -1
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/render.py +1 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/.gitignore +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/README.md +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/scripts/hatch_build.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/acquisition/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/acquisition/http.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/acquisition/parsing.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/acquisition/ranges.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/acquisition/result_download.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/acquisition/retention_admission.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/agent_runtime.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/assets/logo-ink.svg +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/backends/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/backends/pandas_backend.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/backends/polars_backend.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/backends/protocol.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/backends/reference.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/backends/registry.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/backends/restrictions.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/canonical.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/catalog_job.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/cli.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/coordinator.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/deploy.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/deploy_target.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/deployment_evidence.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/event_presentation.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/events.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/fast_delimited.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/fleet.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/formats.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/governors.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_crawler.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_crawler_container_smoke.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_crawler_job.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_crawler_protocol.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_dataset.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_deploy.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_handoff.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_ingestion_contract.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_ingestion_job.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_ingestion_job_smoke.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_session_container_smoke.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_session_worker.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_session_worker_job_smoke.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ingestion/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ingestion/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ingestion/faults.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ingestion/gcs_store.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ingestion/spool.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ingestion/store.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/key_seam.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/linux_process_boundary.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/local_contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/local_search/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/local_search/build_index.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/local_search/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/local_search/query_trace.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/local_search/retrieval.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/local_search/sealed.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/local_search/service.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/CONTRACT.md +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/chrome.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/code_body.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/document.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/frame.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/interactive.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/markdown_body.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/mr_components.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/outputs_data.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/outputs_rich.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/outputs_source.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/outputs_stage.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/outputs_text.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/parse.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/status.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/nbrender/tokens.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/notebook.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/offline.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/operation_registry.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/operator_setup.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/pipeline.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/plan_graph.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/engine.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/errors.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/gates.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/joins.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/profile.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/table.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/preparation/transforms.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/progress_events.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/containers.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/delimited.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/grib2/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/grib2/admission.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/grib2/decode.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/grib2/geometry.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/grib2/portable_math.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/json_tabular.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/parquet_tabular.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/registry.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/README.md +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.gzip/1.0.0/cities_one_stream/cities.csv.gz +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.gzip/1.0.0/cities_one_stream/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.gzip/1.1.0/cities_one_stream/cities.csv.gz +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.gzip/1.1.0/cities_one_stream/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.tar/1.0.0/cities_beside_a_directory_entry/cities.tar +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.tar/1.0.0/cities_beside_a_directory_entry/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.tar/1.1.0/cities_beside_a_directory_entry/cities.tar +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.tar/1.1.0/cities_beside_a_directory_entry/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.zip/1.0.0/cities_beside_a_second_member/cities.zip +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.zip/1.0.0/cities_beside_a_second_member/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.zip/1.1.0/dwd_semicolon_station_member/dwd-station.zip +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.zip/1.1.0/dwd_semicolon_station_member/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.zip/1.2.0/dwd_semicolon_station_member/dwd-station.zip +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/archive.zip/1.2.0/dwd_semicolon_station_member/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/delimited_text/1.0.0/an_ordinary_comma_separated_table/cities.csv +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/delimited_text/1.0.0/an_ordinary_comma_separated_table/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/delimited_text/1.0.0/quoted_fields_holding_the_delimiter/cities.tsv +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/delimited_text/1.0.0/quoted_fields_holding_the_delimiter/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/json.tabular/1.0.0/nested_hourly_observations/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/json.tabular/1.0.0/nested_hourly_observations/stations.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/parquet.tabular/1.0.0/two_columns/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/parquet.tabular/1.0.0/two_columns/prices.parquet +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/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.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/README.md +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/gfs_2m_temperature/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/gfs_2m_temperature/gfs-2m-temperature.grib2 +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_2m_temperature/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_2m_temperature/hrrr-2m-temperature.grib2 +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_categorical_rain/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/1.0.0/hrrr_categorical_rain/hrrr-categorical-rain.grib2 +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/2.0.0/hrrr_2m_temperature/expected.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples/weather.grib2/2.0.0/hrrr_2m_temperature/hrrr-2m-temperature.grib2 +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/samples.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/spreadsheet.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/readers/tabular.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/recipe.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/repair/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/repair/adapters.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/repair/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/repair/coordinator.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/repair/errors.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/review.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/rowset.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/serving.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/serving_edge.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/serving_http.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/session_probes.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/signing.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/source_discovery.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/_adapter_steps.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/adapters.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/authenticated_https.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/authenticated_https_v2.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/cadence.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/cadence_emission.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/cadence_history.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/admission.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/authoring.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/authoring_policy.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/authoring_shards.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/bounded_io.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/channel.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/channel_client.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/coverage.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/delta.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/embedding.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/entry_v2.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/fill.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/fill_partitions.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/fill_staging.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/gating.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/generation_receipt.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/harvest/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/harvest/ckan.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/harvest/datagov_v4.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/harvest/protocol.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/harvest/sdmx.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/harvest/stac.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/health.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/hosted_catalog.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/identity_history.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/neural.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/packed_catalog.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/packed_retrieval.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/packed_writer.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/query_trace.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/recommend.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/retrieval.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/retrieval_manifest.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/rights_decisions.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/sealed.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/search.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/streaming_delta.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/catalog/update.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/collections.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/deletion.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/fitness.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/governance.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/hosted.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/integration.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/range_reader.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/registry.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/rights_rule.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/source_cadence_vectors.v1.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/sports.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream_capture_session.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream_connector.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream_connectors/polymarket.clob-market.v1.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream_recorder.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream_registry.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream_rotation.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream_series.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/sources/stream_transport.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/acquire.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/acquire_cancel.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/approvals.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/commands.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/download.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/narrative.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/parity.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/propose.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/research.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/runs.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/session.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/stream.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/transport.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/vocabulary.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/thin/workers.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ucum/TABLE-PIN.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ucum/ucum-subset.v1.json +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/unit_flow.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/units.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/approve.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/author_yaml.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/cloud_auth.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/approve.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/auth.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/author.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/catalog_author.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/catalog_fill.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/catalog_harvest.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/catalog_publish.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/catalog_search.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/catalog_update.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/deploy.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/deploy_dataset.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/deploy_plan.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/deploy_status.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/diff.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/index.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/inventory.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/list_builds.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/login.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/peek.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/plan_check.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/preflight.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/record.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/review_setup.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/search.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/show.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/commands/whoami.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/credential_native.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/credential_store.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/credentials.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/diffing.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/headline.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/hosted_run_status.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/inventory.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/local_review.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/login.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/path_kind.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/peek.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/plain_file.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/plan_check.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/preflight.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/readers.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/ux/workload.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/viewer.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/__init__.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/authoring.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/contracts.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/materialize.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/observations.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/query.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/reducer.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/sdk.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/store.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/visual_run/transport.py +0 -0
- {mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/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.7
|
|
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/
|
|
@@ -59,6 +59,7 @@ from mostlyright.data_harness.acquisition.url_policy import (
|
|
|
59
59
|
AcquisitionSecurityError,
|
|
60
60
|
EgressPolicy,
|
|
61
61
|
SystemResolver,
|
|
62
|
+
canonical_peer_order,
|
|
62
63
|
validate_public_https_url,
|
|
63
64
|
)
|
|
64
65
|
from mostlyright.data_harness.canonical import canonical_sha256, sha256_bytes
|
|
@@ -3011,7 +3012,10 @@ def _parse_approved_endpoints(
|
|
|
3011
3012
|
)
|
|
3012
3013
|
normalized.append(address.compressed)
|
|
3013
3014
|
key = (hostname, port)
|
|
3014
|
-
|
|
3015
|
+
# The SAME order `url_policy.canonical_peer_order` writes, read from that function rather
|
|
3016
|
+
# than restated: the parent decides connection order there, and a second sorting rule here
|
|
3017
|
+
# would refuse the very sets the parent now produces (#351).
|
|
3018
|
+
if key in endpoints or canonical_peer_order(normalized) != addresses:
|
|
3015
3019
|
raise AcquisitionSecurityError(
|
|
3016
3020
|
"SANDBOX_EGRESS",
|
|
3017
3021
|
"approved endpoint set is duplicate or non-canonical",
|
|
@@ -6,6 +6,7 @@ import ipaddress
|
|
|
6
6
|
import re
|
|
7
7
|
import socket
|
|
8
8
|
import unicodedata
|
|
9
|
+
from collections.abc import Iterable
|
|
9
10
|
from dataclasses import dataclass
|
|
10
11
|
from typing import Protocol
|
|
11
12
|
from urllib.parse import SplitResult, urlsplit, urlunsplit
|
|
@@ -188,6 +189,31 @@ class ValidatedTarget:
|
|
|
188
189
|
return urlunsplit(("", "", parsed.path or "/", parsed.query, ""))
|
|
189
190
|
|
|
190
191
|
|
|
192
|
+
def canonical_peer_order(addresses: Iterable[str]) -> tuple[str, ...]:
|
|
193
|
+
"""The one order an approved peer set is ever written in: IPv4 first, then lexicographic.
|
|
194
|
+
|
|
195
|
+
⚠ THIS IS A CONNECTION ORDER, NOT ONLY A CANONICAL FORM. A fetch spends a bounded request
|
|
196
|
+
budget (``max_requests``, four) walking this tuple, so whatever sorts first is what an
|
|
197
|
+
IPv4-only deployment -- every Cloud Run job -- actually dials. Plain lexicographic sorting put
|
|
198
|
+
``2606:…`` ahead of ``3.x``/``34.x``/``52.x``, which is precisely the A-record shape every
|
|
199
|
+
Fastly and CloudFront host has, so an IPv6-unroutable worker burned its whole budget on AAAA
|
|
200
|
+
candidates and died ``REQUEST_LIMIT`` before reaching a routable address (#351).
|
|
201
|
+
|
|
202
|
+
Family first is therefore the rule, and it is a rule rather than a preference expressed in the
|
|
203
|
+
resolver: ordering is decided HERE, and ``sandbox._parse_approved_endpoints`` refuses an
|
|
204
|
+
endpoint set that is not in this exact order, so the two must move together. Within a family
|
|
205
|
+
the order stays lexicographic on the compressed text, which keeps the set canonical -- the
|
|
206
|
+
resolution digest is computed over it -- and keeps it independent of resolver answer order.
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
return tuple(
|
|
210
|
+
sorted(
|
|
211
|
+
dict.fromkeys(addresses),
|
|
212
|
+
key=lambda address: (0 if ipaddress.ip_address(address).version == 4 else 1, address),
|
|
213
|
+
)
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
|
|
191
217
|
def approved_public_addresses(
|
|
192
218
|
hostname: str,
|
|
193
219
|
port: int,
|
|
@@ -233,7 +259,7 @@ def approved_public_addresses(
|
|
|
233
259
|
) from None
|
|
234
260
|
_require_globally_routable(address)
|
|
235
261
|
approved.append(address.compressed)
|
|
236
|
-
approved_ips =
|
|
262
|
+
approved_ips = canonical_peer_order(dict.fromkeys(approved))
|
|
237
263
|
if not approved_ips:
|
|
238
264
|
raise AcquisitionSecurityError("DNS_EMPTY", "target has no approved public addresses")
|
|
239
265
|
if len(approved_ips) > MAX_DNS_ANSWERS:
|
{mostlyright_data-0.9.6 → mostlyright_data-0.9.7}/src/mostlyright/data_harness/hosted_bootstrap.py
RENAMED
|
@@ -22,7 +22,7 @@ from datetime import UTC, datetime
|
|
|
22
22
|
from pathlib import Path
|
|
23
23
|
from typing import Any, NoReturn, Protocol
|
|
24
24
|
from urllib.error import HTTPError
|
|
25
|
-
from urllib.parse import urlencode, urlsplit
|
|
25
|
+
from urllib.parse import urlencode, urlsplit, urlunsplit
|
|
26
26
|
from urllib.request import (
|
|
27
27
|
HTTPRedirectHandler,
|
|
28
28
|
HTTPSHandler,
|
|
@@ -42,6 +42,7 @@ from mostlyright.data_harness.governors import (
|
|
|
42
42
|
Reservation,
|
|
43
43
|
)
|
|
44
44
|
from mostlyright.data_harness.hosted_worker import (
|
|
45
|
+
CRAWLER_RESULTS_BUCKET_ENV,
|
|
45
46
|
MAX_CAPABILITY_BYTES,
|
|
46
47
|
MAX_DESCRIPTOR_BYTES,
|
|
47
48
|
MAX_SIGNING_KEY_BYTES,
|
|
@@ -62,6 +63,7 @@ BOOTSTRAP_REQUEST_SCHEMA = "mostlyright-worker-bootstrap-request.v3"
|
|
|
62
63
|
BOOTSTRAP_RESPONSE_SCHEMA = "mostlyright-worker-bootstrap-response.v3"
|
|
63
64
|
GENERIC_PROBE_BOOTSTRAP_RESPONSE_SCHEMA = "mostlyright-worker-bootstrap-response.v5"
|
|
64
65
|
BOOTSTRAP_EXCHANGE_PATH = "/_internal/worker-bootstrap:exchange"
|
|
66
|
+
BOOTSTRAP_FAILURE_PATH = "/_internal/worker-bootstrap:fail"
|
|
65
67
|
GENERIC_PROBE_BOOTSTRAP_EXCHANGE_PATH = "/_internal/generic-api-probe-bootstrap:exchange"
|
|
66
68
|
METADATA_IDENTITY_URL = (
|
|
67
69
|
"http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/identity"
|
|
@@ -69,6 +71,21 @@ METADATA_IDENTITY_URL = (
|
|
|
69
71
|
MAX_IDENTITY_BYTES = 16 * 1024
|
|
70
72
|
MAX_BOOTSTRAP_RESPONSE_BYTES = 768 * 1024
|
|
71
73
|
BOOTSTRAP_TIMEOUT_SECONDS = 10.0
|
|
74
|
+
#: Exchange refusals worth waiting out. Everything else in 4xx is Studio's final answer for this
|
|
75
|
+
#: dispatch, so the attempt is dead and something has to say so before this process exits.
|
|
76
|
+
RETRYABLE_EXCHANGE_STATUSES = frozenset({408, 425, 429})
|
|
77
|
+
#: The closed set of reasons a bootstrap can report before it holds a job, one per refusal it can
|
|
78
|
+
#: be told. Keep it closed in lock-step with Studio's accepted set: a code Studio does not know is
|
|
79
|
+
#: refused, the report is lost, and the run waits for the stuck-run poller instead.
|
|
80
|
+
EXCHANGE_REFUSAL_CODES = {
|
|
81
|
+
400: "BOOTSTRAP_EXCHANGE_REJECTED",
|
|
82
|
+
401: "BOOTSTRAP_IDENTITY_REJECTED",
|
|
83
|
+
403: "BOOTSTRAP_IDENTITY_REJECTED",
|
|
84
|
+
404: "BOOTSTRAP_DISPATCH_UNCLAIMABLE",
|
|
85
|
+
409: "BOOTSTRAP_DISPATCH_UNCLAIMABLE",
|
|
86
|
+
410: "BOOTSTRAP_DISPATCH_UNCLAIMABLE",
|
|
87
|
+
422: "BOOTSTRAP_EXCHANGE_REJECTED",
|
|
88
|
+
}
|
|
72
89
|
WORKER_BIN_DIRECTORY = Path("/opt/worker/bin")
|
|
73
90
|
_JWT = re.compile(r"^[A-Za-z0-9_-]{1,8192}\.[A-Za-z0-9_-]{1,8192}\.[A-Za-z0-9_-]{1,8192}$")
|
|
74
91
|
_DISPATCH_QUERY = re.compile(
|
|
@@ -284,6 +301,14 @@ def _local_validation_policy_digests() -> dict[str, str]:
|
|
|
284
301
|
|
|
285
302
|
|
|
286
303
|
def _require_local_policy_binding(binding: WorkerPolicyBinding) -> None:
|
|
304
|
+
"""Fail a misdeployed image before it spends an exchange. Not the authority on a run.
|
|
305
|
+
|
|
306
|
+
The run's own authority is the sealed preflight, which ``_require_worker_policy_preflight``
|
|
307
|
+
holds against this same runtime. This one only catches an image whose deployment record and
|
|
308
|
+
whose code disagree, which no run can be sealed correctly against, and it catches it one
|
|
309
|
+
round trip earlier.
|
|
310
|
+
"""
|
|
311
|
+
|
|
287
312
|
local = _local_validation_policy_digests()
|
|
288
313
|
if binding.validation_policy_digests != local:
|
|
289
314
|
deployed = canonical_json_bytes(binding.validation_policy_digests).decode("utf-8")
|
|
@@ -434,6 +459,46 @@ def _metadata_identity(
|
|
|
434
459
|
return bytearray(raw)
|
|
435
460
|
|
|
436
461
|
|
|
462
|
+
def _report_attempt_failure(
|
|
463
|
+
config: BootstrapConfig,
|
|
464
|
+
transport: BootstrapTransport,
|
|
465
|
+
identity: bytearray,
|
|
466
|
+
status: int,
|
|
467
|
+
) -> bool:
|
|
468
|
+
"""Tell Studio, best effort, that this attempt will never start. Return whether it landed.
|
|
469
|
+
|
|
470
|
+
A refused bootstrap is the one failure the attempt itself cannot report: the process holds no
|
|
471
|
+
job, no capability and no attempt id, so nothing downstream of it will ever call ``fail``. Left
|
|
472
|
+
silent, the run sits in "running" until a human notices. This is the cheapest way to close that
|
|
473
|
+
gap, not the guarantee -- Studio's stuck-run poller is what actually guarantees it, so a report
|
|
474
|
+
that cannot be delivered changes nothing about how this process exits.
|
|
475
|
+
|
|
476
|
+
It reuses the attempt's own identity token, sends only the allowlisted refusal code in
|
|
477
|
+
canonical bytes on the ``:fail`` sibling of the exchange route, and accepts only an empty 204.
|
|
478
|
+
Nothing a compromised Studio could answer here can cross back into the worker.
|
|
479
|
+
"""
|
|
480
|
+
|
|
481
|
+
code = EXCHANGE_REFUSAL_CODES.get(status)
|
|
482
|
+
if code is None:
|
|
483
|
+
return False
|
|
484
|
+
parsed = urlsplit(config.exchange_url)
|
|
485
|
+
try:
|
|
486
|
+
reported, raw = transport.request(
|
|
487
|
+
"POST",
|
|
488
|
+
urlunsplit((parsed.scheme, parsed.netloc, BOOTSTRAP_FAILURE_PATH, parsed.query, "")),
|
|
489
|
+
{
|
|
490
|
+
"Accept": "application/json",
|
|
491
|
+
"Authorization": "Bearer " + identity.decode("ascii"),
|
|
492
|
+
"Content-Type": "application/json",
|
|
493
|
+
},
|
|
494
|
+
canonical_json_bytes({"failure_code": code}),
|
|
495
|
+
0,
|
|
496
|
+
)
|
|
497
|
+
except Exception:
|
|
498
|
+
return False
|
|
499
|
+
return reported == 204 and not raw
|
|
500
|
+
|
|
501
|
+
|
|
437
502
|
def _exchange(
|
|
438
503
|
config: BootstrapConfig,
|
|
439
504
|
transport: BootstrapTransport,
|
|
@@ -457,6 +522,14 @@ def _exchange(
|
|
|
457
522
|
MAX_BOOTSTRAP_RESPONSE_BYTES,
|
|
458
523
|
)
|
|
459
524
|
if status != 200:
|
|
525
|
+
# The generic API probe is excluded on purpose: it has no run and no attempt behind it, so
|
|
526
|
+
# there is no state anywhere that a report would move off "running".
|
|
527
|
+
if (
|
|
528
|
+
config.role != "generic_api"
|
|
529
|
+
and 400 <= status < 500
|
|
530
|
+
and status not in RETRYABLE_EXCHANGE_STATUSES
|
|
531
|
+
):
|
|
532
|
+
_report_attempt_failure(config, transport, identity, status)
|
|
460
533
|
raise HostedWorkerError(
|
|
461
534
|
"BOOTSTRAP_EXCHANGE_FAILED",
|
|
462
535
|
f"Studio bootstrap exchange returned HTTP {status}",
|
|
@@ -475,9 +548,19 @@ def _require_worker_policy_preflight(
|
|
|
475
548
|
job_wire: Any,
|
|
476
549
|
job: Any,
|
|
477
550
|
response_preflight: Any,
|
|
478
|
-
binding: WorkerPolicyBinding,
|
|
479
551
|
) -> None:
|
|
480
|
-
"""Bind the
|
|
552
|
+
"""Bind the Studio response, the sealed preflight and the parsed recipe before execution.
|
|
553
|
+
|
|
554
|
+
The sealed preflight is the run's single fleet authority. The image digests, selection id and
|
|
555
|
+
release fence it names are deliberately NOT re-compared against a second copy carried in this
|
|
556
|
+
worker's environment: that mirror could only ever say "the fleet moved on since this run was
|
|
557
|
+
sealed", which is not a reason to refuse a run whose tooling was chosen for it. Nine hosted
|
|
558
|
+
builds died as WORKER_POLICY_BINDING_MISMATCH saying exactly that.
|
|
559
|
+
|
|
560
|
+
What survives is everything the traveler can be held to without a second copy: both preflight
|
|
561
|
+
copies agree, the field set is exact, it names this job's scope and this recipe's mode, its
|
|
562
|
+
policy set is internally consistent, and that policy set is the one this runtime implements.
|
|
563
|
+
"""
|
|
481
564
|
|
|
482
565
|
if not isinstance(job_wire, dict):
|
|
483
566
|
raise HostedWorkerError(
|
|
@@ -524,6 +607,7 @@ def _require_worker_policy_preflight(
|
|
|
524
607
|
"table_recipe_id": job.table_recipe_id,
|
|
525
608
|
"recipe_version": job.recipe_version,
|
|
526
609
|
"recipe_digest": job.documents.recipe_digest,
|
|
610
|
+
"policy_mode": mode,
|
|
527
611
|
}
|
|
528
612
|
if any(job_preflight.get(name) != value for name, value in expected_scope.items()) or (
|
|
529
613
|
"table_id" in job_preflight and job_preflight["table_id"] != str(job.table_id)
|
|
@@ -532,21 +616,41 @@ def _require_worker_policy_preflight(
|
|
|
532
616
|
"WORKER_POLICY_BINDING_MISMATCH",
|
|
533
617
|
"worker policy preflight scope differs from the bootstrap job",
|
|
534
618
|
)
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
"
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
619
|
+
digests = job_preflight["validation_policy_digests"]
|
|
620
|
+
# Shape first, and before anything renders it. The refusals below quote the sealed set back as
|
|
621
|
+
# canonical JSON, and canonical JSON is a narrower dialect than the one the response was parsed
|
|
622
|
+
# in -- a non-integer number inside this field would raise out of the renderer, past the coded
|
|
623
|
+
# refusal it was rendering, and reach the operator as a traceback with no code on it.
|
|
624
|
+
if (
|
|
625
|
+
not isinstance(digests, dict)
|
|
626
|
+
or set(digests) != {"table", "graph"}
|
|
627
|
+
or any(not isinstance(digest, str) for digest in digests.values())
|
|
628
|
+
):
|
|
629
|
+
raise HostedWorkerError(
|
|
630
|
+
"WORKER_POLICY_BINDING_MISMATCH",
|
|
631
|
+
"worker policy preflight validation policy set is not one table and graph digest pair",
|
|
632
|
+
)
|
|
633
|
+
# The runtime is the authority on which validation policy this image implements, so the sealed
|
|
634
|
+
# set is checked against the code rather than against a deployment variable claiming to
|
|
635
|
+
# describe the code. A run sealed under a policy this image does not implement would attest to
|
|
636
|
+
# a check it never ran.
|
|
637
|
+
local = _local_validation_policy_digests()
|
|
638
|
+
if digests != local:
|
|
639
|
+
sealed = canonical_json_bytes(digests).decode("utf-8")
|
|
640
|
+
computed = canonical_json_bytes(local).decode("utf-8")
|
|
641
|
+
raise HostedWorkerError(
|
|
642
|
+
"WORKER_POLICY_RUNTIME_MISMATCH",
|
|
643
|
+
f"sealed validation policy set {sealed} differs from this worker runtime {computed}; "
|
|
644
|
+
"launch this run on the worker image its preflight sealed",
|
|
645
|
+
)
|
|
646
|
+
if (
|
|
647
|
+
job_preflight["validation_policy_digest"] != digests[mode]
|
|
648
|
+
or job_preflight["policy_set_digest"]
|
|
649
|
+
!= "sha256:" + hashlib.sha256(canonical_json_bytes(digests)).hexdigest()
|
|
650
|
+
):
|
|
547
651
|
raise HostedWorkerError(
|
|
548
652
|
"WORKER_POLICY_BINDING_MISMATCH",
|
|
549
|
-
"worker policy preflight
|
|
653
|
+
"worker policy preflight does not carry one self-consistent policy set",
|
|
550
654
|
)
|
|
551
655
|
|
|
552
656
|
|
|
@@ -611,7 +715,6 @@ def _validate_bootstrap_response(
|
|
|
611
715
|
job_wire=job_wire,
|
|
612
716
|
job=parsed_job,
|
|
613
717
|
response_preflight=value["worker_policy_preflight"],
|
|
614
|
-
binding=worker_policy_binding,
|
|
615
718
|
)
|
|
616
719
|
return {"job": job_raw, "capability": capability_raw}, parsed_job
|
|
617
720
|
|
|
@@ -625,7 +728,6 @@ def _validate_bootstrap_response(
|
|
|
625
728
|
job_wire=job_wire,
|
|
626
729
|
job=parsed_job,
|
|
627
730
|
response_preflight=value["worker_policy_preflight"],
|
|
628
|
-
binding=worker_policy_binding,
|
|
629
731
|
)
|
|
630
732
|
signing_key = value["signing_key"]
|
|
631
733
|
parse_signing_key(signing_key)
|
|
@@ -977,6 +1079,19 @@ def launch(
|
|
|
977
1079
|
"PYTHONDONTWRITEBYTECODE": "1",
|
|
978
1080
|
"PYTHONUNBUFFERED": "1",
|
|
979
1081
|
}
|
|
1082
|
+
# The hygiene exec strips the inherited environment so no credential can leak into
|
|
1083
|
+
# the worker -- and it must keep doing so. But the crawler-results bucket is a public
|
|
1084
|
+
# deployment coordinate, not a secret: it names which GCS bucket a result download's
|
|
1085
|
+
# storage authority may claim, the worker's download check refuses every GCS-served
|
|
1086
|
+
# crawl without it, and the deploy pins it on the job for exactly that check. It is
|
|
1087
|
+
# the ONE inherited name that crosses; anything else stays stripped.
|
|
1088
|
+
# It is the FALLBACK, not the source: a job that carries `results_bucket` travels with
|
|
1089
|
+
# its own pin and the worker prefers that one. This pass-through covers dispatch
|
|
1090
|
+
# payloads minted before the traveler did; it retires once every dispatch mints
|
|
1091
|
+
# the field.
|
|
1092
|
+
results_bucket = os.environ.get(CRAWLER_RESULTS_BUCKET_ENV)
|
|
1093
|
+
if results_bucket:
|
|
1094
|
+
environment[CRAWLER_RESULTS_BUCKET_ENV] = results_bucket
|
|
980
1095
|
allowed = {payload.descriptor for payload in descriptors.values()}
|
|
981
1096
|
changed = _restrict_inherited_descriptors(allowed)
|
|
982
1097
|
try:
|
|
@@ -997,21 +1112,47 @@ def launch(
|
|
|
997
1112
|
|
|
998
1113
|
|
|
999
1114
|
def main(argv: Sequence[str] | None = None) -> int:
|
|
1115
|
+
"""Parse one Cloud Run Job dispatch and launch the bootstrap it names.
|
|
1116
|
+
|
|
1117
|
+
Two dispatch spellings reach this executable, because two Studio enqueuers write them and
|
|
1118
|
+
each names the coordinate it carries. A Builder or verifier task carries
|
|
1119
|
+
``--exchange-url ...?dispatch_id=<uuid> --role {producer,verifier}``. A standalone generic
|
|
1120
|
+
API probe carries ``--generic-api-probe-bootstrap-url ...?probe_id=<uuid>`` and no ``--role``
|
|
1121
|
+
at all: the flag names the probe exchange, so the role is not a second thing to state and
|
|
1122
|
+
Studio's ``GoogleCloudTasksGenericApiProbeEnqueuer`` does not state it.
|
|
1123
|
+
|
|
1124
|
+
Accepting only the first spelling is what made the hosted keyed-source probe lane
|
|
1125
|
+
unreachable: argparse rejected the deployed probe task's argv outright (``unrecognized
|
|
1126
|
+
arguments`` plus a missing ``--role``) and the Job exited 2 before a single line of bootstrap
|
|
1127
|
+
code ran. ``tests/test_hosted_bootstrap.py`` holds this parser against the argv Studio's own
|
|
1128
|
+
``dispatch.py`` emits, so the two cannot drift apart again silently.
|
|
1129
|
+
"""
|
|
1130
|
+
|
|
1000
1131
|
parser = argparse.ArgumentParser()
|
|
1001
|
-
parser.
|
|
1132
|
+
source = parser.add_mutually_exclusive_group(required=True)
|
|
1133
|
+
source.add_argument("--exchange-url")
|
|
1134
|
+
source.add_argument("--generic-api-probe-bootstrap-url")
|
|
1002
1135
|
parser.add_argument("--audience", required=True)
|
|
1003
|
-
parser.add_argument("--role",
|
|
1136
|
+
parser.add_argument("--role", choices=("producer", "verifier", "generic_api"))
|
|
1004
1137
|
arguments = parser.parse_args(argv)
|
|
1138
|
+
if arguments.generic_api_probe_bootstrap_url is not None:
|
|
1139
|
+
if arguments.role not in {None, "generic_api"}:
|
|
1140
|
+
parser.error("--generic-api-probe-bootstrap-url admits only --role generic_api")
|
|
1141
|
+
exchange_url = arguments.generic_api_probe_bootstrap_url
|
|
1142
|
+
role = "generic_api"
|
|
1143
|
+
else:
|
|
1144
|
+
if arguments.role is None:
|
|
1145
|
+
parser.error("--exchange-url requires --role")
|
|
1146
|
+
exchange_url = arguments.exchange_url
|
|
1147
|
+
role = arguments.role
|
|
1005
1148
|
try:
|
|
1006
1149
|
launch(
|
|
1007
1150
|
BootstrapConfig(
|
|
1008
|
-
exchange_url=
|
|
1151
|
+
exchange_url=exchange_url,
|
|
1009
1152
|
audience=arguments.audience,
|
|
1010
|
-
role=
|
|
1153
|
+
role=role,
|
|
1011
1154
|
worker_policy_binding=(
|
|
1012
|
-
None
|
|
1013
|
-
if arguments.role == "generic_api"
|
|
1014
|
-
else _binding_from_environment(os.environ)
|
|
1155
|
+
None if role == "generic_api" else _binding_from_environment(os.environ)
|
|
1015
1156
|
),
|
|
1016
1157
|
)
|
|
1017
1158
|
)
|
|
@@ -139,7 +139,15 @@ def _public_https_retriever(
|
|
|
139
139
|
max_concurrency=2,
|
|
140
140
|
min_interval_seconds=1.0,
|
|
141
141
|
allowed_media_types=_public_expected_media_types(request.query),
|
|
142
|
-
|
|
142
|
+
# The contact URL is load-bearing, not decoration: Akamai-fronted
|
|
143
|
+
# providers (stlouisfed.org, measured 2026-08-27 in harness#430)
|
|
144
|
+
# silently tarpit a bare unknown product token - RST on h2, a
|
|
145
|
+
# 15s+ hang on http/1.1 that surfaces as the acquisition timeout -
|
|
146
|
+
# while the same token WITH the crawler-convention "(+URL)"
|
|
147
|
+
# segment answers in half a second from the same egress IP. An
|
|
148
|
+
# honest identity that names where to reach us is also simply the
|
|
149
|
+
# right thing for a public crawler to send.
|
|
150
|
+
user_agent="MostlyRightDataHarness-PublicHttps/1.0 (+https://mostlyright.md/crawler)",
|
|
143
151
|
),
|
|
144
152
|
limiter=_PUBLIC_HTTPS_LIMITER,
|
|
145
153
|
)
|