mostlyright-data 0.29.10__tar.gz → 0.29.13__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 (132) hide show
  1. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/PKG-INFO +5 -1
  2. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/README.md +4 -0
  3. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/pyproject.toml +1 -1
  4. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/SKILL.md +86 -8
  5. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/2-brief-two-to-four-questions-each-with-a-recommended-answer.md +17 -2
  6. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/3-probe-read-a-source-before-committing-to-it.md +70 -23
  7. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/6-build-one-run-sized-to-acquire-every-measured-source-whole.md +29 -12
  8. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/7-interrogate-ask-the-run-what-it-actually-delivered.md +30 -1
  9. mostlyright_data-0.29.13/skills/mr-data-build/references/8-fix-revise-the-document-and-register-it-again.md +16 -0
  10. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/9-present-only-what-survived-inspection-with-caveats.md +24 -18
  11. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/commands.md +18 -11
  12. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/live-run.md +8 -5
  13. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/making-a-table-incremental.md +48 -10
  14. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/one-install.md +2 -2
  15. mostlyright_data-0.29.13/skills/mr-data-build/references/patterns.md +943 -0
  16. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/promote.md +4 -2
  17. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/readers.md +42 -13
  18. mostlyright_data-0.29.13/skills/mr-data-build/references/recipe-test.md +119 -0
  19. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/reference-pages.md +2 -2
  20. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/sources.md +94 -6
  21. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/agent_protocol.py +4 -0
  22. mostlyright_data-0.29.13/src/mostlyright/data_harness/thin/backoff.py +45 -0
  23. mostlyright_data-0.29.13/src/mostlyright/data_harness/thin/fast_features.py +830 -0
  24. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/recipe.py +114 -21
  25. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/recipe_forecast.py +9 -8
  26. mostlyright_data-0.29.13/src/mostlyright/data_harness/thin/recipe_test.py +875 -0
  27. mostlyright_data-0.29.13/src/mostlyright/data_harness/thin/refresh_rehearsal.py +538 -0
  28. mostlyright_data-0.29.13/src/mostlyright/data_harness/thin/release_check.py +145 -0
  29. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/research.py +17 -7
  30. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/router.py +67 -5
  31. mostlyright_data-0.29.13/src/mostlyright/data_harness/thin/run_prefix.py +187 -0
  32. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/runs.py +17 -1
  33. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/session.py +194 -3
  34. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/stream.py +67 -13
  35. mostlyright_data-0.29.13/src/mostlyright/data_harness/thin/support.py +283 -0
  36. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/transport.py +6 -2
  37. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4.py +35 -3
  38. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_artifacts.py +671 -59
  39. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_datasets.py +29 -3
  40. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_public.py +9 -1
  41. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_query.py +470 -27
  42. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_runs.py +312 -41
  43. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_tables.py +54 -27
  44. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/vocabulary.py +13 -0
  45. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/remediation.py +42 -1
  46. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/render.py +50 -0
  47. mostlyright_data-0.29.10/skills/mr-data-build/references/8-fix-revise-the-document-and-register-it-again.md +0 -11
  48. mostlyright_data-0.29.10/src/mostlyright/data_harness/thin/fast_features.py +0 -347
  49. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/.gitignore +0 -0
  50. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/scripts/hatch_build.py +0 -0
  51. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/agents/openai.yaml +0 -0
  52. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/1-open-the-page-and-the-link-to-it-in-the-first-message.md +0 -0
  53. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/4-decide-say-what-you-chose-what-you-refused-and-ask-one-question.md +0 -0
  54. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/5-draft-one-recipe-document-one-call.md +0 -0
  55. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/agent-protocol.md +0 -0
  56. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/autonomous-delivery.md +0 -0
  57. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/before-the-first-tool-call.md +0 -0
  58. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/boundaries.md +0 -0
  59. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/cloud-authentication-preflight.md +0 -0
  60. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/cross-repository-protocol-reference.md +0 -0
  61. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/installation-parity.md +0 -0
  62. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/narrating-the-run.md +0 -0
  63. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/not-hosted-yet.md +0 -0
  64. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/prediction-labels.md +0 -0
  65. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/preparing-table-search.md +0 -0
  66. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/receipts.md +0 -0
  67. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/recording-a-stream-venue.md +0 -0
  68. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/recovering-an-import-failure.md +0 -0
  69. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/required-protocol.md +0 -0
  70. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/source-credentials.md +0 -0
  71. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/the-one-thing-to-say-about-the-skill-itself.md +0 -0
  72. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/transforms.md +0 -0
  73. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/user-communication-contract.md +0 -0
  74. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/references/writing-a-decision-record.md +0 -0
  75. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/skills/mr-data-build/scripts/write_research_notebook.py +0 -0
  76. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/__init__.py +0 -0
  77. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/canonical.py +0 -0
  78. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/formats.py +0 -0
  79. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/hosted_crawler_protocol.py +0 -0
  80. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/key_seam.py +0 -0
  81. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/page_coverage.py +0 -0
  82. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/part_check_evidence.py +0 -0
  83. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/session_probes.py +0 -0
  84. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/skill_assets.py +0 -0
  85. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/table_manifest.py +0 -0
  86. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/__init__.py +0 -0
  87. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/acquire.py +0 -0
  88. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/acquire_cancel.py +0 -0
  89. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/activity.py +0 -0
  90. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/approvals.py +0 -0
  91. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/categories.py +0 -0
  92. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/commands.py +0 -0
  93. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/dataset-categories-v1.json +0 -0
  94. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/download.py +0 -0
  95. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/narrative.py +0 -0
  96. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/parity.py +0 -0
  97. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/probe.py +0 -0
  98. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/progress_rate.py +0 -0
  99. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/progress_vocabulary.py +0 -0
  100. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/propose.py +0 -0
  101. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/recipe_brief.py +0 -0
  102. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/recipe_explain.py +0 -0
  103. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/recipe_lint.py +0 -0
  104. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/run_diagnose.py +0 -0
  105. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/stream_venue.py +0 -0
  106. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/studio_capabilities.py +0 -0
  107. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/user_agent.py +0 -0
  108. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_catalog.py +0 -0
  109. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_connected.py +0 -0
  110. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_connections.py +0 -0
  111. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_dataset_covers.py +0 -0
  112. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_handoff.py +0 -0
  113. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_narrative.py +0 -0
  114. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_reader.py +0 -0
  115. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_search.py +0 -0
  116. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_secrets.py +0 -0
  117. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/thin/v4_stream.py +0 -0
  118. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/__init__.py +0 -0
  119. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/attendance.py +0 -0
  120. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/clarification.py +0 -0
  121. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/cloud_auth.py +0 -0
  122. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/commands/__init__.py +0 -0
  123. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/commands/auth.py +0 -0
  124. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/commands/clarify.py +0 -0
  125. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/commands/login.py +0 -0
  126. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/commands/whoami.py +0 -0
  127. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/credential_native.py +0 -0
  128. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/credential_store.py +0 -0
  129. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/credentials.py +0 -0
  130. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/login.py +0 -0
  131. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/path_kind.py +0 -0
  132. {mostlyright_data-0.29.10 → mostlyright_data-0.29.13}/src/mostlyright/data_harness/ux/plain_file.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mostlyright-data
3
- Version: 0.29.10
3
+ Version: 0.29.13
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/
@@ -39,6 +39,10 @@ places it in your agent's skill directory; there is nothing to install by hand.
39
39
  edited yourself is never replaced, and `MOSTLYRIGHT_SKILL_AUTOINSTALL=0` switches the placement
40
40
  off.
41
41
 
42
+ Once a day, after a command has printed its answer, `mr-data` asks the Python package index whether
43
+ a newer release is published and says so in one line on stderr. `MOSTLYRIGHT_RELEASE_CHECK=0`
44
+ switches that off.
45
+
42
46
  ## Sign in
43
47
 
44
48
  ```bash
@@ -27,6 +27,10 @@ places it in your agent's skill directory; there is nothing to install by hand.
27
27
  edited yourself is never replaced, and `MOSTLYRIGHT_SKILL_AUTOINSTALL=0` switches the placement
28
28
  off.
29
29
 
30
+ Once a day, after a command has printed its answer, `mr-data` asks the Python package index whether
31
+ a newer release is published and says so in one line on stderr. `MOSTLYRIGHT_RELEASE_CHECK=0`
32
+ switches that off.
33
+
30
34
  ## Sign in
31
35
 
32
36
  ```bash
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mostlyright-data"
3
- version = "0.29.10"
3
+ version = "0.29.13"
4
4
  description = "Mostly Right hosted CLI for reviewed datasets"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -9,6 +9,68 @@ Build the dataset the user requested, verify its contents, and report its actual
9
9
  Use hosted commands with `--json` and returned identifiers. This core workflow governs the
10
10
  references. Load the reference for the current stage only, not the entire library before starting.
11
11
 
12
+ ## Four gates
13
+
14
+ Every build passes these four gates in order. Do not skip one. The numbered steps below carry
15
+ the detail.
16
+
17
+ **Gate 1. Read what Studio serves and what the recipe misses.** Draft the recipe. Run
18
+ `mr-data recipe explain RECIPE.json --json` before you register. Read `studio_capabilities`: a
19
+ capability that is not literal `true` is unavailable on this Studio. Read `fast_features`. On a
20
+ new table, fix every entry marked `missed`, or say in the build message why it stays.
21
+ On a table that is already live, list the missed entries and ask the user first. Each fix changes
22
+ the recipe digest, so the next build is a full resync. A paid source is called again for every
23
+ per-row request whose saved answer no longer applies.
24
+
25
+ **Gate 2. State a pace and leave concurrency out.** A page collection that states no pace sends
26
+ one request a second. State `pages.min_interval_milliseconds` as the gap the publisher documents.
27
+ No documented limit: state 1000 ms and say so. That is a valid reason. Registration refuses a gap
28
+ under 16 ms. That is a platform bound, never a target. Where the deployment spreads requests over
29
+ its egress addresses, the gap is kept per address, so the publisher can see a multiple of the
30
+ stated rate. No command prints how many addresses there are. So when the publisher's limit is
31
+ per key or per account, state 1000 ms unless the user confirms the deployment does not spread
32
+ requests. Leave `pages.concurrency` out: the worker then sizes the width, and a stated value is
33
+ only a ceiling. Keep a stated one only when a run's refusal told you to lower it or the publisher
34
+ documents a limit on concurrent connections, and record the reason in a dataset note so the next
35
+ session finds it. Then choose the source shape that fits.
36
+
37
+ | Source shape | Use | Always state | Recipe |
38
+ | --- | --- | --- | --- |
39
+ | One public file that never changes | `public.https` with a Reader pin | `closed: true` | [one file](references/patterns.md#one-public-file-that-never-changes) |
40
+ | One large public Parquet file whose publisher answers byte ranges | a `parquet.tabular@1.1.0` pin | `columns` | [ranged Parquet](references/patterns.md#one-large-public-parquet-file-read-by-range) |
41
+ | Keyed JSON API paged by page number, whose first page states the page count | `authenticated.https.api_key@2.1.0` with the counted `pagination.parallel` | `total_pages_pointer`, `max_page_bytes`, the gap | [keyed API](references/patterns.md#keyed-json-api-with-pages-fetched-together) |
42
+ | API that takes a date range | `window.request` | `lookback_seconds` | [date range](references/patterns.md#api-that-takes-a-date-range) |
43
+ | Many pages behind one index | `public.https.collection@2.0.0` | the gap | [collection](references/patterns.md#many-pages-behind-one-index) |
44
+ | One request per row of another source | a per-row `request`, with `batch` when a `GET` takes a list of ids | the gap | [per-row](references/patterns.md#one-request-per-row-many-ids-per-request) |
45
+ | Bulk dump beside a windowed source | `reference` | `recheck_seconds` | [reference](references/patterns.md#bulk-dump-beside-a-windowed-source) |
46
+ | Live `wss://` feed | a recorded stream | see [Streams](references/recording-a-stream-venue.md) | none |
47
+
48
+ [Patterns](references/patterns.md) has one complete recipe per row, with the pace set.
49
+ [Sources](references/sources.md#pace-and-width) has the pace rules and the limits of parallel
50
+ pages. [Readers](references/readers.md) has the Reader pins and the limits of a ranged read.
51
+
52
+ **Gate 3. Run a bounded test on a scratch table.** Never test on the real table: its first
53
+ succeeded run goes live, truncated or not. For a public CSV that needs no key, run
54
+ `mr-data source inspect`. For anything else follow [the probe rule](references/3-probe-read-a-source-before-committing-to-it.md#the-probe-rule-test-on-a-scratch-table-never-on-the-real-table): copy the drafted
55
+ recipe under another `table.name`, drop `table.search` from the copy, write small budgets into
56
+ it, and take one bounded run.
57
+ A sample's `--max-rows` cuts rows after the fetch. It does not shorten a collection walk, so the
58
+ scratch recipe states a small `pages.max_fetches_per_run`. A per-row request collection also
59
+ states `pages.stop_at_budget: true`, or it fails at that budget. A source whose provider bills
60
+ per call spends real calls on the test, and the real table cannot reuse them. Forecast it and get
61
+ the user's decision before the test. Retire the scratch table with `mr-data demote TABLE_ID` and
62
+ then `mr-data table archive TABLE_ID --confirm DELETE`.
63
+
64
+ **Gate 4. Forecast, then one full run.** Run
65
+ `mr-data recipe forecast RECIPE_ID --digest DIGEST --json`. Exit 3 means resize before you run.
66
+ Read the registration `warnings`. Then run `--full` once and follow it with `mr-data watch`.
67
+
68
+ The steps below are numbered 1 to 10. The reference files are numbered by stage, 1 to 9. Steps 1
69
+ and 2 are stage 1. Step 3 is stage 2. Step 4 is stage 3. Step 5 is stages 4 and 5. Steps 6 and 7
70
+ are stage 6. Step 8 is stage 7. Step 9 is stage 8. Step 10 is stage 9. Gates 1 and 2 belong to
71
+ step 5, where the recipe is drafted. Gate 3 needs that draft, so it runs after step 5 and before
72
+ step 6. The stage 3 reference holds its rule. Gate 4 is step 6.
73
+
12
74
  ## Start and agree the brief
13
75
 
14
76
  1. Run `mr-data whoami --json` once. If authentication needs repair, read
@@ -27,7 +89,10 @@ references. Load the reference for the current stage only, not the entire librar
27
89
  3. Settle purpose, row grain, tables, coverage, required sources and update cadence before
28
90
  dependent work. In an attended build, ask unresolved material questions in one concise message
29
91
  with recommended choices; recording an assumption is not asking the user. Default to one joined,
30
- ML-ready table at the agreed grain unless the user requests otherwise. Validate join cardinality
92
+ ML-ready table at the agreed grain unless the user requests otherwise. Define membership and
93
+ relationship evidence for the intended use; resolve consequential proxies (for example,
94
+ institution location versus a person’s origin) rather than silently treating them as equivalent.
95
+ Validate join cardinality
31
96
  and point-in-time correctness; surface incompatible grains rather than silently multiplying rows.
32
97
  Ask whether this is a fixed snapshot or an updating dataset, how often updates are needed, and
33
98
  whether automatic cadence adjustment is wanted. Existing answers and explicit delegation remain
@@ -60,12 +125,20 @@ references. Load the reference for the current stage only, not the entire librar
60
125
  Decide how each source continues before you register it, and whether the table needs a
61
126
  declared `rebuild`: read [making a table incremental](references/making-a-table-incremental.md).
62
127
  Run `mr-data recipe explain RECIPE.json --json` first. It names every reason the table could
63
- not refresh, not only the first. Its `fast_features` names each fast feature the recipe
64
- misses, with a one-line fix. Write `table.partition` for any table no window partitions that
128
+ not refresh, not only the first. Its `fast_features` has eight entries, and each missed one
129
+ carries a one-line fix. Write `table.partition` for any table no window partitions that
65
130
  has a date-like column, `batch` for a per-row GET whose API takes a list of ids, and
66
131
  `reference` for a bulk dump beside a window
67
132
  ([fast builds](references/making-a-table-incremental.md#fast-builds-tablepartition-batch-and-reference)).
68
- Put them in the first revision, because each later change costs one resync. Adopting
133
+ State the gap, drop a stated `pages.concurrency`, page a keyed API in parallel and pin the
134
+ ranged Parquet Reader where the entries `pace`, `concurrency`, `parallel_pagination` and
135
+ `ranged_parquet` say so and the source meets each condition
136
+ ([fetching fast](references/making-a-table-incremental.md#fetching-fast-pace-width-parallel-pages-and-ranged-parquet)).
137
+ Put them in the first revision. Registering a revision is free, but building one is a full
138
+ resync, so each later change costs one resync.
139
+ On a table that is already live, list the missed entries and ask the user first. Each fix
140
+ changes the recipe digest, so the next build is a full resync. A paid source is called again
141
+ for every per-row request whose saved answer no longer applies. Adopting
69
142
  `table.partition` on an existing table costs one full resync, so for a paid source ask the
70
143
  user before that resync, as the brief and forecast rules require. Before any
71
144
  `--full` of a paid collection, run `mr-data recipe forecast RECIPE_ID --digest DIGEST --json`
@@ -75,7 +148,8 @@ references. Load the reference for the current stage only, not the entire librar
75
148
  Use `--full` for the requested build: it is progressive by default, with a five-minute
76
149
  inspection checkpoint while the same acquisition continues. Choose bounds from measured
77
150
  source size; row and byte clamps apply per source, not elapsed time. Use explicit `--sample`
78
- only for a deliberate standalone inspection. Preserve the agreed semantics and quality checks.
151
+ only for a bounded test on a scratch table, as gate 3 says. Preserve the agreed semantics and
152
+ quality checks.
79
153
  7. Follow the returned run with `mr-data watch RUN_ID --json`. Its `source_rates` and
80
154
  `mr-data status RUN_ID --json` on a live run give each collection source's rate and time left.
81
155
  Quote those numbers rather than doing the arithmetic. Read `run.status`: returning an existing
@@ -119,8 +193,10 @@ merely to obtain a green run. Read [recovery details](references/agent-protocol.
119
193
 
120
194
  8. Read `mr-data checks RUN_ID --json`, `mr-data receipt RUN_ID --json` and
121
195
  `mr-data peek RUN_ID --json`; use bounded `mr-data query` for agreed quality questions.
122
- Verify row grain, joins, requested fields, coverage and every declared check. Successful
123
- execution alone is not a verified dataset. `receipt` carries one coverage entry per source --
196
+ Verify row grain, joins, requested fields, coverage and every declared check. Inspect representative
197
+ and suspicious rows against source evidence and the agreed definitions; schema and count checks
198
+ alone cannot establish that the rows mean what the dataset claims. Successful execution alone
199
+ is not a verified dataset. `receipt` carries one coverage entry per source --
124
200
  `bytes_fetched`, `rows_kept`, `rows_available`, `truncated` and the window -- where the run
125
201
  record folds all sources into four numbers. That is what each source ACTUALLY weighed and
126
202
  carried, and it is the evidence the refresh decision belongs on rather than the ceiling you
@@ -131,7 +207,8 @@ merely to obtain a green run. Read [recovery details](references/agent-protocol.
131
207
  correction into step 10. Read
132
208
  [verification](references/7-interrogate-ask-the-run-what-it-actually-delivered.md).
133
209
  9. Any truncated source means a preview, not the requested complete dataset. Inspect coverage
134
- even when the run succeeded. A null coverage window does not mean all history was acquired.
210
+ even when the run succeeded. Untruncated acquisition does not prove publisher pagination, nested
211
+ records or population coverage is complete. A null coverage window does not mean all history was acquired.
135
212
  Repair only evidenced faults on the same dataset/table and verify the revision again.
136
213
  Record cadence only when authorized and `mr-data recipe readiness --json` reports the current
137
214
  revision refresh-ready. A blocked mutable snapshot requires an explicit table resync, not a
@@ -164,6 +241,7 @@ merely to obtain a green run. Read [recovery details](references/agent-protocol.
164
241
  | Live stream recording | [Streams](references/recording-a-stream-venue.md) |
165
242
  | Prediction target or leakage | [Prediction labels](references/prediction-labels.md) |
166
243
  | How each source continues, `rebuild`, and the cost of a refresh | [Making a table incremental](references/making-a-table-incremental.md) |
244
+ | Testing a recipe before its full, and its first refresh before the schedule | [Recipe test](references/recipe-test.md) |
167
245
  | Refresh cadence | [Promotion and cadence](references/promote.md) |
168
246
  | Dataset notes and evidence blocks | [Decision records](references/writing-a-decision-record.md) |
169
247
  | Search configuration, example queries and readiness | [Search preparation](references/preparing-table-search.md) |
@@ -17,7 +17,9 @@ user already supplied. Always include update behavior when it remains unresolved
17
17
  separate tables as an equal default. Check join keys, cardinality, unmatched rows and, for
18
18
  prediction, feature availability at prediction time. If a join would mix incompatible grains,
19
19
  duplicate examples or leak future information, explain the tradeoff and resolve it before building.
20
- - **Coverage.** Which entities, geography and date range?
20
+ - **Coverage.** Which entities, geography and date range? Resolve definitions that materially change
21
+ membership here: a person’s institutional country, origin and current residence are different
22
+ populations. Ask about the intended population, not which convenient API filter to use.
21
23
  - **Updates.** A fixed historical snapshot or an updating dataset? If updating, how often is new
22
24
  data needed, and should that schedule stay fixed or adapt to source publication? Recommend a
23
25
  cadence from the use case and available source evidence, mark an unverified recommendation as
@@ -27,10 +29,23 @@ user already supplied. Always include update behavior when it remains unresolved
27
29
  the agent recommend them? Ask about the consequential fork — official but delayed against broader
28
30
  and more recent, or a source that needs a credential — and research the options yourself.
29
31
 
30
- Fields and definitions, quality tradeoffs and delivery constraints are follow-ups, not openers:
32
+ Other field details, quality tradeoffs and delivery constraints are follow-ups:
31
33
  ask one when an answer or a source finding exposes it. There is no second brief — this message is
32
34
  the one that decides the shape.
33
35
 
36
+ **Turn the brief into criteria the result can be checked against.** Record what one row claims,
37
+ what qualifies an entity or relationship, and how repeated observations or versions count. Use the
38
+ existing decision notes and recipe checks; this does not introduce a new approval or schema.
39
+ Resolve only consequential ambiguity and honor supplied answers. For a human collaboration table,
40
+ a software agent credited on a release is not evidence of collaboration with that agent’s vendor;
41
+ the user need not specify this exclusion. Whether software contributions count at all depends on
42
+ their purpose. A release-history dataset can legitimately retain every version.
43
+
44
+ Use a few included and excluded examples when they help expose a boundary. Carry unresolved
45
+ source limitations into the source comparison rather than redefining the goal around available
46
+ fields. Do not infer a person’s origin from their name or silently replace it with institutional
47
+ country. If the intended population cannot be evidenced, explain the gap and resolve the scope.
48
+
34
49
  **Every question is a pending `clarification` block on the dataset and the same words in chat.**
35
50
  The block carries `question` and no `answer`, so the page shows it open; the chat asks it in the
36
51
  same words, so the two readers see one question rather than two. The answer REVISES that cell —
@@ -79,11 +79,12 @@ refusal to the provider and never bypass it.
79
79
  reason codes, only once the discovery lanes and the comparisons are complete — and claim
80
80
  `unsupported` only after every typed-refusal chain ends `lawful_routes_exhausted`.
81
81
 
82
- **Reading the bytes is a bounded run, not `mr-data probe`.** `probe SOURCE_ID QUESTION_ID
82
+ **Reading the bytes is a bounded test run, not `mr-data probe`.** `probe SOURCE_ID QUESTION_ID
83
83
  --dataset DATASET_ID` takes two identifiers rather than a question in words, and no v4 registration
84
84
  receipt returns a question identifier; it also rides the frozen `/v3/sessions` routes, which a
85
- deployment may have switched off. So the reading path on a hosted workspace is the ordinary loop,
86
- run early: register the recipe and take one run without `--window`.
85
+ deployment may have switched off. So the reading path on a hosted workspace is
86
+ [the probe rule](#the-probe-rule-test-on-a-scratch-table-never-on-the-real-table) below: one
87
+ bounded run of a scratch table.
87
88
 
88
89
  **A public CSV can also be looked at before anything is registered.** `mr-data source inspect` reads
89
90
  the start of one HTTPS file that needs no key and answers with what it saw, with no recipe and no
@@ -107,7 +108,7 @@ start of the file and not the file. Its `evidence` carries the `format`, the `co
107
108
  not an answer yet, so read it back again later. A status of `truncated` is an answer that stopped at
108
109
  a limit: keep its limits and its evidence with whatever you record, and never call it complete. The
109
110
  command takes no key and no Reader options, so a source that needs either, or that is not a CSV, is
110
- read by the run below instead. So is any source that answers `capability_unavailable`, which means
111
+ read by the test run below instead. So is any source that answers `capability_unavailable`, which means
111
112
  this deployment cannot inspect it: do not retry it, and do not guess in its place.
112
113
 
113
114
  **Write down what each look found.** An inspection is not a run, and nothing on the page shows what
@@ -128,33 +129,79 @@ observed_at, stage_m and quality_flag.
128
129
  EOF
129
130
  ```
130
131
 
131
- **Both obey the ordinary gate.** Registering needs the brief answered or delegated, so the run
132
- happens AFTER stage 2's answers arrive — or at once under a delegation — and an inspection, which
133
- writes a question and a source onto the dataset, waits for the same answers. What continues while
132
+ **Both obey the ordinary gate.** Registering needs the brief answered or delegated. So the test
133
+ run happens after stage 2's answers arrive, or at once under a delegation. An inspection writes a
134
+ question and a source onto the dataset, so it waits for the same answers. What continues while
134
135
  you wait is research that submits nothing: documentation, publisher comparison, catalog.
135
136
 
137
+ #### The probe rule: test on a scratch table, never on the real table
138
+
139
+ Test a recipe on a scratch table with small budgets. Never test on the real table. A table's
140
+ first succeeded run goes live, truncated or not. A test run on the real table would serve a cut
141
+ table on the dataset page. This stage starts no full build of the real table. Stage 6 starts
142
+ that one build. The test needs a drafted recipe, so run it once stage 5 has a draft and before
143
+ stage 6.
144
+
145
+ 1. Copy the recipe document. Give the copy its own `table.name`. Keep the same `dataset.id`.
146
+ Drop `table.search` from the copy, so the test prepares no search index.
147
+ 2. Write small budgets into the copy, as the list below says.
148
+ 3. Register the copy with `mr-data recipe SCRATCH.json --json`. It returns a recipe id, a digest
149
+ and a table id of its own.
150
+ 4. Take one bounded run and read it back.
151
+ 5. Retire the scratch table. A scratch table goes live too, so withdraw it first.
152
+
136
153
  ```sh
137
- mr-data run --recipe RECIPE_ID --digest RECIPE_DIGEST --full --json
138
- mr-data status RUN --inspection --json # inspect while the same full acquisition continues
154
+ mr-data run --recipe SCRATCH_RECIPE_ID --digest SCRATCH_DIGEST --sample --max-rows 2000 --json
139
155
  mr-data peek RUN --json # the columns and types the run sealed
140
156
  mr-data query RUN "select count(*) from run_table" --json
141
157
  mr-data receipt RUN --json # what was fetched and what those bytes hashed to
158
+ mr-data status RUN --diagnose --json # progress, plan counts and how each attempt ended
159
+ mr-data demote SCRATCH_TABLE_ID --json
160
+ mr-data table archive SCRATCH_TABLE_ID --confirm DELETE --json
142
161
  ```
143
162
 
144
- **Inspect the full build while it runs.** Its progressive checkpoint appears after about five
145
- minutes without stopping acquisition. Use an explicit `--sample` only for a deliberate standalone
146
- experiment: a row ceiling can truncate output after every collection page was fetched and does
147
- not promise a short acquisition. Never derive source size from a truncated sample's ceiling.
148
-
149
- **A reading run that came back whole IS the build, so stage 6 adopts it rather than repeating
150
- it.** Untruncated everywhere is the build, whichever stage started the run: keep this `run_id`.
151
- The run meets Studio's ordinary size confirmation before acquisition when it is large (a size
152
- check, not a charge); its checkpoint requires no
153
- second approval or second full build.
154
-
155
- That is stages 5 through 7 run once to settle the shape. Where the deployment does answer a source
156
- inspection or a probe, keep its status, reason code and exit value internal and describe only what
157
- it settled.
163
+ **Know what a sample bounds and what it does not.**
164
+
165
+ - `--max-rows` cuts each source's rows after that source is fetched and decoded. It does not
166
+ shorten a collection walk. Every page the budgets admit is still fetched.
167
+ - A collection's walk is bounded by `pages.max_fetches_per_run` and `discovery.max_requests`.
168
+ Write both small in the scratch recipe. A listing collection that spends its fetch budget
169
+ still succeeds and reports `complete: false`.
170
+ - A per-row request collection fails with `ROW_REQUESTS_EXCEED_BUDGET` at its fetch budget.
171
+ State `pages.stop_at_budget: true` beside the small budget in the scratch recipe. The run
172
+ then seals the rows it answered and reports `complete: false`.
173
+ - A row clamp does not truncate a per-row request collection. Answers past the clamp fail the
174
+ run with `ROW_REQUESTS_EXCEED_BUDGET`. Keep `--max-rows` above the rows its budget can answer.
175
+ - A document projection source cannot run under a row clamp. The run fails with
176
+ `CLAMP_UNSUPPORTED_FORMAT`. Test it with a full run of the scratch table:
177
+ `mr-data run --recipe SCRATCH_RECIPE_ID --digest SCRATCH_DIGEST --full --json`.
178
+ - A source with a request window is read for its latest `lookback_seconds` only.
179
+ [Stage 6](6-build-one-run-sized-to-acquire-every-measured-source-whole.md) has the exact days.
180
+ - `--max-source-bytes` and `limits.max_source_bytes` refuse in every mode. They never truncate.
181
+ - A sample must state a clamp. Studio refuses a sample with none as `CLAMPS_REQUIRED`. This
182
+ client refuses it first as `THIN_REQUEST_INVALID`. Give `--max-rows`, `--max-source-bytes` or
183
+ `--window`.
184
+
185
+ **A paid source spends real calls on the test.** A per-row request whose provider bills per call
186
+ makes a paid call for every request the scratch run sends. The real table cannot reuse those answers,
187
+ because saved answers belong to the table that holds them. Run `mr-data recipe forecast` on the
188
+ scratch recipe and get the user's decision before the test.
189
+
190
+ **Retire a scratch table by what happened to it.** A scratch table whose run succeeded is live:
191
+ `demote` it, then `table archive` it. One whose run failed never went live, and `demote` answers
192
+ `TABLE_NOT_PROMOTED` for it. Go straight to `table archive`. To test a revision, register it
193
+ under the same scratch `table.name` before you archive. After the archive the name is free
194
+ again, and registering it makes a new table.
195
+
196
+ **Keep the activity line truthful during the test.** The page shows the scratch table going live
197
+ as a table event. That event does not write your activity line. Say in the line that you are
198
+ testing on a scratch table, and do not report `--phase done` for it.
199
+
200
+ Never derive a source's size from a truncated sample's ceiling. A check on the whole table, such
201
+ as a row floor, can fail on a sample of a sound recipe. Read the registration `warnings` first.
202
+
203
+ Where the deployment does answer a source inspection or a probe, keep its status, reason code and
204
+ exit value internal and describe only what it settled.
158
205
 
159
206
  **An acquisition's answer is evidence, and cheap to reuse.** Acquisitions are cacheable by
160
207
  source, query digest and window, so a fetch feeds a later build in the same warm session without
@@ -1,13 +1,17 @@
1
1
  ### 6. Build — one run, sized to acquire every measured source whole
2
2
 
3
- **Stage 3's reading run is usually already this run.** Where it came back with
4
- `coverage.truncated` false everywhere, that run is the build: keep it, present it at stage 7, start
5
- nothing here. Re-running the coordinate replays it; a different ceiling buys only another
6
- acquisition.
7
-
8
- **Otherwise start one progressive full build.** Use the registered recipe and measured bounds
3
+ **Stage 3 tested the recipe on a scratch table. This stage starts the one full build of the real
4
+ table.** Do not test on the real table: its first succeeded run goes live, truncated or not.
5
+ [The probe rule](3-probe-read-a-source-before-committing-to-it.md#the-probe-rule-test-on-a-scratch-table-never-on-the-real-table)
6
+ has the scratch-table steps. Before the full build, run
7
+ `mr-data recipe forecast RECIPE_ID --digest RECIPE_DIGEST --json`. Exit 3 means the run as declared
8
+ would outlast one attempt or overrun a quota, so resize it first. Read the registration
9
+ `warnings` too.
10
+
11
+ **Then start one progressive full build.** Use the registered recipe and measured bounds
9
12
  for the requested coverage. Every full run is progressive by default; agents do not choose
10
- between progressive and sample-first acquisition.
13
+ between progressive and sample-first acquisition. Re-running the same coordinate replays its
14
+ stored result. A different ceiling buys only another acquisition.
11
15
 
12
16
  ```sh
13
17
  mr-data run --recipe RECIPE_ID --digest RECIPE_DIGEST --full --json
@@ -19,11 +23,12 @@ limit. A short build can finish before a checkpoint is needed. Do not submit ano
19
23
  inspecting it. A required size confirmation happens before acquisition; it is not a charge. The
20
24
  older `--progressive` flag is accepted for compatibility but is unnecessary.
21
25
 
22
- **A standalone sample is an explicit inspection choice.** Use `--sample --max-rows 2000` only
23
- when a separate bounded experiment is needed. Rows are clamped after acquisition, so a collection
24
- may still fetch every page and take longer than five minutes. For an already authorized full
25
- build, use the progressive checkpoint. A truncated sample is a preview: report its actual
26
- coverage and the full build's proposed coverage before requesting any missing authorization.
26
+ **A standalone sample belongs on a scratch table.** Use `--sample --max-rows 2000` only for a
27
+ separate bounded experiment, and run it as the probe rule says. Rows are clamped after
28
+ acquisition, so a collection still fetches every page its budgets admit and can take longer than
29
+ five minutes. For an already authorized full build, use the progressive checkpoint. A truncated
30
+ sample is a preview: report its actual coverage and the full build's proposed coverage before
31
+ requesting any missing authorization.
27
32
 
28
33
  > The preview stopped at 2,000 rows on `asos_observations`, which is the ceiling rather than the
29
34
  > end of the feed; the other three sources came back whole. The full build would cover 2000 to 2026
@@ -208,6 +213,18 @@ held answer prints back as `confirm_command`. Any authenticated surface of the s
208
213
  may settle it. Never present it to the user as a cost or a payment. `mr-data run --cancel RUN_ID`
209
214
  stops a run that is queued or running.
210
215
 
216
+ **A full tests its recipe first.** `mr-data run --full` runs `mr-data recipe test` with Studio's
217
+ default bounds, waits up to five minutes for its report, and then starts the full resuming from
218
+ the test's pages, so nothing is fetched twice. A blocking problem, a failed or held test, or a test
219
+ still running after five minutes keeps the full from starting: the status is
220
+ `run_stopped_by_test`, `run_test_awaiting_confirmation` or `run_test_still_running`, `run_id` names
221
+ the test, and `next` ends with the same full plus `--skip-test`. Repair the recipe rather than
222
+ skipping the test, unless the user decides the problem does not matter; a test still running is
223
+ picked back up by the same command. A test that failed in the room (`room_fault: true`) is tested
224
+ again by the same command. Studio admits the test as the full it stands in front of, so a large
225
+ full can be held for a size confirmation twice, once for the test and once for the full. See
226
+ [recipe test](recipe-test.md).
227
+
211
228
  Do not treat the accepted command vocabulary as execution evidence. Before proposing a schedule,
212
229
  classify every source under one truthful continuation strategy and record the supporting evidence,
213
230
  using [making a table incremental](making-a-table-incremental.md).
@@ -9,6 +9,35 @@ mr-data checks RUN --json # every check the recipe declared
9
9
  mr-data receipt RUN --json # sources, digests, coverage, snapshot members
10
10
  ```
11
11
 
12
+ #### Check meaning against the brief
13
+
14
+ Inspect actual rows beyond the first preview: sample across material source/entity/type groups
15
+ and inspect anomalies such as unusually prolific pairs, repeated titles or concentrated counts.
16
+ Trace selected inclusions and suspected exclusions to source records. Record the version, sample
17
+ selection, rows inspected, evidence and unresolved limitations in the dataset notes. A sample is
18
+ not proof of population-wide accuracy; passing declared checks only proves their assertions.
19
+
20
+ Choose checks from the dataset’s claims. For a human co-authorship table, inspect counterpart
21
+ identity and affiliation evidence, distinct people rather than self-edges, work types, and repeated
22
+ release families. A bot credit does not establish a human relationship with its vendor. Use
23
+ source-supported identities or narrowly justified matches; a name substring is not a reliable bot
24
+ classifier. Preserve legitimate human names. Treat software releases and version deduplication
25
+ according to the agreed grain: do not ban software or collapse versions in a release-history task.
26
+ Encode evidenced, repeatable failures as supported recipe checks where possible, then verify the
27
+ repair. Do not relax checks or prune legitimate rows to make them pass.
28
+
29
+ Separate acquisition limits from source and population coverage. Read publisher totals and
30
+ continuation tokens, nested-list caps or completeness flags, and join losses where applicable.
31
+ `coverage.truncated: false` does not prove all publisher pages or all authors inside each record
32
+ were returned. Missing completeness evidence means unknown. A nested cap calls for another
33
+ supported acquisition path or a stated limitation, not silent exclusion of every large record.
34
+
35
+ Known examples can reveal omissions, but compare their eligibility against the same population,
36
+ dates and relationship definition first. A broader benchmark is useful for discussing scope; its
37
+ size is not a valid recall denominator for a narrower dataset. Investigate eligible misses and
38
+ preserve out-of-scope examples as such. Do not manufacture a recall or accuracy percentage from
39
+ an unvalidated list or an anomaly-focused sample.
40
+
12
41
  **The last of those answers `THIN_NO_MATCHING_ARTIFACT` on a run that sealed no receipt**, naming
13
42
  what it sealed instead. That is the ordinary shape of a recipe with one `request`-windowed source
14
43
  rather than a fault. Read `mr-data status RUN --json` for its coverage, as
@@ -57,7 +86,7 @@ instead, and wait through the window the refusal names rather than retrying in a
57
86
 
58
87
  **A query sent straight after another may find no worker to start.** The worker behind the query
59
88
  before is still winding down, and Studio fails the new session at once with
60
- `RESEARCH_SESSION_WORKER_UNAVAILABLE`. `mr-data query` waits 8 seconds and opens one more session,
89
+ `RESEARCH_SESSION_WORKER_UNAVAILABLE`. `mr-data query` waits 8 to 12 seconds and opens one more session,
61
90
  once. The answer then names the first session under `session.retried_after`. If the second has no
62
91
  worker either, the command refuses `THIN_RESEARCH_SESSION_ENDED` and names both sessions, each with
63
92
  its state, close reason and failure code. Nothing was queued, so running the same command again
@@ -0,0 +1,16 @@
1
+ ### 8. Fix — revise the document and register it again
2
+
3
+ Change the document and send it again. Same dataset, same table, new digest:
4
+
5
+ ```sh
6
+ mr-data recipe RECIPE.json --json
7
+ ```
8
+
9
+ **Registering a revision is free and abandons nothing. Building it costs one resync.**
10
+ Registration starts no run. Table identity is stable across revisions: no `_v2.._vN` renaming, no
11
+ proposal wedged on an id somebody has to reclaim, no cleanup after a failed run. The revision has
12
+ a new digest, so the sealed predecessor no longer matches it. Its next build reads every source
13
+ again. A per-row request collection still reuses the answers the live version holds while its
14
+ request, Reader and binding stay the same. Put every change in one revision so the table pays
15
+ once. Forecast a source whose provider bills per call, and ask the user before that resync.
16
+ Build again, interrogate again, until the checks and coverage say what you need.
@@ -1,23 +1,25 @@
1
1
  ### 9. Present — only what survived inspection, with caveats
2
2
 
3
3
  Report what you inspected, and nothing you did not. Nothing else checks this run: `verified` is
4
- what you established by reading it, not a word another worker said. Three facts carry whatever
5
- you say and all three are on the run: how many rows you looked at, what the declared checks
6
- reported, and whether `coverage.truncated` was true anywhere. A null coverage window means the
7
- acquisition was unwindowed rather than that it covered all time. Never present a sampled row as a
4
+ what you established by reading it, not a word another worker said. Report how many rows you
5
+ inspected and how you selected them, what the declared checks reported, and whether `coverage.truncated` was true anywhere. Include the source evidence and
6
+ limitations behind membership, relationships and population coverage. A null coverage window means
7
+ the acquisition was unwindowed rather than that it covered all time. Never present a sampled row as a
8
8
  whole-population value, never call a run verified because it succeeded, and never report coverage
9
- you did not read off `coverage`.
9
+ you did not establish from the run and source evidence.
10
10
 
11
11
  **Read `truncated` first, because it decides which of two endings this is.** When it is false on
12
- every coverage entry, nothing was cut and the table this run sealed is the table a full run would
13
- have sealed. When it is true anywhere, what you have is a shape rather than an answer.
12
+ every coverage entry, the acquisition reports no transport truncation. This alone does not
13
+ establish publisher pagination, nested-list completeness or coverage of the intended population.
14
+ When it is true anywhere, what you have is a shape rather than an answer.
14
15
 
15
- **Untruncated everywhere is the build. Present it as one.** The mode a run started in is not what
16
- makes a table finished, and calling a complete table "a preview" tells somebody their dataset does
17
- not exist yet when it does. Say what was built, and link the page:
16
+ **The real table's full run, untruncated everywhere, is the build. Present it as one.** A
17
+ scratch-table test is never the build, whatever its coverage says. Calling a complete table "a
18
+ preview" tells somebody their dataset does not exist yet when it does. Say what was built, and link the page:
18
19
 
19
- > Built 43,812 rows from four sources, every source acquired whole and nothing truncated. All four
20
- > declared checks passed. Live at <link>. It refreshes every 6 hours, because the publisher posts
20
+ > Built 43,812 rows from four sources with no reported acquisition truncation. All four declared
21
+ > checks passed. Inspected 40 rows across the four sources; publisher totals match acquired records.
22
+ > Live at <link>. It refreshes every 6 hours, because the publisher posts
21
23
  > hourly and the bytes appear about forty minutes late.
22
24
 
23
25
  Say plainly that it is live: the first succeeded run of a table goes live on its own, so there is
@@ -39,20 +41,24 @@ refresh delegation described above. Stage 6 carries the run commands.
39
41
  the dataset page, so before acting on this recipe again read `mr-data runs --json --mode full` and,
40
42
  for any run newer than the preview that you did not start, `mr-data status RUN_ID --json` to see
41
43
  whether it names this recipe and digest. One that does is theirs, and its state says what to do.
42
- `queued`, `running` or `succeeded` is the full build: adopt it as if you had started it — write its
43
- run cell, `mr-data watch RUN_ID --json` if it has not ended, then stage 7. `awaiting_confirmation`
44
+ `queued`, `running` or `succeeded` is the full build of the real table: adopt it as if you had
45
+ started it. Write its run cell, `mr-data watch RUN_ID --json` if it has not ended, then stage 7. A
46
+ run of a scratch table is never adopted as the build. `awaiting_confirmation`
44
47
  is the size gate (not a charge), which the same command settles with `--confirm`.
45
48
  `awaiting_sample_approval` is stage 6's held full: read its `sample_run_id`, interrogate that
46
49
  preview, and release it with `mr-data run --approve-full`. `failed` is the full build too: read its
47
50
  triple and structured recovery. A known retry case can use `mr-data run --retry RUN_ID`; otherwise
48
51
  preserve the document until the evidence identifies a repair. A bare run of the same coordinate
49
52
  replays that failure. `cancelled` means they withdrew the decision, so say so and ask nothing
50
- further unless they raise it. Ask, then give the turn back; do not hold a stream open waiting for
53
+ further unless they raise it. The exception is a run whose `cancel_reason` is
54
+ `preflight_complete`, or that carries `preflight`: that is a recipe test, which always ends
55
+ `cancelled` with its report and never becomes a version. It is not the full build and not a
56
+ withdrawn decision; read its `preflight_report` as [recipe test](recipe-test.md) describes. Ask, then give the turn back; do not hold a stream open waiting for
51
57
  either answer.
52
58
 
53
- Then interrogate that run as stage 7 says, and present it with the preview's caveats removed and
54
- its own read off `coverage`. Do not start a full build because the preview looked good or because a
55
- dataset was asked for — the decision is whether THIS is the recipe to build.
59
+ Then interrogate that run as stage 7 says. Remove only the preview caveats the new evidence
60
+ resolves, and retain unresolved source limitations. Do not start a full build because the preview
61
+ looked good or because a dataset was asked for — the decision is whether THIS is the recipe to build.
56
62
 
57
63
  **Either way, offer the bytes.** A sealed table is downloadable whatever mode produced it —
58
64
  `mr-data download RUN --output DIR --json` — so somebody who wants to look before agreeing to