Lab Manifest (lab.yaml)
A lab manifest (lab.yaml) is the portable description of a reproducible research lab: everything a human or agent needs to inherit the research. It is the contract behind the Reproduce This Lab button — see Reproduce a Lab.
lab.yaml (Hubify Lab Manifest spec v0.1) is a different file from hubify.json (the per-lab-repo manifest that wires a lab repo to Convex sync, GitHub, and compute). This page covers lab.yaml only.Where it lives
Every registered lab has a copy atlabs-registry/<slug>/lab.yaml in the hubify repo:
src/lib/lab-manifest.ts is the only place that parses lab.yaml — every page and component consumes typed LabManifest objects through it, never the raw file:
loadLabManifest(slug)— reads, parses, and validateslabs-registry/<slug>/lab.yaml. ThrowsLabManifestNotFoundErrorif the file is missing, orLabManifestValidationError(with a list of specific issues) if required fields are absent.listRegisteredLabs()— enumerates every slug underlabs-registry/that has a validlab.yaml, sorted.
node:fs) and back the /labs directory page and /labs/[slug] static params — there is no client-side or API accessor for manifest content today. See access patterns for what that means in practice.
Schema
Top level
lab
source
reproducibility
A
LevelEntry is:
Full level semantics: Reproducibility Levels.
programs[]
surfaces
status is a free-text string in the type (not a closed enum) — manifests in the registry today use values like exists_in_source, live, planned, in_progress, and (on freshly reproduced labs) not_configured / not_deployed.
manifests
An optional map of named paths to machine-verifiable manifest files. Today’s only user is manifests.level0, pointing at the JSON file a Level 0 archive was hashed against, e.g.:
sanitization
The planned extension
status: "planned" is a Hubify-side, additive extension to spec v0.1 — an honesty marker distinct from reproducibility. reproducibility says how far a lab’s results have been verified; status: "planned" says the referenced thing (a homepage, a source repo, a research program) doesn’t exist or hasn’t started yet, so the manifest doesn’t have to fabricate a URL, a repo, or a version to satisfy the shape.
It appears in exactly three places, all optional, all backward compatible (absence means the old implicit default of live/exists):
lab.homepage_status— the homepage URL is aspirational.source.status(+ optionalsource.notes) — no source repo exists yet;source.authoritative_repomay be omitted.programs[].status(+ optionalprograms[].notes) — the program hasn’t shipped a versioned artifact;version/paper_pdfmay be omitted.
eti and hubify-self-improving registry entries are fully spec-only labs built entirely from this extension — every program is status: planned, source.status: planned, and reproducibility.level: 0 with every level not_started.
Validation rules
loadLabManifest runs validateManifest before returning anything. It checks, in order:
- The parsed YAML is an object.
hubify_labis a number.labis present, andslug,title,tagline,homepageare all non-empty strings.lab.slugmatches the registry directory name.sourceis present; ifsource.status !== "planned",source.authoritative_repomust be a non-empty string.reproducibilityis present with a numericleveland an objectlevels.programsis an array; for each entry,idandtitleare always required, andversion+paper_pdfare additionally required unless that entry’sstatusis"planned".
LabManifestValidationError listing every issue found — not just the first.
Worked example
The registry copy ofbigbounce/lab.yaml (trimmed comment header), showing a Level 2 lab with real programs and no planned fields:
reproducibility.level: 2 while levels.1.status is still not_started — reporting is per-level and honest, not a cumulative ladder. See Reproducibility Levels for why that’s expected, not a bug.
For a fully planned-status manifest (no repo, no programs shipped), see labs-registry/eti/lab.yaml or labs-registry/hubify-self-improving/lab.yaml in the repo.