honest-scholar dataset capability (sub-spec 3). · Status: verified-source digest; migrates to the plugin’s resources/references/.
Bottom line
Thin customdatasets.yml + rclone (private mirror) + pooch (Tier-B fetch) + a ~200-line resolution-chain core. Reject DVC/DataLad/lakeFS/Quilt on dependency-weight grounds. Adopt huggingface_hub opportunistically for HF-hosted/gated data. git-annex is the fallback single-tool option if a Haskell binary is acceptable.
1. Tooling review
2. Private-mirror architecture — rclone
Single dep-free Go binary; Google Drive + S3/B2/R2/MinIO/SFTP/WebDAV/~65 more;remote:path; verifies integrity on transfer; rclone check/hashsum on demand.
Registry names a remote + path; the credential-bearing config lives outside the repo:
rclone.conf, point via RCLONE_CONFIG=$PWD/.honest-scholar/rclone.conf, commit rclone.conf.example (name/type only); or (2) env-var remotes (RCLONE_CONFIG_<NAME>_TYPE=drive, _TOKEN=…) from CI secrets — preferred for CI. Caveats: rclone obscure is not encryption (never commit it); env-var remote names use underscores; GDrive service account for CI, MD5 present on all files, 750 GiB/day upload quota.
Mirror × tier: A → redundant (skip, or large redistributable blobs); B → primary durability vs link-rot (populate on first fetch); C → essential (only re-fetchable copy after one-time gated acquisition).
3. Resolution chain fetch(name) — verify fixity at every hop
rclone check --download if backends’ hash sets are disjoint). Expected hash lives in the manifest (single source of truth), never trust a backend-reported hash alone. Cache: gitignored; content-addressed on the wire (<alg>/<hash> → dedup, integrity==identity, like HF blobs/), name-addressed for use (symlink/copy).
4. Registry format
Own a thindatasets.yml (YAML: human-editable, comments, pyyaml). Do not adopt DVC’s .dvc/dvc.yaml (bound to DVC’s cache + ~40 deps; lacks multi-source fallback). Keep pooch’s registry.txt (name hash) as an optional export. hash carries an alg: prefix (self-describing). Fixity philosophy from BagIt: an entry is valid only when every listed checksum verifies.
5. Plugin vs repo split
Plugin: manifest schema + loader/validator; resolution-chain + per-hop fixity; rclone integration (subprocesscopyto/check/hashsum; config via --config/env); Tier-B fetchers (pooch or minimal http/doi core) + Tier-A git/LFS + Tier-C drop-and-verify; cache policy; rclone.conf.example generator + secret-hygiene docs. Dep contract: rclone (binary subprocess, not a Python dep) + pyyaml + pooch.
Consumer: the datasets.yml entries + checksums; the rclone remote config (real creds, untracked/CI); Tier-A blobs; the gitignored cache; any heavy loaders (datasets, pandas).
6. One skill or a set? — one skill, verbs register | fetch | verify | mirror | audit (+ init). Verbs share the schema/tier/cache/chain mental model and are sequential lifecycle steps; fetch = verify + mirror-populate composed; audit = verify across the manifest.
Recommended stack
datasets.yml + pooch (Tier-B) + rclone (mirror, any backend) + ~200-line chain core; huggingface_hub opportunistic; reject DVC/DataLad/lakeFS/Quilt.
Sources
Git LFS spec/api; git-annex internals/special_remotes; DataLad (JOSS 10.21105/joss.03262); DVC docs + pyproject; HF Hub docs + setup.py; rclone docs (/s3,/b2,/drive,/docs env-vars); pooch (fatiando.org/pooch) + pyproject; BagIt RFC 8493; Zenodo policies. (URLs verified this session.)Flags
No maintained rclone-native Git-LFS transfer agent found (LFS-over-rclone needs glue). DVC checksum-on-pull via maintainer forum post; ~40 deps = direct required; no-fallback inferred from docs. rclone env-var behavior partly via forum (standard). Dep lists from currentmain packaging (sets stable, versions drift).