Spec Builder
The Spec Builder is where you design custom metadata specifications — your own entity types, fields, relationships, and validation rules — instead of using a built-in profile. Open it from Builder in the header.
A specification exists in two states:
- Draft — editable; listed under My Drafts.
- Published — an immutable released version; listed under Published Specifications.
A draft is identified by its name and version within your account, so you can hold several versions of one specification as drafts at once, for instance the version in use and the next one. Creating or importing a second draft at a name and version you already hold is refused; a draft whose name arrives from a template or an import gets a suffix instead.
Both lists group the versions of one specification together, newest first, under a single card. A profile with three versions in progress, or four releases behind it, is one entry in the list rather than several cards carrying the same title, which is what made a list of a few specifications unreadable. The card carries the name, the description and the author of the newest version; each version is a row with its number, its date and its own buttons. Under Published Specifications the audience is on the card when every version was published to the same one, and on the row otherwise. Published specifications are grouped within the account they live in, so two accounts that each release a specification of the same name are two cards. A card is titled by the specification's display name; when two cards would carry the same title, as two drafts cloned from one template do, each title also names the specification in brackets.
Creating a specification
- On the Specs page, click + New Specification.
- Choose how to start:
- From Scratch — an empty specification.
- From Template — start from a provided template. Each template offers its versions with the newest selected. A template that cannot be loaded is reported on the form; no draft is created in its place.
- Import YAML — upload an existing specification file (see Publishing and sharing).
- The hub asks for a name. Leave it empty and the hub names the draft: after the template, after the imported file, or with a numbered default.
- The draft editor opens.
The draft editor
The editor combines an entity tree, a diagram (ERD) canvas, and a form editor, with Profile, Rules, Checks, Comments, and Sharing tabs in the sidebar. Comments are threaded: a reply can itself be replied to, and the panel shows the whole thread at any depth. A reply to a comment that no longer exists — deleted while you were writing — is refused rather than posted as a new top-level comment.
The toolbar above the diagram arranges it the same way the Explorer does: Layout by force, Tree as the containment tree with the root at the top.
Entities
Click + Entity on the canvas to add an entity, then click an entity to edit it. From the entity editor you can rename the entity and mark one entity as the specification's root.
SEEK mapping
For a specification whose datasets are pushed to FAIRDOM-SEEK, the entity editor has a SEEK section with the table-level settings the push reads:
| Setting | Purpose |
|---|---|
| Role | The ISA object this entity becomes in SEEK: Investigation, Study, ObservationUnit, Sample, Assay or DataFile. Empty for an entity SEEK does not receive. |
| ISA template | For the sample-level roles (ObservationUnit, Sample, DataFile), the title of the ISA Template installed on the SEEK instance whose columns this entity's fields are. Empty for a specification that builds its own Sample Types by nesting. |
| Extended metadata type | For the Investigation, Study and Assay roles, the title of the Extended Metadata Type on the instance that the entity's scalar fields are pushed into. |
These settings are what makes a dataset pushable: the SEEK controls appear on a dataset only when its specification has an entity with the Investigation role. ISA tags, by contrast, are a property of fields and are set in the field editor; they say what column a field is in a Sample Type.
The section shows the settings a specification already carries, including one imported from YAML, so a specification's SEEK mapping is visible wherever its entities are edited.
Fields
Add fields to an entity with + Field. Each field has:
| Property | Purpose |
|---|---|
| Name | The field's identifier |
| Type | string, integer, date, ontology_term, entity, list, and others |
| Required | Whether a value is mandatory |
| Description | Help text |
| Ontologies | For ontology-constrained fields, the source ontologies |
| Within Branch | For ontology-constrained fields, the term whose descendants are the allowed values |
| Reference Resolves | For reference fields, whether the referenced record must be in this dataset or may be held elsewhere |
| ISA tag | The ISA tag the field carries into a SEEK Sample Type attribute |
Every control the field editor shows is saved when you save the field, and clearing one clears the stored value; the same settings are reachable through the MCP spec_update_field tool.
Under Markers the field editor carries the declarative annotations a consumer of the specification reads: the identifier and label markers, the completeness tier, a human-readable label, a unit, an example value, allowed values, the ownership marker for relationship fields, and the DCAT property described below.
DCAT property
A dataset can also be described as a DCAT catalogue record — the discovery-level statement that the dataset exists and where to get it, rather than what is inside it. The record is not written by hand: each field's DCAT property marker names the property of the catalogue record that the field's value supplies. Setting a field's DCAT property to dct:title, for example, makes that field's value the record's title.
The marker is only read on the specification's root entity, because a catalogue record describes the dataset as a whole. The field's own value is what ends up in the record, so the marker belongs on a field that carries dataset-level information (a submission date, a licence, a contact list).
The input suggests the properties metaseed resolves:
| Property | Fills |
|---|---|
dct:title |
The record's title |
dct:description |
The record's description |
dct:identifier |
The record's identifier |
dct:issued |
The publication date |
dct:license |
The licence |
dct:accessRights |
The access rights statement |
dct:publisher |
The publishing organisation |
dct:relation |
Related resources |
dct:source |
Resources this dataset was derived from, such as a repository accession |
dct:conformsTo |
Standards the dataset conforms to |
dcat:contactPoint |
The contact, taken from a contacts field |
dcat:landingPage |
The dataset's landing page |
dcat:keyword |
Keywords |
dcat:theme |
Themes |
The field accepts any value, since DCAT-AP profiles define further properties, but a property outside this list is recorded in the specification without affecting the catalogue record.
Relationships
Relationships are expressed through fields whose type references another entity:
- Use type
entityfor a one-to-one relationship (for example, Study has one principal investigator). - Use type
listfor a one-to-many relationship (for example, Investigation has many Persons).
Set the field's Related Entity to the target entity. A list field also defines a parent–child hierarchy: the related entity appears as a child in the entity tree.
| Relationship | Field type | Related entity |
|---|---|---|
| Investigation has many Persons | list |
Person |
| Study has one principal investigator | entity |
Person |
| Person belongs to an Organization | entity |
Organization |
Checks
The Checks tab in the sidebar reports what the draft looks like to metaseed. It separates two kinds of finding, because they call for different responses:
- Problems are defects. The specification does not build, so a dataset cannot be created from it until they are fixed — an undefined root entity, a field referring to an entity that is not there, a profile version that is not
MAJOR.MINOR. - Advisories are advice. The specification builds and works; something in it is probably not what the author intended. An advisory never makes the draft invalid.
The advisory reported today concerns the identifier. Every entity has one: the field whose value identifies a record, used wherever a record has to be named or linked. If no field is marked as the identifier, the first field that is not a reference is used. That inference is silent, so it is reported when the field it lands on is a weak choice — an optional free-text field with no pattern, allowed values, or uniqueness scope, whose name does not say it is an identifier. Such a field can be empty or repeated across records, so records become indistinguishable. Mark the intended field with the Identifier marker to settle it.
Neither kind blocks saving or publishing. The tab is a report, not a gate.
Saving
Each edit to an entity, field, or rule is saved as you make it; there is no unsaved state to lose, and the editor shows no "unsaved" marker. Save re-checks that the draft has a name and records the draft as a whole, which is what makes it refuse when the draft changed elsewhere since you opened it (below).
A save rewrites the draft's entire specification, so it is refused when the draft has changed elsewhere since you opened it — in another tab, or by a collaborator who has access to it. You get "This spec changed somewhere else since you opened it" rather than a success, because applying your copy would silently discard the other change. Reload the page to pick up the current version and reapply your edit.
Next
- Validation rules — add custom constraints
- Publishing and sharing — import/export YAML, publish, and fork