Profiles Validation Workflow#
This guide walks through creating, validating, and managing profiles in the SimReady Foundation spec. A profile is the top-level unit that asset producers and consumers work with — it defines exactly which features (and therefore which requirements and rules) apply to an asset. You will learn how to create a profile, validate assets against it, version it, and manage multi-profile scenarios.
Core concepts#
What is a profile?#
A profile is a named, versioned collection of features that represents a complete simulation scenario. When you validate an asset, you validate it against a profile. The profile determines which features are active, which in turn determines which requirements (and their backing rules) actually execute.
Profiles are defined in TOML (profiles/profiles.toml) and each profile version lists features by id and version:
[Prop-Robotics-Neutral]
"1.0.0" = {features = [
{"FET000_CORE" = {version = "0.1.0"}},
{"FET001_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET003_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET004_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET005_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET006_BASE_MDL" = {version = "0.1.0"}},
]}
How profiles connect to everything else#
Profile --selects--> Features --group--> Requirements --enforced by--> Rules (Python)
At validation time:
The profile is looked up by name and version.
Its feature list is resolved — each feature id+version is matched to a registered feature JSON.
Each feature’s requirements (including those from dependencies) are collected.
The corresponding rules execute against the asset.
Results are reported per-requirement and per-feature.
Existing profiles#
The current spec ships these profiles:
Profile |
Target |
Key differences |
|---|---|---|
|
Props, runtime-neutral |
Base features only (neutral physics, neutral colliders) |
|
Props, PhysX runtime |
PhysX-expanded physics and collider features |
|
Props, Isaac Sim |
PhysX physics + Isaac composition |
|
Robots, runtime-neutral |
Adds driven joints and base articulation |
|
Robots, PhysX runtime |
PhysX physics, robot core runnable, PhysX joints |
|
Robots, Isaac Sim |
Isaac robot core, Isaac joints, Isaac composition |
1. Determine what the profile needs#
Before creating a profile, answer these questions:
Question |
Example answer |
|---|---|
What asset type does it cover? |
Props, robots, vehicles, environments |
What simulation runtime does it target? |
Neutral (any), PhysX, Isaac Sim |
Which features must the asset have? |
Rigid-body physics, grasp physics, materials, semantic labels |
Which feature variants apply? |
Neutral colliders vs. PhysX merged mesh colliders |
Are there existing profiles to base it on? |
Extend |
Identify required features#
Browse the existing feature JSON files under features/ to find features that match your needs. Each feature has:
An
id(e.g.FET003_BASE_NEUTRAL)A
version(e.g.0.1.0)A
display_name(e.g. “Rigid Body Physics”)A list of
requirementsit enforces
Use the feature dependency graph to understand how features relate to each other and which dependencies they pull in.
Check feature availability#
Every feature referenced by a profile must exist as a registered JSON file under features/. Verify that the feature id and version in your profile match an existing file’s "id" and "version" fields. For example, {"FET003_BASE_PHYSX" = {version = "0.1.0"}} requires a file with "id": "FET003_BASE_PHYSX" and "version": "0.1.0".
2. Create the profile entry#
2a. Add the profile to profiles.toml#
Edit profiles/profiles.toml and add a new TOML table section for your profile:
[Prop-Robotics-Labeled]
"1.0.0" = {features = [
{"FET000_CORE" = {version = "0.1.0"}}, # "Core"
{"FET001_BASE_NEUTRAL" = {version = "0.1.0"}}, # "Minimal"
{"FET003_BASE_NEUTRAL" = {version = "0.1.0"}}, # "RBD Physics"
{"FET004_BASE_NEUTRAL" = {version = "0.1.0"}}, # "Simulate Multi-Body Physics"
{"FET005_BASE_NEUTRAL" = {version = "0.1.0"}}, # "Simulate Grasp Physics"
{"FET006_BASE_MDL" = {version = "0.1.0"}}, # "Materials (MDL)"
{"FET011_BASE_NEUTRAL" = {version = "0.2.0"}}, # "Semantic Labels"
]}
Naming conventions:
Use descriptive names that indicate the asset type and runtime:
<AssetType>-<Domain>-<Runtime>.Use hyphens and title case:
Prop-Robotics-Neutral,Robot-Body-Isaac.The profile name is the TOML table key and must be unique.
Profile structure:
Each profile is a TOML table:
[Profile-Name].Each version is a quoted key (e.g.
"1.0.0") mapping to{features = [...]}.Each feature entry is
{"FEATURE_ID" = {version = "version"}}.Add inline comments with the feature display name for readability.
2b. Create the profile documentation#
Create a markdown file in profiles/ for the new profile (e.g. prop-robotics-labeled.md):
# Prop-Robotics-Labeled
## Purpose
This profile targets robotics prop assets that require semantic labeling
in addition to the standard physics and material features. Use this
profile when assets will be consumed by perception pipelines or synthetic
data generation systems that rely on semantic labels.
## Version 1.0.0
### Features
| Feature | Version | Description |
| --- | --- | --- |
| FET000_CORE | 0.1.0 | Core asset structure |
| FET001_BASE_NEUTRAL | 0.1.0 | Minimal editor requirements |
| FET003_BASE_NEUTRAL | 0.1.0 | Rigid body physics |
| FET004_BASE_NEUTRAL | 0.1.0 | Multi-body physics |
| FET005_BASE_NEUTRAL | 0.1.0 | Grasp physics |
| FET006_BASE_MDL | 0.1.0 | MDL materials |
| FET011_BASE_NEUTRAL | 0.2.0 | Semantic labels |
### Differences from Prop-Robotics-Neutral
- Adds `FET011_BASE_NEUTRAL` for semantic label validation
- All other features are identical
Add the profile to the profiles index in profiles/profiles.md.
3. Validate assets against the profile#
3a. Asset metadata#
Production assets declare their profile in customLayerData:
#usda 1.0
(
customLayerData = {
dictionary SimReady_Metadata = {
string profile = "Prop-Robotics-Labeled"
string profile_version = "1.0.0"
}
}
defaultPrim = "MyAsset"
)
The validator reads this metadata and automatically selects the correct profile.
3b. Run validation#
From the repository root:
python -m simready.foundation.core asset.usda
The validator reads the asset’s SimReady_Metadata, looks up the profile, resolves all features and requirements, and runs every matching rule.
To override or specify a profile explicitly:
python -m simready.foundation.core --feature FET000_CORE asset.usda
python -m simready.foundation.core --capability Hierarchy asset.usda
3c. Interpret results#
The validation report shows:
Per-requirement results: Each requirement code (e.g.
HI.004) with pass/fail and any error messages.Per-feature results: Each feature (e.g.
FET000_CORE) passes only when all of its requirements pass.Profile result: The overall profile passes only when all features pass.
A failed requirement traces directly to the rule that detected the violation and the USD prim/attribute at fault.
4. Version a profile#
Profile versions are immutable — once a version is released, it must not be modified. Changes require a new version.
When to create a new version#
Trigger |
Version bump |
|---|---|
A feature version is updated (e.g. |
Major or minor |
A new feature is added to the profile |
Major or minor |
A feature is removed from the profile |
Major |
Bug fix in a feature’s requirement list |
Patch |
Add the new version#
Add a new version entry under the same profile table in profiles.toml:
[Prop-Robotics-Labeled]
"1.0.0" = {features = [
{"FET000_CORE" = {version = "0.1.0"}},
{"FET001_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET003_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET004_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET005_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET006_BASE_MDL" = {version = "0.1.0"}},
{"FET011_BASE_NEUTRAL" = {version = "0.2.0"}},
]}
"2.0.0" = {features = [
{"FET000_CORE" = {version = "0.1.0"}},
{"FET001_BASE_NEUTRAL" = {version = "1.0.0"}}, # Updated
{"FET003_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET004_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET005_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET006_BASE_MDL" = {version = "0.1.0"}},
{"FET011_BASE_NEUTRAL" = {version = "0.2.0"}},
]}
Update documentation#
Document the version change in the profile’s markdown file:
## Version 2.0.0
### Changes from 1.0.0
- Updated FET001_BASE_NEUTRAL from 0.1.0 to 1.0.0
### Migration notes
- Assets validated against 1.0.0 may need updates for FET001 1.0.0 requirements
- Use feature adapters to upgrade assets (see below)
Upgrade assets#
Assets pinned to the old profile version can be upgraded using the workspace CLI:
workspace upgrade --output_uri output_asset.usda \
--output_profile Prop-Robotics-Labeled \
--output_profile_version 2.0.0
This runs the appropriate feature adapters to transform the asset’s USD content from the old feature versions to the new ones.
5. Create a runtime-specific profile variant#
When the same asset type needs a runtime-specific profile (e.g. neutral → PhysX), follow this pattern:
5a. Identify feature differences#
Compare the base profile’s features with the runtime’s needs:
Feature area |
Neutral |
PhysX |
|---|---|---|
Colliders |
|
|
Multi-body |
|
|
Grasp |
|
|
Materials |
|
|
5b. Create the runtime profile#
[Prop-Robotics-Labeled-Physx]
"1.0.0" = {features = [
{"FET000_CORE" = {version = "0.1.0"}},
{"FET001_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET003_BASE_PHYSX" = {version = "0.1.0"}}, # PhysX variant
{"FET004_BASE_PHYSX" = {version = "0.1.0"}}, # PhysX variant
{"FET005_BASE_NEUTRAL" = {version = "0.1.0"}},
{"FET006_BASE_MDL" = {version = "0.1.0"}},
{"FET011_BASE_NEUTRAL" = {version = "0.2.0"}},
]}
5c. Plan feature adapters#
For each feature that differs between the neutral and runtime profiles, a feature adapter may be needed. See the Feature Adapters Guide for implementation.
Checklist for creating a profile#
Requirements analysis: Identify the asset type, target runtime, and required features.
Feature availability: Verify all feature ids and versions exist as JSON files under
features/.Profile TOML: Add the profile entry to
profiles/profiles.tomlwith all features and versions.Documentation: Create a profile markdown file in
profiles/and add it to the profiles index.Asset metadata: Ensure target assets include
SimReady_Metadatawith the profile name and version incustomLayerData.Validate: Run
python -m simready.foundation.coreagainst test assets and confirm the correct features and requirements execute.Version control: Never modify a released profile version — create a new version instead.
Tips#
Start from an existing profile. Copy the feature list of the closest existing profile and add/remove/swap features as needed.
Use inline comments. Add
# "Display Name"after each feature entry in the TOML for readability.Pin versions. Always use exact version strings (e.g.
"0.1.0"), not ranges.Test with known-good and known-bad assets. Validate against assets that should pass and assets that should fail to confirm the profile catches the right issues.
Cross-check dependencies. If a feature has dependencies, those dependencies’ requirements also execute — make sure they are appropriate for the profile’s target runtime.
Appendix: Profile resolution at runtime#
When the validator processes an asset, the resolution works as follows:
Read metadata. The root layer’s
customLayerData["SimReady_Metadata"]is read to findprofileandprofile_version.Look up profile. The profile name and version are matched against registered entries in
profiles.toml.Resolve features. Each feature entry is looked up by id and version in the registered feature set.
Resolve dependencies. If a feature declares dependencies, those are recursively resolved and their requirements are merged.
Collect requirements. The union of all requirements across all resolved features forms the complete validation set.
Run rules. Every registered rule that matches a requirement in the validation set executes against the USD stage.
Report. Results are aggregated per-requirement, per-feature, and for the profile as a whole.
Appendix: Profile and feature relationship diagram#
Prop-Robotics-Neutral 1.0.0
├── FET000_CORE 0.1.0
│ ├── NP.002, NP.003, NP.004, NP.005, NP.006, NP.007, NP.008
│ ├── SR.001
│ └── HI.010
├── FET001_BASE_NEUTRAL 0.1.0
│ └── AA.001, AA.002, UN.001, UN.002
├── FET003_BASE_NEUTRAL 0.1.0
│ └── RB.COL.001, RB.COL.002, RB.COL.003, RB.COL.004, RB.001, ...
├── FET004_BASE_NEUTRAL 0.1.0
│ └── JT.001, JT.002, RB.MB.001
├── FET005_BASE_NEUTRAL 0.1.0
│ └── (grasp requirements)
└── FET006_BASE_MDL 0.1.0
└── (material requirements)
Each requirement traces to a rule in validation.py inside the corresponding capability folder. Failures propagate upward: a failed requirement fails its feature, which fails the profile.
Appendix: What consumers should expect#
Not every profile in the repository is at the same maturity level. The SimReady Acceptance Workflow describes the full lifecycle.
Indicator |
What it means |
|---|---|
A profile lists the feature in |
The feature has completed the full acceptance workflow and is safe to validate against. |
A feature JSON exists but is not yet referenced by any profile. |
The feature is in late prototyping or testing. It may change before delivery. |
A capability directory contains requirements but no |
The requirements are defined but validators are still in progress. |
Sample assets exist in |
Reference implementations are available; check the corresponding profile version to confirm they are up to date. |
When in doubt, check the feature version and the profile that references it. Pinned versions in a profile represent the accepted, stable contract.