mostlyright-data 0.29.4__tar.gz → 0.29.6__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 (122) hide show
  1. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/PKG-INFO +1 -1
  2. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/pyproject.toml +1 -1
  3. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/5-draft-one-recipe-document-one-call.md +6 -5
  4. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/making-a-table-incremental.md +3 -2
  5. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/session.py +4 -0
  6. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4.py +2 -2
  7. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_datasets.py +32 -55
  8. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/.gitignore +0 -0
  9. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/README.md +0 -0
  10. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/scripts/hatch_build.py +0 -0
  11. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/SKILL.md +0 -0
  12. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/agents/openai.yaml +0 -0
  13. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/1-open-the-page-and-the-link-to-it-in-the-first-message.md +0 -0
  14. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/2-brief-two-to-four-questions-each-with-a-recommended-answer.md +0 -0
  15. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/3-probe-read-a-source-before-committing-to-it.md +0 -0
  16. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/4-decide-say-what-you-chose-what-you-refused-and-ask-one-question.md +0 -0
  17. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/6-build-one-run-sized-to-acquire-every-measured-source-whole.md +0 -0
  18. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/7-interrogate-ask-the-run-what-it-actually-delivered.md +0 -0
  19. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/8-fix-revise-the-document-and-register-it-again.md +0 -0
  20. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/9-present-only-what-survived-inspection-with-caveats.md +0 -0
  21. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/agent-protocol.md +0 -0
  22. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/autonomous-delivery.md +0 -0
  23. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/before-the-first-tool-call.md +0 -0
  24. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/boundaries.md +0 -0
  25. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/cloud-authentication-preflight.md +0 -0
  26. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/commands.md +0 -0
  27. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/cross-repository-protocol-reference.md +0 -0
  28. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/installation-parity.md +0 -0
  29. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/live-run.md +0 -0
  30. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/narrating-the-run.md +0 -0
  31. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/not-hosted-yet.md +0 -0
  32. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/one-install.md +0 -0
  33. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/prediction-labels.md +0 -0
  34. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/preparing-table-search.md +0 -0
  35. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/promote.md +0 -0
  36. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/readers.md +0 -0
  37. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/receipts.md +0 -0
  38. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/recording-a-stream-venue.md +0 -0
  39. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/recovering-an-import-failure.md +0 -0
  40. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/reference-pages.md +0 -0
  41. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/required-protocol.md +0 -0
  42. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/source-credentials.md +0 -0
  43. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/sources.md +0 -0
  44. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/the-one-thing-to-say-about-the-skill-itself.md +0 -0
  45. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/transforms.md +0 -0
  46. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/user-communication-contract.md +0 -0
  47. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/references/writing-a-decision-record.md +0 -0
  48. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/skills/mr-data-build/scripts/write_research_notebook.py +0 -0
  49. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/__init__.py +0 -0
  50. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/agent_protocol.py +0 -0
  51. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/canonical.py +0 -0
  52. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/formats.py +0 -0
  53. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/hosted_crawler_protocol.py +0 -0
  54. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/key_seam.py +0 -0
  55. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/page_coverage.py +0 -0
  56. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/part_check_evidence.py +0 -0
  57. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/session_probes.py +0 -0
  58. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/skill_assets.py +0 -0
  59. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/table_manifest.py +0 -0
  60. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/__init__.py +0 -0
  61. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/acquire.py +0 -0
  62. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/acquire_cancel.py +0 -0
  63. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/activity.py +0 -0
  64. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/approvals.py +0 -0
  65. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/categories.py +0 -0
  66. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/commands.py +0 -0
  67. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/dataset-categories-v1.json +0 -0
  68. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/download.py +0 -0
  69. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/fast_features.py +0 -0
  70. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/narrative.py +0 -0
  71. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/parity.py +0 -0
  72. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/probe.py +0 -0
  73. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/progress_rate.py +0 -0
  74. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/progress_vocabulary.py +0 -0
  75. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/propose.py +0 -0
  76. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/recipe.py +0 -0
  77. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/recipe_brief.py +0 -0
  78. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/recipe_explain.py +0 -0
  79. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/recipe_forecast.py +0 -0
  80. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/recipe_lint.py +0 -0
  81. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/research.py +0 -0
  82. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/router.py +0 -0
  83. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/run_diagnose.py +0 -0
  84. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/runs.py +0 -0
  85. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/stream.py +0 -0
  86. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/stream_venue.py +0 -0
  87. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/studio_capabilities.py +0 -0
  88. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/transport.py +0 -0
  89. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/user_agent.py +0 -0
  90. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_artifacts.py +0 -0
  91. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_catalog.py +0 -0
  92. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_connected.py +0 -0
  93. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_connections.py +0 -0
  94. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_dataset_covers.py +0 -0
  95. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_handoff.py +0 -0
  96. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_narrative.py +0 -0
  97. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_public.py +0 -0
  98. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_query.py +0 -0
  99. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_reader.py +0 -0
  100. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_runs.py +0 -0
  101. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_search.py +0 -0
  102. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_secrets.py +0 -0
  103. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_stream.py +0 -0
  104. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/v4_tables.py +0 -0
  105. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/thin/vocabulary.py +0 -0
  106. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/__init__.py +0 -0
  107. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/attendance.py +0 -0
  108. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/clarification.py +0 -0
  109. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/cloud_auth.py +0 -0
  110. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/commands/__init__.py +0 -0
  111. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/commands/auth.py +0 -0
  112. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/commands/clarify.py +0 -0
  113. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/commands/login.py +0 -0
  114. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/commands/whoami.py +0 -0
  115. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/credential_native.py +0 -0
  116. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/credential_store.py +0 -0
  117. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/credentials.py +0 -0
  118. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/login.py +0 -0
  119. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/path_kind.py +0 -0
  120. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/plain_file.py +0 -0
  121. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/remediation.py +0 -0
  122. {mostlyright_data-0.29.4 → mostlyright_data-0.29.6}/src/mostlyright/data_harness/ux/render.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mostlyright-data
3
- Version: 0.29.4
3
+ Version: 0.29.6
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/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mostlyright-data"
3
- version = "0.29.4"
3
+ version = "0.29.6"
4
4
  description = "Mostly Right hosted CLI for reviewed datasets"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -455,11 +455,12 @@ from the accepted subset — `Cel`, `ug/m3`, `km/h`, `hPa`, `{count}` and the re
455
455
  out in [Units](https://mostlyright.md/docs/reference/units/). Write the code rather than a name:
456
456
  `ug/m3` composes and `microgram_per_cubic_meter` does not.
457
457
 
458
- **Nothing resolves the code, so there is no `UNIT_*` refusal to lean on.** The recipe schema bounds
459
- the length of `unit` and nothing else; registration checks only that `units[].column` names a
460
- declared column and answers `422 RECIPE_DOCUMENT_INCOHERENT` at `/units/N/column` when it does not;
461
- the run never reads `units` at all. A code outside the subset therefore costs nothing at build time
462
- and costs every reader afterwards, and a column declared in metres that holds feet is caught by
458
+ **Registration resolves the code and reads no data.** The recipe schema bounds the length of
459
+ `unit`; registration then checks that `units[].column` names a declared column, answering
460
+ `422 RECIPE_DOCUMENT_INCOHERENT` at `/units/N/column` when it does not, and resolves each
461
+ `units[].unit` against the subset, answering the same code at `/units/N/unit` when it cannot.
462
+ `mr-data recipe` does not resolve the code locally, so that refusal arrives from registration. The
463
+ run does not read `units`, so a column declared in metres that holds feet is caught by
463
464
  nothing. Convert in the statement, then declare the unit of what the column ends up holding. Leave a
464
465
  column out of `units` rather than declare something approximate — a density, a rate, anything whose
465
466
  unit is genuinely new. `none` is not a unit and does not become one. Remember that the two
@@ -105,8 +105,9 @@ Studio records the answer as one classification per source:
105
105
  | a `window` carrying a `request` | `window` | `acquire_incremental` |
106
106
  | none of those | `resync_only` | `resync_required` |
107
107
 
108
- The rows are in Studio's precedence order, and the first match wins. A source that states both
109
- `closed: true` and a request window is `closed`, and its window is never read. One `resync_only`
108
+ The rows are in Studio's precedence order, and the first match wins. A source may not state both
109
+ `closed: true` and a request window: registration refuses that pair with
110
+ `422 RECIPE_DOCUMENT_INCOHERENT` at `/sources/N/closed`. One `resync_only`
110
111
  source makes the whole table resync-only, however truthful its siblings are. Say which sources you
111
112
  left `resync_only` and why, because a recipe that never asked the question registers the same way
112
113
  as one that did.
@@ -75,6 +75,9 @@ CLOUD_DATASETS_LIST_PATH = "/api/cli/datasets"
75
75
  # Projection repair after a Studio metadata write, without a publication mutation.
76
76
  CLOUD_DATASET_IDENTITY_PATH = "/api/cli/datasets/{dataset_id}/identity"
77
77
 
78
+ # Shared UI/CLI archive orchestration, including public projection withdrawal.
79
+ CLOUD_DATASET_ARCHIVE_PATH = "/api/cli/datasets/{dataset_id}/archive"
80
+
78
81
  #: The one Cloud address a Dataset has. ``mostlyright-cloud`` serves it at this route with
79
82
  #: section suffixes, and a run has no page of its own: its evidence lives on this page's Harness
80
83
  #: card, so a receipt names its run with :func:`run_dashboard_url` as a query member here rather
@@ -687,6 +690,7 @@ __all__ = [
687
690
  "CLOUD_APPROVAL_DASHBOARD_PATH",
688
691
  "CLOUD_DATASETS_LIST_PATH",
689
692
  "CLOUD_DATASET_ACCESS_PATH",
693
+ "CLOUD_DATASET_ARCHIVE_PATH",
690
694
  "CLOUD_DATASET_DASHBOARD_PATH",
691
695
  "CLOUD_DATASET_RESOLVED_SCHEMA",
692
696
  "CLOUD_DATASET_RESOLVE_PATH",
@@ -147,8 +147,8 @@ from mostlyright.data_harness.thin.transport import ThinLaneError
147
147
  #: ``JOB_INVALID`` outright, which in production was every refresh a collection epoch was offered
148
148
  #: for rather than only the collection runs. This package must not reach a Studio older than the
149
149
  #: commit it pins; ``docs/V4-WORKER-PROTOCOL.md`` states it beside the layout's own ordering rule.
150
- PINNED_V4_OPENAPI_SOURCE_SHA256 = "bf6312e73ba81725f9146dd6c8b10ff47ae57d1822ba695991aec03931d17d4d"
151
- PINNED_V4_CONTRACT_VERSION = "4.26.0"
150
+ PINNED_V4_OPENAPI_SOURCE_SHA256 = "1f30e109b81f6aa55c00c8999fd877b6678b7e0bea617707d26e7a040380f98b"
151
+ PINNED_V4_CONTRACT_VERSION = "4.27.0"
152
152
 
153
153
  #: The ``schema_version`` every command body that predates 4.14.0 stamps: ``dataset activity``,
154
154
  #: ``table rename``, ``table archive`` and ``dataset archive``. It is the number the 0.25 line
@@ -127,6 +127,7 @@ from mostlyright.data_harness.thin.narrative import (
127
127
  from mostlyright.data_harness.thin.runs import new_idempotency_key
128
128
  from mostlyright.data_harness.thin.session import (
129
129
  CLOUD_DATASET_ACCESS_PATH,
130
+ CLOUD_DATASET_ARCHIVE_PATH,
130
131
  CLOUD_DATASET_IDENTITY_PATH,
131
132
  CLOUD_DATASET_RESOLVE_PATH,
132
133
  CLOUD_DATASET_RESOLVED_SCHEMA,
@@ -149,7 +150,6 @@ from mostlyright.data_harness.thin.stream import RunEventStream
149
150
  from mostlyright.data_harness.thin.transport import ThinLaneError, Transport, UrlLibTransport
150
151
  from mostlyright.data_harness.thin.v4 import (
151
152
  ARCHIVE_DATASET_PATH,
152
- COMMAND_REQUEST_VERSION_FLOOR,
153
153
  CREATE_DATASET_PATH,
154
154
  DATASET_CURRENT_STATE_PATH,
155
155
  DATASET_EVENT_HISTORY_PATH,
@@ -448,6 +448,14 @@ class CloudDatasetAccessClient(CloudClient):
448
448
  credential header and the refusal folding to drift.
449
449
  """
450
450
 
451
+ def archive_dataset(self, dataset_id: str, confirmation_name: str) -> dict[str, Any]:
452
+ return self.call(
453
+ "POST",
454
+ CLOUD_DATASET_ARCHIVE_PATH.format(dataset_id=dataset_id),
455
+ act="archive this dataset and withdraw its public listings",
456
+ body={"confirmation_name": confirmation_name},
457
+ )
458
+
451
459
  def sync_dataset_identity(self, dataset_id: str) -> dict[str, Any]:
452
460
  """Carry Studio's current metadata into Cloud's existing public projection."""
453
461
 
@@ -458,7 +466,6 @@ class CloudDatasetAccessClient(CloudClient):
458
466
  body={},
459
467
  )
460
468
 
461
-
462
469
  def list_datasets(self, *, limit: int | None = None) -> dict[str, Any]:
463
470
  """Name every dataset this workspace holds, most recently updated first.
464
471
 
@@ -1838,75 +1845,46 @@ def write(
1838
1845
 
1839
1846
 
1840
1847
  def archive(
1841
- args: argparse.Namespace, *, client: StudioV4DatasetClient | None = None
1848
+ args: argparse.Namespace, *, client: CloudDatasetAccessClient | None = None
1842
1849
  ) -> dict[str, Any]:
1843
- """``mr-data dataset archive DATASET_ID --confirm-name TITLE``: retire the page, free the name.
1844
-
1845
- ⚠ THE TYPED TITLE IS COMPARED HERE AS WELL AS BY STUDIO, WHICH IS THE OPPOSITE CHOICE FROM
1846
- ``mr-data table archive`` AND THE REASON IS THAT THE READ IS ALREADY HAPPENING. This write is
1847
- fenced on the dataset's version, so the page has to be read before it can be sent; the title
1848
- arrives in the same body, the comparison costs nothing, and the fence is what makes it safe --
1849
- a title that changed after the read moves the version, and the conditional refuses. Where a
1850
- read would have to be bought only to give a second opinion, this lane does not buy it.
1851
-
1852
- ⚠ AND IT IS NOT A DELETION. Runs, artifacts, versions and the decision record all stay. What
1853
- the command ends is the page's claim on its title and its place in the workspace's listing.
1854
- """
1855
-
1850
+ """Use the UI's Cloud archive ceremony; a Studio-only tombstone is incomplete."""
1856
1851
  dataset_id = identifier(getattr(args, "dataset_id", None) or "", "dataset identifier")
1857
1852
  confirmation = getattr(args, "confirm_name", None)
1858
1853
  if not isinstance(confirmation, str) or not confirmation.strip():
1859
1854
  raise ThinLaneError(
1860
1855
  "THIN_REQUEST_INVALID",
1861
1856
  "mr-data dataset archive needs the dataset's current title typed out: "
1862
- f"--confirm-name TITLE. mr-data dataset show {dataset_id} prints the title Studio "
1863
- "holds",
1857
+ "--confirm-name TITLE",
1864
1858
  )
1865
1859
  stated = confirmation.strip()
1866
- selected = client or _client(args)
1867
- record = selected.dataset(dataset_id)
1868
- version = _version(record)
1869
- held = record.get("name")
1870
- if isinstance(held, str) and held.strip() != stated:
1860
+ if client is None:
1861
+ credentials = resolve_cloud_credentials()
1862
+ require_device_key(credentials)
1863
+ selected = CloudDatasetAccessClient(credentials)
1864
+ elif isinstance(client, CloudDatasetAccessClient):
1865
+ selected = client
1866
+ else:
1871
1867
  raise ThinLaneError(
1872
- "THIN_CONFIRMATION_MISMATCH",
1873
- f"this dataset is called {held!r} and --confirm-name said {stated!r}. Archiving "
1874
- "releases the title, so the title is what confirms it: type the one on the page, or "
1875
- "check you have the dataset you meant",
1876
- )
1877
- try:
1878
- archived = selected.archive_dataset(
1879
- dataset_id,
1880
- body={
1881
- "schema_version": COMMAND_REQUEST_VERSION_FLOOR,
1882
- "workspace_id": str(selected.session.workspace_id),
1883
- "confirmation_name": stated,
1884
- },
1885
- expected_version=version,
1868
+ "THIN_REQUEST_INVALID", "dataset archive requires the Cloud archive client"
1886
1869
  )
1887
- except ThinLaneError as refusal:
1888
- if not stale_version(refusal):
1889
- raise
1890
- # ⚠ NAMED, AND NOT RETRIED, WHICH IS THE ONE PLACE THIS DIFFERS FROM `write` AND `rename`.
1891
- # Those two replay at the new version because what they write does not depend on what
1892
- # changed underneath them. This does: the title typed to confirm the archive is exactly
1893
- # what a racing `dataset set` may have just rewritten, so a silent retry could archive a
1894
- # page under a title that is no longer its own. What it gets instead is the same sentence
1895
- # the other two end on, because it is the same thing that happened.
1870
+ answer = selected.archive_dataset(dataset_id, stated)
1871
+ if (
1872
+ answer.get("schema_version") != "mostlyright-dataset-archive.v1"
1873
+ or answer.get("status") != "dataset_archived"
1874
+ or answer.get("dataset_id") != dataset_id
1875
+ or answer.get("name") != stated
1876
+ ):
1896
1877
  raise ThinLaneError(
1897
- "THIN_DATASET_VERSION_CONFLICT",
1898
- f"the dataset moved between the read at version {version} and this archive; somebody "
1899
- f"else is editing it. Read it with mr-data dataset show {dataset_id}, check the title "
1900
- "is still the one you typed, and archive again",
1901
- ) from refusal
1878
+ "THIN_RESPONSE_INVALID",
1879
+ "Cloud did not confirm this dataset's complete archive",
1880
+ )
1902
1881
  return {
1903
1882
  "schema_version": ARCHIVE_SCHEMA,
1904
1883
  "status": "dataset_archived",
1905
1884
  "lane": "hosted",
1906
- "dataset_id": _dataset_id(archived, verb="archive") if archived else dataset_id,
1885
+ "dataset_id": dataset_id,
1907
1886
  "name": stated,
1908
- "version": archived.get("version"),
1909
- "dashboard_url": dataset_dashboard_url(selected.session.cloud_url, dataset_id),
1887
+ "dashboard_url": dataset_dashboard_url(selected.cloud_url, dataset_id),
1910
1888
  "note": (
1911
1889
  f"The dataset is retired and the title {stated!r} is free for another one. Nothing "
1912
1890
  "built was deleted: every run, artifact, version and decision cell stays where it is."
@@ -2488,7 +2466,6 @@ def watch(
2488
2466
  }
2489
2467
 
2490
2468
 
2491
-
2492
2469
  def listing(
2493
2470
  args: argparse.Namespace, *, client: CloudDatasetAccessClient | None = None
2494
2471
  ) -> dict[str, Any]: