mostlyright-data 0.21.2__tar.gz → 0.21.3__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.
Files changed (74) hide show
  1. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/PKG-INFO +6 -1
  2. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/README.md +5 -0
  3. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/pyproject.toml +1 -1
  4. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/skills/mr-data-build/SKILL.md +10 -0
  5. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_runs.py +27 -2
  6. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/render.py +1 -0
  7. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/.gitignore +0 -0
  8. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/scripts/hatch_build.py +0 -0
  9. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/skills/mr-data-build/agents/openai.yaml +0 -0
  10. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/skills/mr-data-build/scripts/write_research_notebook.py +0 -0
  11. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/__init__.py +0 -0
  12. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/canonical.py +0 -0
  13. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/formats.py +0 -0
  14. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/hosted_crawler_protocol.py +0 -0
  15. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/key_seam.py +0 -0
  16. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/page_coverage.py +0 -0
  17. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/part_check_evidence.py +0 -0
  18. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/session_probes.py +0 -0
  19. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/skill_assets.py +0 -0
  20. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/table_manifest.py +0 -0
  21. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/__init__.py +0 -0
  22. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/acquire.py +0 -0
  23. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/acquire_cancel.py +0 -0
  24. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/activity.py +0 -0
  25. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/approvals.py +0 -0
  26. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/categories.py +0 -0
  27. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/commands.py +0 -0
  28. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/dataset-categories-v1.json +0 -0
  29. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/download.py +0 -0
  30. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/narrative.py +0 -0
  31. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/parity.py +0 -0
  32. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/probe.py +0 -0
  33. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/progress_vocabulary.py +0 -0
  34. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/propose.py +0 -0
  35. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/recipe.py +0 -0
  36. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/recipe_brief.py +0 -0
  37. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/recipe_lint.py +0 -0
  38. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/research.py +0 -0
  39. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/router.py +0 -0
  40. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/runs.py +0 -0
  41. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/session.py +0 -0
  42. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/stream.py +0 -0
  43. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/stream_venue.py +0 -0
  44. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/transport.py +0 -0
  45. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/user_agent.py +0 -0
  46. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4.py +0 -0
  47. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_artifacts.py +0 -0
  48. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_catalog.py +0 -0
  49. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_connections.py +0 -0
  50. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_dataset_covers.py +0 -0
  51. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_datasets.py +0 -0
  52. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_handoff.py +0 -0
  53. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_narrative.py +0 -0
  54. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_query.py +0 -0
  55. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_secrets.py +0 -0
  56. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_stream.py +0 -0
  57. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/v4_tables.py +0 -0
  58. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/thin/vocabulary.py +0 -0
  59. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/__init__.py +0 -0
  60. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/attendance.py +0 -0
  61. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/clarification.py +0 -0
  62. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/cloud_auth.py +0 -0
  63. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/commands/__init__.py +0 -0
  64. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/commands/auth.py +0 -0
  65. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/commands/clarify.py +0 -0
  66. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/commands/login.py +0 -0
  67. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/commands/whoami.py +0 -0
  68. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/credential_native.py +0 -0
  69. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/credential_store.py +0 -0
  70. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/credentials.py +0 -0
  71. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/login.py +0 -0
  72. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/path_kind.py +0 -0
  73. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/plain_file.py +0 -0
  74. {mostlyright_data-0.21.2 → mostlyright_data-0.21.3}/src/mostlyright/data_harness/ux/remediation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mostlyright-data
3
- Version: 0.21.2
3
+ Version: 0.21.3
4
4
  Summary: Mostly Right hosted CLI for reviewed datasets
5
5
  Project-URL: Homepage, https://mostlyright.md/
6
6
  Project-URL: Documentation, https://mostlyright.md/docs/guides/cli/
@@ -82,6 +82,11 @@ mr-data checks RUN_ID
82
82
  mr-data download RUN_ID --output ./out
83
83
  ```
84
84
 
85
+ Run submission is idempotent: sending identical recipe, mode and bounds returns the same run,
86
+ including a previous failure. The CLI reports a non-queued result as `run_returned` and exits
87
+ with code 2 when that run failed. Read its failure before retrying; `mr-data run --retry RUN_ID`
88
+ can reissue supported platform execution failures without changing the recipe.
89
+
85
90
  Use the identifiers returned by registration and run submission. `mr-data dataset create`
86
91
  creates a dataset page before a recipe is ready. `mr-data watch RUN_ID` follows a submitted run.
87
92
 
@@ -70,6 +70,11 @@ mr-data checks RUN_ID
70
70
  mr-data download RUN_ID --output ./out
71
71
  ```
72
72
 
73
+ Run submission is idempotent: sending identical recipe, mode and bounds returns the same run,
74
+ including a previous failure. The CLI reports a non-queued result as `run_returned` and exits
75
+ with code 2 when that run failed. Read its failure before retrying; `mr-data run --retry RUN_ID`
76
+ can reissue supported platform execution failures without changing the recipe.
77
+
73
78
  Use the identifiers returned by registration and run submission. `mr-data dataset create`
74
79
  creates a dataset page before a recipe is ready. `mr-data watch RUN_ID` follows a submitted run.
75
80
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mostlyright-data"
3
- version = "0.21.2"
3
+ version = "0.21.3"
4
4
  description = "Mostly Right hosted CLI for reviewed datasets"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -2011,6 +2011,8 @@ decoder. Zero matches and multiple matches both refuse.
2011
2011
  | `archive.gzip@1.1.0` | Same; also accepts a response served as `application/octet-stream`. |
2012
2012
  | `archive.tar@1.0.0` | Same as `archive.zip@1.0.0`. |
2013
2013
  | `archive.tar@1.1.0` | Same; also accepts a response served as `application/octet-stream`. |
2014
+ | `archive.tar@2.0.0` | Explicit `compression: none or gzip`, `encoding: utf-8 or cp1252`, `member` and `member_format: csv, tsv, semicolon or lines`. Lines also accepts exact `members` list, emitting member_name, line_number, raw_line. |
2015
+ | `text.lines@1.0.0` | Explicit `encoding: utf-8 or cp1252`; preserves physical lines as line_number, raw_line without delimiter or quote inference. |
2014
2016
  | `spreadsheet.xlsx@1.0.0` | `sheet`, `header_row`, and `range`. The heading row must be the first row of the range. |
2015
2017
  | `spreadsheet.xlsx@1.1.0` | Same; also accepts a response served as `application/octet-stream`. |
2016
2018
  | `delimited_text@1.0.0` | `delimiter` (comma or tab); optional `header: true`; optional `encoding: utf-8`. |
@@ -2241,3 +2243,11 @@ The floating pill represents only your active work. Start `dataset activity` imm
2241
2243
  When recovering, report what you are trying now; an earlier failed attempt belongs in the record. Before every final handoff, cancellation, or exhausted stop, report `--phase done` with a truthful final sentence (for example, “Dataset ready to explore” or “Stopped before the build completed”). Do this even when tables are not enabled. Only use `waiting_on_you` when a question is actually open — the brief at stage 2, the plan at stage 4, or the full build after a preview — and never under a delegation, which leaves nothing to wait on. A table going live does not finish your agent session.
2242
2244
 
2243
2245
  Stage 1 opened the dataset before research began; keep that same tab. Enable its optional Follow agent control for a watch-along experience; manual scrolling pauses it and must never be overridden.
2246
+
2247
+ ## Recovering an import failure
2248
+
2249
+ For a deterministic reader or transform failure, use the reported source, line and reason before changing settings. Do not repeatedly submit the same failed recipe or guess an encoding. Repeated run submission may return the existing run with `status: run_returned`; inspect `run.status` and its failure rather than treating it as new work. Use `--retry` only when the CLI identifies the failure as retryable.
2250
+
2251
+ For malformed delimited text, use the hosted `text.lines@1.0.0` reader with explicit encoding to retain physical lines, then inspect field counts and metadata before authoring the final parse. For compressed TAR files, use `archive.tar@2.0.0` with an explicit wrapper and exact member names. These readers preserve evidence; they do not repair values or prove a guessed encoding. Reader implementations are backend modules and are not importable from the thin CLI installation.
2252
+
2253
+ Estimate the final output separately from each source. Ordinary builds retain a 10-million-row output ceiling; increasing per-source limits does not increase it. A manifest over parts does not by itself make arbitrary SQL builds incremental. Use a supported partitioned execution capability only when the deployed worker admits it.
@@ -1242,7 +1242,27 @@ def start(args: argparse.Namespace, *, client: StudioV4RunClient | None = None)
1242
1242
  body = create_run_body(args)
1243
1243
  selected = client or _client(args)
1244
1244
  try:
1245
- return _started(selected.create_run(body), selected.session, status="run_queued")
1245
+ run = selected.create_run(body)
1246
+ # The create route is idempotent and can return a previous terminal result.
1247
+ # Report its actual state rather than promising that another worker was queued.
1248
+ state = run.get("status")
1249
+ payload = _started(
1250
+ run, selected.session, status="run_queued" if state == "queued" else "run_returned"
1251
+ )
1252
+ if state != "queued":
1253
+ payload["message"] = (
1254
+ f"Studio returned a run in state {state}. Identical run coordinates reuse "
1255
+ "the same run; this response does not establish that a new attempt was queued."
1256
+ )
1257
+ triple = failure_triple(run)
1258
+ if triple:
1259
+ payload["failure"] = triple
1260
+ payload["next_command"] = (
1261
+ f"mr-data run --retry {run['run_id']}"
1262
+ if triple["room_fault"]
1263
+ else f"mr-data status {run['run_id']}"
1264
+ )
1265
+ return payload
1246
1266
  except ThinLaneError as refusal:
1247
1267
  held_payload = _held_for_confirmation(refusal, body)
1248
1268
  if held_payload is None:
@@ -1271,7 +1291,12 @@ def start(args: argparse.Namespace, *, client: StudioV4RunClient | None = None)
1271
1291
  def run_exit_code(payload: Mapping[str, Any]) -> int:
1272
1292
  """A run held at the spend gate is a gate a script acts on, not a report it reads."""
1273
1293
 
1274
- return 2 if payload.get("status") == "run_awaiting_confirmation" else 0
1294
+ return (
1295
+ 2
1296
+ if payload.get("status") == "run_awaiting_confirmation"
1297
+ or payload.get("run", {}).get("status") in {"failed", "awaiting_confirmation"}
1298
+ else 0
1299
+ )
1275
1300
 
1276
1301
 
1277
1302
  # --------------------------------------------------------------------------------------------
@@ -487,6 +487,7 @@ STATUS_HEADLINES: dict[str, str] = {
487
487
  # what Studio's own state machine reached, and "the watch ended" is honest about the case
488
488
  # where the connection stopped before the run did.
489
489
  "run_queued": "The run is queued. Watch it at the address below.",
490
+ "run_returned": "Studio returned the run below in its current state.",
490
491
  # A run over the spend threshold is HELD, not refused and not started. Three words rather than
491
492
  # one, because "it is waiting for you", "you said yes and it is queued" and "it is stopped" are
492
493
  # three different things to have happened, and one word covering them is how a held run gets