CRISPcore

Principle

Cross-source conform

Silver tables clean within a lane. Enterprise conformity is the full journey: many native shapes conform to one locked canonical model, share one governed vocabulary via SPEC, then Identity decides sameness, Span projects the intersection, and Publish names one consumer result still composed of its Conform sources. CRISP keeps those jobs separate on purpose — this page walks them in order.

1 · Canon shape — per lane, no merge yet

Adaptors map each landed source onto the same typed columns. Teaching example: name is filled now; party_kind exists on the contract but stays unset until Rules. Native kind literals (CORP / COMPANY), ids, and lane-only fields ride in extensions.

Per lane · source → Conform (shape only)

Same canon shape, separate Conform assertions. Native kind tokens ride in extensions for the next pass — A does not absorb B here.

System A

AccountHolder

holder_id

AH-77421

name

NORTHBRIDGE MARINE LTD

holder_type

CORP

sic_code: 65120

Conform · PARTY

System A assertion

name

NORTHBRIDGE MARINE LTD

party_kind

unset

extensions:sys_a

source_id: AH-77421

holder_type: CORP

sic_code: 65120

variance · not typed canon

System B

BillParty

bill_party_id

BP-99102

customer

Northbridge Marine Limited

party_form

COMPANY

lei: 5493001KJT…

Conform · PARTY

System B assertion

name

Northbridge Marine Limited

party_kind

unset

extensions:sys_b

source_id: BP-99102

party_form: COMPANY

lei: 5493001KJT…

variance · not typed canon

A → shape name → name; holder_id → extensions.source_id; CORP held for Rules

B → shape customer → name; bill_party_id → extensions.source_id; COMPANY held for Rules

Adaptors fill canon name from A.name / B.customer, and park native ids plus kind literals under extensions. The party_kind column exists on the contract but stays unset until Rules apply SPEC — CORP and COMPANY are not yet programme codes.

2 · SPEC — variable catalogue across sources

Shape alone is not enough: enums still disagree. Catalogue holds approved core_code values; Map sends each source’s literal into that set.

Cross-source · SPEC map → catalogue

Each lane keeps its own native spelling. A Map scoped by source_system sends that literal into the shared Catalogue. Here both maps produce party_kind = ORGANISATION — one approved programme code, not two competing enums.

SPEC maps from System A and System B produce catalogue ORGANISATIONLeft lobe System A Map: holder_type CORP. Right lobe System B Map: party_form COMPANY. Intersection is the catalogue core_code ORGANISATION for party_kind.System AAccountHolderSPEC · MAPholder_typeCORP→ cataloguenative literalSystem BBillPartySPEC · MAPparty_formCOMPANY→ cataloguenative literalCATALOGUEparty_kindcore_codeORGANISATIONone approved value

A Map CORP

Catalogue ∩ ORGANISATION

B Map COMPANY

Two different SPEC MAP rows — System A holder_type=CORP and System B party_form=COMPANY — resolve to one catalogue core_code ORGANISATION on party_kind. That is variable-catalogue conformity across sources; Identity still decides whether the two subjects are the same party.

Apply that Map and the Conform rows from step 1 now carry the shared programme code:

Per lane · Rules apply SPEC

Re-read the same Conform rows after Map: CORP and COMPANY both stamp party_kind = ORGANISATION.

System A

AccountHolder

holder_id

AH-77421

name

NORTHBRIDGE MARINE LTD

holder_type

CORP

sic_code: 65120

Conform · PARTY

System A assertion

name

NORTHBRIDGE MARINE LTD

party_kind

ORGANISATION

extensions:sys_a

source_id: AH-77421

sic_code: 65120

variance · not typed canon

System B

BillParty

bill_party_id

BP-99102

customer

Northbridge Marine Limited

party_form

COMPANY

lei: 5493001KJT…

Conform · PARTY

System B assertion

name

Northbridge Marine Limited

party_kind

ORGANISATION

extensions:sys_b

source_id: BP-99102

lei: 5493001KJT…

variance · not typed canon

A Map CORP → ORGANISATION

B Map COMPANY → ORGANISATION

After SPEC Map apply, both Conform assertions carry party_kind = ORGANISATION. Same rows as step 1 — only the catalogue stamp changed. Still two assertions; Identity has not clustered them yet.

Two layers of conformity

Cross-source work is not one blob. Shape and codes are both programme meaning — but they are authored and applied differently.

Spec surfaces in more depth

Spec is how variable meaning becomes shareable across sources without rewriting adaptors for every spelling. Two SPEC row kinds share one vocabulary table:

SPEC surfaceQuestionCross-source role
CatalogueWhich programme codes are approved?One closed set of core_code values for a scope (e.g. party kind, country, transaction kind) — not each system’s native spelling.
MapWhich catalogue entry does this native literal belong to?Per-source crosswalk (usually scoped by canonical source_system, optional release): System A’s token and System B’s token → the same core_code.

Together with canon shape: adaptors put evidence on the right columns; SPEC puts the right codes in those columns. Neither step clusters subjects — that remains Identity. Specialised rule families (sign, lifecycle, eligibility) leave the vocabulary table when the outcome is not a simple core_code.

Scopes can be cross-entity (spec_type — e.g. country) or entity-bound (spec_entity — e.g. PARTY_ROLE_TYPE). Both are rows in the shared map — not one physical SPEC table per domain.

3 · Identity + Span — where A and B intersect

Up to here, A and B are parallel Conform rows on one shape. Identity decides they are the same subject; Span projects one consume facade with a winner and participants — the intersecting picture. Variance (A’s sic_code, B’s lei) stays reachable without joining raw feeds.

For this teaching pair, a single IDENTITY_RULE_CLUSTER row folds legal-form suffixes in the match key (Conform display names stay native) and requires the same party_kind:

Identity rule — LTD ↔ LIMITED fold (step 2 · RULE)
# IDENTITY_RULE_CLUSTER · party · name_match_within_kind
rule_id:            PARTY_NAME_KIND_V1
subject:            party
match_expression:   # build key from Conform name
  upper(name)
    .replace("LIMITED", "LTD")
    .replace(/[^A-Z0-9]/g, "")
guard_expression:   party_kind = 'ORGANISATION'   # same subtype only
min_cluster_size:   2
winner_rank:        valid_from ASC                # then steward exceptions

# Applied to our Conform rows:
#   A  name = NORTHBRIDGE MARINE LTD      → key NORTHBRIDGEMARINELTD
#   B  name = Northbridge Marine Limited  → key NORTHBRIDGEMARINELTD
# → one hub, two members; A wins on earliest valid_from

That is one rule type. Identity also uses exception surfaces (equivalence, force-discrete, steward cluster-link) and optional hints — different jobs, fixed rebuild order. More detail: rules, exceptions, and hints · four-step rebuild · Span.

Identity → Span · A ∩ B

Conform kept A and B as separate rows on the same shape. Identity decides they are one party; Span is where the journey shows as an intersection — shared canon in the middle, lane variance still on the lobes via participants / extensions.

Span intersection: Systems A and B cluster into one PARTY consume subjectLeft lobe System A AccountHolder with sic_code. Right lobe System B BillParty with lei. Centre is Identity winner name Northbridge Marine Ltd with ORGANISATION and country GB.System AAccountHolderextensions:sys_aAH-77421NORTHBRIDGEMARINE LTDsic_code65120A-only · not canonSystem BBillPartyextensions:sys_bBP-99102NorthbridgeMarine Limitedlei5493001KJT…B-only · not canonCANON · PARTYidentity winnerNorthbridgeMarine LtdORGANISATIONcountry GB

Left lobe — A participant

Centre ∩ — Span winner / canon

Right lobe — B participant

Only after Identity clusters the two Conform assertions does Span project one consume subject. The ∩ is the winner facade (canon name + party_kind); lobes keep participant variance (sic_code, lei, native ids) reachable without joining raw feeds.

4 · Publish — one consumer result, two Conform sources

Publish is what consumers bind to: one consume_party_key and the winner facade (Northbridge Marine Ltd). That single result is still comprised of both Conform assertions — A as WINNER, B as MEMBER — so lineage and lane-only fields remain reachable without joining raw System A / B feeds. Tableau, Power BI, REST APIs, and SQL all hit the same contract — typically via the short synonym SP_CORE.PARTY for SP_CORE_PUBLISH.PARTY as-is. See Publish.

Publish · one result · two Conform sources

Tableau, Power BI, REST, and SQL all read SP_CORE.PARTY — a synonym for SP_CORE_PUBLISH.PARTY as-is. One named subject; under the facade, both lanes remain addressable.

Publish · PARTY

consume_party_key

CPT-NORTHBRIDGE-01

Northbridge Marine Ltd

party_kind = ORGANISATION

Winner facade · what consumers bind to by default

Conform · System A

participant · WINNER

source_id: AH-77421

NORTHBRIDGE MARINE LTD

party_kind: ORGANISATION

sic_code: 65120

extensions:sys_a

Conform · System B

participant · MEMBER

source_id: BP-99102

Northbridge Marine Limited

party_kind: ORGANISATION

lei: 5493001KJT…

extensions:sys_b

One Publish name · two Conform assertions · no raw-lane join for “the customer”

Publish exposes one consume party (the Identity winner facade). That row is not a wipe of history — it is composed of both Conform assertions as participants. Consumers bind to the Publish contract; lineage still reaches A and B without joining raw feeds.
Consumer query — one row for the winner name
-- Tableau / Power BI / REST bind to the same grain as SQL
-- SP_CORE.PARTY is a synonym for SP_CORE_PUBLISH.PARTY AS_IS
SELECT
  consume_party_key,
  name,
  party_kind
FROM SP_CORE.PARTY
WHERE name = 'Northbridge Marine Ltd';
-- → one row (the winner facade), not two Conform natives

-- Under the facade (lineage / rare lookup — still Publish/Span, not raw A/B):
--   participants include SYS_A (WINNER, AH-77421) and SYS_B (MEMBER, BP-99102)

Pipeline overview

Many lanes · one contract

Source A · PAS
Source B · Claims
Source C · Finance
Conform
Rules

Identity

Cross-source matches

Publish

consume_* keys

Adaptors keep native keys · Identity does not invent cluster ids at load

Many native lanes land on shared Conform entities; Identity clusters subjects later; consumers read Publish consume keys.

The split

Many lanes → one CORE (full journey)
lanes = [SYS_A, SYS_B, SYS_C, …]

# 1–2  Canon shape + SPEC (still separate assertions)
for lane in lanes:
  conform_load(lane)                 # C — name/customer → name
                                     #     holder_id/bill_party_id → extensions.source_id
                                     #     variance → extensions; CORP/COMPANY via Rules
  rules_apply(lane_batch)            # R — CORP/COMPANY → ORGANISATION (+ families)

# 3  Cross-source sameness + consume projection
rebuild_identity("party")            # I — sparse clusters (A ∩ B decided here)
project_span("party")                # S — winner facade + participants[]

# 4  Consumer contract — one row, still two Conform sources
read SP_CORE.PARTY                   # P — synonym for SP_CORE_PUBLISH.PARTY AS_IS
                                     #     consume_party_key = winner
                                     #     participants[] = {A WINNER, B MEMBER}