Repository navigation
feat(harbor): fetch package-store datasets by content hash (M9) - #3743
Conversation
1c6394b to
b22e0e6
Compare
b22e0e6 to
00c97bf
Compare
00c97bf to
3cf1d97
Compare
3cf1d97 to
2bdcada
Compare
yuhezhang-ai
left a comment
There was a problem hiding this comment.
Before merging, please address the four cases below involving protection of local edits, dataset cache identity, duplicate task destinations, and compatibility with Harbor's published file hashes. Each has a local reproduction; they can erase local work, change the requested task set, or reject an intact package. The CLI-identifier and concurrent-fetch comments are nonblocking follow-ups.
Reviewed the M9 increment against adasif/harbor-m8-tb21. Focused tests and reproductions ran on 00c97bf4; after the rebase, I verified both M9 patches and the finding locations are unchanged at 2bdcada5. The rebased tree was not retested, and no live-store fetch or model rollout was performed during this review.
2bdcada to
f716c1e
Compare
c1fe3bc to
b93dbef
Compare
b93dbef to
7889adc
Compare
da57ae8 to
bdbe918
Compare
|
/ok to test bdbe918 |
yuhezhang-ai
left a comment
There was a problem hiding this comment.
Thanks for the fixes. I've verified and resolved the folder-preservation, duplicate-name, and symlink threads.
The remaining threads still need attention: dataset cache identity, published-file hashing, concurrent fetches, and CLI errors. On bdbe9182, a fetch finishing just after the new check can still make preparation omit a task, and run_target still lacks the ValueError catch mentioned in the reply.
|
Nonblocking: update the validation section. It still lists |
|
/ok to test 5b4eb8b |
|
🌿 Preview your docs: https://nvidia-preview-pr-3743-1bc58a7388c8.docs.buildwithfern.com/nemo/gym |
|
/ok to test 9d489d6 |
|
/ok to test 06cb0da |
|
/ok to test 92a5e8f |
|
Status at the new head 92a5e8f. The four remaining threads each have the fix inline:
You are right that the validation section was stale. I am replacing it in the description to match the branch: there is no --force flag anywhere, the recovery flow is to keep the local copy or delete the folder (or move it aside) and fetch again, and the test list names what tests/unit_tests/test_harbor_package_store.py actually holds. |
yuhezhang-ai
left a comment
There was a problem hiding this comment.
Thanks for the fixes. The fixed threads are resolved. Dataset cache identity still needs addressing before merge. Added one new nonblocking finding below for interrupted HTTP downloads.
|
/ok to test 58723ba |
|
/ok to test aaed18f |
|
/ok to test 0306fc7 |
yuhezhang-ai
left a comment
There was a problem hiding this comment.
Thanks for the fixes. Approved for the planned Harbor stack, including #4664 (5df89d45), where I verified the remaining cache-identity fix. The interrupted-download error is fixed in M9.
Focused tests and reproductions pass, as do the main CI checks. The optional, nonblocking harness-conformance check remains failing.
|
/ok to test d5ff29a |
ffrujeri
left a comment
There was a problem hiding this comment.
Approving d5ff29a9. The cache-identity fix now lives in M9 itself: fetch_package_dataset claims the folder through an exclusive manifest.toml create before the first download, records each task as it lands, and refuses an unreadable or foreign manifest. An interrupted fetch can no longer leave a folder another dataset reuses. The interrupted-download error and the other threads are fixed too. Package-store, Harbor, validation, CLI, config, sandbox, sessions and rollout-collection suites pass locally at this head (1514 passed, 13 skipped); CI was still running at approval time.
|
/ok to test bcee436 |
yuhezhang-ai
left a comment
There was a problem hiding this comment.
Rechecked after the rebase: the reviewed M9 changes are unchanged. Approved for the planned Harbor stack, including #4664 (66bcacd0), which contains the verified remaining cache-recovery fixes. Main CI passes; the optional harness-conformance checks remain nonblocking.
M9 of the Harbor tasks RFC. `harbor:<org>/<name>[@<tag> | @sha256:<digest>]` resolves a dataset in Harbor's package store, downloads every task package, checks each against Gym's task digest (the same record format Harbor publishes) and writes `manifest.toml` next to the tasks. Terminal Bench 4 lives there: `harbor:terminal-bench/terminal-bench@4.0.0` materializes all 66 tasks into `datasets/terminal-bench-4.0.0/`. The task model gains the Harbor 1.4 fields those packages use: `[[verifier.collect]]` hooks and typed `artifacts` entries. Names from the package store and the registry are checked before they become path components, and nothing is removed outside the dataset folder. A task folder whose digest differs from the store stops prepare with both digests named; `--force` refetches it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Adil Asif <adasif@nvidia.com>
|
/ok to test 1bc58a7 |
ffrujeri
left a comment
There was a problem hiding this comment.
Re-approving 1bc58a73 after the restack. git range-diff shows the patch is identical to the d5ff29a9 I approved.
|
🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA-NeMo/Gym/actions/runs/39680942488 |
What does this PR do?
M9 of the Harbor tasks RFC (GitLab MR 340, 354, 367): datasets that live in Harbor's package store. Stacked on #3730.
harbor:<org>/<name>[@<tag> | @sha256:<digest>].nemo_gym/tasks/harbor/package_store.pyresolves the dataset version through Harbor's public PostgREST API (tag or digest), lists its task packages, downloads each archive, checks it against Gym's task digest (the same record format Harbor publishes) and writesmanifest.toml. A folder whose digest already matches is kept, so a rerun completes a partial fetch.harbor:terminal-bench/terminal-bench@4.0.0materializes all 66 Terminal Bench 4 tasks intodatasets/terminal-bench-4.0.0/.[[verifier.collect]]hooks and typedartifactsentries (string or table, withhost_path). Artifact sources and destinations may not contain.., and a destination must be relative.Review fixes (2026-10-04)
registry.jsonand from package-store replies passvalidate_task_namebefore they become path components. Empty names,.,.., anything containing.., a path separator or NUL are refused. Characters real Harbor task names use, such as$, are accepted.contained_pathchecks that a folder resolves strictly inside the dataset folder before a fetch removes or replaces it. A spoofed name or a symlink cannot make a fetch touch files outside the dataset.Validation
pytest tests/unit_tests/test_harbor_package_store.py tests/unit_tests/test_harbor_tasks.py tests/unit_tests/test_cli_main.py environment_servers/harbor/tests: pass.TestPackageStore(tests/unit_tests/test_harbor_package_store.py) fakes the store at the HTTP layer: tag and digest resolution, the archive check against the published hash and the manifest, a rerun without downloads, the exclusion-free archive hash next to the folder digest (a package that ships a name the folder digest skips, with and without run noise), a spoofed package name refused before any filesystem use, nothing deleted outside the dataset folder, linked dataset folders and manifests refused, a folder withouttask.tomlleft alone, duplicate task names refused before writing, an edited folder stopping the fetch with both digests named, a deleted folder fetched again, the[dataset]identity check (a folder fetched for another package, a movedlatestrefused with both hashes), two concurrent fetches keeping the completed copy and a failed rename leaving no partial destination, an unreadable archive reported as a one-line error bygym eval runandgym dataset validate, an unreadable manifest rewritten only after the task checks, folder naming andfetch_refdispatch.TestTaskNamescovers refused and accepted names, and a registry entry with an unsafe name is refused.TestSeparateVerifierFieldscovers collect hooks, artifacts and artifact path containment.--forceflag. A folder whose digest differs from the store stops the fetch, and the documented recovery is to keep the local copy, or delete the folder (or move it aside) and run again, which fetches the store's copy.terminal-bench/terminal-bench@4.0.0packages downloaded and every digest matched the store's content hash.pre-commit run --files <changed files>clean.Rollouts
The 52 CPU tasks of the fetched dataset ran through
gym dataset validateon OpenSandbox Cell-3 in the M12 PR of this stack (#3746). Those runs predate the rebase below.Rebased onto main
Rebased onto
main128eab4 (2026-10-04).Compatibility and benchmark impact
Registry references and local folders are unchanged, apart from the task-name check on
registry.jsonentries. Package-store access uses Harbor's public read-only key. No credentials are needed.Checklist
pre-commit run --all-files) (so CI lint/format checks pass).git commit -s) (so the DCO check passes).🤖 Generated with Claude Code