A term year is a named contractual period. It is NOT a window type — it is the time bucket a contract is active. Windows are computed per-product by the Start Date segment rules. The window must overlap a term year for the title to be eligible in that year.
| Title Example | 70 | 71 | 72 | 73 | 74 | 75 |
|---|---|---|---|---|---|---|
| US blockbuster — 1,200 screens | ✅ | — | — | — | — | — |
| Spanish film — 8 US screens, Argentina release | — | ✅ | — | — | — | — |
| Non-US film — 15 US screens, UK release | — | — | ✅ | — | — | — |
| Streaming original — no theatrical | — | — | — | — | — | ✅ |
Segments are confirmed independently per category. Submit is only enabled once all 24 are CONFIRMED.
Territory scope via filterByAttributes — restricts the attribute check to a specific geography. Non-territorial attributes (genre, titleType, language) omit this.
A title qualifies if it satisfies any one complete branch. Documentary <$1M ✅ · Action >$20M ✅ · Action $8M ❌ · Comedy any ❌
{ "ruleConditionId": 1, // All of
"rules": [
{ "attribute": "theatricalRelease",
"operatorId": 4, // NOT_EQUALS_NULL
"filterByAttributes": [{ "attribute":"territoryId", "values":["235"] }] },
{ "attribute": "numberOfScreens", "operatorId": 8, "values": ["100"] },
{ "ruleConditionId": 1, "rules": [
{ "attribute":"genre", "operatorId":13,
"values":["Documentary","Music Video/Concert"] },
{ "ruleConditionId":1, "rules":[/* 7 BETWEEN tiers */] }
]}
]
}
Start: Earlier of — Theatrical Date + 19 months
conditionId: 5 · formulaOperatorId: 11 (after)
"conditionFormula": {
"conditionId": 5, // Earlier of
"rules": [{
"formulaAttributeType": "Theatrical Dates",
"formulaOperatorId": 11, // after
"formulaValue": 19, "formulaUnit": "MONTH"
}]
}
}
conditionId: 5 · rules: [] → platform default theatrical date
"conditionFormula": { "conditionId":5, "rules":[] }
}
Overflow sorted in descending order of Box Office
"rule": { "attribute":"titleCount", "operator":7, "value":2,
"frequencyValue":"per Term Year" },
"exceedsCapSortByValue": "in descending order of Box Office"
}
Overflow sorted by Avail Date (earliest first)
"rule": { "attribute":"titleCount", "operator":7, "value":22,
"frequencyValue":"per Term Year" },
"exceedsCapSortByValue": "by Avail Date"
}
The contract doesn't say "Movie X is available from March 5." It says "The window opens 19 months after US theatrical release." Every movie has a different theatrical date → every movie gets a different computed window start.
A movie is only eligible in a term year if its computed window overlaps that year's date range. The cap (Caps segment) then limits how many of those eligible movies are actually taken.
Contract rule: windowDuration = 4 MONTHS · windowStart = theatricalReleaseDate (USA) + 19 MONTHS
| # | Movie | US Theatrical | Window Start (+19 mo) | Window End (+4 mo) | Eligible TY |
|---|---|---|---|---|---|
| 1 | Movie A | Jun 1, 2022 | Jan 1, 2024 | May 1, 2024 | ✅ TY1 |
| 2 | Movie B | Aug 15, 2022 | Mar 15, 2024 | Jul 15, 2024 | ✅ TY1 |
| 3 | Movie C | Feb 1, 2023 | Sep 1, 2024 | Jan 1, 2025 | ⚠️ TY1 + TY2 |
| 4 | Movie D | Apr 20, 2023 | Nov 20, 2024 | Mar 20, 2025 | ⚠️ TY1 + TY2 |
| 5 | Movie E | Jul 4, 2023 | Feb 4, 2025 | Jun 4, 2025 | ✅ TY2 |
| 6 | Movie F | Oct 10, 2023 | May 10, 2025 | Sep 10, 2025 | ✅ TY2 |
| 7 | Movie G | Jan 5, 2024 | Aug 5, 2025 | Dec 5, 2025 | ✅ TY2 |
| 8 | Movie H | May 20, 2024 | Dec 20, 2025 | Apr 20, 2026 | ⚠️ TY2 + TY3 |
| 9 | Movie I | Sep 1, 2024 | Apr 1, 2026 | Aug 1, 2026 | ✅ TY3 |
| 10 | Movie J | Dec 15, 2024 | Jul 15, 2026 | Nov 15, 2026 | ✅ TY3 |
One reference date + one offset. No condition needed.
"conditionFormula": {
"conditionId": null, // single formula — no condition
"rules": [{
"formulaAttributeType": "Theatrical Dates",
"formulaOperatorId": 11, // after (+)
"formulaValue": 19, "formulaUnit": "MONTH",
"filterByAttributes":[{"attribute":"territoryId","values":["235"]}]
}]
}
}
Protects the licensee — window opens as soon as any formula fires, avoiding long waits if one release date is delayed.
"conditionId": 5, // Earlier of
"rules": [
{ "formulaAttributeType":"Theatrical Dates",
"formulaOperatorId":11, "formulaValue":19, "formulaUnit":"MONTH",
"filterByAttributes":[{"attribute":"territoryId","values":["235"]}] },
{ "formulaAttributeType":"Physical Dates",
"formulaOperatorId":11, "formulaValue":15, "formulaUnit":"MONTH" }
]
}}
Protects the licensor — the window cannot open until ALL holdbacks have expired. Netflix must wait for whichever date comes last.
"conditionId": 6, // Later of
"rules": [
{ "formulaAttributeType":"Theatrical Dates",
"formulaOperatorId":11, "formulaValue":19, "formulaUnit":"MONTH" },
{ "formulaAttributeType":"EST Dates",
"formulaOperatorId":11, "formulaValue":90, "formulaUnit":"DAY" }
]
}}
The territory is not hard-coded.
"$HOME_OFFICE" is stored as a literal string. Module 2 resolves it to the actual territory ID at runtime by looking up the title's countryOfOriginList."formulaOperatorId": 11,
"formulaValue": 19, "formulaUnit": "MONTH",
"filterByAttributes": [{
"attribute": "territoryId",
"values": ["$HOME_OFFICE"]
}]
}
| Contract Phrase | conditionId | operatorId | Protects |
|---|---|---|---|
| "X months after [date]" | null | 11 — after | Single formula |
| "Earlier of [A] or [B]" | 5 | 11 on each | Licensee — window opens sooner |
| "Later of [A] or [B]" | 6 | 11 on each | Licensor — all holdbacks must expire |
| "No later than X months" | n/a | 11 in noLaterThanFormula | Hard ceiling on window start |
| "X days before [date]" | null | 12 — before | Offset subtracted from date |
⚠️ operatorIds 11 and 12 are Start Date only — never use them in Qualifiers. Qualifiers only test static attribute values.
titleCount LESSER_EQUALS N per Term Year| capsOption | Meaning |
|---|---|
| "Cap" | Hard ceiling — max N titles per term year. Standard deal. |
| "No Cap" | No limit — all qualifying titles with valid windows can be taken. |
Fill slots with movies whose windows open soonest. Used for high-volume categories (Cat 70, 71, 72, 75) — maximises use of early-opening windows.
Fill slots with the highest-earning movies first. Used for tight prestige caps (Cat 73, 74) — maximises commercial value when only 2–3 slots exist.
| Rank (Avail Date) | Movie | Window Start | Box Office | Slot (cap = 10) |
|---|---|---|---|---|
| 1 | Movie A | Jan 5 | $45M | ✅ Slot 1 |
| 2 | Movie B | Feb 2 | $12M | ✅ Slot 2 |
| 3–10 | Movies C–J fill remaining slots… | ✅ Slots 3–10 | ||
| 11 | Movie K | Oct 15 | $100M ← biggest BO | ❌ Overflow — excluded |
| 12 | Movie L | Nov 2 | $67M | ❌ Overflow — excluded |
If sort were Box Office ↓, Movie K ($100M) would take Slot 1. Same 10 slots — different movies included.
| Cat | Category | Cap | Frequency | Overflow Sort |
|---|---|---|---|---|
| 70 | First Run Films | 33 | per Term Year | by Avail Date |
| 75 | MFP / MFTV / DTV | 22 | per Term Year | by Avail Date |
| 71 | Limited Release LA | 10 | per Term Year | by Avail Date |
| 72 | Other Limited Release | 10 | per Term Year | by Avail Date |
| 73 | Library Titles | 3 | per Term Year | Box Office ↓ |
| 74 | Local / Art Films | 2 | per Term Year | Box Office ↓ |
{ "capsOption": "Cap",
"rule": {
"attribute": "titleCount", // always
"operator": 7, // LESSER_EQUALS — always
"value": 33,
"frequencyValue": "per Term Year"
},
"exceedsCapSortByValue": "by Avail Date",
"productCategoryIds": [70]
}
| Field | Notes |
|---|---|
| capsOption | "Cap" or "No Cap" |
| attribute | Always "titleCount" — system constant |
| operator | Always 7 (LESSER_EQUALS ≤) — system constant |
| value | Max titles — positive integer, user editable |
| frequencyValue | Always "per Term Year" — system constant |
| exceedsCapSortByValue | Stored as raw contract string — Module 2 parses it |
Pricing / MG / shortfall → Rate Cards. Which titles fill slots → Module 2 runtime. attribute, operator, frequencyValue are system constants — never shown as editable UI fields.
rule-operators.json · rule-conditions.json| ID | Name | Symbol | Segment |
|---|---|---|---|
| 1 | EQUALS | = | Qualifiers |
| 2 | NOT_EQUALS | ≠ | Qualifiers |
| 3 | EQUALS_NULL | ∅ | Qualifiers |
| 4 | NOT_EQUALS_NULL | ∃ | Qualifiers |
| 5 | LESSER | < | Qualifiers |
| 6 | GREATER | > | Qualifiers |
| 7 | LESSER_EQUALS | ≤ | QualifiersCaps |
| 8 | GREATER_EQUALS | ≥ | Qualifiers |
| 9 | IN | ∈ | Qualifiers |
| 10 | BETWEEN | ↔ | Qualifiers |
| 11 | after | + | Start Date |
| 12 | before | − | Start Date |
| 13 | NOT_IN | ∉ | Qualifiers |
| ID | Name | Expr | Meaning |
|---|---|---|---|
| 1 | All of | && | AND — all children must be true |
| 2 | One of | || | OR — any child must be true |
| 8 | None of | null | NOR — no child may be true |
| ID | Name | Meaning |
|---|---|---|
| 3 | on or before | Window start ≤ computed date |
| 4 | on or after | Window start ≥ computed date |
| 5 | Earlier of | min() — pick earliest candidate date |
| 6 | Later of | max() — pick latest candidate date |
· conditionId 11 does NOT exist — use
ruleOperatorId 11 for date offset· Never pass
"NULL" as a value — use EQUALS_NULL(3) / NOT_EQUALS_NULL(4)· ops 11 & 12 are Start Date only — never in Qualifiers