fix(rc/0.4.1): hardening from skeptical-QA (put/register/scope/get) - #248
Merged
Conversation
High-1 (storage visibility): roar was calling create_repo(private=False, exist_ok=True), so 'roar put hf://…' silently created a PUBLIC repo — and '--private' (which only sets DAG visibility) never reached it. roar now treats the HF repo like an S3 bucket: it does NOT create the container and makes no visibility decision. A missing repo fails with an actionable error telling the operator to create it with their intended visibility. Removes the now-meaningless HFBackend(private=) param. F3 (token precedence): the upload backend read env-first while the download backend read ~/.hf_token first, so with both set roar could download and upload under DIFFERENT identities. Both are now env-first (matches huggingface_hub's own convention and lets a per-run HF_TOKEN override a stale token file). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The DAG's scope_request.visibility was derived solely from the bound project's frozen visibility, so an explicit --private on a PUBLIC project was silently ignored and the DAG went out public. Principle (one non-arbitrary rule): the flag governs DAG visibility — it may always tighten to private, but may not escalate a private project to a public DAG (rejected with a clear error). No flag -> the scope default (unchanged). Wiring: the publish builds several GlaasClients lazily/independently, so the CLI records the explicit choice in a request-scoped contextvar that every lazily-built client reconciles against (set_requested_publish_visibility); load_publish_auth_context also takes an explicit requested_public for tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… disabled (#243) The register receipt's secrets line always passed and its note read 'none detected' whenever zero secrets were recorded — including when the scan never ran (registration.omit.enabled=false), so real secrets could publish unredacted while the checklist gave green false assurance. The secrets check now takes secrets_scanned: when the scan is disabled the line fails (ok=False) with 'lineage was NOT scanned for secrets', and the note says the scan was disabled rather than 'none detected'. Scan-enabled parity with the execution's own omit_filter gate; default config keeps the scan on, so the normal path is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ance, warn without --hash Three --cache provenance fixes from the rc/0.4.1 QA pass: - B (documented fallback): a hash mismatch is REPORTED as success=False (not raised), so it bypassed the fallback try/except and hard-failed the whole get. An unsuccessful cache result now triggers the same canonical fallback the help text promises (canonical is still --hash-verified). - D (prefix provenance): a prefix --cache recorded the bare canonical prefix as every file's source_url, collapsing AI-BOM downloadLocation to the directory. Each file's mirror URL is now remapped onto the canonical prefix, so each row records its own canonical object. - A (unverified provenance): --cache without --hash records mirror bytes under the canonical URL unverified; it now warns. Provenance origin is tracked (fetched_from_cache) so a fallback fetch records the canonical per-file URL correctly too. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
rc/0.4.1 hardening — fixes from the skeptical-QA pass
A release-gating QA pass over the 0.4.1 candidate (put HF, get --cache, register/scope)
surfaced several confirmed defects — each reproduced, then fixed here with tests. Ranked
by severity below. (The trackio #247 findings are fixed on that PR's branch, not here.)
HIGH —
put: don't auto-create HF repos; unify token precedenceroar put --private hf://…uploaded bytes to a PUBLIC repo. Root cause + resolution(per design discussion): roar was calling
create_repo(private=False, exist_ok=True), soit created a world-readable repo and made a storage-visibility decision it shouldn't. Now
roar treats an HF repo like an S3 bucket — it does not create the container and makes
no visibility call; a missing repo fails with an actionable error.
--public/--privategoverns only the GLaaS DAG (below), never storage; storage visibility is the operator's.
→ roar could download and upload under different identities. Both are now env-first.
HIGH —
register: no false "Secrets: none detected" (#243)The receipt's secrets line always passed and read "none detected" whenever zero secrets were
recorded — including when the scan never ran (
registration.omit.enabled=false), so realsecrets could publish unredacted under a green checkmark. The check now takes
secrets_scanned:a disabled scan fails the line ("lineage was NOT scanned for secrets") instead of claiming
clean. Default config keeps the scan on, so the normal path is unchanged.
MED-HIGH —
scope: honor--public/--privatefor DAG visibility (#240)Visibility came solely from the bound project's frozen setting, so an explicit
--privateon a public project was silently ignored and the DAG went out public. Principle (one rule):
the flag governs the DAG — it may always tighten to private, but may not escalate a
private project to a public DAG (rejected with a clear error). No flag → the scope default.
Wired via a request-scoped contextvar so every lazily-built GlaasClient reconciles consistently.
MED —
get --cache: provenance fixessuccess=False),not raised, so it bypassed the fallback and hard-failed the get. An unsuccessful cache result
now falls back to the canonical source (still
--hash-verified) as the help promises.--cacherecorded the bare directory as every file'ssource_url(collapsing AI-BOMdownloadLocationto the folder). Each file's mirror URL isnow remapped onto the canonical prefix → each row records its own canonical object.
--cachewithout--hash(mirror bytes recorded under the canonical URL unverified).Tests
New/updated regression tests across
test_hf_backend.py,test_publish_auth_context.py,test_report.py, andtest_service.py(get). All touched-area suites green (383 tests);each fix independently re-verified against its QA repro.
Not included (deliberately)
credentialed-URL passthrough; the duplicated git block in get/service.py) → follow-ups.
Base: rc/0.4.1.