Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
4ff347a
fix(reproduce): configurable per-step timeout (default none) + kill t…
chrisgeyertreqs Aug 6, 2026
b2dac75
fix(reproduce): fail (don't report success) when a recorded pip pin c…
chrisgeyertreqs Aug 6, 2026
5d1fcc0
test(reproduce): P0-1 — honest-fail on unresolvable pin + export; upd…
chrisgeyertreqs Aug 6, 2026
3a75b0f
test(reproduce): P0-2 — default no timeout + timeout kills the whole …
chrisgeyertreqs Aug 6, 2026
cf203d7
test: make process-group-kill test fast (1.5s) and actually exercise …
chrisgeyertreqs Aug 6, 2026
86c9a10
ci(macos): run only the tracer / platform-dependent test subset
chrisgeyertreqs Aug 6, 2026
8226394
style: apply ruff format to pipeline_executor timeout message
chrisgeyertreqs Aug 6, 2026
473dc7b
fix: catch the recovery-path false-green (swallowed combined-install RC)
chrisgeyertreqs Aug 6, 2026
9960e94
Merge pull request #259 from treqs/cg/reproduce-step-timeout
christophergeyer Aug 6, 2026
5a774f6
reproduce: warn + confirm on a Python major.minor mismatch (P0-4)
chrisgeyertreqs Aug 6, 2026
e558fd2
tracker: per-PID inject-log shards + union merge (P0-9)
chrisgeyertreqs Aug 6, 2026
af6ed6d
test: merge inject-log shards in the data-loader roundtrip (P0-9 foll…
chrisgeyertreqs Aug 7, 2026
11bfbf3
Merge remote-tracking branch 'origin/rc/0.4.4' into cg/reproduce-fail…
chrisgeyertreqs Aug 7, 2026
255263f
Merge pull request #260 from treqs/cg/reproduce-fail-on-missing-pin
christophergeyer Aug 7, 2026
02e204b
Merge pull request #261 from treqs/cg/macos-tracer-only-tests
christophergeyer Aug 7, 2026
5645965
sitecustomize: don't let roar's env shadow the workload's sys.path (P…
chrisgeyertreqs Aug 7, 2026
cf8f36d
fix(runtime): preserve workload package precedence
TrevorBasinger Aug 7, 2026
6f97844
Merge pull request #263 from treqs/cg/reproduce-python-mismatch-prompt
christophergeyer Aug 7, 2026
d1405fa
Merge pull request #265 from treqs/cg/per-pid-inject-log
christophergeyer Aug 7, 2026
0c0d84a
sitecustomize: don't let roar's env shadow the workload's sys.path (P…
chrisgeyertreqs Aug 7, 2026
687816c
tracker: attribute imported packages by name, not only by file (P0-6)
chrisgeyertreqs Aug 6, 2026
1d08b1e
test(P0-6): read write_log output write-path-agnostically
chrisgeyertreqs Aug 6, 2026
fce9a77
tracker: keep roar (P0-11) and the workload's own package (P0-12) out…
chrisgeyertreqs Aug 7, 2026
184b330
Merge pull request #266 from treqs/cg/no-crossinterp-syspath-shadow
christophergeyer Aug 7, 2026
072de2f
Merge pull request #264 from treqs/cg/attribute-shadowed-imports
christophergeyer Aug 7, 2026
6a69e44
tracker: scope the name pass to ALIASED imports only (P0-13)
chrisgeyertreqs Aug 7, 2026
3a0d13f
Merge pull request #267 from treqs/cg/name-pass-aliased-only
christophergeyer Aug 7, 2026
6bfbf17
Merge remote-tracking branch 'origin/rc/0.4.4' into tb/sitecustomize-…
chrisgeyertreqs Aug 7, 2026
49cb52f
Merge pull request #268 from treqs/tb/sitecustomize-safe-runtime-paths
TrevorBasinger Aug 7, 2026
d4dcfce
feat(auth): support delegated GLaaS publishing
TrevorBasinger Aug 12, 2026
f00575b
fix(auth): use registration sessions for delegated publishing
TrevorBasinger Aug 14, 2026
f3d21ae
fix(auth): sync publish labels through registration scope
TrevorBasinger Aug 14, 2026
8caed23
style(auth): format delegated publishing paths
TrevorBasinger Aug 14, 2026
618207f
feat(publish): support delegated registration sessions
TrevorBasinger Aug 18, 2026
45714af
fix(publish): finalize scoped existing bindings
TrevorBasinger Aug 18, 2026
ed81abc
fix(publish): scope delegated retries to one operation
TrevorBasinger Aug 18, 2026
abf56d6
style(publish): use modern mapping import
TrevorBasinger Aug 18, 2026
e0a27de
fix(publish): persist delegated put identity
TrevorBasinger Aug 18, 2026
6f533c2
fix(publish): make delegated put retries durable
TrevorBasinger Aug 18, 2026
71f8ff7
fix(publish): fingerprint the staged put lineage
TrevorBasinger Aug 18, 2026
2519fda
tracker: record packages from dist-packages, not just site-packages (…
chrisgeyertreqs Aug 7, 2026
a6e28ae
Merge remote-tracking branch 'origin/main' into rc/0.4.4
chrisgeyertreqs Aug 7, 2026
03a6043
security: redact HF tokens by default (P0-16)
chrisgeyertreqs Aug 7, 2026
44db676
Merge pull request #274 from treqs/cg/attribute-dist-packages
christophergeyer Aug 8, 2026
e2ee09f
fix: cold-host wandb-trackio stub crash (P0-15) + huggingface-hub run…
chrisgeyertreqs Aug 7, 2026
c277981
Merge pull request #273 from treqs/cg/redact-hf-token
christophergeyer Aug 8, 2026
3f6e4dc
P0-18/P0-11: attribute the freeze to the workload, not roar's footprint
chrisgeyertreqs Aug 10, 2026
6ebe861
Merge pull request #272 from treqs/cg/cold-host-publish-fixes
christophergeyer Aug 8, 2026
7113386
Revert "Merge pull request #275 from treqs/p0-18/frame-attribution"
chrisgeyertreqs Aug 10, 2026
13d351f
Merge pull request #275 from treqs/p0-18/frame-attribution
christophergeyer Aug 10, 2026
8b1a5c2
P0-11 (broad): subtract roar's footprint by LOCATION, not name
chrisgeyertreqs Aug 10, 2026
0931664
Merge pull request #277 from treqs/revert/p0-28-rc3-overcorrect
christophergeyer Aug 10, 2026
b54e298
trackio shim: provide run.get_url() so wandb callers don't crash
chrisgeyertreqs Aug 10, 2026
31cd98e
Merge pull request #278
christophergeyer Aug 10, 2026
80d797d
trackio shim: adapt lerobot's wandb calls (resume=None, log(data=))
chrisgeyertreqs Aug 11, 2026
b6c25b2
Merge pull request #279
christophergeyer Aug 10, 2026
c8209a1
chore(lint): ruff format the #278 files (unbreak CI lint on rc/0.4.4)
chrisgeyertreqs Aug 11, 2026
868bd17
Merge pull request #280
christophergeyer Aug 11, 2026
00040e5
P0-22 (Option B): dedup job edges by content hash to match glaas (W2,…
chrisgeyertreqs Aug 11, 2026
82dba97
Merge pull request #283 (ruff format #278 files)
christophergeyer Aug 11, 2026
9d2f5d2
fix: record the command the user ran, not the one /proc reports
chrisgeyertreqs Aug 18, 2026
f82bccc
ci: pin validated bpf-linker toolchain
chrisgeyertreqs Aug 12, 2026
24a33d9
Merge pull request #284 from treqs/w2b/p0-22-content-dedup (P0-22)
christophergeyer Aug 11, 2026
15cf733
test: keep the recorded-command tests off macOS protected launchers
chrisgeyertreqs Aug 18, 2026
32da3d6
Merge pull request #288 from treqs/ci/pin-bpf-linker-0-10-4
TrevorBasinger Aug 14, 2026
0c5de2f
Merge pull request #291 from treqs/cg/root-argv-from-launcher
christophergeyer Aug 18, 2026
83327ed
fix: flush inject shards from fork workers
chrisgeyertreqs Aug 12, 2026
57b25df
test: document forced-exit capture boundary
chrisgeyertreqs Aug 12, 2026
7fa2901
fix: also emit the shard when a fork worker is terminated
chrisgeyertreqs Aug 18, 2026
c6c9d14
fix: capture killed fork workers without touching signal disposition
chrisgeyertreqs Aug 19, 2026
fb00383
fix: fail closed when Python package capture is suppressed
chrisgeyertreqs Aug 12, 2026
90b9437
test: skip protected macOS preload launchers
chrisgeyertreqs Aug 12, 2026
97c7d6c
test: resolve `true` instead of hardcoding /bin/true
chrisgeyertreqs Aug 18, 2026
818eb07
test: skip the non-Python capture case on macOS
chrisgeyertreqs Aug 18, 2026
f20ecb0
fix(release): preserve the Linux wheel baseline
TrevorBasinger Aug 18, 2026
1494715
Merge pull request #286 from treqs/cg/p039-fail-closed
christophergeyer Aug 19, 2026
da73261
feat: recommend a separate virtual environment for roar at init
chrisgeyertreqs Aug 19, 2026
0afeddc
Merge pull request #292 from treqs/cg/warn-shared-venv-install
christophergeyer Aug 19, 2026
cb1d8c2
Merge pull request #289 from treqs/cg/fork-worker-inject-shards
TrevorBasinger Aug 19, 2026
f28cbb5
Merge pull request #293 from treqs/tb/preserve-linux-wheel-baseline
TrevorBasinger Aug 19, 2026
3ec06bf
Merge pull request #290 from treqs/tb/glaas-credential-broker
TrevorBasinger Aug 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ jobs:
rustup component add rust-src --toolchain nightly

- name: Install bpf-linker
run: cargo install bpf-linker
# Keep CI reproducible; upgrade alongside its required LLVM toolchain.
run: cargo install bpf-linker --version 0.10.4 --locked

- name: Build and stage Rust binaries
uses: ./.github/actions/build-rust-binaries
Expand Down Expand Up @@ -272,11 +273,32 @@ jobs:

python -m roar run "$(python -c 'import sys; print(sys.executable)')" smoke.py

- name: Run tests (parallel)
- name: Run tracer / platform-dependent tests (parallel)
# macOS CI exists to cover the OS-specific surface: the DYLD preload
# tracer, sitecustomize/runtime injection, the native _hash_native
# extension, and the real `roar run` product path. The rest of the suite
# is OS-independent pure-Python logic already fully covered by the Linux
# `test` job (5 Python versions), so running all ~1180 tests here only
# adds slow-runner wall-clock (and timeouts) without adding signal.
#
# Select the platform-dependent trees by path rather than by marker:
# low-churn, self-documenting, and fails safe — Linux-only tracer
# regressions living inside these dirs carry their own
# skipif(platform != "Linux") and simply skip on macOS, and there is no
# per-file marker to forget to apply (which is how a macOS-only tracer
# test would otherwise be silently dropped). The two hashing-value files
# are kept so a macOS-specific _hash_native ABI/endianness regression
# still can't slip through, even though the hashing *logic* is covered
# on Linux.
run: >
pytest --tb=short -x -m "not glaas and not live_glaas and not ebpf and not large_pipeline"
--ignore=tests/backends/osmo
--ignore-glob=tests/backends/test_osmo*.py
tests/execution/runtime
tests/integration
tests/happy_path
tests/application/run
tests/backends/local/integration
tests/unit/test_hashing_backend.py
tests/unit/test_canonical_session_hash.py
--ignore=tests/execution/runtime/test_sitecustomize_perf.py

test-tracer-privileged:
Expand Down Expand Up @@ -360,7 +382,7 @@ jobs:
- name: Install build tools
run: |
python -m pip install --upgrade pip
pip install maturin
pip install 'maturin[zig]'

- name: Download Rust binaries
uses: actions/download-artifact@v4
Expand All @@ -378,7 +400,18 @@ jobs:
- name: Build abi3 wheel
env:
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macos-deployment-target }}
run: maturin build --release --manifest-path rust/crates/artifact-hash-py/Cargo.toml --out dist
ROAR_WHEEL_PLATFORM: ${{ matrix.platform }}
run: |
args=(
build
--release
--manifest-path rust/crates/artifact-hash-py/Cargo.toml
--out dist
)
if [[ "$ROAR_WHEEL_PLATFORM" == "linux" ]]; then
args+=(--zig --compatibility manylinux_2_17)
fi
maturin "${args[@]}"

- name: Install uv
run: |
Expand Down
19 changes: 16 additions & 3 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ jobs:
rustup component add rust-src --toolchain nightly

- name: Install bpf-linker
run: cargo install bpf-linker
# Keep release builds aligned with the version validated in CI.
run: cargo install bpf-linker --version 0.10.4 --locked

- name: Verify version matches release tag
if: github.event_name == 'release' && matrix.arch == 'x86_64'
Expand Down Expand Up @@ -164,7 +165,7 @@ jobs:
- name: Install build tools
run: |
python -m pip install --upgrade pip
pip install maturin
pip install 'maturin[zig]'

- name: Download Rust binaries artifact
uses: actions/download-artifact@v4
Expand All @@ -184,7 +185,19 @@ jobs:
# macOS floor on macOS jobs so the single abi3 build host doesn't drift it.
env:
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macos-deployment-target }}
run: maturin build --release --manifest-path rust/crates/artifact-hash-py/Cargo.toml --interpreter python --out dist
ROAR_WHEEL_PLATFORM: ${{ matrix.platform }}
run: |
args=(
build
--release
--manifest-path rust/crates/artifact-hash-py/Cargo.toml
--interpreter python
--out dist
)
if [[ "$ROAR_WHEEL_PLATFORM" == "linux" ]]; then
args+=(--zig --compatibility manylinux_2_17)
fi
maturin "${args[@]}"

- name: Verify wheel contains native extension and binaries
env:
Expand Down
19 changes: 16 additions & 3 deletions .github/workflows/publish-testpypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ jobs:
rustup component add rust-src --toolchain nightly

- name: Install bpf-linker
run: cargo install bpf-linker
# Keep release builds aligned with the version validated in CI.
run: cargo install bpf-linker --version 0.10.4 --locked

- name: Build and stage Rust binaries
uses: ./.github/actions/build-rust-binaries
Expand Down Expand Up @@ -131,7 +132,7 @@ jobs:
- name: Install build tools
run: |
python -m pip install --upgrade pip
pip install maturin
pip install 'maturin[zig]'

- name: Download Rust binaries artifact
uses: actions/download-artifact@v4
Expand All @@ -151,7 +152,19 @@ jobs:
# macOS floor on macOS jobs so the single abi3 build host doesn't drift it.
env:
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macos-deployment-target }}
run: maturin build --release --manifest-path rust/crates/artifact-hash-py/Cargo.toml --interpreter python --out dist
ROAR_WHEEL_PLATFORM: ${{ matrix.platform }}
run: |
args=(
build
--release
--manifest-path rust/crates/artifact-hash-py/Cargo.toml
--interpreter python
--out dist
)
if [[ "$ROAR_WHEEL_PLATFORM" == "linux" ]]; then
args+=(--zig --compatibility manylinux_2_17)
fi
maturin "${args[@]}"

- name: Verify wheel contains native extension and binaries
env:
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "maturin"

[project]
name = "roar-cli"
version = "0.4.3"
version = "0.4.4"
description = "Reproducibility and provenance tracker for ML training pipelines"
authors = [
{ name="TReqs Team", email="info@treqs.ai" }
Expand Down Expand Up @@ -49,6 +49,7 @@ dependencies = [
"pydantic-settings>=2.0.0",
"textual>=0.80",
"tomli>=2.0.0; python_version < '3.11'",
"huggingface_hub>=0.20.0", # `roar put hf://` is a shipped path, not dev-only (P0-19)
]

[project.urls]
Expand All @@ -68,7 +69,6 @@ dev = [
"mypy>=1.13.0",
"boto3>=1.28.0",
"google-cloud-storage>=2.10.0",
"huggingface_hub>=0.20.0",
]

[project.scripts]
Expand Down Expand Up @@ -129,7 +129,7 @@ markers = [
"ray_contract: User-facing Ray contract tests using `roar run ray job submit ...`",
"ray_diagnostic: Diagnostic Ray tests that intentionally inspect internal runtime details",
]
addopts = "-v --strict-markers -n auto --dist loadfile --ignore=tests/ebpf --ignore=tests/live_glaas --ignore=tests/benchmarks --ignore=tests/e2e --ignore=tests/integration/test_cli_startup.py --ignore=tests/execution/runtime/test_sitecustomize_perf.py --ignore-glob=tests/backends/*/e2e --ignore-glob=tests/backends/*/live"
addopts = "-v --strict-markers -n auto --dist loadfile --ignore=tests/ebpf --ignore=tests/live_glaas --ignore=tests/benchmarks --ignore=tests/e2e --ignore=tests/backends/osmo --ignore=tests/integration/test_cli_startup.py --ignore=tests/execution/runtime/test_sitecustomize_perf.py --ignore-glob=tests/backends/*/e2e --ignore-glob=tests/backends/*/live"
timeout = 60
filterwarnings = [
"ignore::DeprecationWarning",
Expand Down
28 changes: 28 additions & 0 deletions roar/application/publish/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ def collect_register_lineage(
dry_run: bool = False,
) -> tuple[CollectedRegisterLineage | None, str | None]:
"""Collect local lineage for a resolved register target."""
if target.kind == "active_session":
return _collect_active_session_lineage(
roar_dir=roar_dir,
lineage_collector=lineage_collector,
)
if target.kind == "step_reference":
return _collect_step_lineage(
step_reference=target.value,
Expand Down Expand Up @@ -81,6 +86,29 @@ def collect_register_lineage(
return None, f"Unsupported register target type: {target.kind}"


def _collect_active_session_lineage(
*,
roar_dir: Path,
lineage_collector: LineageCollector,
) -> tuple[CollectedRegisterLineage | None, str | None]:
with create_database_context(roar_dir) as db_ctx:
session = db_ctx.sessions.get_active()
if not session:
return None, "No active session. Run 'roar run' to create a session first."
session_id = int(session["id"])
lineage = lineage_collector.collect_session(session_id, roar_dir)

return (
CollectedRegisterLineage(
lineage=lineage,
session_id=session_id,
artifact_hash="",
session_hash_override=None,
),
None,
)


def _collect_step_lineage(
*,
step_reference: str,
Expand Down
2 changes: 2 additions & 0 deletions roar/application/publish/lineage_composites.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def preregister_lineage_composites_with_glaas(
registration_errors: list[str],
composite_builder: Any,
logger: ILogger,
registration_session_id: str | None = None,
) -> list[dict[str, Any]]:
"""Prepare and preregister lineage composites before batch link resolution."""
payloads = build_lineage_composite_payloads(
Expand All @@ -68,6 +69,7 @@ def preregister_lineage_composites_with_glaas(
payloads=payloads,
registration_errors=registration_errors,
logger=logger,
registration_session_id=registration_session_id,
)


Expand Down
12 changes: 11 additions & 1 deletion roar/application/publish/put_composites.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def preregister_put_lineage_composites_with_glaas(
dataset_identifiers: list[dict[str, Any]] | None,
composite_builder: Any,
logger: ILogger,
registration_session_id: str | None = None,
) -> list[dict[str, Any]]:
"""Prepare and preregister lineage composites for the put workflow."""
payloads = build_put_lineage_composite_payloads(
Expand All @@ -55,6 +56,7 @@ def preregister_put_lineage_composites_with_glaas(
payloads=payloads,
registration_errors=registration_errors,
logger=logger,
registration_session_id=registration_session_id,
)


Expand Down Expand Up @@ -164,6 +166,7 @@ def register_put_composites_with_glaas(
registration_errors: list[str],
dataset_identifiers: list[dict[str, Any]] | None,
logger: ILogger,
registration_session_id: str | None = None,
) -> list[dict[str, Any]]:
"""Register generated composite artifacts with GLaaS and persist local state."""
composite_registrations: list[dict[str, Any]] = []
Expand All @@ -186,7 +189,14 @@ def register_put_composites_with_glaas(
if metadata_json is not None:
payload["metadata"] = metadata_json

response = resolved_remote_registry.register_composite_artifact(payload)
response = (
resolved_remote_registry.client.register_composite_artifact_under_registration_session(
registration_session_id,
payload,
)
if registration_session_id
else resolved_remote_registry.register_composite_artifact(payload)
)
result, error = parse_composite_registration_response(response)

composite_registration: dict[str, Any] = {
Expand Down
Loading
Loading