roar-cli 0.3.0__tar.gz → 0.3.2__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 (423) hide show
  1. {roar_cli-0.3.0 → roar_cli-0.3.2}/PKG-INFO +2 -2
  2. {roar_cli-0.3.0 → roar_cli-0.3.2}/README.md +1 -1
  3. {roar_cli-0.3.0 → roar_cli-0.3.2}/pyproject.toml +1 -1
  4. roar_cli-0.3.2/roar/__init__.py +11 -0
  5. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/git_remote.py +3 -2
  6. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/register_tag_push.py +1 -1
  7. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/results.py +1 -0
  8. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/service.py +46 -6
  9. roar_cli-0.3.2/roar/application/run/dirty_tree_classify.py +123 -0
  10. roar_cli-0.3.2/roar/application/run/dirty_tree_error.py +279 -0
  11. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/run/execution.py +64 -10
  12. roar_cli-0.3.2/roar/application/run/gitignore_suggest.py +89 -0
  13. roar_cli-0.3.2/roar/application/run/output_followup.py +119 -0
  14. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/run/service.py +2 -2
  15. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/host_execution.py +23 -6
  16. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/submit.py +61 -3
  17. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/__init__.py +8 -1
  18. roar_cli-0.3.2/roar/cli/_format.py +80 -0
  19. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/auth.py +7 -3
  20. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/put.py +3 -1
  21. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/register.py +5 -1
  22. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/publish_intent.py +18 -2
  23. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/provenance.py +2 -0
  24. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/framework/registry.py +33 -0
  25. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/framework/runtime_imports.py +16 -0
  26. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/data_loader.py +2 -0
  27. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/runtime_collector.py +8 -2
  28. roar_cli-0.3.2/roar/execution/runtime/abi_probe.py +41 -0
  29. roar_cli-0.3.2/roar/execution/runtime/inject/sitecustomize.py +80 -0
  30. roar_cli-0.3.2/roar/execution/runtime/inject/support.py +124 -0
  31. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/inject/tracker.py +3 -0
  32. roar_cli-0.3.2/roar/execution/runtime/lazy_install.py +217 -0
  33. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/tracer.py +67 -1
  34. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/config/access.py +37 -4
  35. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/run_report.py +15 -10
  36. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/terminal.py +2 -1
  37. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/hooks.py +53 -1
  38. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/paths.py +2 -0
  39. roar_cli-0.3.0/roar/application/run/dirty_tree_error.py +0 -163
  40. roar_cli-0.3.0/roar/cli/_format.py +0 -70
  41. roar_cli-0.3.0/roar/execution/runtime/inject/sitecustomize.py +0 -48
  42. roar_cli-0.3.0/roar/execution/runtime/inject/support.py +0 -51
  43. roar_cli-0.3.0/roar/tui/screens/__init__.py +0 -0
  44. {roar_cli-0.3.0 → roar_cli-0.3.2}/LICENSE +0 -0
  45. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/__main__.py +0 -0
  46. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/analyzers/__init__.py +0 -0
  47. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/analyzers/base.py +0 -0
  48. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/analyzers/experiment_trackers.py +0 -0
  49. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/__init__.py +0 -0
  50. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/get/__init__.py +0 -0
  51. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/get/requests.py +0 -0
  52. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/get/results.py +0 -0
  53. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/get/service.py +0 -0
  54. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/get/transfer.py +0 -0
  55. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/git.py +0 -0
  56. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/label_rendering.py +0 -0
  57. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/labels.py +0 -0
  58. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/lookup/__init__.py +0 -0
  59. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/lookup/models.py +0 -0
  60. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/lookup/policy.py +0 -0
  61. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/lookup/refs.py +0 -0
  62. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/lookup/remote_artifacts.py +0 -0
  63. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/lookup/runner.py +0 -0
  64. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/__init__.py +0 -0
  65. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/blake3_upgrade.py +0 -0
  66. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/collection.py +0 -0
  67. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/composite_builder.py +0 -0
  68. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/composites.py +0 -0
  69. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/datasets.py +0 -0
  70. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/job_links.py +0 -0
  71. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/job_preparation.py +0 -0
  72. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/lineage.py +0 -0
  73. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/lineage_composites.py +0 -0
  74. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/metadata.py +0 -0
  75. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/put_composites.py +0 -0
  76. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/put_execution.py +0 -0
  77. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/put_preparation.py +0 -0
  78. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/register_execution.py +0 -0
  79. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/register_preparation.py +0 -0
  80. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/register_preview_jobs.py +0 -0
  81. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/registration.py +0 -0
  82. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/registration_package.py +0 -0
  83. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/remote_job_uids.py +0 -0
  84. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/remote_registry.py +0 -0
  85. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/requests.py +0 -0
  86. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/runtime.py +0 -0
  87. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/secrets.py +0 -0
  88. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/session.py +0 -0
  89. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/source_resolution.py +0 -0
  90. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/publish/targets.py +0 -0
  91. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/__init__.py +0 -0
  92. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/dag.py +0 -0
  93. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/diff.py +0 -0
  94. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/diff_engine.py +0 -0
  95. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/diff_graph.py +0 -0
  96. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/diff_refs.py +0 -0
  97. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/git_readiness.py +0 -0
  98. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/inputs.py +0 -0
  99. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/label.py +0 -0
  100. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/lineage.py +0 -0
  101. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/log.py +0 -0
  102. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/requests.py +0 -0
  103. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/results.py +0 -0
  104. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/show.py +0 -0
  105. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/query/status.py +0 -0
  106. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/reproduce/__init__.py +0 -0
  107. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/reproduce/environment.py +0 -0
  108. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/reproduce/lookup.py +0 -0
  109. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/reproduce/requests.py +0 -0
  110. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/reproduce/results.py +0 -0
  111. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/reproduce/service.py +0 -0
  112. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/run/__init__.py +0 -0
  113. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/run/dag_references.py +0 -0
  114. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/run/requests.py +0 -0
  115. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/run/verbosity.py +0 -0
  116. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/system_labels.py +0 -0
  117. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/workflow/__init__.py +0 -0
  118. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/workflow/requests.py +0 -0
  119. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/workflow/results.py +0 -0
  120. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/application/workflow/service.py +0 -0
  121. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/auth_store.py +0 -0
  122. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/__init__.py +0 -0
  123. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/local/__init__.py +0 -0
  124. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/local/plugin.py +0 -0
  125. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/__init__.py +0 -0
  126. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/config.py +0 -0
  127. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/export.py +0 -0
  128. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/lineage.py +0 -0
  129. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/plugin.py +0 -0
  130. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/runtime_bundle.py +0 -0
  131. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/osmo/workflow.py +0 -0
  132. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/__init__.py +0 -0
  133. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/_agent_names.py +0 -0
  134. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/collector.py +0 -0
  135. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/config.py +0 -0
  136. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/constants.py +0 -0
  137. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/env_contract.py +0 -0
  138. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/fragment.py +0 -0
  139. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/fragment_reconstituter.py +0 -0
  140. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/node_agent.py +0 -0
  141. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/plugin.py +0 -0
  142. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/proxy_fragments.py +0 -0
  143. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/roar_worker.py +0 -0
  144. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/runtime_hooks.py +0 -0
  145. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/s3_key_paths.py +0 -0
  146. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/submit.py +0 -0
  147. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/backends/ray/submit_context.py +0 -0
  148. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/command_registry.py +0 -0
  149. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/__init__.py +0 -0
  150. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/build.py +0 -0
  151. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/config.py +0 -0
  152. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/dag.py +0 -0
  153. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/diff.py +0 -0
  154. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/env.py +0 -0
  155. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/export_registration_package.py +0 -0
  156. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/get.py +0 -0
  157. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/init.py +0 -0
  158. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/init_agents.py +0 -0
  159. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/inputs.py +0 -0
  160. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/label.py +0 -0
  161. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/lineage.py +0 -0
  162. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/log.py +0 -0
  163. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/login.py +0 -0
  164. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/logout.py +0 -0
  165. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/osmo.py +0 -0
  166. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/pop.py +0 -0
  167. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/projects.py +0 -0
  168. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/proxy.py +0 -0
  169. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/reproduce.py +0 -0
  170. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/reset.py +0 -0
  171. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/run.py +0 -0
  172. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/scope.py +0 -0
  173. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/show.py +0 -0
  174. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/status.py +0 -0
  175. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/telemetry.py +0 -0
  176. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/tracer.py +0 -0
  177. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/tui.py +0 -0
  178. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/whoami.py +0 -0
  179. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/commands/workflow.py +0 -0
  180. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/context.py +0 -0
  181. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/decorators.py +0 -0
  182. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/templates/agents/SKILL.md.tmpl +0 -0
  183. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/cli/templates/agents/agents_section.md.tmpl +0 -0
  184. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/__init__.py +0 -0
  185. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/bootstrap.py +0 -0
  186. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/canonical_session.py +0 -0
  187. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/digests.py +0 -0
  188. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/dto/__init__.py +0 -0
  189. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/dto/registration.py +0 -0
  190. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/exceptions.py +0 -0
  191. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/__init__.py +0 -0
  192. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/config.py +0 -0
  193. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/lineage.py +0 -0
  194. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/logger.py +0 -0
  195. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/presenter.py +0 -0
  196. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/provenance.py +0 -0
  197. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/registration.py +0 -0
  198. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/repositories.py +0 -0
  199. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/reproduction.py +0 -0
  200. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/run.py +0 -0
  201. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/services.py +0 -0
  202. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/telemetry.py +0 -0
  203. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/interfaces/vcs.py +0 -0
  204. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/label_constants.py +0 -0
  205. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/label_origins.py +0 -0
  206. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/logging.py +0 -0
  207. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/__init__.py +0 -0
  208. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/artifact.py +0 -0
  209. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/base.py +0 -0
  210. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/dag.py +0 -0
  211. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/dataset_identifier.py +0 -0
  212. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/glaas.py +0 -0
  213. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/job.py +0 -0
  214. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/lineage.py +0 -0
  215. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/run.py +0 -0
  216. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/session.py +0 -0
  217. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/telemetry.py +0 -0
  218. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/models/vcs.py +0 -0
  219. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/operation_metadata.py +0 -0
  220. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/session_hash.py +0 -0
  221. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/step_name.py +0 -0
  222. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/tracer_modes.py +0 -0
  223. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/core/validation.py +0 -0
  224. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/__init__.py +0 -0
  225. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/context.py +0 -0
  226. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/engine.py +0 -0
  227. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/hashing/__init__.py +0 -0
  228. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/hashing/backend.py +0 -0
  229. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/hashing/blake3.py +0 -0
  230. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/models.py +0 -0
  231. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/query_context.py +0 -0
  232. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/repositories/__init__.py +0 -0
  233. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/repositories/artifact.py +0 -0
  234. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/repositories/collection.py +0 -0
  235. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/repositories/composite.py +0 -0
  236. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/repositories/hash_cache.py +0 -0
  237. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/repositories/job.py +0 -0
  238. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/repositories/label.py +0 -0
  239. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/repositories/session.py +0 -0
  240. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/schema.py +0 -0
  241. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/services/__init__.py +0 -0
  242. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/services/hashing.py +0 -0
  243. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/services/job_recording.py +0 -0
  244. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/services/lineage.py +0 -0
  245. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/services/session.py +0 -0
  246. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/db/step_priority.py +0 -0
  247. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/__init__.py +0 -0
  248. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/cluster/__init__.py +0 -0
  249. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/cluster/bridge.py +0 -0
  250. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/cluster/proxy.py +0 -0
  251. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/cluster/proxy_config.py +0 -0
  252. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/fragments/__init__.py +0 -0
  253. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/fragments/lineage.py +0 -0
  254. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/fragments/models.py +0 -0
  255. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/fragments/reconstitution.py +0 -0
  256. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/fragments/sessions.py +0 -0
  257. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/fragments/transport.py +0 -0
  258. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/framework/__init__.py +0 -0
  259. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/framework/contract.py +0 -0
  260. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/framework/planning.py +0 -0
  261. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/__init__.py +0 -0
  262. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/assembler.py +0 -0
  263. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/build_pip_collector.py +0 -0
  264. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/build_tool_collector.py +0 -0
  265. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/file_filter.py +0 -0
  266. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/package_collector.py +0 -0
  267. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/process_summarizer.py +0 -0
  268. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/provenance/service.py +0 -0
  269. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/recording/__init__.py +0 -0
  270. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/recording/dataset_identifier.py +0 -0
  271. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/recording/dataset_metadata.py +0 -0
  272. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/recording/dataset_profile.py +0 -0
  273. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/recording/job_recording.py +0 -0
  274. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/reproduction/__init__.py +0 -0
  275. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/reproduction/environment_setup.py +0 -0
  276. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/reproduction/installers.py +0 -0
  277. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/reproduction/pipeline_executor.py +0 -0
  278. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/reproduction/pipeline_metadata.py +0 -0
  279. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/__init__.py +0 -0
  280. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/backup.py +0 -0
  281. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/coordinator.py +0 -0
  282. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/driver_entrypoint.py +0 -0
  283. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/errors.py +0 -0
  284. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/host_execution.py +0 -0
  285. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/inject/__init__.py +0 -0
  286. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/proxy_resource.py +0 -0
  287. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/resources.py +0 -0
  288. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/signal_handler.py +0 -0
  289. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/tracer_backends.py +0 -0
  290. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/tracer_banner.py +0 -0
  291. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/execution/runtime/worker_bootstrap.py +0 -0
  292. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/filters/__init__.py +0 -0
  293. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/filters/files.py +0 -0
  294. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/filters/omit.py +0 -0
  295. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/glaas_auth.py +0 -0
  296. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/glaas_client.py +0 -0
  297. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/__init__.py +0 -0
  298. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/bootstrap.py +0 -0
  299. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/config/__init__.py +0 -0
  300. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/config/loader.py +0 -0
  301. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/config/raw.py +0 -0
  302. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/config/schema.py +0 -0
  303. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/discovery.py +0 -0
  304. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/download/__init__.py +0 -0
  305. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/download/base.py +0 -0
  306. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/download/gcs.py +0 -0
  307. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/download/get.py +0 -0
  308. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/download/http.py +0 -0
  309. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/download/noop.py +0 -0
  310. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/download/s3.py +0 -0
  311. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/git/__init__.py +0 -0
  312. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/git/base.py +0 -0
  313. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/git/context.py +0 -0
  314. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/git/provider.py +0 -0
  315. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/__init__.py +0 -0
  316. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/auth.py +0 -0
  317. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/client.py +0 -0
  318. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/fragment_streamer.py +0 -0
  319. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/registration/__init__.py +0 -0
  320. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/registration/_artifact_ref.py +0 -0
  321. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/registration/artifact.py +0 -0
  322. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/registration/coordinator.py +0 -0
  323. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/registration/job.py +0 -0
  324. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/registration/session.py +0 -0
  325. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/glaas/transport.py +0 -0
  326. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/registry.py +0 -0
  327. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/resolution.py +0 -0
  328. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/storage/__init__.py +0 -0
  329. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/storage/base.py +0 -0
  330. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/storage/gcs.py +0 -0
  331. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/storage/memory.py +0 -0
  332. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/storage/noop.py +0 -0
  333. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/storage/publish.py +0 -0
  334. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/storage/s3.py +0 -0
  335. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/telemetry/__init__.py +0 -0
  336. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/telemetry/base.py +0 -0
  337. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/integrations/telemetry/wandb.py +0 -0
  338. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/__init__.py +0 -0
  339. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/console.py +0 -0
  340. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/dag_data_builder.py +0 -0
  341. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/dag_renderer.py +0 -0
  342. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/diff_renderer.py +0 -0
  343. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/formatting.py +0 -0
  344. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/null.py +0 -0
  345. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/show_renderer.py +0 -0
  346. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/presenters/spinner.py +0 -0
  347. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/publish_auth.py +0 -0
  348. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/require.py +0 -0
  349. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/scope_config.py +0 -0
  350. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/__init__.py +0 -0
  351. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/_io.py +0 -0
  352. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/capabilities.py +0 -0
  353. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/config.py +0 -0
  354. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/install.py +0 -0
  355. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/payload.py +0 -0
  356. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/queue.py +0 -0
  357. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/stats.py +0 -0
  358. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/telemetry/uploader.py +0 -0
  359. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/__init__.py +0 -0
  360. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/app.py +0 -0
  361. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/data.py +0 -0
  362. {roar_cli-0.3.0/roar → roar_cli-0.3.2/roar/tui/screens}/__init__.py +0 -0
  363. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/screens/config_editor.py +0 -0
  364. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/screens/label_editor.py +0 -0
  365. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/screens/launcher.py +0 -0
  366. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/screens/log.py +0 -0
  367. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/screens/main.py +0 -0
  368. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/screens/search.py +0 -0
  369. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/screens/session_picker.py +0 -0
  370. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/tmux.py +0 -0
  371. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/widgets/__init__.py +0 -0
  372. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/tui/widgets/detail.py +0 -0
  373. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/utils/__init__.py +0 -0
  374. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/utils/cloud.py +0 -0
  375. {roar_cli-0.3.0 → roar_cli-0.3.2}/roar/utils/git_url.py +0 -0
  376. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/Cargo.lock +0 -0
  377. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/Cargo.toml +0 -0
  378. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/artifact-hash-core/Cargo.toml +0 -0
  379. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/artifact-hash-core/src/lib.rs +0 -0
  380. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/artifact-hash-py/Cargo.toml +0 -0
  381. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/artifact-hash-py/src/lib.rs +0 -0
  382. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/tracer-fd/Cargo.toml +0 -0
  383. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/tracer-fd/src/lib.rs +0 -0
  384. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/tracer-runtime/Cargo.toml +0 -0
  385. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/tracer-runtime/src/lib.rs +0 -0
  386. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/tracer-schema/Cargo.toml +0 -0
  387. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/crates/tracer-schema/src/lib.rs +0 -0
  388. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/services/proxy/Cargo.lock +0 -0
  389. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/services/proxy/Cargo.toml +0 -0
  390. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/services/proxy/src/forward.rs +0 -0
  391. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/services/proxy/src/main.rs +0 -0
  392. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/services/proxy/src/s3.rs +0 -0
  393. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/common/Cargo.toml +0 -0
  394. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/common/src/lib.rs +0 -0
  395. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/probe/Cargo.toml +0 -0
  396. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/probe/rust-toolchain.toml +0 -0
  397. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/probe/src/main.rs +0 -0
  398. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/Cargo.toml +0 -0
  399. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/build.rs +0 -0
  400. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/attach.rs +0 -0
  401. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/bin/roard.rs +0 -0
  402. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/client.rs +0 -0
  403. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/daemon.rs +0 -0
  404. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/events.rs +0 -0
  405. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/ipc.rs +0 -0
  406. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/lib.rs +0 -0
  407. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/main.rs +0 -0
  408. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ebpf/userspace/src/state.rs +0 -0
  409. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/Cargo.toml +0 -0
  410. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/build.rs +0 -0
  411. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/src/bin/io_fixture.rs +0 -0
  412. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/src/interpose.c +0 -0
  413. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/src/ipc.rs +0 -0
  414. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/src/lib.rs +0 -0
  415. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/src/main.rs +0 -0
  416. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/tests/comprehensive.rs +0 -0
  417. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/preload/tests/standalone.rs +0 -0
  418. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ptrace/Cargo.toml +0 -0
  419. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ptrace/rustfmt.toml +0 -0
  420. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ptrace/src/arch.rs +0 -0
  421. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ptrace/src/main.rs +0 -0
  422. {roar_cli-0.3.0 → roar_cli-0.3.2}/rust/tracers/ptrace/src/seccomp.rs +0 -0
  423. {roar_cli-0.3.0 → roar_cli-0.3.2}/scripts/sync_packaged_rust_artifacts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roar-cli
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Intended Audience :: Science/Research
@@ -69,7 +69,7 @@ Requires Python 3.10+.
69
69
 
70
70
  > For the full prereqs, platform support matrix, tracer-backend setup,
71
71
  > macOS SIP notes, and sdist build steps, see the canonical
72
- > [Installing roar](https://glaas.ai/docs/roar-guide#installing-roar) docs page.
72
+ > [Installation](https://glaas.ai/docs/installation) docs page.
73
73
  > What's below is a TL;DR.
74
74
 
75
75
  ### Platform Support
@@ -20,7 +20,7 @@ Requires Python 3.10+.
20
20
 
21
21
  > For the full prereqs, platform support matrix, tracer-backend setup,
22
22
  > macOS SIP notes, and sdist build steps, see the canonical
23
- > [Installing roar](https://glaas.ai/docs/roar-guide#installing-roar) docs page.
23
+ > [Installation](https://glaas.ai/docs/installation) docs page.
24
24
  > What's below is a TL;DR.
25
25
 
26
26
  ### Platform Support
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "roar-cli"
7
- version = "0.3.0"
7
+ version = "0.3.2"
8
8
  description = "Reproducibility and provenance tracker for ML training pipelines"
9
9
  authors = [
10
10
  { name="TReqs Team", email="info@treqs.ai" }
@@ -0,0 +1,11 @@
1
+ """roar - Run Observation & Artifact Registration."""
2
+
3
+ from importlib.metadata import PackageNotFoundError
4
+ from importlib.metadata import version as _version
5
+
6
+ try:
7
+ __version__: str = _version("roar-cli")
8
+ except PackageNotFoundError:
9
+ __version__ = "0.0.0+unknown"
10
+
11
+ __all__ = ["__version__"]
@@ -84,10 +84,11 @@ def resolve_canonical_remote(repo_root: Path | str, configured_remote: str | Non
84
84
  if not remotes:
85
85
  raise GitRemoteError(
86
86
  "No git remote configured. `roar register` needs a remote to push "
87
- "roar tags to so teammates can resolve GLaaS links.\n"
87
+ "roar tags to so anyone reading the GLaaS record can resolve them "
88
+ "back to the commit.\n"
88
89
  "Add one: `git remote add origin <url>`.\n"
89
90
  "Or skip the push: `roar config set git.push_tags_on_register never` "
90
- "(local-only — GLaaS links will not resolve for teammates)."
91
+ "(commit links on GLaaS may be broken)."
91
92
  )
92
93
  if len(remotes) > 1:
93
94
  raise GitRemoteError(
@@ -81,7 +81,7 @@ def _create_local_tags(repo_root: Path, commit_to_tag: Iterable[tuple[str, str]]
81
81
  "If the commit is no longer reachable locally (e.g. rebase, "
82
82
  "garbage collection), recover it via `git reflog` before retrying — "
83
83
  "or set `git.push_tags_on_register=never` to register local-only "
84
- "(GLaaS links will not resolve for teammates)."
84
+ "(commit links on GLaaS may be broken)."
85
85
  )
86
86
 
87
87
 
@@ -36,6 +36,7 @@ class RegisterLineageResponse:
36
36
  secrets_redacted: bool = False
37
37
  aborted_by_user: bool = False
38
38
  tag_summary: RegisterTagSummary | None = None
39
+ warnings: list[str] = field(default_factory=list)
39
40
 
40
41
 
41
42
  @dataclass(frozen=True)
@@ -476,10 +476,17 @@ def register_lineage_target(request: RegisterLineageRequest) -> RegisterLineageR
476
476
 
477
477
  # P1-23: push roar tags BEFORE writing the GLaaS record so the
478
478
  # record never references a tag that doesn't yet exist on the
479
- # canonical remote. Fail-closed.
479
+ # canonical remote. Attributed registers fail-closed here.
480
+ #
481
+ # Anonymous registers degrade tag-push failures to warnings: the
482
+ # user explicitly opted into a no-account publish, so requiring
483
+ # git-remote auth (a separate concern from GLaaS) would defeat
484
+ # the whole point. The local tag still gets created; only the
485
+ # push to the canonical remote is skipped on failure.
480
486
  from ...integrations.config import config_get
481
487
  from .register_tag_push import TagPushError, ensure_roar_tags_pushed
482
488
 
489
+ tag_push_warning: str | None = None
483
490
  try:
484
491
  tag_summary = ensure_roar_tags_pushed(
485
492
  repo_root=prepared.git_tag_repo_root or request.cwd,
@@ -493,11 +500,14 @@ def register_lineage_target(request: RegisterLineageRequest) -> RegisterLineageR
493
500
  logger=logger,
494
501
  )
495
502
  except TagPushError as exc:
496
- return RegisterLineageResponse(
497
- success=False,
498
- artifact_hash=collected_lineage.artifact_hash,
499
- error=str(exc),
500
- )
503
+ if not request.anonymous:
504
+ return RegisterLineageResponse(
505
+ success=False,
506
+ artifact_hash=collected_lineage.artifact_hash,
507
+ error=str(exc),
508
+ )
509
+ tag_push_warning = _format_anonymous_tag_push_warning(str(exc))
510
+ tag_summary = None
501
511
 
502
512
  service = RegisterService(
503
513
  glaas_client=runtime.glaas_client,
@@ -514,6 +524,10 @@ def register_lineage_target(request: RegisterLineageRequest) -> RegisterLineageR
514
524
  prepared=prepared,
515
525
  )
516
526
 
527
+ warnings: list[str] = []
528
+ if tag_push_warning:
529
+ warnings.append(tag_push_warning)
530
+
517
531
  return RegisterLineageResponse(
518
532
  success=result.success,
519
533
  session_hash=result.session_hash,
@@ -527,11 +541,37 @@ def register_lineage_target(request: RegisterLineageRequest) -> RegisterLineageR
527
541
  secrets_redacted=result.secrets_redacted,
528
542
  aborted_by_user=result.aborted_by_user,
529
543
  tag_summary=tag_summary,
544
+ warnings=warnings,
530
545
  )
531
546
  except PublishAuthError as exc:
532
547
  return RegisterLineageResponse(success=False, error=str(exc))
533
548
 
534
549
 
550
+ def _format_anonymous_tag_push_warning(tag_push_error: str) -> str:
551
+ """Wrap a tag-push failure as a self-contained user-facing warning.
552
+
553
+ Anonymous register continues past the push failure (GLaaS publish
554
+ succeeds), so the message has to (a) make clear the failure is git
555
+ remote auth, not GLaaS, (b) tell the user GLaaS registration still
556
+ happened, (c) explain why the missing push matters (the GLaaS
557
+ record references a tag that doesn't yet exist on the remote, so
558
+ anyone reading the record can't ``git checkout`` it), and
559
+ (d) point at the real fix (configure git remote auth + push the
560
+ tag). We deliberately do *not* suggest
561
+ ``git.push_tags_on_register=never`` here — that "fix" breaks
562
+ reproducibility for everyone viewing the GLaaS record, not just
563
+ silences a local warning.
564
+ """
565
+ return (
566
+ "roar tag push to git remote failed (git auth, not GLaaS) — "
567
+ "anonymous register continued without pushing the tag.\n"
568
+ " The local tag exists, but viewers of the GLaaS record need it "
569
+ "on the remote to reproduce.\n"
570
+ " Fix git remote auth, then push: `git push <remote> <tag>`.\n"
571
+ f" Verbatim git error: {tag_push_error}"
572
+ )
573
+
574
+
535
575
  def put_artifacts(request: PutRequest) -> PutResponse:
536
576
  """Run the `roar put` application workflow."""
537
577
  if not request.dry_run:
@@ -0,0 +1,123 @@
1
+ """Classify dirty-tree paths into buckets so the start-of-run error
2
+ can recommend the right fix per bucket.
3
+
4
+ Three buckets:
5
+
6
+ * **code** — tracked file with an uncommitted modification (porcelain
7
+ status code starts with ``M`` / ``A`` / ``D`` / ``R`` / ``C`` / ``U``).
8
+ Right fix is ``git add`` + ``git commit``.
9
+ * **roar_output** — untracked path that the local roar DB already
10
+ knows about (artifact ``first_seen_path`` matches). Looks like an
11
+ output of an earlier ``roar run``. Right fix is ``.gitignore`` —
12
+ or commit if the user really wants the file in the repo.
13
+ * **unknown** — untracked, no match in the local DB. Could be a stray
14
+ log, a fresh dataset, anything. Offer both options.
15
+
16
+ We deliberately do *not* hash untracked files to look for content
17
+ matches in the DB. Hashing every untracked file on every blocked run
18
+ isn't worth it just to choose between two near-identical hint blocks
19
+ (``roar_output`` vs ``unknown`` both recommend the same fix — the only
20
+ difference is the framing line).
21
+ """
22
+
23
+ from __future__ import annotations
24
+
25
+ from dataclasses import dataclass, field
26
+ from pathlib import Path
27
+ from typing import Any, Protocol
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class DirtyClassification:
32
+ """Bucketed view of a ``git status --porcelain`` output."""
33
+
34
+ code: list[str] = field(default_factory=list)
35
+ roar_outputs: list[str] = field(default_factory=list)
36
+ unknown: list[str] = field(default_factory=list)
37
+
38
+ @property
39
+ def is_empty(self) -> bool:
40
+ return not (self.code or self.roar_outputs or self.unknown)
41
+
42
+ @property
43
+ def all_code(self) -> bool:
44
+ return bool(self.code) and not self.roar_outputs and not self.unknown
45
+
46
+ @property
47
+ def all_roar_outputs(self) -> bool:
48
+ return bool(self.roar_outputs) and not self.code and not self.unknown
49
+
50
+ @property
51
+ def all_unknown(self) -> bool:
52
+ return bool(self.unknown) and not self.code and not self.roar_outputs
53
+
54
+
55
+ class _ArtifactLookup(Protocol):
56
+ """Minimal protocol the classifier needs from the DB."""
57
+
58
+ def get_by_path(self, path: str) -> Any: ...
59
+
60
+
61
+ def classify_dirty_paths(
62
+ status_output: str,
63
+ repo_root: str | Path,
64
+ artifact_lookup: _ArtifactLookup | None,
65
+ ) -> DirtyClassification:
66
+ """Bucket each path in a porcelain output into code / roar-output / unknown.
67
+
68
+ ``artifact_lookup`` may be ``None`` when no DB context is available
69
+ (very early in a fresh init, for example). In that case the
70
+ classifier never produces ``roar_output`` entries — everything
71
+ untracked falls through to ``unknown``.
72
+ """
73
+ code: list[str] = []
74
+ roar_outputs: list[str] = []
75
+ unknown: list[str] = []
76
+
77
+ repo_path = Path(repo_root)
78
+ for status_code, path in _parse_porcelain(status_output):
79
+ if _is_tracked_modification(status_code):
80
+ code.append(path)
81
+ continue
82
+ if artifact_lookup is not None and _is_known_roar_output(artifact_lookup, repo_path, path):
83
+ roar_outputs.append(path)
84
+ continue
85
+ unknown.append(path)
86
+
87
+ return DirtyClassification(code=code, roar_outputs=roar_outputs, unknown=unknown)
88
+
89
+
90
+ def _parse_porcelain(status_output: str) -> list[tuple[str, str]]:
91
+ """Yield ``(status_code, path)`` pairs from porcelain v1 output.
92
+
93
+ Porcelain v1 format is ``XY path``, where ``X`` and ``Y`` are the
94
+ index/worktree status codes. For renames the line is ``XY old -> new``;
95
+ we keep the new path (that's what the user works with).
96
+ """
97
+ pairs: list[tuple[str, str]] = []
98
+ for line in status_output.splitlines():
99
+ if not line:
100
+ continue
101
+ code = line[:2]
102
+ path = line[3:] if len(line) > 3 else line
103
+ if " -> " in path:
104
+ path = path.split(" -> ", 1)[1]
105
+ path = path.strip().strip('"')
106
+ if path:
107
+ pairs.append((code, path))
108
+ return pairs
109
+
110
+
111
+ def _is_tracked_modification(status_code: str) -> bool:
112
+ """A status code other than ``??`` means git is tracking the path."""
113
+ return status_code.strip() != "??"
114
+
115
+
116
+ def _is_known_roar_output(artifact_lookup: _ArtifactLookup, repo_root: Path, rel_path: str) -> bool:
117
+ """True if the path matches an artifact's recorded ``first_seen_path``."""
118
+ abs_path = str((repo_root / rel_path).resolve())
119
+ try:
120
+ record = artifact_lookup.get_by_path(abs_path)
121
+ except Exception:
122
+ return False
123
+ return bool(record)
@@ -0,0 +1,279 @@
1
+ """Construct the user-facing error message for a dirty git working tree.
2
+
3
+ When ``roar run`` / ``roar build`` detects uncommitted changes, the
4
+ error has to teach (a) *why* roar requires a clean tree, (b) the right
5
+ remediation for what's actually dirty, and (c) handle two common
6
+ fresh-install pitfalls:
7
+
8
+ * The dirty file is roar's own state directory (``.roar/``) — usually a
9
+ fresh ``roar init`` whose ``.gitignore`` change isn't committed yet.
10
+ * The user is running ``roar`` from ``$HOME`` instead of a project dir.
11
+
12
+ The message is a single string raised as ``ValueError(message)``,
13
+ which the CLI surface presents.
14
+
15
+ The path-classifier (``dirty_tree_classify``) splits dirty paths into
16
+ three buckets — code changes, prior-roar outputs (path match in DB),
17
+ and unknown untracked files — so the message can recommend the right
18
+ fix per bucket. When buckets mix, the message segments accordingly.
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import os
24
+ import shlex
25
+ from pathlib import Path
26
+ from typing import Any
27
+
28
+ from .dirty_tree_classify import DirtyClassification, classify_dirty_paths
29
+ from .gitignore_suggest import gitignore_lines
30
+
31
+ DOCS_URL = "https://glaas.ai/docs/why-clean-commits"
32
+ _MAX_LISTED_PATHS = 8
33
+ _MAX_NAMED_FOR_GIT_ADD = 5
34
+
35
+
36
+ def _all_under_roar_dir(paths: list[str]) -> bool:
37
+ if not paths:
38
+ return False
39
+ return all(p == ".roar" or p.startswith(".roar/") for p in paths)
40
+
41
+
42
+ def _is_home_dir(repo_root: str | Path) -> bool:
43
+ home = os.path.expanduser("~")
44
+ if not home:
45
+ return False
46
+ try:
47
+ return Path(repo_root).resolve() == Path(home).resolve()
48
+ except OSError:
49
+ return False
50
+
51
+
52
+ def _format_user_command(verb: str, args: list[str] | None) -> str:
53
+ if not args:
54
+ return f"roar {verb} <your-command>"
55
+ return f"roar {verb} " + " ".join(shlex.quote(a) for a in args)
56
+
57
+
58
+ def _format_git_add(paths: list[str]) -> str:
59
+ if len(paths) <= _MAX_NAMED_FOR_GIT_ADD:
60
+ return "git add " + " ".join(shlex.quote(p) for p in paths)
61
+ return "git add -A"
62
+
63
+
64
+ def _format_capped_list(paths: list[str]) -> list[str]:
65
+ visible = paths[:_MAX_LISTED_PATHS]
66
+ lines = [f" {p}" for p in visible]
67
+ if len(paths) > _MAX_LISTED_PATHS:
68
+ lines.append(f" ... and {len(paths) - _MAX_LISTED_PATHS} more")
69
+ return lines
70
+
71
+
72
+ def format_dirty_tree_error(
73
+ *,
74
+ status_output: str,
75
+ repo_root: str | Path,
76
+ verb: str = "run",
77
+ args: list[str] | None = None,
78
+ artifact_lookup: Any = None,
79
+ ) -> str:
80
+ """Build the user-facing dirty-tree refusal message.
81
+
82
+ ``artifact_lookup`` is an optional object with a ``get_by_path``
83
+ method (typically ``db_ctx.artifacts``). When provided, untracked
84
+ paths that match a recorded artifact are classified as
85
+ ``roar_outputs`` and the message recommends ``.gitignore`` for
86
+ them. When ``None``, every untracked path is treated as unknown
87
+ (the message offers both commit and gitignore).
88
+ """
89
+ user_cmd = _format_user_command(verb, args)
90
+
91
+ if _is_home_dir(repo_root):
92
+ return _format_home_dir_message(user_cmd)
93
+
94
+ classification = classify_dirty_paths(status_output, repo_root, artifact_lookup)
95
+ all_paths = classification.code + classification.roar_outputs + classification.unknown
96
+ if _all_under_roar_dir(all_paths):
97
+ return _format_roar_only_message(user_cmd)
98
+
99
+ if classification.all_code:
100
+ return _format_code_only_message(classification.code, user_cmd)
101
+ if classification.all_roar_outputs:
102
+ return _format_roar_outputs_only_message(classification.roar_outputs, user_cmd)
103
+ if classification.all_unknown:
104
+ return _format_unknown_only_message(classification.unknown, user_cmd)
105
+ return _format_mixed_message(classification, user_cmd)
106
+
107
+
108
+ # ---------------------------------------------------------------------------
109
+ # Variants
110
+ # ---------------------------------------------------------------------------
111
+
112
+
113
+ def _format_code_only_message(paths: list[str], user_cmd: str) -> str:
114
+ lines = [
115
+ "Run blocked: working tree is dirty.",
116
+ "",
117
+ "roar tags every run with the current git commit SHA so the lineage",
118
+ 'record answers "what code produced this artifact?" Uncommitted',
119
+ "changes mean we can't record that honestly — same reason you wouldn't",
120
+ "deploy uncommitted code to production.",
121
+ "",
122
+ ]
123
+ if len(paths) > _MAX_NAMED_FOR_GIT_ADD:
124
+ lines.append("Dirty files:")
125
+ lines.extend(_format_capped_list(paths))
126
+ lines.append("")
127
+ lines.extend(
128
+ [
129
+ "To proceed:",
130
+ f" {_format_git_add(paths)}",
131
+ ' git commit -m "<describe your changes>"',
132
+ f" {user_cmd}",
133
+ "",
134
+ f"Why: {DOCS_URL}",
135
+ ]
136
+ )
137
+ return "\n".join(lines)
138
+
139
+
140
+ def _format_roar_outputs_only_message(paths: list[str], user_cmd: str) -> str:
141
+ lines = [
142
+ "Run blocked: untracked outputs from earlier roar run(s).",
143
+ "",
144
+ "These match artifacts in the local roar DB — they look like",
145
+ "products of past runs, not source code roar should pin commits to.",
146
+ "",
147
+ "Untracked outputs:",
148
+ ]
149
+ lines.extend(_format_capped_list(paths))
150
+ lines.extend(
151
+ [
152
+ "",
153
+ "Fix — gitignore them:",
154
+ ]
155
+ )
156
+ lines.extend(f" {sug}" for sug in gitignore_lines(paths))
157
+ lines.extend(
158
+ [
159
+ " git add .gitignore && git commit -m 'ignore roar outputs'",
160
+ f" {user_cmd}",
161
+ "",
162
+ "(Or `git add` + `git commit` them if they belong in the repo.)",
163
+ "",
164
+ f"Why: {DOCS_URL}",
165
+ ]
166
+ )
167
+ return "\n".join(lines)
168
+
169
+
170
+ def _format_unknown_only_message(paths: list[str], user_cmd: str) -> str:
171
+ lines = [
172
+ "Run blocked: untracked files in the working tree.",
173
+ "",
174
+ "roar tags every run with the current git commit SHA. Untracked",
175
+ "files mean the commit alone can't explain what was on disk at",
176
+ "run time.",
177
+ "",
178
+ "Untracked files:",
179
+ ]
180
+ lines.extend(_format_capped_list(paths))
181
+ lines.extend(
182
+ [
183
+ "",
184
+ "If they're outputs you want kept around but not in the repo, gitignore them:",
185
+ ]
186
+ )
187
+ lines.extend(f" {sug}" for sug in gitignore_lines(paths))
188
+ lines.extend(
189
+ [
190
+ " git add .gitignore && git commit -m 'ignore outputs'",
191
+ "",
192
+ "If they belong in the repo, commit them:",
193
+ f" {_format_git_add(paths)}",
194
+ ' git commit -m "<describe your changes>"',
195
+ "",
196
+ f"Then retry: {user_cmd}",
197
+ "",
198
+ f"Why: {DOCS_URL}",
199
+ ]
200
+ )
201
+ return "\n".join(lines)
202
+
203
+
204
+ def _format_mixed_message(classification: DirtyClassification, user_cmd: str) -> str:
205
+ lines = [
206
+ "Run blocked: working tree is dirty.",
207
+ "",
208
+ ]
209
+
210
+ if classification.code:
211
+ lines.append("Code changes:")
212
+ lines.extend(_format_capped_list(classification.code))
213
+ lines.append("")
214
+ lines.append("Fix:")
215
+ lines.append(f" {_format_git_add(classification.code)}")
216
+ lines.append(' git commit -m "<describe your changes>"')
217
+ lines.append("")
218
+
219
+ if classification.roar_outputs:
220
+ lines.append("Roar outputs (untracked):")
221
+ lines.extend(_format_capped_list(classification.roar_outputs))
222
+ lines.append("")
223
+ lines.append("Fix — gitignore them:")
224
+ lines.extend(f" {sug}" for sug in gitignore_lines(classification.roar_outputs))
225
+ lines.append(" git add .gitignore && git commit -m 'ignore roar outputs'")
226
+ lines.append("")
227
+
228
+ if classification.unknown:
229
+ lines.append("Other untracked files:")
230
+ lines.extend(_format_capped_list(classification.unknown))
231
+ lines.append("")
232
+ lines.append("Fix — gitignore or commit:")
233
+ lines.extend(f" {sug}" for sug in gitignore_lines(classification.unknown))
234
+ lines.append(" git add .gitignore && git commit -m 'ignore outputs'")
235
+ lines.append(f" (or `{_format_git_add(classification.unknown)}` + commit)")
236
+ lines.append("")
237
+
238
+ lines.append(f"Then retry: {user_cmd}")
239
+ lines.append("")
240
+ lines.append(f"Why: {DOCS_URL}")
241
+ return "\n".join(lines)
242
+
243
+
244
+ def _format_roar_only_message(user_cmd: str) -> str:
245
+ return "\n".join(
246
+ [
247
+ "Run blocked: working tree is dirty.",
248
+ "",
249
+ "The only dirty path is roar's own state directory (.roar/).",
250
+ "It should be in .gitignore so it doesn't trip future runs.",
251
+ "",
252
+ "Quickest fix:",
253
+ " echo '.roar/' >> .gitignore",
254
+ " git add .gitignore && git commit -m 'ignore .roar/'",
255
+ f" {user_cmd}",
256
+ "",
257
+ "Or re-run `roar init` — it will set this up for you.",
258
+ "",
259
+ f"Why: {DOCS_URL}",
260
+ ]
261
+ )
262
+
263
+
264
+ def _format_home_dir_message(user_cmd: str) -> str:
265
+ return "\n".join(
266
+ [
267
+ "Run blocked: you're running roar from your home directory.",
268
+ "",
269
+ "roar tags every run with the current git commit SHA. Your home",
270
+ "directory is rarely under clean version control, and is almost",
271
+ "never the right place to track ML pipeline lineage.",
272
+ "",
273
+ "Switch to your project directory and run there:",
274
+ " cd <your project>",
275
+ f" {user_cmd}",
276
+ "",
277
+ f"Why: {DOCS_URL}",
278
+ ]
279
+ )