OpenCM 1.0 — Structural Causal Model Interchange Standard


**Version**: 1.0 (Stable)

**Status**: Published

**Authors**: Cognition Universal Intelligence Development Team

**Date**: February 2026




1. Abstract


OpenCM is a language-agnostic, JSON-based specification for representing **Structural Causal Models (SCMs)**. While standards exist for machine learning models (ONNX) and APIs (OpenAPI), causal inference has lacked a portable, versionable interchange format. OpenCM fills this gap — enabling researchers and engineers to share, validate, and compose causal structures across different software ecosystems.


An OpenCM file encodes a Directed Acyclic Graph (DAG) augmented with structural equations, noise parameters, business metadata, and explicit assumptions.




2. File Conventions


| Property | Rule |

|---|---|

| **Extension** | `.opencm.json` |

| **Encoding** | UTF-8 |

| **Top-level** | Single JSON object |

| **Model ID** | Lowercase alphanumeric with underscores: `^[a-z][a-z0-9_]*$` |

| **Versioning** | SemVer (`MAJOR.MINOR.PATCH`) |




3. Top-Level Structure


Every `.opencm.json` file **must** contain these fields:


```json

{

"opencm_version": "1.0",

"model": { ... },

"variables": { ... },

"edges": [ ... ]

}

```


**Optional** fields:


```json

{

"structural_equations": { ... },

"assumptions": [ ... ],

"validation": { ... },

"metadata": { ... }

}

```




4. Model Identity (`model`)


Every model must declare its identity:


| Field | Type | Required | Description |

|---|---|---|---|

| `id` | string | ✅ | Unique slug (`porters_five_forces`) |

| `name` | string | ✅ | Human-readable title |

| `version` | string | ❌ | SemVer string (default `"1.0.0"`) |

| `domain` | string | ❌ | Feature area (see §11) |

| `description` | string | ❌ | Technical summary |




5. Variables (`variables`)


Variables are the **nodes** of the causal graph. Each key is the variable ID (PascalCase recommended), mapping to a definition object.


| Field | Type | Required | Description |

|---|---|---|---|

| `type` | string | ❌ | `continuous` (default), `discrete`, `binary`, `categorical` |

| `domain` | `[min, max]` | ❌ | Value range for continuous variables (default `[0, 1]`) |

| `unit` | string | ❌ | Business unit (`$`, `%`, `users`, `index`, `score`) |

| `description` | string | ❌ | What the variable represents |

| `observed` | boolean | ❌ | Is this variable measurable? (default `true`) |

| `default_value` | number | ❌ | Starting value if known |

| `categories` | string[] | ❌ | Valid values for `categorical` type |


**Constraints:**

  • `domain[0]` must be strictly less than `domain[1]`
  • `categorical` variables should provide `categories`
  • Variable IDs must appear in at least one edge (`source` or `target`)



  • 6. Causal Relationships (`edges`)


    Edges define the directed causal structure. The array is ordered but order has no semantic meaning.


    | Field | Type | Required | Description |

    |---|---|---|---|

    | `source` | string | ✅ | Parent variable ID |

    | `target` | string | ✅ | Child variable ID |

    | `type` | string | ❌ | Relationship type (default `"causes"`) |

    | `strength` | number | ❌ | Absolute influence `[-1.0, 1.0]` (default `0.5`) |

    | `description` | string | ❌ | Narrative justification |

    | `confidence` | number | ❌ | Confidence in this edge `[0, 1]` (default `1.0`) |

    | `is_learned` | boolean | ❌ | Was this edge derived from data? (default `false`) |


    6.1 Edge Types


    | Type | Semantics | Strength Convention |

    |---|---|---|

    | `causes` | X → Y (direct cause) | Positive = amplifies |

    | `inhibits` | X ⊣ Y (suppresses) | Positive value auto-negated during simulation |

    | `correlates` | X ↔ Y (shared cause) | Non-directional association |

    | `mediates` | X → M → Y (M mediates) | Mediation pathway |

    | `moderates` | X modulates Z → Y | Interaction effect |


    **Constraints:**

  • `source` and `target` must exist in `variables`
  • No self-loops (`source ≠ target`)
  • The edge set must form a **Directed Acyclic Graph (DAG)** — cycles are invalid



  • 7. Structural Equations (`structural_equations`)


    The heart of OpenCM. Equations define how parent variables determine child values beyond simple linear weights.


    7.1 Simple Format (string)


    ```json

    "structural_equations": {

    "IndustryProfitability": "0.7 - 0.15*SupplierPower - 0.20*BuyerPower + 0.20*PricingPower"

    }

    ```


    A plain string expression. Default equation type is `linear`, default noise is `normal(0, 0.05)`.


    7.2 Rich Format (object)


    ```json

    "structural_equations": {

    "ConversionRate": {

    "type": "logistic",

    "expression": "1 / (1 + exp(-3 * (Desire - 0.5)))",

    "noise_distribution": "normal",

    "noise_params": { "mean": 0.0, "std": 0.02 }

    }

    }

    ```


    | Field | Type | Description |

    |---|---|---|

    | `type` | string | `linear`, `polynomial`, `exponential`, `logistic`, `interaction`, `synergy`, `custom` |

    | `expression` | string | Python-style arithmetic expression |

    | `noise_distribution` | string | `normal` or `uniform` |

    | `noise_params` | object | Distribution parameters (`mean`/`std` or `low`/`high`) |


    7.3 Expression Syntax


  • **Arithmetic:** `+`, `-`, `*`, `/`, `**` (exponentiation)
  • **Built-in functions:** `abs()`, `min()`, `max()`, `log()`, `exp()`, `sqrt()`
  • **Constants:** numeric literals (`0.5`, `3.14`)
  • **Variable references:** must reference direct parents only (as defined in `edges`)

  • **Constraints:**

  • Equation targets must exist in `variables`
  • Referenced variables must be direct parents per the edge set
  • Not all variables require equations — variables without equations are exogenous (root nodes)



  • 8. Assumptions


    A list of explicit boundary conditions. Models should be transparent about what they assume.


    ```json

    "assumptions": [

    "Static equilibrium analysis — does not model dynamic responses",

    "Forces are assumed independent at the input level",

    "Industry boundaries are clearly defined"

    ]

    ```


    Models without assumptions will trigger a validation **warning** (not error).




    9. Validation (`validation`)


    Optional requirements for calibrating the model against real data.


    | Field | Type | Description |

    |---|---|---|

    | `min_data_points` | integer | Minimum observations needed (default `20`) |

    | `required_variables` | string[] | Variables that must have observed data |

    | `suggested_datasets` | string[] | Recommended data sources |




    10. Metadata (`metadata`)


    Provenance and attribution.


    | Field | Type | Description |

    |---|---|---|

    | `author` | string | Creator or adaptor |

    | `citation` | string | Academic source |

    | `license` | string | Usage rights (default `"CC0-1.0-Universal"`) |

    | `tags` | string[] | Searchable keywords |

    | `source_url` | string | Original framework URL |

    | `adaptation_notes` | string | How the model was adapted for OpenCM |

    | `created_at` | string | ISO-8601 timestamp |

    | `updated_at` | string | ISO-8601 timestamp |




    11. Domain Registry


    Recognized domain values for `model.domain`:


    | Domain | Scope |

    |---|---|

    | `strategy` | Competitive strategy, positioning |

    | `marketing` | Demand, funnel, brand |

    | `finance` | Valuation, capital, risk |

    | `operations` | Supply chain, throughput |

    | `organization` | Culture, motivation, structure |

    | `technology` | Adoption, network effects |

    | `economics` | Macro/micro theory |

    | `psychology` | Behavioral, cognitive |

    | `healthcare` | Clinical, epidemiological |

    | `supply_chain` | Logistics, procurement |

    | `general` | Cross-domain |




    12. Validation Rules (Normative)


    A file is **valid OpenCM 1.0** if and only if:


    1. ✅ Contains `opencm_version`, `model`, `variables`, `edges`

    2. ✅ `model.id` matches `^[a-z][a-z0-9_]*$`

    3. ✅ `model.name` is a non-empty string

    4. ✅ At least one variable is defined

    5. ✅ All `source`/`target` IDs in edges exist in `variables`

    6. ✅ No self-loops

    7. ✅ Edge set forms a **DAG** (no directed cycles)

    8. ✅ Variable domains satisfy `min < max`

    9. ✅ Edge strengths are in `[-1.0, 1.0]`

    10. ✅ Equation targets exist in `variables`


    Items that trigger **warnings** (not errors):

  • Unknown `model.domain`
  • Missing `assumptions`
  • Unknown edge type



  • 13. Composition Protocol


    OpenCM models are designed to be **composable**. Two or more models can be merged into a single unified graph.


    13.1 Merge Algorithm


    ```

    COMPOSE(Model_A, Model_B) → Model_C:

    1. Union all variables; skip duplicates (first model wins)

    2. Union all edges; for duplicate (source, target) pairs,

    keep higher-confidence edge

    3. Merge equations; first model wins for shared targets

    4. Concatenate assumptions with model-ID prefixes

    5. Validate merged graph for DAG acyclicity

    ```


    13.2 Shared Variables as Join Points


    When models share variable names (e.g., `CompetitiveRivalry` in both Porter's and PESTLE), those variables become **join points** that bridge the two causal structures. This enables cross-domain analysis without manual graph surgery.


    13.3 Lensing


    A model can be **applied as a lens** — configuring an inference engine to reason through a specific causal structure. Multiple lenses can be compared by running the same intervention through each and contrasting outcomes.




    14. Example: Porter's Five Forces


    ```json

    {

    "opencm_version": "1.0",

    "model": {

    "id": "porters_five_forces",

    "name": "Porter's Five Forces",

    "version": "1.0.0",

    "domain": "strategy",

    "description": "Analyzing competitive intensity through five structural forces."

    },

    "variables": {

    "SupplierPower": { "type": "continuous", "domain": [0, 1], "unit": "index" },

    "BuyerPower": { "type": "continuous", "domain": [0, 1], "unit": "index" },

    "ThreatOfSubstitutes": { "type": "continuous", "domain": [0, 1], "unit": "index" },

    "ThreatOfNewEntrants": { "type": "continuous", "domain": [0, 1], "unit": "index" },

    "CompetitiveRivalry": { "type": "continuous", "domain": [0, 1], "unit": "index" },

    "IndustryProfitability":{ "type": "continuous", "domain": [0, 1], "unit": "margin" },

    "MarketShare": { "type": "continuous", "domain": [0, 1], "unit": "%" },

    "PricingPower": { "type": "continuous", "domain": [0, 1], "unit": "index" }

    },

    "edges": [

    { "source": "SupplierPower", "target": "IndustryProfitability", "type": "inhibits", "strength": 0.65 },

    { "source": "BuyerPower", "target": "IndustryProfitability", "type": "inhibits", "strength": 0.70 },

    { "source": "CompetitiveRivalry", "target": "IndustryProfitability", "type": "inhibits", "strength": 0.80 },

    { "source": "PricingPower", "target": "IndustryProfitability", "type": "causes", "strength": 0.75 },

    { "source": "MarketShare", "target": "IndustryProfitability", "type": "causes", "strength": 0.60 }

    ],

    "structural_equations": {

    "IndustryProfitability": "0.7 - 0.15*SupplierPower - 0.20*BuyerPower - 0.25*CompetitiveRivalry + 0.20*PricingPower + 0.15*MarketShare"

    },

    "assumptions": [

    "Static equilibrium — does not model dynamic responses",

    "Forces are independent at the input level"

    ],

    "metadata": {

    "author": "GetCognition (adapted from Porter, 1979)",

    "citation": "Porter, M.E. (1979). How Competitive Forces Shape Strategy. HBR.",

    "license": "CC0-1.0-Universal",

    "tags": ["competition", "industry-analysis", "strategy"]

    }

    }

    ```






    To the extent possible under law, Jamie Nixx and the GetCognition team have waived all copyright and related or neighboring rights to the OpenCM 1.0 Specification. This work is published from: United States.


    [![CC0](https://licensebuttons.net/p/zero/1.0/88x31.png)](http://creativecommons.org/publicdomain/zero/1.0/)


    See It in Action

    The spec is easier to grasp with real models. These examples cover the most common SCM patterns:

    Strategy

    Porter's Five Forces

    Michael Porter's framework for analyzing competitive intensity and industry attractiveness throug...

    Strategy

    Ansoff Matrix Strategy

    Igor Ansoff's Product/Market Expansion Grid for identifying growth opportunities through market p...

    Marketing

    Bass Diffusion Model

    Frank Bass's model for new product adoption, driven by innovators (coefficient p) and imitators (...

    Finance

    Altman Z-Score (Bankruptcy Risk)

    Edward Altman's formula for predicting the probability that a firm will go into bankruptcy within...

    See all 53 models →