Curation
Curation decides which episodes of a dataset train. You do it in the dashboard, on the dataset page and in the episode studio. The CLI and the SDK can do the same edits in bulk.
Every episode stands one of three ways:
- kept: nothing that blocks is open on it. It trains. A kept episode that nobody has ruled on is kept automatically: the rail and the studio mark it with an outline instead of the filled check, and keeping it yourself makes it yours. It does not mean no issue was ever found: an issue someone dismissed also leaves an episode kept.
- flagged: an issue that blocks a keep is open on it. It waits for a person to keep it, reject it, or dismiss the issue.
- rejected: left out of training.
The API, the CLI and the SDK call flagged UNREVIEWED (a filter says
state = UNREVIEWED), and the dashboard’s own filter text keeps
state:unreviewed.
In the rail, a row a person kept is tinted green, and one a person rejected red, with a bar of its colour down the row’s edge. A row kept automatically, one rejected by ingest validation or by a rule, and a person’s keep flagged again since stay plain.
Nothing here deletes data. A reject leaves the episode out of training; the recording stays and the reject can be withdrawn. An issue is a flag on an episode, never a removal. An outlier on the outliers tab raises no issue and changes no ruling: an outlier that was kept is still kept.
Keep and reject in the studio
Section titled “Keep and reject in the studio”Open a dataset from Datasets. The rail on the left lists every episode, under the all tab. Its other tabs, flagged, kept and rejected, each say how many episodes they hold; pick one to list only those. Click an episode in the rail to open it in the studio, or click review (or press Space) to walk the flagged episodes one by one. Review moves the whole page to the flagged tab, so its chip, the counts and the trajectories follow; click the chip, or all, to bring every episode back. An episode an issue flags keeps its yellow issue count in every tab.
The decision panel has two buttons:
| Button | Key | What it does |
|---|---|---|
keep | Enter | Keep the episode; it trains |
reject | Backspace | Reject the episode; it leaves training |
A ruling moves you to the next episode. Other keys in the studio:
| Key | What it does |
|---|---|
| ↑ / ↓ | Previous / next episode under the filter |
| Ctrl+Z | Withdraw your last ruling |
| f | Go to the box for a note or an issue |
| c | Cut the take at the playhead |
| 1 – 4 | The rail: all, flagged, kept, rejected |
| Space | Play / pause |
| Esc | Back to the dataset |
| ? | Show every key |
Hold ↑ or ↓ and the rail moves with the key. The episode opens where you stop, and only that one counts as viewed.
Keep, by Enter or the keep button, closes the issues open on the episode in the same step, with no question asked. A toast says how many it closed and has an Undo button. Reject leaves the issues open: they stay as the record of why.
Undo, and Ctrl+Z, withdraw the ruling; they do not restore an earlier one (a keep made over a reject does not bring the reject back). Ctrl+Z withdraws the ruling you just made even after the studio has moved on to the next episode, and takes you back to it; on any other episode you opened since, it withdraws that ruling all the same and names the episode, and you stay where you are. A withdrawn keep opens again the issues it closed, and the episode then stands as derived: flagged while a blocking issue is open on it, kept otherwise.
Keep and reject in bulk
Section titled “Keep and reject in bulk”The dataset page rules on whatever the current filter leaves. There are no checkboxes. Narrow the page first:
- the rail tabs: all, flagged, kept, rejected
- the filter chips and presets, for example “outcome: failure”, “length < 20s”, “ruled by a person” (a person kept or rejected it) or “kept automatically”
- a segment of the standing bar, or an issue kind in the issues table
The count beside the filter says how many episodes are left. Then click Keep or Reject (or press Enter or Backspace). A dialog asks first: “Keep n episodes?”. At most 10,000 episodes are ruled on at once; narrow the filter if there are more.
From the CLI, the same filter selects the episodes. Count and list what it leaves first, then rule on it, or on episodes by id:
qualia dataset summary <DATASET_UUID> --filter 'state = UNREVIEWED' --facet open_issue_codesqualia dataset episodes <DATASET_UUID> --filter 'state = UNREVIEWED AND open_issue_codes:"jerky"'qualia dataset keep <DATASET_UUID> --filter 'state = UNREVIEWED AND open_issue_codes:"jerky"'qualia dataset reject <DATASET_UUID> <EPISODE_UUID> --reason "operator in frame"qualia dataset reset <DATASET_UUID> <EPISODE_UUID>qualia dataset restore <DATASET_UUID> <EPISODE_UUID> --reason "the fps metadata was right"Each ruling prints how many episodes changed, already stood that way, or were
skipped. reset withdraws a ruling, as Ctrl+Z does. restore puts back an
episode ingest validation rejected. A take someone has open in the studio is
left as it was: the command lists it with who holds it on stderr, and you run it
again once they are done. See
qualia dataset keep.
Trim, split and subtasks
Section titled “Trim, split and subtasks”A trim keeps one continuous stretch of a recording. A split keeps two or more stretches. A subtask labels a span, such as “grasp” or “place”. All three are saved as a draft on the original take; they do not change the dataset or an existing version while you work.
Open the studio’s editor tab:
- Drag a trim handle, or select a stretch in the film and keep or drop it.
- Click cut (or press c) at the playhead; drag the cut to move it. Drop the unwanted stretches between cuts.
- Handles and cuts snap to recorder markers. Hold Ctrl (⌘ on Mac) to place one freely, or switch snapping off.
- In subtasks, name a track and add or move its segments. Segments cannot overlap; the pieces you publish keep the subtasks inside them.
- reset discards the saved drawing, with a short chance to take it back.
The studio saves as you draw. A saved draft stays when you walk, rule on the take, leave or return later. A failed or unsaved drawing asks whether to stay or discard it before leaving. Another person editing the take makes it view only; after they leave, an authorized teammate can continue the shared draft. Nothing applies a drawing to the live recording. Labels and keep/reject rulings are separate changes.
An issue with timed evidence can open the editor at that stretch or suggest a dropped stretch. That drawing is saved like any other draft. It does not dismiss or reopen the issue; manage the issue or ruling separately.
Publish turns the selected saved drawings into a version. Each kept window becomes an immutable episode of that version: take 12 split in two reads as 12.1 and 12.2, with its source window and original take still linked. The original take and its draft stay available for another edit. A published piece is read only; change the original draft and publish another version.
The CLI and SDK draw the same drafts. Marker helpers can cover a selection:
qualia dataset markers <EPISODE_UUID> -d <DATASET_UUID>qualia dataset trim <EPISODE_UUID> -d <DATASET_UUID> --start-at-first ready --end-at-last donequalia dataset subtasks <EPISODE_UUID> -d <DATASET_UUID> --at grasp --at placeSee qualia dataset trim,
qualia dataset subtasks and
qualia dataset split.
Issues
Section titled “Issues”An issue says something is wrong with an episode. A check raises it, or the operator while recording, or a person. A note is the same kind of message that asks nothing of anyone.
An open issue that blocks holds the keep: the episode stays flagged until someone keeps it, rejects it, or dismisses the issue. An issue never deletes or rejects an episode.
On the dataset page, the issues table lists issues by kind, with who raised them and what they say. It has two views, open and dismissed.
- Click a kind to narrow the page to its episodes. Then open an episode from the rail.
- × dismisses that kind on every episode of the dataset. Episodes with no other open issue become kept. reopen on the dismissed view undoes it.
In the studio, the notes and issues of the open episode are on the Notes & issues tab. Click one to open its thread. A thread can be dismissed (dismiss) or reopened (reopen), or replied to. Press f to go to the box under them. Enter is a new line there: the Add note and Raise issue buttons (and Reply in a thread) are the only way to send, because Enter keeps the episode in the studio. An issue puts the episode back in review until someone rules on it.
Checks and the VLM check
Section titled “Checks and the VLM check”The Checks panel on the overview tab lists the checks that can run on the dataset, by category, with each one’s last result. Run them with Run all, Run category or Run selected. The Run checks dialog lets you pick the episodes (all, or the current filter), check only a sample, and set a Credit ceiling. It shows the estimate first: “Up to c credits for e episodes and k checks.” Findings land in the issues table.
The VLM check has a vision-language model read each episode against the published Task it was recorded for. It costs credits. It reads only episodes linked to a published Task and with a published video; see Robots and tasks for linking a Task.
- A confident failure becomes an issue. It holds the keep.
- A doubtful failure or an uncertain reading becomes a note.
- A new run refreshes what the last one found. Your dismissals stay.
Where the check catalog is not available, the overview shows a VLM check panel instead. Its run… button opens Run the VLM check, with the same choices and the credits it will reserve.
From the CLI, estimate first; it starts and charges nothing:
qualia check estimate <DATASET_UUID> --max-episodes 50qualia check run <DATASET_UUID> --max-episodes 50 --max-cost 200 --waitqualia check findings <DATASET_UUID>--max-episodes checks a sample; --max-cost caps the credits. qualia dataset checks list|run runs catalog checks by id or category, and qualia dataset checks findings reads what they found. See
qualia check.
Reach solver
Section titled “Reach solver”The reach solver walks each handheld take on a robot and finds where the robot
cannot follow the hand. It is for UMI datasets (tagged umi or egocentric).
It needs the dataset’s robot, picked in the Setup strip of the
trajectories tab, and that robot needs a model (its URDF). See
Robots and tasks.
Open the trajectories tab. The Setup strip has Play on robot, the Poses and a Solver, each a pick or one line; click (?) beside a row for what it means. Pick the robot. If every arm of that robot has a TCP, the poses are moved to tool center point by themselves (once, and only when they are not there yet), and Run solver waits for them. Then pick the IK solver and click Run solver. Nothing is solved until you do. When it cannot be pressed, the reason is written beside it. A dataset that is not UMI has no Solver row and no Run solver button. When it is done, the stretches out of reach are drawn amber on the take lines.
The solver flags; it never rejects. A take is raised as an issue when the robot cannot follow the hand for long enough in a row, or when two of the robot’s parts overlap. You decide what to keep.
To move and turn where the takes sit relative to the robot, open the Placement line under the solver in the Setup strip: forward, left and up in metres from the midpoint of the robot’s home hands, and a heading in degrees. The takes move on the 3D canvas as you type. Click Save placement to keep the position and heading together, or Discard to go back to the saved ones. Run solver saves a placement you have typed and not saved, then walks the takes from it.
A dataset’s options
Section titled “A dataset’s options”On Datasets, each card has … in its top right corner. Right-click a card to open the same menu. In the list view, the menu is at the end of each row. It offers:
- Download: the newest version. See Download a version.
- Open in new tab, Copy link and Copy ID. The ID is what the SDK
and the CLI take, for example
qualia dataset delete <ID>. - Copy to… and Move to…: put it in another workspace. The dialog lists every workspace you can reach, grouped by organization. One you can’t use stays in the list, greyed, with the reason under it. A copy is a new dataset that starts at the version you pick (the current one by default) and shares the content, so inside one organization nothing is uploaded again. A move keeps its name, history and links, and works only within its organization; across organizations, copy it. Adding to a workspace needs Contributor or higher there; moving out of a workspace, or copying out of the organization, needs Admin or Owner. When it is done, the dialog says what it copied, for example “Copied 4.0 GiB, 34 episodes in 0.8 s”, and links to it. Closing the dialog does not stop it; a message with the same line and link says when it is done. Both items are also in … beside the name on the dataset’s own page, where closing the dialog after a move takes you to the dataset in its new workspace. A version’s page has Copy to… with that version picked.
- Rename…: changes the name it is shown by. Its address stays, so links keep working.
- New mixture from this…: a new mixture that reads it. See Mixtures.
- Merge with… on an upload, or Add uploads… on a merged dataset: opens
the merge with it picked. A whole merge cannot be undone, but one upload can
later be removed and becomes a standalone upload again. The item is disabled while an
upload cannot be merged yet; hover it to see why. If a mixture reads the
upload as it changes (
stableorhead), the merge dialog says so and offers two ways on: keep that mixture on the upload’s newest version, when it reads just what that version holds (it reads the same episodes after the merge), or remove the upload from it. If the upload changed after the list loaded (a new version, or new changes), keeping the mixture is refused, since it would drop those changes, and only the removal is offered. - Delete…: the dataset leaves every list and every mixture. Nothing is erased, and versions already made from it keep working. A mixture that reads it blocks the delete until that source is removed.
Viewers see the download, open and copy items, and Copy to… and Move to…, whose dialog says where they can copy to.
To merge several uploads at once, Shift-click each of their cards (in the table, Cmd- or Ctrl-click the rows): a click picks only the one you click. Then click Merge in the bar at the bottom of the page. Click a picked one again to drop it, and click empty space, press Escape or click Clear to drop them all. Changing a filter or collapsing a group drops the ones it hides, so nothing hidden is merged.
Mixtures
Section titled “Mixtures”A mixture is a dataset that reads other datasets: uploads, other mixtures, every upload with a tag, or every upload linked to a Task. It stays up to date as they change.
On Datasets, click mix. In New mixture, give it a Name, choose
sources from the tags, tasks, uploads and mixtures tabs, and
click create mixture. Each source follows its latest version (stable) or
what it holds now (head).
To start a mixture from one dataset, click … on its card, then New
mixture from this…. New mixture opens with that dataset picked, named
after it and pinned to its newest version (a dataset with no version yet is
read at head). The mixture has its own keep and reject and its own versions;
the table below says what stays shared. Nothing is copied in storage.
A dataset source can also stay on its newest version: choose pinned and
that tag instead of stable or head. A mixture that follows an upload
(stable or head) keeps it from being merged; one pinned to a version does
not.
What belongs to a mixture and what is shared:
| Per mixture | Shared when editing the original take |
|---|---|
| Keep and reject | Saved trim, split and subtask drawings |
| Issues raised in the mixture, and dismissals | Tags, task link and outcome |
A reject made in a mixture belongs to that mixture. A reject on the upload holds in every mixture; only the upload can take it back. A bulk keep or reject in a mixture skips episodes settled upstream. Upload issues show in the mixture as “upstream” and are settled on the upload.
One upload can feed several mixtures with different selections. Its original take has one shared drawing; publishing freezes the selected drawing in that version’s immutable pieces. A mixture reads those edits through the published version, according to what its source follows:
head: the current recordings, without saved drawings. Saving a trim, split or subtask drawing does not change this source’s episodes.stable: the edited pieces after the source publishes a version containing that drawing.- a pinned tag: after you move the pin to a newer tag. A tag keeps the episode as it was when the tag was made.
Versions
Section titled “Versions”A version is a named, immutable selection for training and downloads. Later drawings, labels, rulings or re-ingest do not rewrite it.
Click Publish on an upload or merged dataset. In Publish version:
- Choose which groups to include. Kept by a person is the default; you may explicitly include all kept, flagged or rejected takes. You do not have to finish reviewing the dataset first.
- Click Apply all. It saves open studios’ work, freezes the selection and measures its exact kept windows. It changes no recording or draft.
- Inspect the episodes, duration, edited takes, splits, measurements and Takes left out, each named with its reason. No measurement means an included window is unmeasured; a listed omitted take is left out.
- Name the version, add a note and click Create version. It publishes exactly that preview as base takes and immutable cut episodes.
If you change the include groups or want newer drawings, use Apply all again. A message saying takes changed since Apply all means Create still uses the preview you inspected. A recording/settings change can require a new preview. If creating finds another take it cannot include, it returns for another explicit decision; inspect the updated omissions before trying Create again. You can close the dialog while measurement or publication continues. Retry opening version retries only the final read if creation already succeeded.
The versions tab shows the frozen result. Edits lists every included
edited window and opens the exact pinned piece; All episodes has its own
paging and source filter. On a frozen version, search 12 to find the
original take and its 12.* pieces, or 12.1 for its one-based piece. Search
reads the complete pinned membership and reports an error instead of partial
matches if that read is incomplete or too large. The publication’s
edited/trimmed/split counts count takes; its piece count counts the new
episodes those drawings produced. The curation record below describes what
happened after that version was created.
Comparisons show before/after pieces grouped by original take, after reading all pages. Added/removed/changed episode totals are separate from affected takes. Changes since the newest preview-made version count changed takes, not saves or clicks: saving an unchanged drawing adds no change.
A mixture follows or pins versions to include their published edits. A
source followed at head is as recorded, without edits. A mixture’s own
Publish tags its resolved head; it has no draft preview. A source following
stable moves to the new tag; a source pinned to an older tag stays there.
Version names are 1–64 letters, digits, dots, dashes or underscores, starting
with a letter or digit. stable, head and all-hex names are reserved.
From the CLI:
qualia dataset version-preview <DATASET_UUID> --jsonqualia dataset pin <DATASET_UUID> 1.0 --preview <PREVIEW_NAME> --note "first cut"# Explicitly include another group, or tag current head without drawings:qualia dataset pin <DATASET_UUID> 1.1 --include kept_by_person --include flaggedqualia dataset pin <DATASET_UUID> 1.2 --as-recordedversion-preview reads every page and prints windows, omissions and measured
metric count/mean/p5/p50/p95. --json keeps the full typed items and analysis.
Omitted/nonfinite/unmeasured or incompatible-profile values do not enter the
summaries; zero is a valid scalar. Percentiles choose sorted index floor(p×N),
capped at N−1. No pose-vector MAD or head metric is invented for a window.
pin DATASET TAG also creates and measures a preview when no explicit mode
is given. It refuses omitted takes unless you review and acknowledge them
with --allow-left-out. --include, --preview, --as-recorded and --digest
are mutually exclusive. Without TAG, pin DEFINITION_UUID keeps the separate
definition-pin behavior.
The SDK offers the same explicit sequence:
preview = client.versions.preview(dataset)page = client.versions.preview_items(preview)items = list(page.items)while page.page_info.has_next: page = client.versions.preview_items(preview, cursor=page.page_info.end_cursor) items.extend(page.items)# Review preview.unprocessable and items before publishing this exact selection.version = client.versions.create(dataset, "1.0", preview=preview)create returns the actual Version. It refuses omissions unless
allow_left_out=True; as_recorded=True tags head without saved drawings.
For asynchronous control, call preview(wait=False) and
publish_preview(wait=False) yourself; both return VersionPreview. Reuse
request IDs and the same arguments when retrying a logical operation.
Timeouts do not authorize a different selection or make a replacement preview.
These helpers require the matching version-publication server and SDK/CLI
builds; the documentation does not announce a new released package version.
Re-ingest never rewrites a saved version. With the separately activated footage-based re-cut path, unchanged recordings keep their IDs and drafts; changed recordings get new IDs, and source settings lists state not carried from the old takes. Legacy applied trims/splits return as recorded with their losses named. An unavailable report is not a clean result. The production feature flag is currently off; see re-cut availability and results.
To download a version, see Download. Published windows, subtasks, tags and normalization come from that exact pinned version, including its immutable cut pieces; later draft saves and re-ingest do not change the download.