StandardsModel CompatibilityRules & Statuses

Rules and statuses

When you compare a source port with a target port, the comparison rules from each profile run against the two port contracts. Each rule produces a finding, and the findings combine into one status. This page lists the operators rules can use, what each status means, and what a finding looks like.

Rules are data, not code. A rule names a field in each contract using a JSON Pointer path, such as /contract/measurement/unit, and picks one operator from the list below. It can’t contain JavaScript, Python, templates or other expressions, so loading a profile never runs code. Field values are checked against JSON Schema (Draft 2020-12) first.

Here is a rule from the gene expression counts profile:

{
  "source": "/contract/biological_context/species",
  "target": "/contract/biological_context/species",
  "operator": "context-compatible",
  "missing": "unknown",
  "reason_code": "BMCS_VALUE_MISMATCH",
  "severity": "error"
}

It reads the species from both contracts and compares them. If either side leaves the species out, the result is UNKNOWN. The missing field can also be conditional, incompatible or ignore.

Operators

OperatorPasses when
equalBoth values are the same
not-equalThe values differ
inThe source value is one of the target’s listed values
not-inThe source value isn’t in the target’s list
subsetEvery item in the source list is in the target list
supersetThe source list contains every item in the target list
rangeThe source range (minimum to maximum) sits inside the target range
patternThe value matches a pattern
same-dimensionBoth quantities have the same physical dimension, for example both are concentrations
labels-equalBoth label lists are identical and in the same order
labels-permutationBoth lists have the same labels in a different order, so a reorder can connect them
unit-convertibleThe units are the same, or the release’s unit table has a conversion between them (currently nM, µM and mM)
term-equivalentTwo ontology terms mean the same thing
term-subsumesOne ontology term includes the other, for example a broader cell type
mapping-totalEvery source identifier maps to a target identifier
mapping-bijectiveIdentifiers map one-to-one in both directions
context-compatibleThe contexts match, or the target accepts any context (any, unspecified or null)
digest-equalTwo sha256 hashes match

Version 0.1.0-alpha.5 implements every operator above in both Python and TypeScript. Ontology and identifier-mapping rules need an exact, sha256-pinned snapshot when equality alone is not enough. If a needed snapshot is missing or invalid, the result is UNKNOWN with a stable reason code. Reports and plans record the snapshots they used.

Pattern checks are limited in length and reject unsafe forms. This keeps profile rules useful without letting a profile run arbitrary or expensive code.

For maintainers

A new profile that only uses existing operators needs a new data release and nothing else. A new operator needs code and conformance tests in both the Python and TypeScript implementations.

Order of checks

The specification groups checks from structure to policy:

  1. Port direction and name
  2. Whether the port carries a state or an event, and when data is produced and used
  3. Signal type, data type, shape and schema
  4. Dimensions, axes and feature order
  5. Units, scale, normalization and endpoint
  6. Biological meaning
  7. Identifier namespace and mappings
  8. Biological and experimental context
  9. Time context
  10. Origin, provenance, uncertainty and missing values
  11. File format
  12. Security, licensing, where data may be stored, and workspace policy

In this release, the reference implementations run each profile’s rules in the order the profile lists them.

Statuses

StatusMeaningDefault policy decision
EXACTThe two contracts are identical (same sha256)ALLOW
DIRECT_COMPATIBLEThe source satisfies the target as it is, with no conversionALLOW
LOSSLESS_CONVERSION_AVAILABLEA conversion that loses no information can connect them, such as nM to µMALLOW
LOSSY_CONVERSION_REQUIRES_APPROVALA conversion exists, but it may lose informationAPPROVAL_REQUIRED
INFERENCE_MODEL_REQUIREDThe target needs data the source doesn’t have, so a model must estimate itAPPROVAL_REQUIRED
CONDITIONALCompatibility depends on a condition that hasn’t been checkedAPPROVAL_REQUIRED
INCOMPATIBLEAt least one field contradicts the target, for example mouse data sent to a human-only inputBLOCK
UNKNOWNNot enough information to decide, usually because a required field is missingBLOCK

When you build a plan, a policy can change the decision for UNKNOWN, CONDITIONAL, and the conversion and inference statuses.

How findings combine:

  • If any rule finds a contradiction, the status is INCOMPATIBLE, even if other fields are missing.
  • Otherwise, if any rule lacks the information it needs, the status is UNKNOWN.
  • If either port has no contract at all, the status is UNKNOWN with reason code BMCS_CONTRACT_NOT_DECLARED.

Findings

Every finding has:

  • dimension: the part of the contract that was checked, such as biological_context
  • state: the result of this rule
  • severity: error, warning or info
  • reason_code: a stable BMCS_* code that you can match on in code
  • explanation: a short message for people

A finding can also include evidence (the two values that were compared), source_path, target_path and remediation.

Here the source outputs mouse data and the target expects human data. Both ports use the gene expression counts profile:

{
  "dimension": "biological_context",
  "state": "INCOMPATIBLE",
  "severity": "error",
  "reason_code": "BMCS_VALUE_MISMATCH",
  "explanation": "/contract/biological_context/species: 'context-compatible' check failed.",
  "evidence": {
    "source": "NCBITaxon:10090",
    "target": "NCBITaxon:9606"
  }
}

If the source leaves out the species instead, the finding is UNKNOWN:

{
  "dimension": "biological_context",
  "state": "UNKNOWN",
  "severity": "info",
  "reason_code": "BMCS_REQUIRED_EVIDENCE_MISSING",
  "explanation": "/contract/biological_context/species is missing from the source or target contract."
}

Every reason code and its meaning is listed in reason-codes.json.