Skip to main content
One skill for the whole dataset lifecycle. It keeps a thin, git-tracked registry (datasets.yml), classifies each dataset into a storage tier, fetches and verifies bytes through a resolution chain, and mirrors durable copies to a private rclone remote. It is upstream of the experiment backend: runs declare the datasets they need, this skill materializes and verifies them, and the id + version + sha256 fingerprint flows into the backend’s provenance stamp so every reported result resolves to exact bytes. Grounding: ../../docs/design/03-dataset.md, ../../docs/design/04-substrate-and-contract.md (§2 substrate), ../../resources/references/dataset-management-standards.md, ../../resources/references/dataset-tooling-mirror.md, and ADRs ../../decisions/0009-dataset-thin-manifest.md, ../../decisions/0010-storage-tiers.md, ../../decisions/0011-rclone-mirror-sha256.md, ../../decisions/0012-shared-substrate.md. Agency: this skill fetches, verifies, and reports. It never decides which dataset is appropriate for a claim — that is a scientific judgement the researcher owns (and a defend methodology probe may ask them to defend). Tier is proposed here but confirmed by the human on register. Dependencies: pyyaml + pooch (Python) and rclone (a Go binary invoked as a subprocess, not a Python dep). Heavy loaders (datasets, pandas) stay in the consumer project, never in this skill.

When to use

  • A run/experiment declares a dataset dependency and needs it materialized + verified before it counts.
  • Adding a dataset to the project (register), or bootstrapping the registry the first time (init).
  • Pulling bytes for local work (fetch), or confirming on-disk bytes still match the manifest (verify).
  • Refreshing the private durability copy (mirror), or a whole-manifest health check before release/submission (audit).
  • Emitting a Croissant file for a venue (e.g. NeurIPS D&B) or ingesting one to bootstrap an entry.
Do not use it to choose a dataset for a hypothesis, judge whether data support a conclusion, or promote a tier because a mirror exists — those are out of scope.

Verbs

Composed: fetch = resolve + verify + mirror-populate; audit = verify across every entry plus schema/license/datasheet/tier completeness. Croissant ingest rides inside register (bootstrap an entry from a published Croissant); emit is the standalone export verb.

Manifest

Registry is a single thin, repo-owned, public YAML file: datasets.yml. Field names map onto schema.org / Croissant + DataCite so an entry can ingest and emit a Croissant file. It is not DVC machinery (dependency mass fails the light posture). Each entry extends the shared substrate base asset record. Required core fields (every tier): id, version, tier, license (SPDX id or explicit terms + URL), redistributable (bool), access (open|gated), files[] (each path + sha256), datasheet (path/URL; required — a "N/A + reason" placeholder is permitted only as an explicit, audit-flagged deficiency, never a clean state). Additionally: source/retrieval required for Tier B; acquisition instructions required for Tier C; sensitivity required if PII/confidential.
Tooling. This is honest_scholar/dataset/manifest.py, exposed via honest-scholar dataset validate (loader/validator) and honest-scholar dataset ingest|emit (Croissant) — ensure via ensure-tooling; design in ../../docs/design/proposals/dataset-manifest-tooling.md. By hand (if the CLI isn’t available):
  • loader/validator — load with python -c + yaml.safe_load and eyeball the base record + tier-conditional required fields (self-describing sha256: values) against the table above.
  • Croissant ingest/emit — hand-map registry fields ⇄ Croissant JSON-LD (name, license, citeAs, version, distribution[].contentUrl/.sha256) on register/export; keep the registry as the superset source of truth, Croissant as an export format.

Tiers

Tier = f(redistribution license × access automation). Redistribution dominates “can it be committed (Tier A)?”. Proposed by the skill, confirmed by the human. Every entry carries a Gebru datasheet (composition, collection, distribution, maintenance). It is also a defend methodology target (“what are this dataset’s known biases / collection limits?”).

Retrieval & mirror

fetch runs the substrate resolution chain, verifying SHA-256 at every hop; a file failing verification is treated as absent and the chain continues:
  • SHA-256 in the manifest is authoritative (integrity == identity == citation-verifiability). rclone’s native per-backend hash (often MD5 on Drive/S3) is only a transport check; local bytes are always re-hashed against the manifest after any transfer, so verification is backend-independent.
  • Cache is gitignored and content-addressed on the wire (sha256/<hash> keys → dedup, integrity == identity), name-addressed for use (symlink/copy).
  • The mirror is populated on first successful acquisition → link-rot insurance (Tier B) and a re-acquirable home for gated assets (Tier C).
  • Credentials never enter the repo: gitignore rclone.conf, point via RCLONE_CONFIG=$PWD/.honest-scholar/rclone.conf, commit only rclone.conf.example (remote name + type). CI uses env-var remotes from secrets. rclone obscure is not encryption — never commit it.
Tooling. The resolution chain is honest_scholar/dataset/retrieval.py, exposed via honest-scholar dataset fetch|verify|mirror|audit — ensure via ensure-tooling; design in ../../docs/design/proposals/dataset-retrieval-mirror-tooling.md. rclone is an optional external binary the wrappers shell out to, not a Python dep. By hand (if the CLI isn’t available):
  • Tier-B fetchcurl/wget then sha256sum and manually compare to the manifest before use (the module will use pooch.retrieve(url, known_hash="sha256:…") into the content-addressed cache).
  • rclone mirror — run the commands by hand with --config .honest-scholar/rclone.conf: mirror = rclone copyto <local> mirror:base/sha256/<hash>; resolution step 2 = rclone copyto mirror:base/sha256/<hash> <cache> then re-hash; audit may use rclone check --download when backend hash sets are disjoint.

Composition

  • Feeds the experiment backend. On each run, the backend’s provenance stamp copies id + version + sha256 for every declared dataset; verify must pass before a run’s evidence counts. See ../../docs/design/04-substrate-and-contract.md §3.
  • Shares the substrate mechanism (base record, rclone mirror, fixity, persistent-ID/citation) with literature; they share the mechanism, not the file (ADR-0012). This skill owns the dataset extension (tier, retrieval, datasheet, sensitivity) and datasets.yml.
  • Interop seams. Croissant emit/ingest (venue-mandated at NeurIPS D&B); DataCite citation + DOI make a dataset citable and DOI-archivable at Zenodo/Dryad/figshare — iff redistributable.
  • Datasheets close the loop with the rigor kit’s per-dataset datasheets and are a defend methodology target.

Guardrails

  • A private mirror is storage, NOT a redistribution grant. Tier and redistributable are set by the license, never by mirror presence. Refuse to promote to Tier A because a mirror exists; never surface mirror contents publicly. (ADR-0010; FAIR A1.2/A2: metadata stays open even when bytes are gated.)
  • Human confirms tier + license on register. The skill proposes; the researcher decides. Tier/license is a judgement, not an automation.
  • Tier must stay consistent with its inputs. tier is f(redistributable × access); a human confirms it but is not free to contradict the license. audit flags any entry whose tier disagrees with its (access, redistributable) fields (e.g. tier: A + access: gated, or tier: A
    • redistributable: false).
  • SHA-256 mismatch is a hard fail at every hop — never return or count unverified bytes. Never trust a backend-reported hash alone.
  • Tier C is verify-only — print acquisition instructions and wait for an operator drop; never attempt to fetch gated/credentialed data automatically.
  • Secret hygiene — never commit rclone.conf, tokens, or rclone obscure output; only rclone.conf.example (name + type) is tracked.
  • No blobs above Tier A in the repo — Tier B/C bytes live in the gitignored cache and/or the private mirror, never committed.
  • Never decide dataset appropriateness for a claim — out of scope (agency principle).

Commit attribution

When you commit artifacts produced by this skill, add these git trailers — discovery + provenance (see ../../resources/commit-attribution.md):