roar-cli 0.4.1__tar.gz → 0.4.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {roar_cli-0.4.1 → roar_cli-0.4.3}/PKG-INFO +1 -1
- {roar_cli-0.4.1 → roar_cli-0.4.3}/pyproject.toml +2 -1
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/put_execution.py +118 -9
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/registration_package.py +34 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/service.py +12 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/reproduce/requests.py +5 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/reproduce/service.py +127 -1
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/execution.py +28 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/requests.py +1 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/service.py +8 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/system_labels.py +4 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/tags.py +12 -4
- roar_cli-0.4.3/roar/backends/k8s/attach.py +402 -0
- roar_cli-0.4.3/roar/backends/k8s/bundles.py +135 -0
- roar_cli-0.4.3/roar/backends/k8s/config.py +194 -0
- roar_cli-0.4.3/roar/backends/k8s/fragment_reconstituter.py +261 -0
- roar_cli-0.4.3/roar/backends/k8s/host_execution.py +196 -0
- roar_cli-0.4.3/roar/backends/k8s/lineage.py +144 -0
- roar_cli-0.4.3/roar/backends/k8s/manifest.py +756 -0
- roar_cli-0.4.3/roar/backends/k8s/mount_map.py +182 -0
- roar_cli-0.4.3/roar/backends/k8s/object_io.py +220 -0
- roar_cli-0.4.3/roar/backends/k8s/plugin.py +114 -0
- roar_cli-0.4.3/roar/backends/k8s/pod_entry.py +366 -0
- roar_cli-0.4.3/roar/backends/k8s/rayjob.py +230 -0
- roar_cli-0.4.3/roar/backends/k8s/secret_cleanup.py +105 -0
- roar_cli-0.4.3/roar/backends/k8s/submit.py +440 -0
- roar_cli-0.4.3/roar/backends/k8s/webhook.py +313 -0
- roar_cli-0.4.3/roar/backends/k8s/workload_wait.py +133 -0
- roar_cli-0.4.3/roar/backends/osmo/export.py +48 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/fragment_reconstituter.py +22 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/roar_worker.py +86 -33
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/runtime_hooks.py +67 -3
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/submit.py +2 -1
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/command_registry.py +3 -0
- roar_cli-0.4.3/roar/cli/commands/k8s.py +226 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/register.py +43 -13
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/reproduce.py +16 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/run.py +16 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/context.py +15 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/provenance.py +4 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/run.py +3 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/services/job_recording.py +7 -3
- {roar_cli-0.4.1/roar/backends/osmo → roar_cli-0.4.3/roar/execution/fragments}/export.py +32 -13
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/fragments/lineage.py +12 -6
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/fragments/models.py +18 -0
- roar_cli-0.4.3/roar/execution/fragments/sessions.py +83 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/fragments/transport.py +19 -2
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/framework/registry.py +63 -2
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/assembler.py +5 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/runtime_collector.py +74 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/recording/job_recording.py +1 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/coordinator.py +4 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/inject/sitecustomize.py +11 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/worker_bootstrap.py +22 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/__init__.py +1 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/client.py +5 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/fragment_streamer.py +66 -3
- roar_cli-0.4.3/roar/integrations/wandb_trackio.py +233 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/show_renderer.py +8 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/publish_auth.py +14 -1
- roar_cli-0.4.3/roar/tui/screens/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/services/proxy/src/main.rs +12 -0
- roar_cli-0.4.1/roar/execution/fragments/sessions.py +0 -38
- {roar_cli-0.4.1 → roar_cli-0.4.3}/LICENSE +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/README.md +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/__main__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/analyzers/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/analyzers/base.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/analyzers/experiment_trackers.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/composite/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/composite/canonical.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/composite/detect.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/composite/qualifying.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/get/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/get/requests.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/get/results.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/get/service.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/get/transfer.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/git.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/label_rendering.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/labels.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/lookup/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/lookup/models.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/lookup/policy.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/lookup/refs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/lookup/remote_artifacts.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/lookup/runner.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/anchor_attribution.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/blake3_upgrade.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/collection.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/composite_builder.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/composites.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/datasets.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/form_composites.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/git_remote.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/job_links.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/job_preparation.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/lineage.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/lineage_composite_formation.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/lineage_composites.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/metadata.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/put_composites.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/put_preparation.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/register_execution.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/register_preparation.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/register_preview_jobs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/register_tag_push.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/registration.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/remote_job_uids.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/remote_registry.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/requests.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/results.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/runtime.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/secrets.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/session.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/source_resolution.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/targets.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/publish/view_edges.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/dag.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/db_status.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/diff.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/diff_engine.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/diff_graph.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/diff_refs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/git_readiness.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/inputs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/label.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/lineage.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/log.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/requests.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/results.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/show.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/status.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/query/tag.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/reproduce/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/reproduce/environment.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/reproduce/lookup.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/reproduce/results.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/reproducibility/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/reproducibility/report.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/dag_references.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/dirty_tree_classify.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/dirty_tree_error.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/gitignore_suggest.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/output_followup.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/run/verbosity.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/workflow/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/workflow/requests.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/workflow/results.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/application/workflow/service.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/auth_store.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/__init__.py +0 -0
- {roar_cli-0.4.1/roar/tui/screens → roar_cli-0.4.3/roar/backends/k8s}/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/local/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/local/plugin.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/osmo/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/osmo/config.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/osmo/host_execution.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/osmo/lineage.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/osmo/plugin.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/osmo/runtime_bundle.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/osmo/submit.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/osmo/workflow.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/_agent_names.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/collector.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/config.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/constants.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/env_contract.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/fragment.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/node_agent.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/plugin.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/proxy_fragments.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/s3_key_paths.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/backends/ray/submit_context.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/_format.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/_tag_kinds.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/auth.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/build.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/config.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/dag.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/db.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/diff.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/env.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/export_registration_package.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/filter.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/get.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/init.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/init_agents.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/inputs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/label.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/lineage.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/log.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/login.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/logout.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/osmo.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/pop.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/projects.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/proxy.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/put.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/reset.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/scope.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/session.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/show.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/status.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/tag.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/telemetry.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/tracer.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/tui.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/whoami.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/commands/workflow.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/decorators.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/publish_intent.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/templates/agents/SKILL.md.tmpl +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/cli/templates/agents/agents_section.md.tmpl +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/bootstrap.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/canonical_session.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/digests.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/dto/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/dto/registration.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/exceptions.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/config.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/lineage.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/logger.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/presenter.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/provenance.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/registration.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/repositories.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/reproduction.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/run.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/services.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/telemetry.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/interfaces/vcs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/label_constants.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/label_origins.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/logging.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/artifact.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/base.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/dag.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/dataset_identifier.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/glaas.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/job.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/lineage.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/session.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/telemetry.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/models/vcs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/operation_metadata.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/session_hash.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/step_name.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/tracer_modes.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/core/validation.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/context.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/engine.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/hashing/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/hashing/backend.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/hashing/blake3.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/models.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/query_context.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/repositories/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/repositories/artifact.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/repositories/collection.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/repositories/composite.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/repositories/hash_cache.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/repositories/job.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/repositories/label.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/repositories/session.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/schema.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/services/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/services/hashing.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/services/lineage.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/services/session.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/db/step_priority.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/cluster/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/cluster/bridge.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/cluster/proxy.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/cluster/proxy_config.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/fragments/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/fragments/reconstitution.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/framework/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/framework/contract.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/framework/planning.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/framework/runtime_imports.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/build_pip_collector.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/build_tool_collector.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/data_loader.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/file_filter.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/package_collector.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/process_summarizer.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/provenance/service.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/recording/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/recording/dataset_identifier.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/recording/dataset_metadata.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/recording/dataset_profile.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/reproduction/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/reproduction/environment_setup.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/reproduction/installers.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/reproduction/pipeline_executor.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/reproduction/pipeline_metadata.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/abi_probe.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/active_runs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/backup.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/driver_entrypoint.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/errors.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/host_execution.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/inject/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/inject/support.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/inject/tracker.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/lazy_install.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/proxy_resource.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/resources.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/signal_handler.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/tracer.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/tracer_backends.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/execution/runtime/tracer_banner.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/filters/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/filters/files.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/filters/omit.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/glaas_auth.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/glaas_client.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/bootstrap.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/config/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/config/access.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/config/loader.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/config/raw.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/config/schema.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/discovery.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/download/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/download/base.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/download/gcs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/download/get.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/download/hf.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/download/http.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/download/noop.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/download/s3.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/git/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/git/base.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/git/context.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/git/provider.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/auth.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/registration/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/registration/_artifact_ref.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/registration/artifact.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/registration/coordinator.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/registration/job.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/registration/session.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/glaas/transport.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/registry.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/resolution.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/storage/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/storage/base.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/storage/gcs.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/storage/hf.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/storage/memory.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/storage/noop.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/storage/publish.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/storage/s3.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/telemetry/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/telemetry/base.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/integrations/telemetry/wandb.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/console.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/dag_data_builder.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/dag_renderer.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/diff_renderer.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/formatting.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/null.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/run_report.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/spinner.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/presenters/terminal.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/require.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/scope_config.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/_io.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/capabilities.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/config.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/hooks.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/install.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/paths.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/payload.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/queue.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/stats.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/telemetry/uploader.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/app.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/data.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/screens/config_editor.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/screens/label_editor.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/screens/launcher.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/screens/log.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/screens/main.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/screens/search.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/screens/session_picker.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/tmux.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/widgets/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/tui/widgets/detail.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/utils/__init__.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/utils/cloud.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/utils/git_url.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/roar/version_check.py +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/Cargo.lock +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/artifact-hash-core/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/artifact-hash-core/src/lib.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/artifact-hash-py/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/artifact-hash-py/src/lib.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/tracer-fd/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/tracer-fd/src/lib.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/tracer-runtime/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/tracer-runtime/src/lib.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/tracer-schema/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/crates/tracer-schema/src/lib.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/services/proxy/Cargo.lock +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/services/proxy/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/services/proxy/src/forward.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/services/proxy/src/s3.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/common/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/common/src/lib.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/probe/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/probe/rust-toolchain.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/probe/src/main.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/build.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/attach.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/bin/roard.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/client.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/daemon.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/events.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/ipc.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/lib.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/main.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ebpf/userspace/src/state.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/build.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/src/bin/io_fixture.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/src/interpose.c +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/src/ipc.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/src/lib.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/src/main.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/tests/comprehensive.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/preload/tests/standalone.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ptrace/Cargo.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ptrace/rustfmt.toml +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ptrace/src/arch.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ptrace/src/main.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/rust/tracers/ptrace/src/seccomp.rs +0 -0
- {roar_cli-0.4.1 → roar_cli-0.4.3}/scripts/sync_packaged_rust_artifacts.py +0 -0
|
@@ -5,7 +5,7 @@ build-backend = "maturin"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "roar-cli"
|
|
8
|
-
version = "0.4.
|
|
8
|
+
version = "0.4.3"
|
|
9
9
|
description = "Reproducibility and provenance tracker for ML training pipelines"
|
|
10
10
|
authors = [
|
|
11
11
|
{ name="TReqs Team", email="info@treqs.ai" }
|
|
@@ -124,6 +124,7 @@ markers = [
|
|
|
124
124
|
"diagnostic: Opt-in diagnostics or aspirational performance budgets outside the default gate",
|
|
125
125
|
"large_pipeline: Stress-style pipeline coverage with larger DAG fixtures",
|
|
126
126
|
"osmo_e2e: OSMO end-to-end tests requiring a Docker Compose managed KIND harness",
|
|
127
|
+
"k8s_e2e: Kubernetes end-to-end tests requiring the KIND harness (tests/backends/k8s)",
|
|
127
128
|
"ray_e2e: Ray end-to-end tests requiring a running Docker cluster",
|
|
128
129
|
"ray_contract: User-facing Ray contract tests using `roar run ray job submit ...`",
|
|
129
130
|
"ray_diagnostic: Diagnostic Ray tests that intentionally inspect internal runtime details",
|
|
@@ -9,6 +9,7 @@ roar put ALWAYS registers lineage with GLaaS. This is not optional.
|
|
|
9
9
|
|
|
10
10
|
from __future__ import annotations
|
|
11
11
|
|
|
12
|
+
import shlex
|
|
12
13
|
import time
|
|
13
14
|
from dataclasses import dataclass, field
|
|
14
15
|
from pathlib import Path
|
|
@@ -33,6 +34,7 @@ from ...application.publish.remote_job_uids import (
|
|
|
33
34
|
from ...application.publish.session import build_staged_lineage_counts
|
|
34
35
|
from ...application.system_labels import refresh_job_system_labels
|
|
35
36
|
from ...core.interfaces.registration import GitContext
|
|
37
|
+
from ...core.label_origins import LABEL_ORIGIN_SYSTEM
|
|
36
38
|
from ...core.logging import get_logger
|
|
37
39
|
from ...db.context import DatabaseContext
|
|
38
40
|
from ...db.hashing import hash_files_blake3
|
|
@@ -52,6 +54,47 @@ from .put_composites import (
|
|
|
52
54
|
from .results import PutCompositeRegistration, PutDryRunItem, PutUploadedFile
|
|
53
55
|
|
|
54
56
|
|
|
57
|
+
def build_put_command(
|
|
58
|
+
sources: list[str],
|
|
59
|
+
destination: str | None,
|
|
60
|
+
*,
|
|
61
|
+
message: str,
|
|
62
|
+
public: bool = True,
|
|
63
|
+
anonymous: bool = False,
|
|
64
|
+
no_tag: bool = False,
|
|
65
|
+
as_dataset: bool = False,
|
|
66
|
+
step_name: str | None = None,
|
|
67
|
+
) -> str:
|
|
68
|
+
"""Reconstruct a faithful ``roar put`` command string for the job record.
|
|
69
|
+
|
|
70
|
+
The recorded command drives ``roar reproduce``, so it must include the
|
|
71
|
+
destination and every provenance-relevant flag — not just the sources and
|
|
72
|
+
message. Interaction/mode flags (``--yes``, ``--dry-run``) are intentionally
|
|
73
|
+
omitted: they control confirmation/preview, not the published result.
|
|
74
|
+
"""
|
|
75
|
+
parts = ["roar", "put"]
|
|
76
|
+
if sources:
|
|
77
|
+
parts.extend(shlex.quote(s) for s in sources)
|
|
78
|
+
else:
|
|
79
|
+
parts.append("(session outputs)")
|
|
80
|
+
if destination:
|
|
81
|
+
parts.append(shlex.quote(destination))
|
|
82
|
+
if anonymous:
|
|
83
|
+
parts.append("--anonymous")
|
|
84
|
+
elif public is False:
|
|
85
|
+
parts.append("--private")
|
|
86
|
+
elif public:
|
|
87
|
+
parts.append("--public")
|
|
88
|
+
if no_tag:
|
|
89
|
+
parts.append("--no-tag")
|
|
90
|
+
if as_dataset:
|
|
91
|
+
parts.append("--as-dataset")
|
|
92
|
+
if step_name:
|
|
93
|
+
parts.extend(["--step-name", shlex.quote(step_name)])
|
|
94
|
+
parts.extend(["-m", shlex.quote(message)])
|
|
95
|
+
return " ".join(parts)
|
|
96
|
+
|
|
97
|
+
|
|
55
98
|
def _upload_progress_message(done: int, total: int, uploaded_bytes: int) -> str:
|
|
56
99
|
"""Status line for the upload spinner, e.g. ``Uploading 12/100 files · 1.10 GB``."""
|
|
57
100
|
return f"Uploading {done}/{total} files · {uploaded_bytes / 1e9:.2f} GB"
|
|
@@ -145,6 +188,7 @@ class PutService:
|
|
|
145
188
|
git_commit: str | None = None,
|
|
146
189
|
git_tag: str | None = None,
|
|
147
190
|
declared: bool = False,
|
|
191
|
+
command: str | None = None,
|
|
148
192
|
) -> PutResult:
|
|
149
193
|
"""
|
|
150
194
|
Execute a put operation.
|
|
@@ -266,6 +310,13 @@ class PutService:
|
|
|
266
310
|
artifact_hashes = [u.hash for u in uploads]
|
|
267
311
|
artifacts_info = [(u.artifact_id, u.local_path) for u in uploads]
|
|
268
312
|
|
|
313
|
+
# Record each uploaded artifact's distribution URL as a reserved system
|
|
314
|
+
# label, scoped to this publication, so GLaaS can surface it as the
|
|
315
|
+
# AI-BOM downloadLocation (see _set_publish_distribution_labels).
|
|
316
|
+
self._set_publish_distribution_labels(
|
|
317
|
+
uploads, normalize_registration_source_type(destination_type)
|
|
318
|
+
)
|
|
319
|
+
|
|
269
320
|
self._logger.debug(
|
|
270
321
|
"Upload complete: %d file(s), collecting lineage for hashes: %s",
|
|
271
322
|
len(uploaded_files),
|
|
@@ -294,6 +345,7 @@ class PutService:
|
|
|
294
345
|
git_context=git_context,
|
|
295
346
|
sources=sources,
|
|
296
347
|
message=message,
|
|
348
|
+
command=command,
|
|
297
349
|
uploads=uploads,
|
|
298
350
|
uploaded_files=uploaded_files,
|
|
299
351
|
artifacts_info=artifacts_info,
|
|
@@ -416,9 +468,10 @@ class PutService:
|
|
|
416
468
|
for item in composite_registrations
|
|
417
469
|
]
|
|
418
470
|
|
|
419
|
-
# Build command string
|
|
420
|
-
|
|
421
|
-
command
|
|
471
|
+
# Build command string. Prefer the faithful command (destination + flags)
|
|
472
|
+
# supplied by the caller; fall back to a destination-aware reconstruction.
|
|
473
|
+
if command is None:
|
|
474
|
+
command = build_put_command(sources, self._destination, message=message)
|
|
422
475
|
|
|
423
476
|
# Build metadata
|
|
424
477
|
metadata_json = build_put_operation_metadata_json(
|
|
@@ -493,6 +546,7 @@ class PutService:
|
|
|
493
546
|
job_uid=job_uid,
|
|
494
547
|
remote_job_uid=job_uid,
|
|
495
548
|
registration_errors=registration_result.errors,
|
|
549
|
+
uploads=uploads,
|
|
496
550
|
)
|
|
497
551
|
|
|
498
552
|
registration_error = (
|
|
@@ -551,6 +605,7 @@ class PutService:
|
|
|
551
605
|
git_context: GitContext,
|
|
552
606
|
sources: list[str],
|
|
553
607
|
message: str,
|
|
608
|
+
command: str | None = None,
|
|
554
609
|
uploads: list[_UploadedArtifact],
|
|
555
610
|
uploaded_files: list[PutUploadedFile],
|
|
556
611
|
artifacts_info: list[tuple[str, str]],
|
|
@@ -571,8 +626,8 @@ class PutService:
|
|
|
571
626
|
registration_errors: list[str] = []
|
|
572
627
|
lineage_composite_registrations: list[dict[str, Any]] = []
|
|
573
628
|
composite_registrations: list[dict[str, Any]] = []
|
|
574
|
-
|
|
575
|
-
|
|
629
|
+
if command is None:
|
|
630
|
+
command = build_put_command(sources, self._destination, message=message)
|
|
576
631
|
source_type = normalize_registration_source_type(destination_type)
|
|
577
632
|
|
|
578
633
|
provisional_metadata_json = build_put_operation_metadata_json(
|
|
@@ -764,6 +819,7 @@ class PutService:
|
|
|
764
819
|
job_uid=job_uid,
|
|
765
820
|
remote_job_uid=remote_put_job_uid,
|
|
766
821
|
registration_errors=registration_errors,
|
|
822
|
+
uploads=uploads,
|
|
767
823
|
)
|
|
768
824
|
|
|
769
825
|
composite_result_items = [
|
|
@@ -912,8 +968,12 @@ class PutService:
|
|
|
912
968
|
"size": size,
|
|
913
969
|
"source_type": source_type,
|
|
914
970
|
}
|
|
915
|
-
|
|
916
|
-
|
|
971
|
+
# Deliberately do NOT record the upload destination as the artifact's
|
|
972
|
+
# global ``source_url`` here. That row is content-addressed and shared
|
|
973
|
+
# across orgs, so a per-publication URL would leak between tenants.
|
|
974
|
+
# The download location is published instead as a session-scoped
|
|
975
|
+
# ``roar.distribution.url`` label (see _set_publish_distribution_labels),
|
|
976
|
+
# which both the registration-session and this legacy inline path emit.
|
|
917
977
|
|
|
918
978
|
payloads.append(entry)
|
|
919
979
|
|
|
@@ -994,6 +1054,48 @@ class PutService:
|
|
|
994
1054
|
return False
|
|
995
1055
|
return True
|
|
996
1056
|
|
|
1057
|
+
def _set_publish_distribution_labels(
|
|
1058
|
+
self,
|
|
1059
|
+
uploads: list[_UploadedArtifact],
|
|
1060
|
+
source_type: str | None,
|
|
1061
|
+
) -> None:
|
|
1062
|
+
"""Record each uploaded artifact's distribution URL as a reserved system
|
|
1063
|
+
label (``roar.distribution.url``), scoped to this publication.
|
|
1064
|
+
|
|
1065
|
+
GLaaS reads this as the artifact's AI-BOM ``downloadLocation``. Because
|
|
1066
|
+
the label lives on the ``(artifact, session)`` scope rather than the
|
|
1067
|
+
global content-addressed artifact row, two orgs publishing identical
|
|
1068
|
+
bytes each carry their own download location — no cross-tenant bleed.
|
|
1069
|
+
Gated on a recognized remote ``source_type`` so we never assert a
|
|
1070
|
+
distribution URL for a non-remote destination (e.g. ``memory://``).
|
|
1071
|
+
"""
|
|
1072
|
+
if not source_type:
|
|
1073
|
+
return
|
|
1074
|
+
labels_repo = getattr(self._db, "labels", None)
|
|
1075
|
+
if labels_repo is None:
|
|
1076
|
+
return
|
|
1077
|
+
for uploaded in uploads:
|
|
1078
|
+
if not uploaded.remote_url or not uploaded.artifact_id:
|
|
1079
|
+
continue
|
|
1080
|
+
current = labels_repo.get_current("artifact", artifact_id=uploaded.artifact_id)
|
|
1081
|
+
metadata = current.get("metadata") if isinstance(current, dict) else None
|
|
1082
|
+
metadata = dict(metadata) if isinstance(metadata, dict) else {}
|
|
1083
|
+
roar_ns = metadata.get("roar")
|
|
1084
|
+
roar_ns = dict(roar_ns) if isinstance(roar_ns, dict) else {}
|
|
1085
|
+
distribution = roar_ns.get("distribution")
|
|
1086
|
+
distribution = dict(distribution) if isinstance(distribution, dict) else {}
|
|
1087
|
+
if distribution.get("url") == uploaded.remote_url:
|
|
1088
|
+
continue # already recorded — avoid a redundant label version
|
|
1089
|
+
distribution["url"] = uploaded.remote_url
|
|
1090
|
+
roar_ns["distribution"] = distribution
|
|
1091
|
+
metadata["roar"] = roar_ns
|
|
1092
|
+
labels_repo.create_version(
|
|
1093
|
+
"artifact",
|
|
1094
|
+
metadata,
|
|
1095
|
+
artifact_id=uploaded.artifact_id,
|
|
1096
|
+
write_origin=LABEL_ORIGIN_SYSTEM,
|
|
1097
|
+
)
|
|
1098
|
+
|
|
997
1099
|
def _sync_put_job_labels_with_glaas(
|
|
998
1100
|
self,
|
|
999
1101
|
*,
|
|
@@ -1003,15 +1105,22 @@ class PutService:
|
|
|
1003
1105
|
job_uid: str,
|
|
1004
1106
|
remote_job_uid: str,
|
|
1005
1107
|
registration_errors: list[str],
|
|
1108
|
+
uploads: list[_UploadedArtifact] | None = None,
|
|
1006
1109
|
) -> None:
|
|
1007
|
-
"""Sync the local current label document for the publish-time put job
|
|
1110
|
+
"""Sync the local current label document for the publish-time put job
|
|
1111
|
+
and its published artifacts (carrying ``roar.distribution.url``)."""
|
|
1112
|
+
artifacts = (
|
|
1113
|
+
[{"id": u.artifact_id, "hash": u.hash} for u in uploads if u.artifact_id and u.hash]
|
|
1114
|
+
if uploads
|
|
1115
|
+
else []
|
|
1116
|
+
)
|
|
1008
1117
|
sync_publish_labels(
|
|
1009
1118
|
glaas_client=glaas_client,
|
|
1010
1119
|
db_ctx=self._db,
|
|
1011
1120
|
session_id=None,
|
|
1012
1121
|
session_hash=session_hash,
|
|
1013
1122
|
jobs=[{"id": job_id, "job_uid": job_uid, "remote_job_uid": remote_job_uid}],
|
|
1014
|
-
artifacts=
|
|
1123
|
+
artifacts=artifacts,
|
|
1015
1124
|
errors=registration_errors,
|
|
1016
1125
|
)
|
|
1017
1126
|
|
|
@@ -206,6 +206,8 @@ def build_registration_package(
|
|
|
206
206
|
if composites:
|
|
207
207
|
package["composites"] = composites
|
|
208
208
|
|
|
209
|
+
if labels:
|
|
210
|
+
labels = _drop_labels_for_absent_jobs(labels, job_records)
|
|
209
211
|
if labels:
|
|
210
212
|
filtered_labels, label_detections = _filter_label_secrets(labels, omit_filter)
|
|
211
213
|
package["labels"] = filtered_labels
|
|
@@ -292,6 +294,38 @@ def _apply_redaction(
|
|
|
292
294
|
)
|
|
293
295
|
|
|
294
296
|
|
|
297
|
+
def _drop_labels_for_absent_jobs(
|
|
298
|
+
labels: list[dict[str, Any]],
|
|
299
|
+
job_records: list[dict[str, Any]],
|
|
300
|
+
) -> list[dict[str, Any]]:
|
|
301
|
+
"""Drop job-scoped labels whose target job is not in the package.
|
|
302
|
+
|
|
303
|
+
Labels are collected from the raw lineage, but the package's jobs are
|
|
304
|
+
noise-filtered by ``normalize_jobs_for_registration``. A job label left
|
|
305
|
+
pointing at a dropped job makes the package internally inconsistent — GLaaS
|
|
306
|
+
rejects it on publish with "Package label references a job not in the
|
|
307
|
+
package". The job label's target reaches the publish side through the job
|
|
308
|
+
record's ``job_uid`` (GLaaS's ``sourceUid``), so match on that. Non-job
|
|
309
|
+
labels (dag, artifact) are unaffected.
|
|
310
|
+
"""
|
|
311
|
+
package_job_uids = {str(job.get("job_uid")) for job in job_records if job.get("job_uid")}
|
|
312
|
+
kept: list[dict[str, Any]] = []
|
|
313
|
+
dropped = 0
|
|
314
|
+
for label in labels:
|
|
315
|
+
if str(label.get("entity_type")) == "job":
|
|
316
|
+
job_uid = label.get("job_uid")
|
|
317
|
+
if not isinstance(job_uid, str) or job_uid not in package_job_uids:
|
|
318
|
+
dropped += 1
|
|
319
|
+
continue
|
|
320
|
+
kept.append(label)
|
|
321
|
+
if dropped:
|
|
322
|
+
get_logger().debug(
|
|
323
|
+
"Dropped %d job label(s) referencing jobs not in the registration package",
|
|
324
|
+
dropped,
|
|
325
|
+
)
|
|
326
|
+
return kept
|
|
327
|
+
|
|
328
|
+
|
|
295
329
|
def _filter_label_secrets(
|
|
296
330
|
labels: list[dict[str, Any]],
|
|
297
331
|
omit_filter: OmitFilter | None,
|
|
@@ -894,6 +894,8 @@ def put_artifacts(request: PutRequest) -> PutResponse:
|
|
|
894
894
|
)
|
|
895
895
|
put_commit_on_remote = is_shareable_remote(prepared.git_context.repo)
|
|
896
896
|
|
|
897
|
+
from .put_execution import build_put_command
|
|
898
|
+
|
|
897
899
|
result = service.put_prepared(
|
|
898
900
|
prepared=prepared,
|
|
899
901
|
sources=request.sources,
|
|
@@ -902,6 +904,16 @@ def put_artifacts(request: PutRequest) -> PutResponse:
|
|
|
902
904
|
git_commit=git_commit,
|
|
903
905
|
git_tag=expected_tag,
|
|
904
906
|
declared=request.as_dataset,
|
|
907
|
+
command=build_put_command(
|
|
908
|
+
request.sources,
|
|
909
|
+
request.destination,
|
|
910
|
+
message=request.message,
|
|
911
|
+
public=request.public,
|
|
912
|
+
anonymous=request.anonymous,
|
|
913
|
+
no_tag=request.no_tag,
|
|
914
|
+
as_dataset=request.as_dataset,
|
|
915
|
+
step_name=request.step_name,
|
|
916
|
+
),
|
|
905
917
|
)
|
|
906
918
|
|
|
907
919
|
# Apply step name label if provided.
|
|
@@ -20,3 +20,8 @@ class ReproduceRequest:
|
|
|
20
20
|
package_sync: bool = False
|
|
21
21
|
list_requirements: bool = False
|
|
22
22
|
out_path: str | None = None
|
|
23
|
+
# Skip publish (`roar put`) steps — for third-party reproduction that
|
|
24
|
+
# rebuilds the artifact without re-publishing to the owner's destination.
|
|
25
|
+
no_puts: bool = False
|
|
26
|
+
# Emit an editable reproduction shell script instead of previewing/running.
|
|
27
|
+
emit_script: bool = False
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import json
|
|
6
6
|
import re
|
|
7
|
+
import shlex
|
|
7
8
|
from contextlib import contextmanager
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from typing import TYPE_CHECKING, Literal
|
|
@@ -42,7 +43,7 @@ def reproduce_artifact(
|
|
|
42
43
|
server_url = _load_server_url(request.cwd)
|
|
43
44
|
glaas_client = _build_glaas_client(server_url)
|
|
44
45
|
|
|
45
|
-
if request.out_path:
|
|
46
|
+
if request.out_path and not request.emit_script:
|
|
46
47
|
_write_reproduction_output(
|
|
47
48
|
request.hash_prefix,
|
|
48
49
|
request.target_kind,
|
|
@@ -51,6 +52,9 @@ def reproduce_artifact(
|
|
|
51
52
|
output,
|
|
52
53
|
)
|
|
53
54
|
|
|
55
|
+
if request.emit_script and request.run_pipeline:
|
|
56
|
+
raise ValueError("choose either --script or --run, not both")
|
|
57
|
+
|
|
54
58
|
pipeline, _pipeline_source = _resolve_pipeline(
|
|
55
59
|
hash_prefix=request.hash_prefix,
|
|
56
60
|
server_url=server_url,
|
|
@@ -58,6 +62,30 @@ def reproduce_artifact(
|
|
|
58
62
|
glaas_client=glaas_client,
|
|
59
63
|
target_kind=request.target_kind,
|
|
60
64
|
)
|
|
65
|
+
|
|
66
|
+
# --no-puts: drop publish (`roar put`) steps so a third-party reproduction
|
|
67
|
+
# rebuilds the artifact without re-publishing to the owner's destination.
|
|
68
|
+
# Applied to the pipeline itself so preview, --script, and --run all agree
|
|
69
|
+
# (and the steps_run/steps_total accounting stays consistent).
|
|
70
|
+
if request.no_puts:
|
|
71
|
+
dropped = _drop_put_steps(pipeline)
|
|
72
|
+
# In --script mode stdout is the script itself; the omission is documented
|
|
73
|
+
# by a comment inside it, so don't pollute stdout with a notice here.
|
|
74
|
+
if dropped and not request.emit_script:
|
|
75
|
+
output.print(f"Skipping {dropped} publish (roar put) step(s) [--no-puts]")
|
|
76
|
+
|
|
77
|
+
# --script: emit an editable reproduction script instead of previewing/running.
|
|
78
|
+
if request.emit_script:
|
|
79
|
+
output.print(
|
|
80
|
+
build_reproduction_script(
|
|
81
|
+
pipeline,
|
|
82
|
+
request.hash_prefix,
|
|
83
|
+
target_kind=request.target_kind,
|
|
84
|
+
no_puts=request.no_puts,
|
|
85
|
+
)
|
|
86
|
+
)
|
|
87
|
+
return
|
|
88
|
+
|
|
61
89
|
preview = build_preview_summary(
|
|
62
90
|
pipeline,
|
|
63
91
|
hash_prefix=request.hash_prefix,
|
|
@@ -357,6 +385,104 @@ def _resolve_pipeline(
|
|
|
357
385
|
return pipeline, lookup.source
|
|
358
386
|
|
|
359
387
|
|
|
388
|
+
def _is_put_step(step: dict) -> bool:
|
|
389
|
+
"""A publish step: recorded as job_type 'put' or a `roar put …` command."""
|
|
390
|
+
kind = step.get("job_type") or step.get("jobType")
|
|
391
|
+
if isinstance(kind, str) and kind.strip().lower() == "put":
|
|
392
|
+
return True
|
|
393
|
+
cmd = str(step.get("command") or "").strip()
|
|
394
|
+
return cmd.split()[:2] == ["roar", "put"]
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
def _drop_put_steps(pipeline: PipelineInfo) -> int:
|
|
398
|
+
"""Remove publish steps from the pipeline in place; return how many were dropped."""
|
|
399
|
+
before = len(pipeline.run_steps)
|
|
400
|
+
pipeline.run_steps = [s for s in pipeline.run_steps if not _is_put_step(s)]
|
|
401
|
+
pipeline.total_steps = len(pipeline.build_steps) + len(pipeline.run_steps)
|
|
402
|
+
return before - len(pipeline.run_steps)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def build_reproduction_script(
|
|
406
|
+
pipeline: PipelineInfo,
|
|
407
|
+
hash_prefix: str,
|
|
408
|
+
*,
|
|
409
|
+
target_kind: str = "artifact",
|
|
410
|
+
no_puts: bool = False,
|
|
411
|
+
) -> str:
|
|
412
|
+
"""Render an editable bash reproduction script (clone → env → pipeline).
|
|
413
|
+
|
|
414
|
+
Dry by design: nothing runs until the user executes it. Mirrors what
|
|
415
|
+
`--run` would do, so it composes with `--no-puts` (which has already
|
|
416
|
+
filtered publish steps out of *pipeline*).
|
|
417
|
+
"""
|
|
418
|
+
from ..tags import run_modifier_flags
|
|
419
|
+
|
|
420
|
+
lines = [
|
|
421
|
+
"#!/usr/bin/env bash",
|
|
422
|
+
f"# Reproduction script for {target_kind} {hash_prefix}",
|
|
423
|
+
"# Generated by `roar reproduce --script`. Dry & editable: review the steps",
|
|
424
|
+
"# (e.g. change --device, or run on your own infra) before executing.",
|
|
425
|
+
]
|
|
426
|
+
if no_puts:
|
|
427
|
+
lines.append("# Publish (roar put) steps are omitted (--no-puts).")
|
|
428
|
+
lines += ["set -euo pipefail", ""]
|
|
429
|
+
|
|
430
|
+
repo = pipeline.git_repo or "<unknown-git-repo>"
|
|
431
|
+
lines += [
|
|
432
|
+
"# 1. Clone the recorded code at its exact commit",
|
|
433
|
+
f"git clone {shlex.quote(repo)} reproduction",
|
|
434
|
+
"cd reproduction",
|
|
435
|
+
]
|
|
436
|
+
if pipeline.git_commit:
|
|
437
|
+
lines.append(f"git checkout {shlex.quote(pipeline.git_commit)}")
|
|
438
|
+
if not pipeline.single_commit:
|
|
439
|
+
lines.append("# NOTE: the recorded session spanned multiple commits; results may differ.")
|
|
440
|
+
lines.append("")
|
|
441
|
+
|
|
442
|
+
lines += [
|
|
443
|
+
"# 2. Recreate the Python environment",
|
|
444
|
+
"python3 -m venv .venv",
|
|
445
|
+
"source .venv/bin/activate",
|
|
446
|
+
]
|
|
447
|
+
for block in _build_requirement_blocks(pipeline):
|
|
448
|
+
if not block.values:
|
|
449
|
+
continue
|
|
450
|
+
if block.label in ("Pip packages", "Build tool pip packages"):
|
|
451
|
+
lines.append("pip install " + " ".join(shlex.quote(v) for v in block.values))
|
|
452
|
+
else: # system / build-tool dpkg packages need sudo — emit as a comment
|
|
453
|
+
lines.append(f"# {block.label} (apt; requires sudo): " + " ".join(block.values))
|
|
454
|
+
lines.append("")
|
|
455
|
+
|
|
456
|
+
lines.append("# 3. Run the pipeline (recorded order)")
|
|
457
|
+
for step in pipeline.build_steps:
|
|
458
|
+
cmd = str(step.get("command") or "").strip()
|
|
459
|
+
if cmd:
|
|
460
|
+
lines.append(f"roar build {cmd}")
|
|
461
|
+
for step in pipeline.run_steps:
|
|
462
|
+
cmd = str(step.get("command") or "").strip()
|
|
463
|
+
if not cmd:
|
|
464
|
+
continue
|
|
465
|
+
# A step whose command is already a `roar …` invocation (e.g. `roar put`)
|
|
466
|
+
# is emitted as-is; other commands are wrapped in `roar run` (replaying
|
|
467
|
+
# any recorded run-modifiers) exactly as the executor would.
|
|
468
|
+
if cmd.split()[:1] == ["roar"]:
|
|
469
|
+
lines.append(cmd)
|
|
470
|
+
continue
|
|
471
|
+
metadata = step.get("metadata")
|
|
472
|
+
if isinstance(metadata, str):
|
|
473
|
+
try:
|
|
474
|
+
metadata = json.loads(metadata)
|
|
475
|
+
except (ValueError, TypeError):
|
|
476
|
+
metadata = {}
|
|
477
|
+
mods = (
|
|
478
|
+
run_modifier_flags(metadata.get("run_modifiers")) if isinstance(metadata, dict) else ""
|
|
479
|
+
)
|
|
480
|
+
prefix = f"roar run {mods}".strip()
|
|
481
|
+
lines.append(f"{prefix} {cmd}")
|
|
482
|
+
lines.append("")
|
|
483
|
+
return "\n".join(lines)
|
|
484
|
+
|
|
485
|
+
|
|
360
486
|
def build_preview_summary(
|
|
361
487
|
pipeline: PipelineInfo,
|
|
362
488
|
*,
|
|
@@ -28,6 +28,32 @@ class ExecutionReport:
|
|
|
28
28
|
setup_error: bool = False
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
RUN_REPORT_FILE_ENV = "ROAR_RUN_REPORT_FILE"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def write_run_report_file(report: ExecutionReport) -> None:
|
|
35
|
+
"""Write a machine-readable run outcome when ROAR_RUN_REPORT_FILE is set.
|
|
36
|
+
|
|
37
|
+
Wrappers that cannot see past the exit code (the k8s pod entrypoint) use
|
|
38
|
+
``setup_error`` to distinguish "roar failed before launching the
|
|
39
|
+
workload" from "the workload ran and failed" — only the former is safe
|
|
40
|
+
to rerun uninstrumented. Advisory only: never fails the run.
|
|
41
|
+
"""
|
|
42
|
+
target = str(os.environ.get(RUN_REPORT_FILE_ENV) or "").strip()
|
|
43
|
+
if not target:
|
|
44
|
+
return
|
|
45
|
+
import contextlib
|
|
46
|
+
import json
|
|
47
|
+
|
|
48
|
+
payload = {
|
|
49
|
+
"exit_code": report.exit_code,
|
|
50
|
+
"setup_error": report.setup_error,
|
|
51
|
+
"tracer_backend": report.tracer_backend,
|
|
52
|
+
}
|
|
53
|
+
with contextlib.suppress(OSError):
|
|
54
|
+
Path(target).write_text(json.dumps(payload), encoding="utf-8")
|
|
55
|
+
|
|
56
|
+
|
|
31
57
|
def validate_git_clean(
|
|
32
58
|
*,
|
|
33
59
|
verb: str = "run",
|
|
@@ -192,6 +218,7 @@ def execute_and_report(
|
|
|
192
218
|
tracer_fallback: bool | None = None,
|
|
193
219
|
block_tags: list[str] | None = None,
|
|
194
220
|
add_tags: list[str] | None = None,
|
|
221
|
+
wandb_to_trackio: bool = False,
|
|
195
222
|
) -> ExecutionReport:
|
|
196
223
|
"""Execute command via selected backend and show the run report."""
|
|
197
224
|
hash_algos = cast(list[Literal["blake3", "sha256", "sha512", "md5"]], hash_algorithms)
|
|
@@ -214,6 +241,7 @@ def execute_and_report(
|
|
|
214
241
|
tracer_fallback=tracer_fallback,
|
|
215
242
|
block_tags=block_tags or [],
|
|
216
243
|
add_tags=add_tags or [],
|
|
244
|
+
wandb_to_trackio=wandb_to_trackio,
|
|
217
245
|
)
|
|
218
246
|
|
|
219
247
|
backend = get_execution_backend(backend_name)
|
|
@@ -19,6 +19,7 @@ class RunRequest:
|
|
|
19
19
|
hash_algorithms: tuple[str, ...] = field(default_factory=tuple)
|
|
20
20
|
block_tags: tuple[str, ...] = field(default_factory=tuple)
|
|
21
21
|
add_tags: tuple[str, ...] = field(default_factory=tuple)
|
|
22
|
+
wandb_to_trackio: bool = False
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
@dataclass(frozen=True)
|
|
@@ -17,6 +17,7 @@ from .execution import (
|
|
|
17
17
|
execute_and_report,
|
|
18
18
|
get_hash_algorithms,
|
|
19
19
|
validate_git_clean,
|
|
20
|
+
write_run_report_file,
|
|
20
21
|
)
|
|
21
22
|
from .requests import BuildRequest, RunRequest
|
|
22
23
|
from .verbosity import resolve_verbosity
|
|
@@ -63,6 +64,7 @@ def run_command(request: RunRequest) -> int:
|
|
|
63
64
|
tracer_fallback=request.tracer_fallback,
|
|
64
65
|
block_tags=list(request.block_tags),
|
|
65
66
|
add_tags=list(request.add_tags),
|
|
67
|
+
wandb_to_trackio=request.wandb_to_trackio,
|
|
66
68
|
)
|
|
67
69
|
|
|
68
70
|
|
|
@@ -111,6 +113,7 @@ def _execute_tracked_command(
|
|
|
111
113
|
tracer_fallback: bool | None,
|
|
112
114
|
block_tags: list[str] | None = None,
|
|
113
115
|
add_tags: list[str] | None = None,
|
|
116
|
+
wandb_to_trackio: bool = False,
|
|
114
117
|
) -> int:
|
|
115
118
|
resolved_config_start_dir = config_start_dir or _config_start_dir(roar_dir)
|
|
116
119
|
try:
|
|
@@ -138,6 +141,7 @@ def _execute_tracked_command(
|
|
|
138
141
|
tracer_fallback=tracer_fallback,
|
|
139
142
|
block_tags=block_tags,
|
|
140
143
|
add_tags=add_tags,
|
|
144
|
+
wandb_to_trackio=wandb_to_trackio,
|
|
141
145
|
)
|
|
142
146
|
)
|
|
143
147
|
except Exception:
|
|
@@ -150,6 +154,10 @@ def _execute_tracked_command(
|
|
|
150
154
|
)
|
|
151
155
|
raise
|
|
152
156
|
|
|
157
|
+
# Written before finalizers so a late finalizer crash cannot leave a
|
|
158
|
+
# wrapper believing the workload never launched.
|
|
159
|
+
write_run_report_file(report)
|
|
160
|
+
|
|
153
161
|
try:
|
|
154
162
|
if planned.finalize_run:
|
|
155
163
|
planned.finalize_run(cast(Any, _FinalizerContext(roar_dir=roar_dir)))
|
|
@@ -176,6 +176,10 @@ def _populate_run_build_common_labels(roar: dict[str, Any], metadata: dict[str,
|
|
|
176
176
|
row.get(key),
|
|
177
177
|
)
|
|
178
178
|
|
|
179
|
+
# Per-run GPU-usage fingerprint from NVIDIA accounting mode. Only
|
|
180
|
+
# present when accounting was enabled; land it alongside cuda/gpu.
|
|
181
|
+
_copy_scalar_map(runtime.get("gpu_accounting"), roar, ["runtime", "gpu_accounting"])
|
|
182
|
+
|
|
179
183
|
packages = metadata.get("packages")
|
|
180
184
|
if isinstance(packages, dict):
|
|
181
185
|
for manager, package_map in packages.items():
|
|
@@ -570,20 +570,26 @@ def parse_add_tags(pairs: Iterable[str]) -> dict[str, list[str]]:
|
|
|
570
570
|
|
|
571
571
|
|
|
572
572
|
def build_run_modifiers(
|
|
573
|
-
block_tags: Iterable[str],
|
|
574
|
-
|
|
573
|
+
block_tags: Iterable[str],
|
|
574
|
+
add_tags: Iterable[str],
|
|
575
|
+
wandb_to_trackio: bool = False,
|
|
576
|
+
) -> dict[str, Any] | None:
|
|
575
577
|
"""Build the ``run_modifiers`` metadata block, or None if there's nothing to record.
|
|
576
578
|
|
|
577
579
|
Stores the raw flag strings verbatim (e.g. ``"license=GPL-3.0"``) so reproduce
|
|
578
|
-
replays exactly what was passed.
|
|
580
|
+
replays exactly what was passed. ``wandb_to_trackio`` records that the run used
|
|
581
|
+
``roar run --wandb-to-trackio`` so reproduce re-emits the flag (and the
|
|
582
|
+
reproduction's ``import wandb`` resolves the same way the original run's did).
|
|
579
583
|
"""
|
|
580
584
|
blocks = [b.strip() for b in block_tags if b.strip()]
|
|
581
585
|
adds = [a.strip() for a in add_tags if a.strip()]
|
|
582
|
-
modifiers: dict[str,
|
|
586
|
+
modifiers: dict[str, Any] = {}
|
|
583
587
|
if blocks:
|
|
584
588
|
modifiers["block_tags"] = blocks
|
|
585
589
|
if adds:
|
|
586
590
|
modifiers["add_tags"] = adds
|
|
591
|
+
if wandb_to_trackio:
|
|
592
|
+
modifiers["wandb_to_trackio"] = True
|
|
587
593
|
return modifiers or None
|
|
588
594
|
|
|
589
595
|
|
|
@@ -602,6 +608,8 @@ def run_modifier_flags(run_modifiers: Any) -> str:
|
|
|
602
608
|
parts.append(f"--block-tag {shlex.quote(str(item))}")
|
|
603
609
|
for item in run_modifiers.get("add_tags") or []:
|
|
604
610
|
parts.append(f"--add-tag {shlex.quote(str(item))}")
|
|
611
|
+
if run_modifiers.get("wandb_to_trackio"):
|
|
612
|
+
parts.append("--wandb-to-trackio")
|
|
605
613
|
return " ".join(parts)
|
|
606
614
|
|
|
607
615
|
|