Conceptual Data Model — Caméléon CVM
Version : v0.18-dev Authors : O. Cugnon de Sévricourt, C. Cugnon de Sévricourt
1. Overview
The Caméléon data model is organized in three tiers, classified by their grounding in Petri net theory :
- Formal concepts — directly mapped to a Petri net primitive (transition, place, net, color set)
- Applicative concept — first-rank in Caméléon but without Petri net equivalent (UI-specific)
- Structural entities — supporting structures owned by formal or applicative concepts
2. Formal Concepts — Petri-grounded
Each formal concept maps to a primitive from classical Petri net theory or from Colored Petri Nets (Jensen, 1981).
2.1 Operator «transition»
The central concept. An Operator is a Petri net transition — it consumes tokens from input places and produces tokens on output places.
| Attribute | Type | Description | ||
|---|---|---|---|---|
id | string | Snake_case identifier, unique within its library | ||
label | string | Display name | ||
family | "structural" \ | "transform" | Structural operators copy references; transform operators process data | |
category | string? | Optional grouping (e.g. "io", "data", "struct") | ||
description | string? | Human-readable purpose | ||
firingPolicy | FiringPolicy | When the operator becomes READY (see §4.1) | ||
interaction | "human" \ | "live" \ | absent | Human-in-the-loop mode (see §4.2) |
run() | function | run(inputs, { signal, config }) → outputs | ||
canFire() | function? | Custom firing guard for COND policy | ||
rollback() | function? | Undo logic for backward execution |
| Lifecycle states : `IDLE → READY → RUNNING → COMPLETED | FAILED | CANCELLED` |
|---|
2.2 Connection «place»
A Connection is a Petri net place — it holds a data token and governs the firing readiness of downstream operators through its state automaton.
| Attribute | Type | Description | ||
|---|---|---|---|---|
id | string | Unique identifier | ||
from | string | Qualified output plug id | ||
to | string | Qualified input plug id | ||
state | ConnState | EMPTY \ | NEW \ | OLD |
value | any | The data token (when state ≠ EMPTY) |
The state automaton EMPTY → NEW → OLD → EMPTY is the core mechanism of the execution model — it determines which transitions are enabled at each step.
2.3 Composition «net»
A Composition is a Petri net (P, T, F) — a complete workflow topology describing operator instances and their connections.
| Attribute | Type | Description |
|---|---|---|
name | string | Composition name |
description | string? | Purpose |
version | string? | Semantic version |
authors | string[]? | Contributors |
nodes | object | Map of alias → { operatorId, configValues?, position? } |
connections | array | List of { from, to } linking qualified plug ids |
Compositions are stored as .cm.js files — pure topology, no logic.
2.4 Type «color set»
A Type classifies the data that flows through plugs and connections. It maps to the color set concept from Colored Petri Nets (Jensen, 1981) — tokens are not anonymous dots but carry typed data.
| Attribute | Type | Description |
|---|---|---|
id | string | Unique identifier (e.g. DataString, DataJSON) |
label | string | Display name |
color | string | Visual color for UI rendering |
Built-in types : DataString, DataJSON, DataBool, Binary, Any
Each Type can have an associated viewer Control (read-only display) and an editor Control (interactive input).
3. Applicative Concept — UI-specific
3.1 Control «applicative»
A Control is a UI component bound to a Type. It renders data values and optionally captures user input. Control has no equivalent in Petri net theory — it is a Caméléon-specific concept for bridging the execution model with user interaction.
| Attribute | Type | Description |
|---|---|---|
id | string | Unique identifier |
label | string | Display name |
type | Type.id | The data type this control handles |
render() | function | render(value, container) — displays the value |
onInput() | function? | onInput(callback, container) — captures user input |
Behavioral roles (duck-typing)
Control has two behavioral roles, determined by which methods are present — there is no class hierarchy:
- «viewer» — has
render()only → read-only display of a typed value - «editor» — has
render()+onInput()→ interactive input for a typed value
Controls are also used for operator interaction — when an operator has interaction: "human" or interaction: "live", a Control provides the UI for human-in-the-loop.
4. Enumerated Attributes
4.1 FiringPolicy
Determines when an Operator transitions from IDLE to READY.
| Value | Semantics |
|---|---|
ANY | ≥1 input connection is NEW |
ALL | All input connections are NEW |
COND | Custom canFire(states) returns true |
Source operators (no inputs) are READY when all output connections are EMPTY.
4.2 Interaction
| Value | Semantics |
|---|---|
| absent | Autonomous — fires and completes without user input |
"human" | Blocking — waits for a single user resolve, then completes |
"live" | Re-fires on every user input until explicitly stopped |
4.3 Connection State
| Value | Semantics |
|---|---|
EMPTY | No token — place is free |
NEW | Token just deposited — not yet consumed |
OLD | Token consumed by downstream operator |
5. Structural Entities
5.1 Plug
A typed connection point on an Operator — either input or output.
| Attribute | Type | Description | |
|---|---|---|---|
id | string | Identifier within the operator | |
label | string | Display name | |
type | Type.id | Data type reference | |
side | "input" \ | "output" | Direction |
Qualified addressing : alias.plug_id (e.g. transform_1.in_data).
5.2 Config
Static parameterization of an operator instance — not part of the Petri net data flow.
| Attribute | Type | Description |
|---|---|---|
key | string | Parameter name |
type | Type.id | Expected data type |
label | string | Display name |
default | any? | Default value |
required | boolean? | Whether the parameter must be set |
Config values are resolved at execution time : configValues[key] ?? schema.default.
5.3 Library
A package of reusable operators.
| Attribute | Type | Description |
|---|---|---|
name | string | Package name (e.g. std-io-lib) |
label | string | Display name |
version | string | Semantic version |
author | string | Creator |
domain | string? | Specialization domain |
Naming convention : std--lib.js (standard) or cst--lib.js (custom).
6. Relationships and Cardinalities
Library 1 ──── 0..N Operator (a library exports N operators)
Operator 1 ──── 0..N Plug (input) (N input plugs)
Operator 1 ──── 0..N Plug (output) (N output plugs)
Operator 1 ──── 0..N Config (N config parameters)
Plug N ────── 1 Type (each plug has one type)
Config N ────── 1 Type (each config entry has one type)
Type 1 ──── 0..1 Control «viewer» (one viewer per type)
Type 1 ──── 0..1 Control «editor» (one editor per type)
Operator 0..1 ── 0..1 Control (interaction control, if interactive)
Composition 1 ──── 1..N OpInstance (instantiated nodes)
OpInstance 1 ────── 1 Operator (template reference)
Composition 1 ──── 0..N Connection (graph arcs)
Connection 1 ────── 1 Plug (output) (from)
Connection 1 ────── 1 Plug (input) (to)
7. Petri Net Mapping
The Caméléon execution model is a direct implementation of Petri net semantics :
| Petri Net | Caméléon | Stereotype | Reference |
|---|---|---|---|
| Place | Connection | «place» | Petri, 1962 |
| Transition | Operator | «transition» | Petri, 1962 |
| Token | Data value | — | typed via «color set» (Jensen, 1981) |
| Arc | Plug binding | — | structural entity |
| Firing rule | FiringPolicy | — | ANY / ALL / COND |
| Net (P, T, F) | Composition | «net» | topology .cm.js |
| Color set | Type | «color set» | Jensen, 1981 |
| Marking | Global state | — | set of all connection states |
Forward execution
- Evaluate firing rules → identify READY operators
- Select one operator (deterministic order)
- Consume inputs (NEW → OLD)
- Execute
run(inputs, { signal, config }) - Deposit outputs on output connections (EMPTY → NEW)
- Record step in history
Backward execution (rollback)
- Pop last step from history
- Call
rollback()if defined - Restore input connections to NEW
- Reset output connections to EMPTY
- Operator returns to READY
This bidirectional execution is what makes Caméléon unique — every step is reversible by construction.
8. Invariants
- Type safety — a Connection can only link plugs of compatible types (same type or one is
Any) - No self-loops — an operator cannot connect an output to its own input
- Single consumer — each input plug receives at most one connection
- Deterministic firing — at each step, exactly one operator fires (no concurrency)
- History completeness — every forward step is recorded; backward always possible
- State consistency — connection states are always in {EMPTY, NEW, OLD}; operator states follow the lifecycle FSM