Capabilities Overview
In order for the deal engine to provide its services to other components in the client framework, it must support the following capabilities:
| Capability | Description |
|---|---|
| Generalized deals | Enable a deal to be generalized into both schema (what data exists for the deal) and behavior (or computation) which defineshow the deal initializes, validates, and calculates its values. |
| Registry | Provide a registry of deal types that are supported (e.g., “Touring”, “TV Writing”, “Retainer”). The includes the versioning of the deal types as they evolve over time. |
| Storage | Provide fast storage and retrieval of deals for use by other components and downstream systems. |
| Authorization | Ensure secure access to deal information via auditable authorization rules. |
| Inputs | Enable the computation of the value of the deals based on variables set by downstream applications. Deal Engine can do this based on stored data recorded as part of a contract, or using ephemeral data supplied to it for the purpose of generating “what if” scenarios. |
| Event Registration | Allow the ability to register and to respond to both internal events (“is a milestone date reached?”) and external events (“How many yards did the player rush?”) that are of interest to the open deals in the system. |
| Artifacts | Enable flexible generation of artifacts, such as data capture forms, PDF contract documents, and notifications – all from the same data. The generation of such artifacts is handled by downstream systems and is not in deal engine scope, but deal engine must have enough information to support the downstream system. |
TODO
Move the detail here to architecture
Generalizing agency deals
The primary responsibility of the deal engine is to store and provide calculations for a wide variety of deal types, each with its own unique data requirements and business logic.
Each UTA department generates at least one type of deal, and each deal type is unique.
The process of generalizing the deals is called deal modeling. In order to model the deal, we need a language for describing the components of a deal.
Deal modeling
Deals are made up of a series of clauses. A clause is a discrete deal term.
There are two types of clauses:
| Clause Type | Description |
|---|---|
| Simple | Non-financial terms that need only be captured as text |
| Financial | The specific conditions under which money is paid. Financial clauses are composed of subtypes described below |
Financial clauses
The financial clauses are in turn divided into two subtypes:
| Clause Type | Description |
|---|---|
| Guarantee clauses | Describe payments due that are not dependent on, for example, an optional performance expectation (“plays in 25 games”), or an external condition (“worldwide box office exceeds two times production cost”). Guarantees are paid on a schedule, even if there is only one payment. |
| Contingent compensation clauses | Describe payments that may or may not become due based on either the performance of the client, or some achievement or external event occurring such as “worldwide box office” or “net box office receipts.” A contingent clause describes a scenario that is merely possible: something must activate the clause. |
graph TD
deal((Deal))
simple((Simple Clauses))
financial((Financial Clauses))
guarantee((Guarantee Clauses))
contingent((Contingent Clauses))
deal --> simple
deal --> financial
financial --> guarantee
financial --> contingentClause Blocks
These financial clauses -- guarantee and contingent -- can be grouped together as clause blocks to form more complex contractual structures.
graph TD
deal((Deal))
f1((Financial Clauses))
g1((Guarantee Clause))
c1((Contingent Clause))
cb1((Clause Block 1))
cb2((Clause Block 2))
f2((Financial Clauses))
f3((Financial Clauses))
g2((Guarantee Clause))
c2((Contingent Clause))
g3((Guarantee Clause))
c3((Contingent Clause))
deal --> f1
f1 --> g1
f1 --> c1
deal --> cb1
deal --> cb2
cb1 --> f2
cb2 --> f3
f2 --> g2
f2 --> c2
f3 --> g3
f3 --> c3Clause Operators
Clause Operators define how two or more clauses (or clause blocks) are combined in a deal model.
They describe logical or financial relationships between clauses, similar to how AND, OR, or mathematical functions connect terms in an expression.
Operators are declared once in a model and referenced later inside group or type expressions.
operator {
name: escalates_to
display: escalates-to
type: and
}
operator {
name: versus
display: versus
type: or
}Each operator definition includes:
| Field | Description |
|---|---|
name | Identifier used in expressions (e.g., guarantee escalates_to bonus) |
display | How it appears on contracts or UIs |
type | and or or (semantic classification) |
Behavior
| Type | Meaning | Example |
|---|---|---|
and | Clauses are additive; both apply if eligible. | guarantee escalates_to bonus (pay both if guard passes). |
or | Clauses are exclusive; select one result. | guarantee versus gross_share (choose higher/better). |
Operators are combinators — they don’t trigger clauses; they define how to merge results once clauses are active.
Usage
Operators are used in clause or block expressions:
block {
name: payout_plan
expr: guarantee versus gross_share
}During evaluation:
- Each referenced clause computes its amount (if active).
- The operator’s type determines how to aggregate or select the results.
Clause Conditionals (when)
Clause Conditionals determine when a clause (or group) becomes active.
They are guards, not operators — they don’t combine clauses but control if a clause contributes.
A conditional references an event defined elsewhere in the model.
event {
name: box_office_doubles_cost
description: worldwide box office >= 2 × production cost
condition: worldwide_box_office >= 2 * production_cost in season
}
clause {
name: bonus
description: Escalation bonus if box office condition met
when: box_office_doubles_cost
}Behavior
| Element | Purpose |
|---|---|
event | Defines the measurable condition or event (can be time-bounded with in). |
when | Attaches that event to a clause or block; clause is skipped unless true. |
Lifecycle
- Evaluate events — compute each event’s
conditionusing current variables. - Activate clauses — any clause whose
whenevent is true becomes active. - Combine clauses — active clauses are combined according to operators (
and,or,versus, etc.). - Compute totals — only active clauses contribute to payments/outputs.
Example
clause {
name: escalation_bonus
description: Additional payment if performance target met
when: performance_trigger
}If performance_trigger evaluates to false, this clause is ignored for the current deal instance.
Putting It Together
Operators answer “How do multiple active clauses relate?”
Conditionals (when) answer “Is this clause/block active at all?”
operator { name: versus display: vs type: or }
event {
name: nbor_threshold
description: net receipts cross threshold
condition: nbor >= 1000000
}
clause { name: guarantee description: Minimum payment }
clause { name: nbor_share description: Share of NBOR when: nbor_threshold }
block { name: payout expr: guarantee versus nbor_share }
type { name: versus_deal compose: payout }Evaluation Semantics
For reference, here is some pseudo-code of how an engine might evaluate conditionals and operators:
// assume: clauses -> { name, when?, amountFn(inputs) }
// operators -> { name, type: 'and' | 'or' }
// expr is an infix sequence like: [ 'guarantee', 'versus', 'nbor_share' ]
function isActive(clause, triggers, inputs) {
if (!clause.when) return true;
return evaluateTrigger(clause.when, triggers, inputs); // bool
}
function evaluateClause(clause, inputs) {
return clause.amountFn(inputs); // money/number
}
function combine(a, op, b) {
if (op.type === 'and') return a + b; // additive by policy
if (op.type === 'or') return Math.max(a, b); // choose best by policy
throw new Error('unknown operator');
}
function evaluateExpression(expr, env) {
// parse to AST or RPN first; shown conceptually here:
const stack = [];
for (const token of expr) {
if (isClauseName(token)) {
const clause = env.clauses[token];
if (isActive(clause, env.triggers, env.inputs)) {
stack.push(evaluateClause(clause, env.inputs));
} else {
stack.push(0); // or a special “inactive” marker handled by combine
}
} else if (isOperatorName(token)) {
const right = stack.pop();
const left = stack.pop();
const op = env.operators[token];
stack.push(combine(left, op, right));
}
}
return stack.pop();
}TODO
Exact policies for or (pick highest? first? contract-specified?) and and (sum? cap? merge schedules?) are implementation choices—document them alongside operator registry.
Summary
| Concept | Role | Example |
|---|---|---|
| Operator | Combines multiple active clauses/groups | guarantee versus bonus |
Conditional (when) | Activates/suppresses a clause/group | when: box_office_doubles_cost |
Together they enable expressive models:
“Pay the guarantee versus 10% of NBOR, but only when the box office doubles production cost.”
Registry
Provide a registry of deal types that are supported (e.g., “Touring”, “TV Writing”, “Retainer”). The includes the versioning of the deal types as they evolve over time.
Existing deal types are nicely cataloged, however the key difference between the current templates and the ideas proposed here are that we want to capture all financial terms at a “data” level, rather than solely a “text” level. For example, consider the following template for an MP Talent deal:


Look closely at the Deal Terms section.
TODO: Walk through this example with the team. For example, what are the backend points? What are they based on? How can we determine if the backend is owed? How can we forecast how much backend we might be owed under various conditions?
What about the box office bonus thresholds? How are they computed? Does it depend on anything else, like exceeding production cost? Where will we record production cost? How do we forecast how much we might be owed on hitting the threshold?
Cataloging Deal Types: The Modeling Process
Once the modeling framework is designed as described above, then each deal type needs to be modeled and stored as a template in deal management.
Modeling is the process of breaking down potential deal structures into computable units that can be represented in software. The modeling process involved in creating such a catalog of deal types is non-trivial: department personnel have to be interviewed, contract and bookings reviewed, and then the data, anecdotes, lore, and wisdom must be synthesized in order to understand specific deal structures in different domains. From that discovery work a model of a deal type can be constructed.
Experience shows that this modeling effort is about 20% technical work, and 80% acquiring in in-depth understanding of the underlying business. Gaining that understanding is harder than it looks: the modeler soon realizes it is common to find no single point person in a department that understands all the nuances of a particular deal type. The collective department often needs to be consulted to get a full picture.
The modeling process is further complicated by the business context of a talent agency: the talent agent and agency are often not a party to the deal. The agency may represent the talent, but the talent makes the deal with the buyer. In some cases, such as touring, or where UTA provides direct services, such as consulting or advisory services, the agency creates the contract and thus has direct knowledge of and responsibility for constructing the clauses. In other cases, the agency participates in negotiations for the deal but the final deal terms between the buyer and seller parties are memorialized outside of the agency’s systems world by the respective attorneys. Thus the agency’s knowledge of the final deal terms comes to it via a PDF copy of a contract document that was emailed by the buyer or the seller.
Challenges to modeling
TODO
This may belong in the overview, wherever we first present modeling. Not architectural. May even be something we want to delete
- Modeling can take some time per deal type. The modelers will need to know the domain well enough to ask the right questions. Just dealing with the logistics of setting the modeling meetings with the correct business affairs, sales operations, and agent personnel in the departments will itself take a great deal of time.
- Modeling is never complete. Deal management must be built with the understanding that a deal model will change, both because the modeling process is imperfect and not all information will be collected on the initial implementation, and because the industry evolves contract clauses all the time.
- There are exceptions everywhere. The system design must not assume absolutely every deal type can be perfectly templated. For any generalized business rule, there will always be a need to override it, or a particular clause structure might need to be constructed for a specific deal.
- Risk of concentrating expertise in a small number of individuals. If modeling becomes a slow and complex multi-year effort, this can lead to considerable expertise building up in a “chief modeler,” a rare individual who is entirely comfortable with deal complexity. The modeling effort risks bottlenecking on this individual who has become the “one person who knows how to model,” resulting in exponential delays in delivering deal management.
These challenges are not insurmountable, and moving forward incrementally capturing what deals we can will accrue significant benefits: as experimentation with deal modeling moves forward, the agency begins to codify knowledge previously held in in a few people’s heads. The more the agency models deals, the better it understands deals.
To mitigate the risks described above, it is crucial that modeling deals into a catalog must be made as straightforward as possible. The design goal would be any analyst in a sales operations role should be able to construct a deal type that is robust, correct, and well-documented, and get it registered to accept transactions. Similarly, as new information is learned, updating the deal models should be a simple effort.
Storage
Provide fast storage and retrieval of deals for use by other components and downstream systems.
Authorization
Ensure secure access to deal information via auditable authorization rules.
Inputs
Enable the computation of the value of the deals based on inputs provided by downstream applications. Deal Engine can do this based on stored data recorded as part of a contract, or using ephemeral data supplied to it for the purpose of generating “what if” scenarios.
Event Registration
Allow the ability to register and to respond to both internal events (“is a milestone date reached?”) and external events (“How many yards did the player rush?”) that are of interest to the open deals in the system.
Artifacts
Enable flexible generation of artifacts, such as data capture forms, PDF contract documents, and notifications – all from the same data.