Skip to main content
Private Preview·Early access by invitation.Request access →
Kirimana.
Docs · Contracts

Model a silver contract — flat, Data Vault 2.0, Kimball

Silver is where raw bronze becomes trustworthy: cleaned, deduplicated, typed, and shaped for consumption. Kirimana supports three ways to shape it — flat, data_vault, and kimball_dimensional — and your project picks one at kiri init. This page shows the actual ODCS contract each technique produces.

Across all three, the business meaning is declared the same way, in the technique-neutral kiri.semantic.* namespace: entity, business_keys, and grain. The same declaration projects into a Data Vault hub key, a Kimball natural key, or a flat unique constraint.

Flat

A flat silver contract is the closest to the source: one table, cleaned and typed, keyed on its business key. No hubs, no dimensions — just a governed, deduplicated projection.

apiVersion: 3.0.0
kind: DataContract
id: com.acme.sales.silver_order
name: silver_order
version: 1.0.0
status: active
domain: sales
description: >
  Cleaned + deduplicated sales orders. One row per order_id, typed and
  governed. No historization — the latest state of each order.
owner: sales-eng@acme.example
schema:
  - name: silver_order
    logicalType: table
    properties:
      - name: order_id
        logicalType: string
        primaryKey: true
        required: true
      - name: customer_id
        logicalType: string
        required: true
      - name: amount
        logicalType: number
      - name: order_ts
        logicalType: timestamp
        required: true
customProperties:
  - property: kiri.classification
    value: internal
  - property: kiri.lifecycle.state
    value: silver
  - property: kiri.medallion.silver_zone
    value: standard
  - property: kiri.semantic.entity
    value: order
  - property: kiri.semantic.business_keys
    value: [order_id]
  - property: kiri.dedup.strategy
    value: upsert
  - property: kiri.dedup.keys
    value: [order_id]

Referential integrity between flat tables is declared with kiri.relationships.foreign_keys and validated by the FK gate — technique-neutral, so it works identically here as under Kimball or Data Vault.

Data Vault 2.0

Data Vault splits each entity into three insert-only roles. Hubs hold business keys and their deterministic hash key; links hold the relationships between hubs; satellites hold descriptive attributes with hashdiff-gated SCD2. The role is declared with kiri.dv.kind.

A hub — the business key and its hash:

apiVersion: 3.0.0
kind: DataContract
id: com.acme.retail.hub_customer
name: hub_customer
version: 0.1.0
status: active
domain: retail
description: Data Vault hub for the customer entity. Business key + hash key.
owner: data-platform@acme.example
schema:
  - name: hub_customer
    logicalType: table
    properties:
      - name: customer_hk
        logicalType: string
        primaryKey: true
        required: true
      - name: customer_id
        logicalType: string
        required: true
      - name: load_date
        logicalType: timestamp
        required: true
      - name: record_source
        logicalType: string
        required: true
customProperties:
  - property: kiri.classification
    value: internal
  - property: kiri.lifecycle.state
    value: silver
  - property: kiri.dv.kind
    value: hub
  - property: kiri.semantic.business_keys
    value: [customer_id]
  - property: kiri.dv.hash_algorithm
    value: sha256

A link connects two or more hubs, keyed by a hash of both connected business keys. It names the hubs it joins with kiri.dv.connects:

customProperties:
  - property: kiri.dv.kind
    value: link
  - property: kiri.dv.connects
    value:
      - urn:kirimana:silver:hub_customer
      - urn:kirimana:silver:hub_order
  - property: kiri.dv.hash_algorithm
    value: sha256

A satellite hangs descriptive attributes off a hub (or a link). It carries load_date + load_end_date + a hashdiff for SCD2, and points at its parent with kiri.dv.attached_to:

schema:
  - name: sat_customer
    logicalType: table
    properties:
      - name: customer_hk
        logicalType: string
        primaryKey: true
        required: true
      - name: load_date
        logicalType: timestamp
        primaryKey: true
        required: true
      - name: load_end_date
        logicalType: timestamp
      - name: hashdiff
        logicalType: string
        required: true
      - name: full_name
        logicalType: string
      - name: email
        logicalType: string
customProperties:
  - property: kiri.dv.kind
    value: satellite
  - property: kiri.dv.attached_to
    value: urn:kirimana:silver:hub_customer
  - property: kiri.dv.hash_algorithm
    value: sha256

The referential-integrity validator reads these: it refuses a satellite that points at a non-existent parent, a link missing declared business keys on either side, and a raw-vault satellite that embeds business rules. Run the checks with kiri fk gate (structural FK-001FK-004) and the Data Vault silver-quality catalogue (kiri dv quality run).

PIT and bridge tables

Point-in-time (PIT) and bridge tables are query-acceleration entities. They carry no kiri.dv.kind; they opt in via their own typed namespaces and live in the silver pit zone. A PIT anchors on a hub and lets readers resolve a full satellite picture as of any snapshot date without a many-way as-of join:

customProperties:
  - property: kiri.medallion.silver_zone
    value: pit
  - property: kiri.pit.anchor_hub
    value: urn:kirimana:silver:hub_customer
  - property: kiri.pit.as_of_column
    value: as_of_date
  - property: kiri.pit.refresh
    value: snapshot
  - property: kiri.pit.snapshot_grain
    value: daily

A bridge pre-joins two or more hubs through a link at a stated grain:

customProperties:
  - property: kiri.medallion.silver_zone
    value: pit
  - property: kiri.bridge.connected_hubs
    value:
      - urn:kirimana:silver:hub_customer
      - urn:kirimana:silver:hub_order
  - property: kiri.bridge.grain_keys
    value: [customer_id, order_id]
  - property: kiri.bridge.as_of_column
    value: as_of_date

The graph plan schedules PIT after its anchor hub and driving satellites, and bridges after PIT. Render a bounded view of the vault with kiri dv graph --view zone:pit — a mature vault is never one flat graph, so pick a scope.

Kimball conformed-dimensional silver

Under kimball_dimensional, silver is already shaped as conformed dimensions and facts. Dimensions declare their SCD type, business keys, and surrogate-key strategy on kiri.silver.*:

schema:
  - name: dim_customer
    logicalType: table
    customProperties:
      - property: kiri.silver.kind
        value: dimension
      - property: kiri.silver.scd_type
        value: type_1
      - property: kiri.silver.business_keys
        value: [customer_id]
      - property: kiri.silver.surrogate_key_column
        value: customer_nyckel
      - property: kiri.silver.surrogate_key_strategy
        value: hash
    properties:
      - name: customer_nyckel
        logicalType: string
        required: true
        description: Surrogate key — sha256(customer_id).
      - name: customer_id
        logicalType: string
        required: true

A fact declares its grain and measures with additivity:

  - name: fakta_order
    logicalType: table
    customProperties:
      - property: kiri.silver.kind
        value: fact
      - property: kiri.silver.grain
        value: [order_id]
      - property: kiri.silver.measures
        value:
          - name: antal
            column: order_id
            aggregation: count
            additivity: additive

Named zones

Silver can be split into governed zones, each a schema with its own read barriers. Beyond the Data Vault vocabulary (raw, business, pit), there is a general-medallion set valid under any technique:

  • standard — SCD2 standardized entities directly off bronze.
  • curated — facts and business-logic outputs.
  • conformed — master / information-model entities.

Declare a zone with kiri.medallion.silver_zone. The zone gates what a contract may read: a standard table may depend only on bronze, a curated table on standard / conformed / curated, and a conformed table on standard / conformed. Using a reserved zone name on a bronze or gold contract is a fail-closed validation error.

SCD2 options

History is opt-in per contract. Set kiri.historize: scd2 with a kiri.historize_grain, or, under Data Vault, satellites are SCD2 by construction (hashdiff decides when a new version is written). For a flat or Kimball SCD2 table the pattern is the same shape you’d expect — valid_from / valid_to / is_current columns tracking each version:

customProperties:
  - property: kiri.historize
    value: scd2
  - property: kiri.historize_grain
    value: [customer_id]

Once an SCD2 silver table is built, query it as it looked at any instant with kiri timetravel --source <src> --table <t> --at 2026-03-01.

Validate and preview

kiri silver plan                 # locked technique + what apply would build
kiri contract validate contracts/hub_customer.yml --strict
kiri contract lint --format pr   # technique-specific governance lint

Where next

Updated 5 July 2026 · v1.0.0-beta.1