Deal Type Specification v1.3
Document Purpose: Define the complete structure, semantics, and usage of Deal Types in the Deal Engine architecture revision.
Status: Draft for review
Version: 1.3
1. Overview
1.1 What is a Deal Type?
A Deal Type is a template that guides deal composition by defining:
- Deal-level schema (parties, dates, territory)
- Commonly-used clause types for that deal category
- Deal-level logic for cross-clause aggregation
Deal Types are suggestions, not constraints. They accelerate deal creation by providing sensible defaults, but users can freely deviate—adding clause types, omitting suggestions, or substituting alternatives.
1.2 Deal Type vs. Deal Instance
| Aspect | Deal Type | Deal Instance |
|---|---|---|
| Purpose | Template for creating deals | Actual contract |
| Storage | Design-time catalog | Runtime storage |
| Schema | Defines structure | Contains actual data |
| Clause Types | Suggests which to use | Contains copied logic + data |
| Logic | Provides defaults | Self-contained snapshot |
| Versioning** | Catalog versioning (for new deals) | Instance versioning (audit trail) |
Note on versioning: Deal types and deal instances have separate versioning concerns. A deal type may have catalog versions (1.0.0, 1.1.0, 2.0.0) representing template evolution for future deals. A deal instance has its own version chain (1, 2, 3...) representing the runtime evolution of that specific contract through data changes and amendments. See Section 9.4 for details.
When a deal is created from a deal type:
- Deal-level schema is instantiated with actual values
- Selected clause types are copied (logic + schema) into the instance
- Deal-level logic is copied into the instance
- Any changes to deal-level logic create a new version of that deal instance
- The resulting deal instance has no runtime dependency on the catalog
1.3 The Guiding Principle
Deal Types follow the principle: Suggest, don't dictate.
Deal Type: "Music Touring"
├── Suggests: show-settlement clause
├── Suggests: tour-versus clause
├── Suggests: travel-reimbursement clause
└── User decides which to includeA user creating a music touring deal might:
- Use all suggested clause types as-is
- Omit travel-reimbursement (not in this contract)
- Add a merchandise clause (not suggested, but needed)
- Modify show-settlement with custom logic
- Start from scratch without using any suggestions
All paths are valid.
2. Deal Type Structure
A deal type consists of these sections:
deal_type {
header { ... } // Identity and classification
schema { ... } // Deal-level data structure
suggested_clauses { ... } // Commonly-used clause types
logic { ... } // Deal-level aggregation and events
outputs { ... } // Deal-level computed values
}2.1 Header Section
header {
id: music-touring
version: 1.0.0
name: "Music Touring Deal"
description: "Multi-show touring agreement with per-show settlement"
department: music
tags: [touring, live-events, settlement]
}| Field | Required | Description |
|---|---|---|
id | Yes | Unique identifier (kebab-case) |
version | Yes | Semantic version (e.g., 1.0.0) |
name | Yes | Human-readable name |
description | Yes | Brief description of deal category |
department | Yes | Organizational department (music, film, sports, etc.) |
tags | No | Searchable keywords |
2.2 Schema Section
Defines the JSON Schema for deal-level data—information that applies to the entire deal, not specific clauses.
schema {
type: object
required: [parties, dates, currency]
properties {
// Parties to the deal (references Authoritative Data schemas)
parties {
type: object
required: [talent, buyer]
properties {
talent { $ref: "authoritative://schemas/talent" }
buyer { $ref: "authoritative://schemas/buyer" }
agency { $ref: "authoritative://schemas/agency" }
}
}
// Key dates
dates {
type: object
required: [effective_date]
properties {
effective_date { type: string, format: date }
term_start { type: string, format: date }
term_end { type: string, format: date }
execution_date { type: string, format: date }
}
}
// Financial defaults
currency { type: string, enum: [USD, EUR, GBP, CAD, AUD] }
// Territory and exclusivity
territory {
type: object
properties {
primary { type: string }
secondary { type: array, items: { type: string } }
exclusions { type: array, items: { type: string } }
}
}
// Deal-level metadata
metadata {
type: object
properties {
deal_id { type: string }
created_at { type: string, format: date-time }
created_by { type: string }
status { type: string, enum: [draft, pending, active, completed, terminated] }
}
}
}
}Schema organization principles:
| Section | Purpose | Examples |
|---|---|---|
parties | Who is involved | Talent, buyer, agency |
dates | When | Effective date, term boundaries |
currency | Financial defaults | USD, EUR |
territory | Where | Geographic scope |
metadata | System fields | Deal ID, status, audit info |
2.3 Suggested Clauses Section
Lists clause types commonly used with this deal type. This is guidance, not requirement.
suggested_clauses {
// Core compensation
show_settlement {
clause_type: show-settlement
cardinality: one
required: false
description: "Per-show guarantee vs percentage settlement"
}
// Tour-level versus
tour_versus {
clause_type: versus-block
cardinality: one
required: false
depends_on: [show_settlement]
description: "Tour-level guarantee vs aggregate percentage"
}
// Travel and expenses
travel_reimbursement {
clause_type: reimbursement
cardinality: many
required: false
description: "Travel expense reimbursement"
}
// Non-financial terms
exclusivity {
clause_type: exclusivity
cardinality: one
required: false
description: "Category exclusivity terms"
}
}| Field | Required | Description |
|---|---|---|
clause_type | Yes | Reference to clause type in catalog |
cardinality | Yes | one or many (can multiple instances exist?) |
required | Yes | Is this clause type suggested as essential? (still not enforced) |
depends_on | No | Other clauses this one typically works with |
description | Yes | Why this clause type is suggested |
Cardinality semantics:
| Cardinality | Meaning | Example |
|---|---|---|
one | Typically one instance | Tour-level versus block |
many | Often multiple instances | Per-show settlements, bonus groups |
Note: required: true is a suggestion to the user, not an enforcement. The system will not prevent deal creation if a "required" clause is omitted.
2.4 Logic Section
Defines deal-level computations that aggregate across clause instances.
logic {
// Deal-level events
events {
all_shows_settled {
description: "All shows in the tour have been settled"
condition: @show_settlement.all_settled ?? false
}
deal_complete {
description: "All compensation finalized"
condition: all_shows_settled && (@tour_versus.settled ?? true)
}
}
// Deal-level computations
computations {
// Aggregate earnings across all clause instances
var total_guaranteed = sum(
@show_settlement.total_guarantee ?? 0,
@tour_versus.tour_guarantee ?? 0
)
var total_earned = sum(
@show_settlement.total_earned ?? 0,
@tour_versus.versus_earned ?? 0,
@travel_reimbursement[*].total ?? 0
)
var total_received = sum(
@show_settlement.total_received ?? 0,
@tour_versus.received ?? 0,
@travel_reimbursement[*].received ?? 0
)
// Pending amounts
var total_pending = total_earned - total_received
// Final outputs
output total_guaranteed
output total_earned
output total_received
output total_pending
}
}Cross-clause reference syntax:
| Syntax | Meaning |
|---|---|
@clause_name.output | Reference output from named clause |
@clause_name[*].output | Reference output from all instances (cardinality: many) |
2.5 Outputs Section
Declares deal-level outputs available for reporting and downstream systems.
outputs {
// Financial totals
total_guaranteed: number
total_earned: number
total_received: number
total_pending: number
// Status
deal_complete: boolean
}3. Schema Inheritance and Composition
3.1 Authoritative Data Integration
Deal types reference schemas from the Authoritative Data system for master data entities. This ensures consistency across the agency and eliminates schema duplication.
Reference syntax:
$ref: "authoritative://schemas/talent"
$ref: "authoritative://schemas/buyer"
$ref: "authoritative://schemas/agency"
$ref: "authoritative://schemas/venue"Example: Talent schema from Authoritative Data
// Provided by authoritative://schemas/talent
{
type: object
properties {
id { type: string, description: "Authoritative Data ID" }
name { type: string }
legal_entity { type: string }
representative { type: string }
// Additional fields defined by Authoritative Data...
}
}3.2 Common Schema Patterns
Beyond Authoritative Data entities, deal types share common patterns for deal-specific structures:
Standard dates schema:
dates_schema {
effective_date: date (required)
term_start: date
term_end: date
execution_date: date
}Standard territory schema:
territory_schema {
primary: string
secondary: array of string
exclusions: array of string
}3.3 Extension Pattern
Deal types can extend common patterns with deal-specific fields:
schema {
// Include common patterns
include: [dates_schema, territory_schema]
// Reference Authoritative Data for parties
properties {
parties {
talent { $ref: "authoritative://schemas/talent" }
buyer { $ref: "authoritative://schemas/buyer" }
}
// Add deal-specific fields
tour_info {
type: object
properties {
tour_name { type: string }
total_shows { type: integer }
tour_region { type: string }
}
}
}
}3.4 Department-Specific Patterns
Different departments extend base patterns with specific needs:
| Department | Specific Schema Elements | Authoritative Data Refs |
|---|---|---|
| Music | Tour info, venue types, ticket pricing | talent, venue, promoter |
| Film | Production info, release windows | talent, studio, distributor |
| Sports | League info, team, season | athlete, team, brand |
| Fashion | Brand info, product categories | talent, brand, agency |
4. Logic Patterns
4.1 Aggregation Across Clauses
The most common deal-level logic pattern: summing outputs from multiple clause instances.
logic {
computations {
// Sum from single instance
var base_from_settlement = @show_settlement.total_earned ?? 0
// Sum from multiple instances (cardinality: many)
var bonus_total = sum(@bonus_groups[*].earned ?? 0)
// Combined total
output total_earned = base_from_settlement + bonus_total
}
}4.2 Conditional Aggregation
Filter clause outputs based on conditions:
logic {
computations {
// Only settled shows
var settled_earnings = sum(
@show_settlement.shows where show.settled == true,
show.earned
)
// Only earnings (exclude reimbursements)
var earnings_only = sum(
@clauses where clause.value_type == "earning",
clause.amount
)
output total_earnings = earnings_only
}
}4.3 Deal-Level Events
Events that depend on clause states:
logic {
events {
// All clause instances in settled state
all_settled {
description: "All financial clauses settled"
condition: @show_settlement.all_settled
&& (@tour_versus.settled ?? true)
}
// Revenue threshold crossed
revenue_milestone {
description: "Total earnings exceed milestone"
condition: total_earned >= deal.metadata.revenue_milestone
}
// Compound event
deal_can_close {
description: "All conditions met to close deal"
condition: all_settled && revenue_milestone
}
}
}4.4 Value Type Aggregation
Aggregate by value type for downstream systems:
logic {
computations {
// Separate earnings from reimbursements
var total_earnings = sum(
@clauses where clause.value_type == "earning",
clause.amount
)
var total_reimbursements = sum(
@clauses where clause.value_type == "reimbursement",
clause.amount
)
var total_third_party = sum(
@clauses where clause.value_type == "third_party",
clause.amount
)
output total_earnings
output total_reimbursements
output total_third_party
output grand_total = total_earnings + total_reimbursements + total_third_party
}
}5. Complete Examples
5.1 Music Touring Deal Type
deal_type {
header {
id: music-touring
version: 1.0.0
name: "Music Touring Deal"
description: "Multi-show touring agreement with per-show settlement and tour-level versus"
department: music
tags: [touring, live-events, settlement, versus]
}
schema {
type: object
required: [parties, dates, currency]
properties {
parties {
type: object
required: [talent, promoter]
properties {
talent { $ref: "authoritative://schemas/talent" }
promoter { $ref: "authoritative://schemas/promoter" }
agency { $ref: "authoritative://schemas/agency" }
}
}
dates {
type: object
required: [effective_date]
properties {
effective_date { type: string, format: date }
tour_start { type: string, format: date }
tour_end { type: string, format: date }
}
}
currency { type: string, default: USD }
tour_info {
type: object
properties {
tour_name { type: string }
tour_region { type: string }
headliner { type: boolean, default: true }
}
}
}
}
suggested_clauses {
show_settlement {
clause_type: show-settlement
cardinality: one
required: true
description: "Per-show guarantee vs percentage settlement for all tour dates"
}
tour_versus {
clause_type: versus-block
cardinality: one
required: false
depends_on: [show_settlement]
description: "Tour-level guarantee vs aggregate box office percentage"
}
tour_bonus {
clause_type: tiered-bonus
cardinality: one
required: false
description: "Bonus tiers based on ticket sales or revenue thresholds"
}
travel_expenses {
clause_type: reimbursement
cardinality: many
required: false
description: "Travel, accommodation, and production expense reimbursement"
}
merchandise {
clause_type: merchandise-split
cardinality: one
required: false
description: "Merchandise revenue sharing"
}
}
logic {
events {
all_shows_occurred {
description: "All scheduled shows have occurred"
condition: @show_settlement.all_occurred ?? false
}
all_shows_settled {
description: "All shows have been settled with promoter"
condition: @show_settlement.all_settled ?? false
}
tour_complete {
description: "Tour fully settled including versus"
condition: all_shows_settled && (@tour_versus.settled ?? true)
}
}
computations {
// Show-level aggregates
var total_show_guarantees = @show_settlement.total_guarantee ?? 0
var total_show_earned = @show_settlement.total_earned ?? 0
// Tour-level versus
var tour_guarantee = @tour_versus.tour_guarantee ?? 0
var tour_versus_earned = @tour_versus.versus_earned ?? 0
// Combined compensation
var total_guaranteed = total_show_guarantees + tour_guarantee
var total_earned = total_show_earned + tour_versus_earned
// Add bonuses if present
var bonus_earned = @tour_bonus.earned ?? 0
var total_with_bonus = total_earned + bonus_earned
// Receipts tracking
var total_received = sum(
@show_settlement.total_received ?? 0,
@tour_versus.received ?? 0,
@tour_bonus.received ?? 0
)
// Reimbursements (tracked separately by value_type)
var total_reimbursements = sum(@travel_expenses[*].total ?? 0)
// Outputs
output total_guaranteed
output total_earned = total_with_bonus
output total_received
output total_pending = total_earned - total_received
output total_reimbursements
}
}
outputs {
total_guaranteed: number
total_earned: number
total_received: number
total_pending: number
total_reimbursements: number
tour_complete: boolean
}
}5.2 Sports Endorsement Deal Type
deal_type {
header {
id: sports-endorsement
version: 1.0.0
name: "Sports Endorsement Deal"
description: "Athlete endorsement with base compensation and performance bonuses"
department: sports
tags: [endorsement, athlete, bonuses, performance]
}
schema {
type: object
required: [parties, dates, currency, sport_info]
properties {
parties {
type: object
required: [talent, brand]
properties {
talent { $ref: "authoritative://schemas/athlete" }
brand { $ref: "authoritative://schemas/brand" }
agency { $ref: "authoritative://schemas/agency" }
}
}
dates {
type: object
required: [effective_date, term_end]
properties {
effective_date { type: string, format: date }
term_start { type: string, format: date }
term_end { type: string, format: date }
}
}
currency { type: string, default: USD }
sport_info {
type: object
required: [sport, league]
properties {
sport { type: string }
league { type: string }
season { type: string }
}
}
endorsement_scope {
type: object
properties {
product_categories { type: array, items: { type: string } }
usage_rights { type: array, items: { type: string } }
appearance_obligations { type: integer }
}
}
}
}
suggested_clauses {
base_compensation {
clause_type: base-guarantee
cardinality: one
required: true
description: "Guaranteed base compensation over contract term"
}
performance_bonuses {
clause_type: tiered-bonus
cardinality: many
required: false
description: "Performance-based bonus groups (awards, stats, playoffs)"
}
appearance_fee {
clause_type: per-event-fee
cardinality: one
required: false
description: "Fee per promotional appearance"
}
product_allowance {
clause_type: in-kind-benefit
cardinality: many
required: false
description: "Product and equipment allowances"
}
exclusivity {
clause_type: exclusivity
cardinality: one
required: true
description: "Category exclusivity and competitive restrictions"
}
}
logic {
events {
contract_year_complete {
description: "Contract year has ended"
condition: current_date >= deal.dates.term_end
}
all_bonuses_determined {
description: "All bonus eligibility has been determined"
condition: count(@performance_bonuses[*] where bonus.determined == true)
== count(@performance_bonuses[*])
}
deal_complete {
description: "All compensation finalized"
condition: contract_year_complete && all_bonuses_determined
}
}
computations {
// Base compensation
var base_guaranteed = @base_compensation.amount ?? 0
var base_earned = @base_compensation.earned ?? 0
var base_received = @base_compensation.received ?? 0
// Performance bonuses
var bonus_potential = sum(@performance_bonuses[*].potential ?? 0)
var bonus_earned = sum(@performance_bonuses[*].earned ?? 0)
var bonus_received = sum(@performance_bonuses[*].received ?? 0)
// Appearance fees
var appearance_earned = @appearance_fee.earned ?? 0
var appearance_received = @appearance_fee.received ?? 0
// Totals
var total_guaranteed = base_guaranteed
var total_potential = base_guaranteed + bonus_potential
var total_earned = base_earned + bonus_earned + appearance_earned
var total_received = base_received + bonus_received + appearance_received
// Outputs
output total_guaranteed
output total_potential
output total_earned
output total_received
output total_pending = total_earned - total_received
output bonus_earned
}
}
outputs {
total_guaranteed: number
total_potential: number
total_earned: number
total_received: number
total_pending: number
bonus_earned: number
deal_complete: boolean
}
}5.3 Influencer Endorsement Deal Type
deal_type {
header {
id: influencer-endorsement
version: 1.0.0
name: "Influencer Endorsement Deal"
description: "Brand partnership with milestone-based payments and optional extensions"
department: digital
tags: [influencer, social-media, brand-partnership, milestones]
}
schema {
type: object
required: [parties, dates, currency, campaign_info]
properties {
parties {
type: object
required: [talent, brand]
properties {
talent { $ref: "authoritative://schemas/talent" }
brand { $ref: "authoritative://schemas/brand" }
agency { $ref: "authoritative://schemas/agency" }
}
}
dates {
type: object
required: [effective_date, term_end]
properties {
effective_date { type: string, format: date }
term_start { type: string, format: date }
term_end { type: string, format: date }
}
}
currency { type: string, default: USD }
campaign_info {
type: object
required: [product_category]
properties {
campaign_name { type: string }
product_category { type: string }
deliverables_count { type: integer }
platforms { type: array, items: { type: string } }
}
}
}
}
suggested_clauses {
base_fee {
clause_type: milestone-payment
cardinality: one
required: true
description: "Base fee paid on contract execution and work completion milestones"
}
deliverable_fee {
clause_type: per-deliverable-fee
cardinality: one
required: false
description: "Fee per social post or content deliverable"
}
optional_usage {
clause_type: optional-extension
cardinality: many
required: false
description: "Optional extended usage rights for additional fee"
}
exclusivity {
clause_type: exclusivity
cardinality: one
required: true
description: "Category and competitor exclusivity"
}
usage_rights {
clause_type: usage-rights
cardinality: one
required: true
description: "Content usage rights and territories"
}
}
logic {
events {
contract_executed {
description: "Contract signed by all parties"
condition: @base_fee.contract_executed ?? false
}
work_complete {
description: "All deliverables completed"
condition: @base_fee.work_complete ?? false
&& (@deliverable_fee.all_delivered ?? true)
}
deal_complete {
description: "All compensation finalized"
condition: work_complete
&& (count(@optional_usage[*] where option.determined == true)
== count(@optional_usage[*]))
}
}
computations {
// Base compensation
var base_amount = @base_fee.amount ?? 0
var base_earned = @base_fee.earned ?? 0
var base_received = @base_fee.received ?? 0
// Deliverable fees
var deliverable_earned = @deliverable_fee.earned ?? 0
var deliverable_received = @deliverable_fee.received ?? 0
// Optional extensions
var optional_potential = sum(@optional_usage[*].amount ?? 0)
var optional_earned = sum(@optional_usage[*].earned ?? 0)
var optional_received = sum(@optional_usage[*].received ?? 0)
// Totals
var total_guaranteed = base_amount
var total_potential = base_amount + optional_potential
var total_earned = base_earned + deliverable_earned + optional_earned
var total_received = base_received + deliverable_received + optional_received
// Outputs
output total_guaranteed
output total_potential
output total_earned
output total_received
output total_pending = total_earned - total_received
output optional_earned
}
}
outputs {
total_guaranteed: number
total_potential: number
total_earned: number
total_received: number
total_pending: number
optional_earned: number
deal_complete: boolean
}
}6. How Deal Types Guide Composition
6.1 The Composition Process
When creating a deal from a deal type:
1. USER selects deal type (e.g., "Music Touring")
2. SYSTEM presents:
- Deal-level schema to fill out
- List of suggested clause types
3. USER decides for each suggested clause:
- Include as-is
- Include with modifications
- Skip / don't include
4. USER can also:
- Add clause types not in suggestions
- Create custom clause logic inline
- Remove suggestions marked "required"
5. SYSTEM creates deal instance:
- Copies deal-level schema with user data
- Copies selected clause types (logic + schema)
- Copies deal-level logic
- Result is self-contained instance6.2 Flexibility Examples
Example 1: Using suggestions as-is
User creates Music Touring deal:
- Includes show_settlement (suggested, required: true)
- Includes tour_versus (suggested)
- Includes travel_expenses (suggested)
- Skips merchandise (suggested)
Result: Standard touring dealExample 2: Partial use
User creates Music Touring deal:
- Includes show_settlement
- Skips tour_versus (not applicable)
- Adds custom-production-fee (not suggested)
Result: Customized touring dealExample 3: Starting fresh
User creates deal without deal type:
- Adds base-guarantee clause
- Adds custom-bonus clause
- Defines deal-level logic manually
Result: Fully custom deal6.3 What "Required" Really Means
The required: true flag on suggested clauses is advisory only:
| What it IS | What it is NOT |
|---|---|
| A strong suggestion | A system enforcement |
| Guidance for typical deals | A validation rule |
| Default selection in UI | A blocker for deal creation |
The system may:
- Pre-select "required" clauses in the UI
- Show a warning if "required" clause is omitted
- Allow creation regardless of warnings
7. Validation Rules
7.1 Deal Type Structure Validation
| Rule | Description |
|---|---|
| DT-1 | id must be unique across catalog |
| DT-2 | version must be valid semver |
| DT-3 | department must be valid department identifier |
| DT-4 | All clause_type references must exist in catalog |
7.2 Schema Validation
| Rule | Description |
|---|---|
| DS-1 | parties section required |
| DS-2 | dates section required |
| DS-3 | currency field required |
| DS-4 | Schema must be valid JSON Schema |
| DS-5 | Authoritative Data references must be valid |
7.3 Logic Validation
| Rule | Description |
|---|---|
| DL-1 | Cross-clause references (@clause.output) must target declared outputs |
| DL-2 | Event conditions must evaluate to boolean |
| DL-3 | No circular dependencies in computations |
| DL-4 | All outputs must be computed |
7.4 Suggested Clauses Validation
| Rule | Description |
|---|---|
| SC-1 | cardinality must be one or many |
| SC-2 | depends_on references must be valid clause names |
8. Design Rationale
8.1 Why Suggestions, Not Requirements?
Entertainment contracts are highly variable. Even within the same deal category:
- Music touring deals vary by artist tier, region, deal structure
- Some tours have versus, others don't
- Some have merchandise splits, others don't
Rigid templates would require constant exceptions. Suggestions provide guidance while respecting real-world variability.
8.2 Why Copy Logic at Instantiation?
When a deal is created, clause logic is copied into the instance because:
- Immutability: Contract terms shouldn't change if clause type is updated
- Auditability: The exact logic that computed results is preserved
- Independence: Deal instances have no external dependencies
- Legal validity: Frozen logic matches contractual agreement
8.3 Why Deal-Level Aggregation?
Individual clauses compute their own amounts, schedules, and states. But business needs require aggregated views:
- "What's the total earned across all clauses?"
- "What's still pending?"
- "Is the entire deal complete?"
Deal-level logic provides this without burdening individual clause types.
8.4 Why Two Cardinalities?
one vs many cardinality guides both UI and logic:
one: UI shows single instance form; logic uses@clause.outputmany: UI allows adding instances; logic uses@clause[*].outputwith aggregation
8.5 Why Authoritative Data Integration?
Party information (talent, buyer, brand, etc.) is master data managed by the Authoritative Data system. Referencing these schemas:
- Ensures consistency across all deals
- Eliminates schema duplication
- Keeps Deal Engine focused on deal logic, not entity management
- Enables entity linking and reporting across systems
8.6 Why Deal Types Don't Version Instances
Deal Types define the starting point for deals. They suggest structure, provide defaults, and guide composition. However, once a deal instance is created, it evolves independently through its own versioning system.
| Concern | Handled By |
|---|---|
| Template structure | Deal Type |
| Suggested clauses | Deal Type |
| Initial deal-level logic | Deal Type |
| Runtime data changes | Deal Instance versioning |
| Contract amendments | Deal Instance versioning |
| Clause replacement | Deal Instance versioning |
| Audit history | Deal Instance versioning |
The separation is intentional:
Deal Types are stable templates. Updating a deal type (e.g., adding a new suggested clause) doesn't affect existing deals — they already have their logic frozen.
Deal Instances evolve. Each deal has its own version history reflecting its unique amendments, settlements, and changes.
No retroactive changes. If a deal type is updated to version 2.0, existing deals created from version 1.0 continue unchanged. New deals can use either version.
This mirrors how legal templates work: updating a contract template doesn't modify already-signed contracts.
8.7 The "Deal Must Compile" Principle
When deal-level logic references clause outputs via @clause.output syntax, those references must resolve to actual declared outputs. This is validated when:
- A deal is first created from a deal type
- A clause is added to an existing deal
- A clause is replaced in an existing deal
- Deal-level logic is amended
If references cannot resolve — for example, a clause was removed but deal logic still references its outputs — the deal will not compile and the change is rejected.
Implications for deal type design:
- Use null coalescing (
??) for optional clauses:@optional_bonus.earned ?? 0 - Document which outputs are required vs. optional in suggested_clauses descriptions
- Consider output interface stability when designing clause types
9. Relationship to Other Specifications
9.1 Clause Type Specification
Deal types reference clause types by ID. The clause type specification defines:
- What outputs a clause type exposes (for
@clause.outputreferences) - What schema a clause type expects
- What category/value_type the clause has
9.2 Deal Instance Specification
When a deal is created from a deal type:
- Deal type schema → Deal instance deal-level data
- Selected clause types → Deal instance clause instances
- Deal type logic → Deal instance deal-level logic
The deal instance specification defines the runtime structure.
9.3 Authoritative Data
Deal types reference Authoritative Data schemas for master data entities:
authoritative://schemas/talentauthoritative://schemas/brandauthoritative://schemas/agency- etc.
The Authoritative Data system owns these schemas; Deal Engine consumes them.
9.4: Deal Instance Versioning
Deal Types guide creation, but Deal Instances have their own lifecycle. After a deal is created from a deal type, it evolves through versioning:
Deal Type Deal Instance
───────────────── ─────────────────────────────────────
music-touring ──▶ deal-2024-001234
v1.0.0 ├── Version 1 (created from deal type)
├── Version 2 (show 1 settled)
[template remains ├── Version 3 (show 2 settled)
unchanged] ├── Version 4 (bonus clause replaced)
└── Version 5 (show 3 settled)What Triggers Instance Versions
| Change | Creates New Version |
|---|---|
| Data update (settlement, event) | Yes |
| Clause logic amended | Yes |
| Clause added | Yes |
| Clause replaced | Yes |
| Clause removed | Yes |
| Deal-level logic amended | Yes |
Key Versioning Concepts
| Concept | Description |
|---|---|
| Immutable versions | Each version is a complete, frozen snapshot |
| Effective dates | Versions have effective dates for point-in-time queries |
| Archived clauses | Replaced clauses are archived with frozen final state |
| Full recalculation | Any change triggers complete recalculation of active clauses |
Relationship to Deal Types
| Aspect | Deal Type Role | Deal Instance Role |
|---|---|---|
| Initial structure | Defines | Receives at creation |
| Ongoing changes | None | Manages via versioning |
| Logic updates | New deal type version (for future deals) | New instance version (for this deal) |
| Audit trail | N/A | Complete version history |
Reference: See Deal Instance Specification Section 4-6 for complete versioning details.
Document History
- v1.3 (2026-01-XX) - Deal instance version changes
- v1.2 (2026-01-XX) - Initial specification
- Deal type structure: header, schema, suggested_clauses, logic, outputs
- Suggestion model (guide, not constrain)
- Cross-clause reference syntax (@clause.output)
- Authoritative Data schema integration
- Aggregation patterns (by value_type for downstream systems)
- Three complete examples (music touring, sports endorsement, influencer)
- Validation rules
- Design rationale