roar-cli 0.3.7__tar.gz → 0.4.0__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.3.7 → roar_cli-0.4.0}/PKG-INFO +1 -1
- {roar_cli-0.3.7 → roar_cli-0.4.0}/pyproject.toml +1 -1
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/register_execution.py +19 -6
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/service.py +17 -7
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/view_edges.py +15 -6
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/__init__.py +12 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/requests.py +52 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/results.py +74 -0
- roar_cli-0.4.0/roar/application/query/tag.py +224 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/execution.py +4 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/requests.py +2 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/service.py +6 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/system_labels.py +7 -1
- roar_cli-0.4.0/roar/application/tags.py +746 -0
- roar_cli-0.4.0/roar/cli/_tag_kinds.py +69 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/command_registry.py +7 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/__init__.py +1 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/register.py +106 -3
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/run.py +39 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/status.py +10 -0
- roar_cli-0.4.0/roar/cli/commands/tag.py +241 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/publish_intent.py +16 -1
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/label_constants.py +12 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/run.py +2 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/services/job_recording.py +75 -5
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/recording/job_recording.py +2 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/reproduction/pipeline_executor.py +29 -19
- roar_cli-0.4.0/roar/execution/runtime/active_runs.py +144 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/coordinator.py +9 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/config/access.py +8 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/config/schema.py +12 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/show_renderer.py +30 -2
- {roar_cli-0.3.7 → roar_cli-0.4.0}/LICENSE +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/README.md +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/__main__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/analyzers/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/analyzers/base.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/analyzers/experiment_trackers.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/composite/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/composite/canonical.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/composite/detect.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/composite/qualifying.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/get/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/get/requests.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/get/results.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/get/service.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/get/transfer.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/git.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/label_rendering.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/labels.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/lookup/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/lookup/models.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/lookup/policy.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/lookup/refs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/lookup/remote_artifacts.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/lookup/runner.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/anchor_attribution.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/blake3_upgrade.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/collection.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/composite_builder.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/composites.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/datasets.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/form_composites.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/git_remote.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/job_links.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/job_preparation.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/lineage.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/lineage_composite_formation.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/lineage_composites.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/metadata.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/put_composites.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/put_execution.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/put_preparation.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/register_preparation.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/register_preview_jobs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/register_tag_push.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/registration.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/registration_package.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/remote_job_uids.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/remote_registry.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/requests.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/results.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/runtime.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/secrets.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/session.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/source_resolution.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/publish/targets.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/dag.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/db_status.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/diff.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/diff_engine.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/diff_graph.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/diff_refs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/git_readiness.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/inputs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/label.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/lineage.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/log.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/show.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/query/status.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/reproduce/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/reproduce/environment.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/reproduce/lookup.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/reproduce/requests.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/reproduce/results.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/reproduce/service.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/reproducibility/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/reproducibility/report.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/dag_references.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/dirty_tree_classify.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/dirty_tree_error.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/gitignore_suggest.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/output_followup.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/run/verbosity.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/workflow/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/workflow/requests.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/workflow/results.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/application/workflow/service.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/auth_store.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/local/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/local/plugin.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/config.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/export.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/host_execution.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/lineage.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/plugin.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/runtime_bundle.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/submit.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/osmo/workflow.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/_agent_names.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/collector.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/config.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/constants.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/env_contract.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/fragment.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/fragment_reconstituter.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/node_agent.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/plugin.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/proxy_fragments.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/roar_worker.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/runtime_hooks.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/s3_key_paths.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/submit.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/backends/ray/submit_context.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/_format.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/auth.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/build.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/config.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/dag.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/db.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/diff.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/env.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/export_registration_package.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/filter.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/get.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/init.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/init_agents.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/inputs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/label.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/lineage.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/log.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/login.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/logout.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/osmo.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/pop.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/projects.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/proxy.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/put.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/reproduce.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/reset.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/scope.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/session.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/show.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/telemetry.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/tracer.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/tui.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/whoami.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/commands/workflow.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/context.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/decorators.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/templates/agents/SKILL.md.tmpl +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/cli/templates/agents/agents_section.md.tmpl +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/bootstrap.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/canonical_session.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/digests.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/dto/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/dto/registration.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/exceptions.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/config.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/lineage.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/logger.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/presenter.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/provenance.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/registration.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/repositories.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/reproduction.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/run.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/services.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/telemetry.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/interfaces/vcs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/label_origins.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/logging.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/artifact.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/base.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/dag.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/dataset_identifier.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/glaas.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/job.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/lineage.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/provenance.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/session.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/telemetry.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/models/vcs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/operation_metadata.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/session_hash.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/step_name.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/tracer_modes.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/core/validation.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/context.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/engine.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/hashing/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/hashing/backend.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/hashing/blake3.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/models.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/query_context.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/repositories/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/repositories/artifact.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/repositories/collection.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/repositories/composite.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/repositories/hash_cache.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/repositories/job.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/repositories/label.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/repositories/session.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/schema.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/services/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/services/hashing.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/services/lineage.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/services/session.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/db/step_priority.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/cluster/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/cluster/bridge.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/cluster/proxy.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/cluster/proxy_config.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/fragments/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/fragments/lineage.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/fragments/models.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/fragments/reconstitution.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/fragments/sessions.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/fragments/transport.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/framework/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/framework/contract.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/framework/planning.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/framework/registry.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/framework/runtime_imports.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/assembler.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/build_pip_collector.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/build_tool_collector.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/data_loader.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/file_filter.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/package_collector.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/process_summarizer.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/runtime_collector.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/provenance/service.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/recording/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/recording/dataset_identifier.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/recording/dataset_metadata.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/recording/dataset_profile.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/reproduction/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/reproduction/environment_setup.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/reproduction/installers.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/reproduction/pipeline_metadata.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/abi_probe.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/backup.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/driver_entrypoint.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/errors.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/host_execution.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/inject/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/inject/sitecustomize.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/inject/support.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/inject/tracker.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/lazy_install.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/proxy_resource.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/resources.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/signal_handler.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/tracer.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/tracer_backends.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/tracer_banner.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/execution/runtime/worker_bootstrap.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/filters/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/filters/files.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/filters/omit.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/glaas_auth.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/glaas_client.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/bootstrap.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/config/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/config/loader.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/config/raw.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/discovery.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/download/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/download/base.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/download/gcs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/download/get.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/download/hf.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/download/http.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/download/noop.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/download/s3.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/git/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/git/base.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/git/context.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/git/provider.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/auth.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/client.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/fragment_streamer.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/registration/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/registration/_artifact_ref.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/registration/artifact.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/registration/coordinator.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/registration/job.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/registration/session.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/glaas/transport.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/registry.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/resolution.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/storage/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/storage/base.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/storage/gcs.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/storage/memory.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/storage/noop.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/storage/publish.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/storage/s3.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/telemetry/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/telemetry/base.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/integrations/telemetry/wandb.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/console.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/dag_data_builder.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/dag_renderer.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/diff_renderer.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/formatting.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/null.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/run_report.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/spinner.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/presenters/terminal.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/publish_auth.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/require.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/scope_config.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/_io.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/capabilities.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/config.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/hooks.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/install.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/paths.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/payload.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/queue.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/stats.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/telemetry/uploader.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/app.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/data.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/screens/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/screens/config_editor.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/screens/label_editor.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/screens/launcher.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/screens/log.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/screens/main.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/screens/search.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/screens/session_picker.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/tmux.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/widgets/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/tui/widgets/detail.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/utils/__init__.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/utils/cloud.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/utils/git_url.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/roar/version_check.py +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/Cargo.lock +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/artifact-hash-core/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/artifact-hash-core/src/lib.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/artifact-hash-py/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/artifact-hash-py/src/lib.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/tracer-fd/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/tracer-fd/src/lib.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/tracer-runtime/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/tracer-runtime/src/lib.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/tracer-schema/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/crates/tracer-schema/src/lib.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/services/proxy/Cargo.lock +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/services/proxy/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/services/proxy/src/forward.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/services/proxy/src/main.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/services/proxy/src/s3.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/common/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/common/src/lib.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/probe/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/probe/rust-toolchain.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/probe/src/main.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/build.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/attach.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/bin/roard.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/client.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/daemon.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/events.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/ipc.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/lib.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/main.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ebpf/userspace/src/state.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/build.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/src/bin/io_fixture.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/src/interpose.c +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/src/ipc.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/src/lib.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/src/main.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/tests/comprehensive.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/preload/tests/standalone.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ptrace/Cargo.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ptrace/rustfmt.toml +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ptrace/src/arch.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ptrace/src/main.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/rust/tracers/ptrace/src/seccomp.rs +0 -0
- {roar_cli-0.3.7 → roar_cli-0.4.0}/scripts/sync_packaged_rust_artifacts.py +0 -0
|
@@ -222,8 +222,15 @@ class RegisterService:
|
|
|
222
222
|
skip_confirmation: bool,
|
|
223
223
|
confirm_callback: Callable[[list[str]], bool] | None,
|
|
224
224
|
prepared: PreparedRegisterExecution,
|
|
225
|
+
composite_leaf_hashes: frozenset[str] = frozenset(),
|
|
225
226
|
) -> RegisterResult:
|
|
226
|
-
"""Register already-collected local lineage with GLaaS.
|
|
227
|
+
"""Register already-collected local lineage with GLaaS.
|
|
228
|
+
|
|
229
|
+
``composite_leaf_hashes`` are true composite-member hashes subsumed into a view
|
|
230
|
+
edge (see ``_prepare_view_edges_for_lineage``) — they have no session-scoped edge
|
|
231
|
+
on GLaaS, so they're excluded from label sync even though they still appear in
|
|
232
|
+
``lineage.artifacts`` for ordinary artifact registration.
|
|
233
|
+
"""
|
|
227
234
|
self._logger.debug(
|
|
228
235
|
"Collected lineage: %d jobs, %d artifacts",
|
|
229
236
|
len(lineage.jobs),
|
|
@@ -276,6 +283,12 @@ class RegisterService:
|
|
|
276
283
|
omit_filter=omit_filter,
|
|
277
284
|
)
|
|
278
285
|
|
|
286
|
+
label_artifacts = (
|
|
287
|
+
[a for a in lineage.artifacts if a.get("hash") not in composite_leaf_hashes]
|
|
288
|
+
if composite_leaf_hashes
|
|
289
|
+
else lineage.artifacts
|
|
290
|
+
)
|
|
291
|
+
|
|
279
292
|
registration_jobs = order_jobs_for_registration(
|
|
280
293
|
normalize_jobs_for_registration(lineage.jobs)
|
|
281
294
|
)
|
|
@@ -344,7 +357,7 @@ class RegisterService:
|
|
|
344
357
|
session_id=session_id,
|
|
345
358
|
session_hash=finalized_session_hash,
|
|
346
359
|
jobs=remote_registration_jobs,
|
|
347
|
-
artifacts=
|
|
360
|
+
artifacts=label_artifacts,
|
|
348
361
|
errors=registration_errors,
|
|
349
362
|
)
|
|
350
363
|
elif batch_result.jobs_failed == 0 and batch_result.links_failed == 0:
|
|
@@ -391,7 +404,7 @@ class RegisterService:
|
|
|
391
404
|
session_id=session_id,
|
|
392
405
|
session_hash=finalized_session_hash,
|
|
393
406
|
jobs=remote_registration_jobs,
|
|
394
|
-
artifacts=
|
|
407
|
+
artifacts=label_artifacts,
|
|
395
408
|
errors=registration_errors,
|
|
396
409
|
)
|
|
397
410
|
except Exception as e:
|
|
@@ -411,7 +424,7 @@ class RegisterService:
|
|
|
411
424
|
session_id=session_id,
|
|
412
425
|
session_hash=finalized_session_hash,
|
|
413
426
|
jobs=remote_registration_jobs,
|
|
414
|
-
artifacts=
|
|
427
|
+
artifacts=label_artifacts,
|
|
415
428
|
errors=registration_errors,
|
|
416
429
|
)
|
|
417
430
|
else:
|
|
@@ -456,7 +469,7 @@ class RegisterService:
|
|
|
456
469
|
),
|
|
457
470
|
db_ctx=db_ctx,
|
|
458
471
|
session_id=session_id,
|
|
459
|
-
label_artifacts=
|
|
472
|
+
label_artifacts=label_artifacts,
|
|
460
473
|
)
|
|
461
474
|
else:
|
|
462
475
|
batch_result = register_publish_lineage(
|
|
@@ -473,7 +486,7 @@ class RegisterService:
|
|
|
473
486
|
),
|
|
474
487
|
db_ctx=None,
|
|
475
488
|
session_id=None,
|
|
476
|
-
label_artifacts=
|
|
489
|
+
label_artifacts=label_artifacts,
|
|
477
490
|
)
|
|
478
491
|
registration_errors.extend(batch_result.errors)
|
|
479
492
|
|
|
@@ -496,7 +496,7 @@ def _load_remote_job_uid_mapping(*, roar_dir: Path, session_id: Any) -> dict[str
|
|
|
496
496
|
|
|
497
497
|
def _prepare_view_edges_for_lineage(
|
|
498
498
|
*, roar_dir: Path, lineage: Any, logger: Any
|
|
499
|
-
) -> dict[str, list[Any]]:
|
|
499
|
+
) -> tuple[dict[str, list[Any]], set[str]]:
|
|
500
500
|
"""Compute consumes/produces view edges per job and prune the subsumed leaves in-place.
|
|
501
501
|
|
|
502
502
|
A job that read part of a dataset gets a ``consumes`` view edge over its inputs; a job
|
|
@@ -505,15 +505,21 @@ def _prepare_view_edges_for_lineage(
|
|
|
505
505
|
and any anchor linked as a plain input/output — are removed from the bundle so the job
|
|
506
506
|
links the dataset *view* (job -> view -> anchor -> leaves), not the loose leaves or the
|
|
507
507
|
anchor directly. The anchor composite stays in ``lineage.artifacts`` (already
|
|
508
|
-
collected) so it is still registered.
|
|
509
|
-
|
|
508
|
+
collected) so it is still registered.
|
|
509
|
+
|
|
510
|
+
Returns ``({job_uid: [view_edge, ...]}, composite_leaf_hashes)``: the view edges to
|
|
511
|
+
push after the main registration, and the union of true component/leaf hashes (never
|
|
512
|
+
the anchor's own hash) subsumed across all jobs — a leaf has no session-scoped edge on
|
|
513
|
+
GLaaS, so the caller uses this set to keep leaf label/tag documents out of publish-time
|
|
514
|
+
label sync too.
|
|
510
515
|
"""
|
|
511
516
|
from .view_edges import resolve_view_edges_for_job
|
|
512
517
|
|
|
513
518
|
jobs = getattr(lineage, "jobs", []) or []
|
|
514
519
|
if not jobs:
|
|
515
|
-
return {}
|
|
520
|
+
return {}, set()
|
|
516
521
|
view_edges_by_job: dict[str, list[Any]] = {}
|
|
522
|
+
composite_leaf_hashes: set[str] = set()
|
|
517
523
|
with create_database_context(roar_dir) as db:
|
|
518
524
|
for job in jobs:
|
|
519
525
|
if not isinstance(job, dict):
|
|
@@ -530,7 +536,7 @@ def _prepare_view_edges_for_lineage(
|
|
|
530
536
|
hashes = list(job.get(hashes_key) or [])
|
|
531
537
|
if not hashes:
|
|
532
538
|
continue
|
|
533
|
-
resolved, prune = resolve_view_edges_for_job(
|
|
539
|
+
resolved, prune, leaf_hashes = resolve_view_edges_for_job(
|
|
534
540
|
db_ctx=db, input_hashes=hashes, relation=relation
|
|
535
541
|
)
|
|
536
542
|
if not resolved:
|
|
@@ -539,9 +545,10 @@ def _prepare_view_edges_for_lineage(
|
|
|
539
545
|
job[hashes_key] = [h for h in hashes if h not in prune]
|
|
540
546
|
if isinstance(job.get(items_key), list):
|
|
541
547
|
job[items_key] = [i for i in job[items_key] if i.get("hash") not in prune]
|
|
548
|
+
composite_leaf_hashes |= leaf_hashes
|
|
542
549
|
if edges:
|
|
543
550
|
view_edges_by_job[str(job_uid)] = edges
|
|
544
|
-
return view_edges_by_job
|
|
551
|
+
return view_edges_by_job, composite_leaf_hashes
|
|
545
552
|
|
|
546
553
|
|
|
547
554
|
def register_lineage_target(request: RegisterLineageRequest) -> RegisterLineageResponse:
|
|
@@ -628,13 +635,15 @@ def register_lineage_target(request: RegisterLineageRequest) -> RegisterLineageR
|
|
|
628
635
|
# bloom over the touched leaves) and prune the subsumed leaves from the bundle.
|
|
629
636
|
# Pushed after the main registration. Best-effort.
|
|
630
637
|
view_edges_by_job: dict[str, list[Any]] = {}
|
|
638
|
+
composite_leaf_hashes: frozenset[str] = frozenset()
|
|
631
639
|
if not request.dry_run:
|
|
632
640
|
try:
|
|
633
|
-
view_edges_by_job = _prepare_view_edges_for_lineage(
|
|
641
|
+
view_edges_by_job, leaf_hashes = _prepare_view_edges_for_lineage(
|
|
634
642
|
roar_dir=request.roar_dir,
|
|
635
643
|
lineage=collected_lineage.lineage,
|
|
636
644
|
logger=logger,
|
|
637
645
|
)
|
|
646
|
+
composite_leaf_hashes = frozenset(leaf_hashes)
|
|
638
647
|
except Exception as exc: # view-edge prep is best-effort
|
|
639
648
|
logger.debug("view-edge preparation skipped: %s", exc)
|
|
640
649
|
|
|
@@ -728,6 +737,7 @@ def register_lineage_target(request: RegisterLineageRequest) -> RegisterLineageR
|
|
|
728
737
|
skip_confirmation=request.skip_confirmation,
|
|
729
738
|
confirm_callback=request.confirm_callback,
|
|
730
739
|
prepared=prepared,
|
|
740
|
+
composite_leaf_hashes=composite_leaf_hashes,
|
|
731
741
|
)
|
|
732
742
|
|
|
733
743
|
# Push the consumes view edges now that the jobs + the anchor composite are
|
|
@@ -115,16 +115,23 @@ def resolve_view_edges_for_job(
|
|
|
115
115
|
db_ctx: Any,
|
|
116
116
|
input_hashes: list[str],
|
|
117
117
|
relation: Literal["consumes", "produces"] = "consumes",
|
|
118
|
-
) -> tuple[list[dict[str, Any]], set[str]]:
|
|
118
|
+
) -> tuple[list[dict[str, Any]], set[str], set[str]]:
|
|
119
119
|
"""Resolve a job's leaf *hashes* into view edges + hashes to prune.
|
|
120
120
|
|
|
121
121
|
Works from the collected-lineage hashes (not artifact ids). ``relation`` is the side
|
|
122
122
|
being resolved: ``consumes`` over a job's input hashes (a run that read part of a
|
|
123
123
|
dataset) or ``produces`` over its output hashes (a run that wrote one). The resolution
|
|
124
124
|
is identical either way — each leaf is matched to the anchor composite(s) that carry
|
|
125
|
-
it as a component. Returns ``(view_edges, prune_hashes)
|
|
126
|
-
|
|
127
|
-
|
|
125
|
+
it as a component. Returns ``(view_edges, prune_hashes, leaf_hashes)``:
|
|
126
|
+
|
|
127
|
+
- ``prune_hashes``: the leaf hashes that collapse into a view edge plus any anchor
|
|
128
|
+
composite hash linked as a plain input/output (the view edge replaces it). Used to
|
|
129
|
+
drop these from a job's plain input/output edges.
|
|
130
|
+
- ``leaf_hashes``: strictly the true component/leaf hashes subsumed into a view edge
|
|
131
|
+
(a subset of ``prune_hashes`` that excludes a directly-linked anchor's own hash).
|
|
132
|
+
A composite member never has its own session-scoped edge on GLaaS — it has no
|
|
133
|
+
standing to carry its own labels/tags either, so callers use this set to keep
|
|
134
|
+
per-leaf label/tag documents out of publish-time label sync.
|
|
128
135
|
|
|
129
136
|
BOUNDARY: matching uses ``find_by_component_digest``, which only knows the anchor's
|
|
130
137
|
*stored* components (capped at ``_MAX_STORED_COMPONENTS`` = 1000). For a dataset with
|
|
@@ -138,7 +145,7 @@ def resolve_view_edges_for_job(
|
|
|
138
145
|
artifacts_repo: Any = optional_repo(db_ctx, "artifacts")
|
|
139
146
|
composites_repo: Any = optional_repo(db_ctx, "composites")
|
|
140
147
|
if artifacts_repo is None or composites_repo is None:
|
|
141
|
-
return [], set()
|
|
148
|
+
return [], set(), set()
|
|
142
149
|
|
|
143
150
|
# anchor_id -> {"algorithm": str, "leaves": set, "shards": set}
|
|
144
151
|
by_anchor: dict[str, dict[str, Any]] = {}
|
|
@@ -174,6 +181,7 @@ def resolve_view_edges_for_job(
|
|
|
174
181
|
_attribute(blake3_digest, "blake3", digest)
|
|
175
182
|
|
|
176
183
|
view_edges: list[dict[str, Any]] = []
|
|
184
|
+
leaf_hashes: set[str] = set()
|
|
177
185
|
for anchor_id, bucket in by_anchor.items():
|
|
178
186
|
anchor = artifacts_repo.get(anchor_id)
|
|
179
187
|
anchor_digest = _primary_composite_digest(anchor)
|
|
@@ -189,8 +197,9 @@ def resolve_view_edges_for_job(
|
|
|
189
197
|
)
|
|
190
198
|
)
|
|
191
199
|
prune |= bucket["shards"]
|
|
200
|
+
leaf_hashes |= bucket["shards"]
|
|
192
201
|
|
|
193
|
-
return view_edges, prune
|
|
202
|
+
return view_edges, prune, leaf_hashes
|
|
194
203
|
|
|
195
204
|
|
|
196
205
|
def _primary_composite_digest(artifact: dict[str, Any] | None) -> str | None:
|
|
@@ -21,6 +21,10 @@ _EXPORTS = {
|
|
|
21
21
|
"LogQueryRequest": ".requests",
|
|
22
22
|
"ShowQueryRequest": ".requests",
|
|
23
23
|
"StatusQueryRequest": ".requests",
|
|
24
|
+
"TagAddRequest": ".requests",
|
|
25
|
+
"TagHistoryRequest": ".requests",
|
|
26
|
+
"TagRmRequest": ".requests",
|
|
27
|
+
"TagShowRequest": ".requests",
|
|
24
28
|
"LabelCurrentSummary": ".results",
|
|
25
29
|
"LabelHistorySummary": ".results",
|
|
26
30
|
"LineageSummary": ".results",
|
|
@@ -37,6 +41,10 @@ _EXPORTS = {
|
|
|
37
41
|
"build_show_labels_summary": ".label",
|
|
38
42
|
"build_sync_labels_summary": ".label",
|
|
39
43
|
"build_unset_labels_summary": ".label",
|
|
44
|
+
"build_tag_add_summary": ".tag",
|
|
45
|
+
"build_tag_history_summary": ".tag",
|
|
46
|
+
"build_tag_rm_summary": ".tag",
|
|
47
|
+
"build_tag_show_summary": ".tag",
|
|
40
48
|
"copy_labels": ".label",
|
|
41
49
|
"label_history": ".label",
|
|
42
50
|
"remote_label_history": ".label",
|
|
@@ -51,6 +59,10 @@ _EXPORTS = {
|
|
|
51
59
|
"set_labels": ".label",
|
|
52
60
|
"show_labels": ".label",
|
|
53
61
|
"sync_labels": ".label",
|
|
62
|
+
"tag_add": ".tag",
|
|
63
|
+
"tag_history": ".tag",
|
|
64
|
+
"tag_rm": ".tag",
|
|
65
|
+
"tag_show": ".tag",
|
|
54
66
|
"unset_labels": ".label",
|
|
55
67
|
}
|
|
56
68
|
|
|
@@ -176,3 +176,55 @@ class InputsQueryRequest:
|
|
|
176
176
|
output_json: bool = False
|
|
177
177
|
unsourced: bool = False # show only unsourced inputs (no producer)
|
|
178
178
|
sourced: bool = False # show only sourced inputs (produced/ingested by roar)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@dataclass(frozen=True)
|
|
182
|
+
class TagAddRequest:
|
|
183
|
+
roar_dir: Path
|
|
184
|
+
cwd: Path
|
|
185
|
+
kv: str # "kind=value"
|
|
186
|
+
target: str
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@dataclass(frozen=True)
|
|
190
|
+
class TagRmRequest:
|
|
191
|
+
roar_dir: Path
|
|
192
|
+
cwd: Path
|
|
193
|
+
key_or_kv: str # "kind" or "kind=value"
|
|
194
|
+
target: str
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@dataclass(frozen=True)
|
|
198
|
+
class TagShowRequest:
|
|
199
|
+
roar_dir: Path
|
|
200
|
+
cwd: Path
|
|
201
|
+
target: str
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
@dataclass(frozen=True)
|
|
205
|
+
class TagHistoryRequest:
|
|
206
|
+
roar_dir: Path
|
|
207
|
+
cwd: Path
|
|
208
|
+
target: str
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@dataclass(frozen=True)
|
|
212
|
+
class TagBindRequest:
|
|
213
|
+
roar_dir: Path
|
|
214
|
+
cwd: Path
|
|
215
|
+
targets: tuple[str, ...]
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
@dataclass(frozen=True)
|
|
219
|
+
class TagUnbindRequest:
|
|
220
|
+
roar_dir: Path
|
|
221
|
+
cwd: Path
|
|
222
|
+
targets: tuple[str, ...]
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@dataclass(frozen=True)
|
|
226
|
+
class TagWhyRequest:
|
|
227
|
+
roar_dir: Path
|
|
228
|
+
cwd: Path
|
|
229
|
+
target: str
|
|
230
|
+
key: str # "kind" or "kind=value" — value narrows the explanation to one value
|
|
@@ -7,6 +7,7 @@ from enum import Enum
|
|
|
7
7
|
from typing import TYPE_CHECKING, Any
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
|
+
from ..tags import WhyNode
|
|
10
11
|
from .diff_graph import JobMatch, JobNode
|
|
11
12
|
from .git_readiness import GitReadinessSummary
|
|
12
13
|
|
|
@@ -146,6 +147,79 @@ class LabelHistorySummary:
|
|
|
146
147
|
return "\n\n".join(version.render() for version in self.versions)
|
|
147
148
|
|
|
148
149
|
|
|
150
|
+
@dataclass(frozen=True)
|
|
151
|
+
class TagBindArtifactSummary:
|
|
152
|
+
"""One target's outcome from `roar tag bind`/`unbind` — what the CLI echoes."""
|
|
153
|
+
|
|
154
|
+
display_target: str
|
|
155
|
+
action: str # "bind" | "unbind"
|
|
156
|
+
changed: bool
|
|
157
|
+
promoted: dict[str, list[str]] = field(default_factory=dict)
|
|
158
|
+
size: int | None = None
|
|
159
|
+
|
|
160
|
+
def render(self) -> str:
|
|
161
|
+
verb = "Bound" if self.action == "bind" else "Unbound"
|
|
162
|
+
header = self.display_target
|
|
163
|
+
if self.size is not None:
|
|
164
|
+
header += f" ({self.size} bytes)"
|
|
165
|
+
lines = [f"{verb}: {header}"]
|
|
166
|
+
if self.size == 0:
|
|
167
|
+
lines.append(
|
|
168
|
+
" warning: this is the empty-content hash — shared by every empty "
|
|
169
|
+
"file in every session. Binding it promotes its tags everywhere."
|
|
170
|
+
)
|
|
171
|
+
if not self.changed:
|
|
172
|
+
if self.promoted:
|
|
173
|
+
lines.append(" no change: already up to date")
|
|
174
|
+
else:
|
|
175
|
+
noun = "currently bound" if self.action == "unbind" else "to bind"
|
|
176
|
+
lines.append(f" no change: nothing {noun}")
|
|
177
|
+
return "\n".join(lines)
|
|
178
|
+
for kind in sorted(self.promoted):
|
|
179
|
+
lines.append(f" {kind}={', '.join(self.promoted[kind])}")
|
|
180
|
+
return "\n".join(lines)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@dataclass(frozen=True)
|
|
184
|
+
class TagBindSummary:
|
|
185
|
+
artifacts: list[TagBindArtifactSummary] = field(default_factory=list)
|
|
186
|
+
|
|
187
|
+
def render(self) -> str:
|
|
188
|
+
if not self.artifacts:
|
|
189
|
+
return "No targets."
|
|
190
|
+
return "\n".join(artifact.render() for artifact in self.artifacts)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@dataclass(frozen=True)
|
|
194
|
+
class TagWhySummary:
|
|
195
|
+
"""Renders the provenance walk produced by ``roar tag why``.
|
|
196
|
+
|
|
197
|
+
``roots`` is a forest of ``WhyNode`` (one tree per explained value); each
|
|
198
|
+
node's ``label`` describes one hop back toward a human act (``tag add`` /
|
|
199
|
+
``run --add-tag`` / a cross-session ``bind``).
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
heading: str
|
|
203
|
+
roots: list[WhyNode] = field(default_factory=list)
|
|
204
|
+
empty_message: str = "(no such tag on target — nothing to explain)"
|
|
205
|
+
|
|
206
|
+
def render(self) -> str:
|
|
207
|
+
lines = [self.heading]
|
|
208
|
+
if not self.roots:
|
|
209
|
+
lines.append(f" {self.empty_message}")
|
|
210
|
+
return "\n".join(lines)
|
|
211
|
+
for root in self.roots:
|
|
212
|
+
lines.extend(self._render_node(root, depth=0))
|
|
213
|
+
return "\n".join(lines)
|
|
214
|
+
|
|
215
|
+
def _render_node(self, node: WhyNode, *, depth: int) -> list[str]:
|
|
216
|
+
indent = " " + " " * depth
|
|
217
|
+
lines = [f"{indent}{'└─ ' if depth else ''}{node.label}"]
|
|
218
|
+
for child in node.children:
|
|
219
|
+
lines.extend(self._render_node(child, depth=depth + 1))
|
|
220
|
+
return lines
|
|
221
|
+
|
|
222
|
+
|
|
149
223
|
@dataclass(frozen=True)
|
|
150
224
|
class ShowHashSummary:
|
|
151
225
|
algorithm: str
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""Application orchestration for roar tag workflows."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from ...core.label_constants import TAG_NAMESPACE
|
|
8
|
+
from ...db.context import create_database_context
|
|
9
|
+
from ..tags import BindResult, TagService, parse_tag_kv, tag_display_pairs
|
|
10
|
+
from .requests import (
|
|
11
|
+
TagAddRequest,
|
|
12
|
+
TagBindRequest,
|
|
13
|
+
TagHistoryRequest,
|
|
14
|
+
TagRmRequest,
|
|
15
|
+
TagShowRequest,
|
|
16
|
+
TagUnbindRequest,
|
|
17
|
+
TagWhyRequest,
|
|
18
|
+
)
|
|
19
|
+
from .results import (
|
|
20
|
+
LabelCurrentSummary,
|
|
21
|
+
LabelEntrySummary,
|
|
22
|
+
LabelHistorySummary,
|
|
23
|
+
LabelHistoryVersionSummary,
|
|
24
|
+
TagBindArtifactSummary,
|
|
25
|
+
TagBindSummary,
|
|
26
|
+
TagWhySummary,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def tag_add(request: TagAddRequest) -> str:
|
|
31
|
+
"""Append a value to a tag set and return a rendered summary."""
|
|
32
|
+
return build_tag_add_summary(request).render()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def build_tag_add_summary(request: TagAddRequest) -> LabelCurrentSummary:
|
|
36
|
+
"""Build the typed summary for a tag add operation."""
|
|
37
|
+
kind, value = parse_tag_kv(request.kv)
|
|
38
|
+
with create_database_context(request.roar_dir) as db_ctx:
|
|
39
|
+
svc = TagService(db_ctx, request.cwd)
|
|
40
|
+
resolved = svc.resolve_target(request.target)
|
|
41
|
+
changed = svc.add(resolved, kind, value)
|
|
42
|
+
tags = svc.get_tags(resolved)
|
|
43
|
+
|
|
44
|
+
if changed:
|
|
45
|
+
heading = f"Tagged {request.target}: {TAG_NAMESPACE}.{kind} += [{value!r}]"
|
|
46
|
+
else:
|
|
47
|
+
heading = f"No change: {value!r} already present in {TAG_NAMESPACE}.{kind}"
|
|
48
|
+
|
|
49
|
+
return LabelCurrentSummary(
|
|
50
|
+
heading=heading,
|
|
51
|
+
entries=_tag_entries(tags),
|
|
52
|
+
empty_message="(no tags)",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def tag_rm(request: TagRmRequest) -> str:
|
|
57
|
+
"""Remove a value (or entire kind) from a tag set and return a rendered summary."""
|
|
58
|
+
return build_tag_rm_summary(request).render()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def build_tag_rm_summary(request: TagRmRequest) -> LabelCurrentSummary:
|
|
62
|
+
"""Build the typed summary for a tag rm operation."""
|
|
63
|
+
kind, value = _parse_kind_or_kv(request.key_or_kv)
|
|
64
|
+
with create_database_context(request.roar_dir) as db_ctx:
|
|
65
|
+
svc = TagService(db_ctx, request.cwd)
|
|
66
|
+
resolved = svc.resolve_target(request.target)
|
|
67
|
+
changed = svc.remove(resolved, kind, value)
|
|
68
|
+
tags = svc.get_tags(resolved)
|
|
69
|
+
|
|
70
|
+
if changed:
|
|
71
|
+
if value is not None:
|
|
72
|
+
heading = f"Removed {value!r} from {TAG_NAMESPACE}.{kind} on {request.target}"
|
|
73
|
+
else:
|
|
74
|
+
heading = f"Removed {TAG_NAMESPACE}.{kind} from {request.target}"
|
|
75
|
+
else:
|
|
76
|
+
if value is not None:
|
|
77
|
+
heading = f"No change: {value!r} not found in {TAG_NAMESPACE}.{kind}"
|
|
78
|
+
else:
|
|
79
|
+
heading = f"No change: {TAG_NAMESPACE}.{kind} not present on {request.target}"
|
|
80
|
+
|
|
81
|
+
return LabelCurrentSummary(
|
|
82
|
+
heading=heading,
|
|
83
|
+
entries=_tag_entries(tags),
|
|
84
|
+
empty_message="(no tags remaining)",
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def tag_show(request: TagShowRequest) -> str:
|
|
89
|
+
"""Show current tags for a target and return a rendered summary."""
|
|
90
|
+
return build_tag_show_summary(request).render()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def build_tag_show_summary(request: TagShowRequest) -> LabelCurrentSummary:
|
|
94
|
+
"""Build the typed summary for showing tags."""
|
|
95
|
+
with create_database_context(request.roar_dir) as db_ctx:
|
|
96
|
+
svc = TagService(db_ctx, request.cwd)
|
|
97
|
+
resolved = svc.resolve_target(request.target)
|
|
98
|
+
tags = svc.get_tags(resolved)
|
|
99
|
+
|
|
100
|
+
return LabelCurrentSummary(
|
|
101
|
+
heading=f"Tags on {request.target}:",
|
|
102
|
+
entries=_tag_entries(tags),
|
|
103
|
+
empty_message="(no tags)",
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def tag_history(request: TagHistoryRequest) -> str:
|
|
108
|
+
"""Show label version history for a target (all keys) and return a rendered summary."""
|
|
109
|
+
return build_tag_history_summary(request).render()
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def build_tag_history_summary(request: TagHistoryRequest) -> LabelHistorySummary:
|
|
113
|
+
"""Build the typed summary for tag history."""
|
|
114
|
+
with create_database_context(request.roar_dir) as db_ctx:
|
|
115
|
+
svc = TagService(db_ctx, request.cwd)
|
|
116
|
+
resolved = svc.resolve_target(request.target)
|
|
117
|
+
history = svc.history(resolved)
|
|
118
|
+
|
|
119
|
+
return LabelHistorySummary(
|
|
120
|
+
versions=[
|
|
121
|
+
LabelHistoryVersionSummary(
|
|
122
|
+
version=int(row["version"]),
|
|
123
|
+
entries=_tag_entries(row["metadata"].get(TAG_NAMESPACE) or {}),
|
|
124
|
+
)
|
|
125
|
+
for row in history
|
|
126
|
+
if isinstance(row.get("metadata"), dict)
|
|
127
|
+
]
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def tag_why(request: TagWhyRequest) -> str:
|
|
132
|
+
"""Explain how a target acquired a tag and return a rendered summary."""
|
|
133
|
+
return build_tag_why_summary(request).render()
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def build_tag_why_summary(request: TagWhyRequest) -> TagWhySummary:
|
|
137
|
+
"""Build the typed summary for a tag why provenance walk."""
|
|
138
|
+
kind, value = _parse_kind_or_kv(request.key)
|
|
139
|
+
with create_database_context(request.roar_dir) as db_ctx:
|
|
140
|
+
svc = TagService(db_ctx, request.cwd)
|
|
141
|
+
resolved = svc.resolve_target(request.target)
|
|
142
|
+
roots = svc.why(resolved, kind, value)
|
|
143
|
+
|
|
144
|
+
label = f"{kind}={value}" if value is not None else kind
|
|
145
|
+
return TagWhySummary(heading=f"Why does {request.target} have {label}?", roots=roots)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def tag_bind(request: TagBindRequest) -> str:
|
|
149
|
+
"""Promote each target's current tags to cross-session scope and return a rendered summary."""
|
|
150
|
+
return build_tag_bind_summary(request).render()
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def build_tag_bind_summary(request: TagBindRequest) -> TagBindSummary:
|
|
154
|
+
"""Build the typed summary for a tag bind operation."""
|
|
155
|
+
return _build_bind_or_unbind_summary(
|
|
156
|
+
request.roar_dir, request.cwd, request.targets, action="bind"
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def tag_unbind(request: TagUnbindRequest) -> str:
|
|
161
|
+
"""Revoke each target's currently-bound tags and return a rendered summary."""
|
|
162
|
+
return build_tag_unbind_summary(request).render()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def build_tag_unbind_summary(request: TagUnbindRequest) -> TagBindSummary:
|
|
166
|
+
"""Build the typed summary for a tag unbind operation."""
|
|
167
|
+
return _build_bind_or_unbind_summary(
|
|
168
|
+
request.roar_dir, request.cwd, request.targets, action="unbind"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _build_bind_or_unbind_summary(
|
|
173
|
+
roar_dir: Path, cwd: Path, targets: tuple[str, ...], *, action: str
|
|
174
|
+
) -> TagBindSummary:
|
|
175
|
+
artifacts: list[TagBindArtifactSummary] = []
|
|
176
|
+
with create_database_context(roar_dir) as db_ctx:
|
|
177
|
+
svc = TagService(db_ctx, cwd)
|
|
178
|
+
for target in targets:
|
|
179
|
+
resolved = svc.resolve_target(target)
|
|
180
|
+
result: BindResult = svc.bind(resolved) if action == "bind" else svc.unbind(resolved)
|
|
181
|
+
|
|
182
|
+
size = None
|
|
183
|
+
if resolved.entity_type == "artifact" and resolved.artifact_id:
|
|
184
|
+
artifact = db_ctx.artifacts.get(resolved.artifact_id)
|
|
185
|
+
if artifact:
|
|
186
|
+
size = artifact.get("size")
|
|
187
|
+
|
|
188
|
+
artifacts.append(
|
|
189
|
+
TagBindArtifactSummary(
|
|
190
|
+
display_target=resolved.display_target or target,
|
|
191
|
+
action=action,
|
|
192
|
+
changed=result.changed,
|
|
193
|
+
promoted=result.promoted,
|
|
194
|
+
size=size,
|
|
195
|
+
)
|
|
196
|
+
)
|
|
197
|
+
return TagBindSummary(artifacts=artifacts)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# ---------------------------------------------------------------------------
|
|
201
|
+
# Helpers
|
|
202
|
+
# ---------------------------------------------------------------------------
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _parse_kind_or_kv(key_or_kv: str) -> tuple[str, str | None]:
|
|
206
|
+
"""Parse ``kind`` or ``kind=value``. Returns (kind, value_or_None)."""
|
|
207
|
+
if "=" in key_or_kv:
|
|
208
|
+
kind, value = parse_tag_kv(key_or_kv)
|
|
209
|
+
return kind, value
|
|
210
|
+
kind = key_or_kv.strip()
|
|
211
|
+
if not kind:
|
|
212
|
+
raise ValueError("Kind cannot be empty.")
|
|
213
|
+
return kind, None
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _tag_entries(tags: dict) -> list[LabelEntrySummary]:
|
|
217
|
+
"""Convert a tag.* subtree to display entries via the shared renderer.
|
|
218
|
+
|
|
219
|
+
Uses ``tag_display_pairs`` so ``roar tag show`` and ``roar show`` render tags
|
|
220
|
+
identically (values only; skips the bind ledger).
|
|
221
|
+
"""
|
|
222
|
+
return [
|
|
223
|
+
LabelEntrySummary(key=kind, display_value=value) for kind, value in tag_display_pairs(tags)
|
|
224
|
+
]
|
|
@@ -190,6 +190,8 @@ def execute_and_report(
|
|
|
190
190
|
config_start_dir: str | Path | None = None,
|
|
191
191
|
tracer_mode: str | None = None,
|
|
192
192
|
tracer_fallback: bool | None = None,
|
|
193
|
+
block_tags: list[str] | None = None,
|
|
194
|
+
add_tags: list[str] | None = None,
|
|
193
195
|
) -> ExecutionReport:
|
|
194
196
|
"""Execute command via selected backend and show the run report."""
|
|
195
197
|
hash_algos = cast(list[Literal["blake3", "sha256", "sha512", "md5"]], hash_algorithms)
|
|
@@ -210,6 +212,8 @@ def execute_and_report(
|
|
|
210
212
|
hash_algorithms=hash_algos,
|
|
211
213
|
tracer_mode=tracer_mode, # type: ignore[arg-type]
|
|
212
214
|
tracer_fallback=tracer_fallback,
|
|
215
|
+
block_tags=block_tags or [],
|
|
216
|
+
add_tags=add_tags or [],
|
|
213
217
|
)
|
|
214
218
|
|
|
215
219
|
backend = get_execution_backend(backend_name)
|
|
@@ -17,6 +17,8 @@ class RunRequest:
|
|
|
17
17
|
tracer_mode: str | None = None
|
|
18
18
|
tracer_fallback: bool | None = None
|
|
19
19
|
hash_algorithms: tuple[str, ...] = field(default_factory=tuple)
|
|
20
|
+
block_tags: tuple[str, ...] = field(default_factory=tuple)
|
|
21
|
+
add_tags: tuple[str, ...] = field(default_factory=tuple)
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
@dataclass(frozen=True)
|