Checked Contract Metadata¶
Checked contract metadata is the tooling surface for canonical model bundles, contract-backed model materialization, and artifact introspection. It is separate from checked API metadata: model bundles describe structural row-shaped contracts that can be projected to Incan model source, while API metadata describes checked public declarations already present in source.
Project Configuration¶
Declare model bundle JSON files in incan.toml:
[tool.incan.metadata]
model-bundles = ["contracts/order_summary.json"]
Paths are resolved relative to the project root unless they are absolute.
Bundle Shape¶
A bundle may be stored as a single canonical model object:
{
"schema_version": 1,
"stable_model_id": "orders.summary",
"logical_type_name": "OrderSummary",
"publishable": true,
"fields": [
{
"name": "order_id",
"type": "str",
"alias": "orderId",
"description": "Stable order identifier"
},
{
"name": "coupon_code",
"type": "str",
"nullable": true
}
]
}
Or as a package object with model_bundles:
{
"schema_version": 1,
"model_bundles": [
{
"schema_version": 1,
"stable_model_id": "orders.summary",
"logical_type_name": "OrderSummary",
"publishable": true,
"fields": [
{
"name": "order_id",
"type": "str"
}
]
}
]
}
Fields:
| Field | Type | Meaning |
|---|---|---|
schema_version |
number | Bundle or package schema version. |
stable_model_id |
string or null | Artifact-facing identity for publishable bundles. |
logical_type_name |
string | Incan model type name. |
publishable |
bool | Whether the bundle may be embedded into artifact contract metadata. |
fields |
array | Ordered canonical field list. |
field.name |
string | Incan field name. |
field.type |
string | Incan type spelling. |
field.nullable |
bool | When true, emit uses Option[T] unless the type is already optional. |
field.alias |
string or null | Field alias used as the wire name. |
field.description |
string or null | Field description surfaced through model reflection. |
field.metadata |
object | Producer metadata that does not affect type identity. |
Publishable bundles require stable_model_id. Bundle validation rejects duplicate logical type names, duplicate stable ids, duplicate field names, duplicate aliases, empty aliases/descriptions, empty metadata keys, and unknown or opaque type spellings.
Materialization¶
When a project declares model bundles, build and run commands materialize them as ordinary public model declarations before typechecking the project entry point. Materialized models participate in constructors, member access, model lowering, JSON alias metadata, and __fields__() reflection the same way handwritten models do for the represented field subset.
def main() -> None:
let row = OrderSummary(order_id="o-1", coupon_code=None)
println(row.order_id)
If a materialized model name collides with a visible source declaration or another bundle, the compiler reports a hard error instead of shadowing or mangling the generated name.
Model Emit¶
Use incan tools metadata model to project a model bundle to formatted Incan source:
incan tools metadata model path/to/project OrderSummary --format incan
incan tools metadata model path/to/project orders.summary --format json
incan tools metadata model contracts/order_summary.json OrderSummary
The first positional argument is a project directory, bundle JSON file, source file inside a project, or .incnlib artifact. The second positional argument is either logical_type_name or stable_model_id.
--format incan prints formatted model source:
pub model OrderSummary:
order_id [alias="orderId", description="Stable order identifier"]: str
coupon_code: Option[str]
--format json prints the canonical bundle JSON for the selected model.
Projection is intentionally lossy. It preserves logical type name, field order, type spelling, nullability, alias, and description. It does not reconstruct comments, imports, author-only formatting, producer implementation details, or metadata fields that do not have an Incan model syntax.
Artifact Inspection¶
incan build --lib embeds publishable model bundles and checked API metadata into the .incnlib manifest under contract_metadata. Tooling can inspect a built artifact without requiring the original source checkout:
incan build --lib
incan tools metadata model target/lib/my_package.incnlib OrderSummary --format incan
Artifacts that do not carry checked model metadata are reported as non-introspectable for model emit instead of being reconstructed from generated Rust or machine code.
LSP Command¶
The language server registers workspace/executeCommand command incan.metadata.model.emit. Clients pass either one object argument or positional arguments:
{
"command": "incan.metadata.model.emit",
"arguments": [
{
"uri": "file:///path/to/project/src/main.incn",
"model": "OrderSummary",
"format": "incan"
}
]
}
The command returns a JSON object containing format, model, stableModelId, and either source for Incan output or bundle for JSON output. The same validation and formatter path as the CLI command are used.