# Canonical Object Model Guide
The Canonical Object Model must be derived from [`SPEC.md`](../../SPEC.md).
Root type in [`src/model/contract.rs`](../../src/model/contract.rs):
```rust
pub struct TransformationContract {
pub dtcs_version: String,
pub id: String,
pub name: String,
pub version: String,
pub metadata: Option<Metadata>,
pub inputs: Vec<Input>,
pub outputs: Vec<Output>,
pub semantic_actions: Vec<SemanticAction>,
pub expressions: Vec<Expression>,
pub functions: Vec<Function>,
pub rules: Vec<Rule>,
pub lineage: Option<Lineage>,
pub versioning: Option<Versioning>,
pub semantics: Option<TransformationSemantics>,
pub extensions: IndexMap<String, serde_json::Value>,
}
```
Design rules:
- Prefer explicit structs over loose maps.
- Preserve namespaced extension fields via `extensions` flatten.
- Do not add execution behavior to the model.
- Keep spec terminology in Rust names where practical.
- If this sketch conflicts with `SPEC.md`, follow `SPEC.md`.
## Lineage
Every valid contract with outputs must declare `lineage.mappings` tracing each output to one or more inputs. See [`examples/customer_normalize.dtcs.yaml`](../../examples/customer_normalize.dtcs.yaml).
## Field references
When the same field name appears in multiple interface schemas, use qualified targets such as `customer_raw.email`.