Coalesce renewal-seed flat deltas into one contract line

Dealops 2 renewal seeding gets an opt-in pricing-spec mode that turns repeated flat delta rows for one SKU into one rep-facing line and fixes ARR-at-scale undercounting.

Author: @mehulshinde PR: dealops#6569 Status: open Base: main Head: mehul/ecm-renewal-flat-delta-coalescing Files: 15 Diff: +1890 / -15 Area: Dealops 2 renewals

What it adds

A new org-level knob: pricingEngineSpec.renewalSeedFlatDeltaCoalesce.

Modes are off, samePrice, and latestAmendmentPrice.

What it fixes

Delta replay can seed one SKU as multiple coincident renewal rows.

TCV stays right, but reps see duplicate lines and computeArrAtScale can keep only the last row’s run rate.

What it preserves

Default mode is off.

Orgs that do not opt in skip the rule entirely, keeping today’s seed behavior unchanged.

Also included

Merge Test Org feature-flag allow-lists, first commitment date seeding from the quote start date, an ECM exposure gate, and a knowledge concept doc.

Delta contract replay
Renewal seed assembly
Flat-delta coalescer
ARR at scale
Pricing-spec mode
ECM rollout guard

1. Why this exists

Today: correct money, wrong shape
25 @ $720 + 5 @ $720Same SKU, same renewal window, two rows
  • accumulateChainProducts emits one product row per chain step.
  • mergeDuplicateContractProducts intentionally leaves flat rows alone.
  • The rep sees the same SKU twice on the renewal.
Target: one authored line
30 @ $720One SKU line; same TCV; ARR reads it correctly
  • Volume is summed only when the rest of the row payload matches.
  • No fields are discarded: features, terms, promotions, overages, and tags must match exactly.
  • Ladders and ramps stay out of scope.
ARR defect: computeArrAtScale groups by productSpecId. When every row in the group is fully dated, it treats them as sequential periods and keeps the chronologically last run rate. Coincident rows are not sequential, so ARR can report 25 × $720 instead of 30 × $720; netNewArr inherits the miss.

2. What changes

off

Default

Every replayed row seeds as its own line. The caller skips the new rule entirely.

samePrice

Same-price merge

Rows identical apart from id, commitment link, and counted volume merge at the same currency and price.

latestAmendmentPrice

Reprice, then merge

Overlapping rows for one line adopt the latest amendment price, then flow through the same coalescer.

Core server path

Before
Replay chain
Assemble seed
Product rules
Ladder collapse
After
Replay chain
Optional latest reprice
Assemble seed
Product rules
Optional coalesce
Ladder collapse

resolveEngagementRenewalSeed reads the mode with getRenewalSeedFlatDeltaCoalesce. latestAmendmentPrice applies repriceFlatDeltasToLatest before assembly; both opt-in modes apply coalesceSamePriceFlatDeltas after product rules.

Meaningful files

Renewal seed logic
apps/server/src/trpc/router/pricingQuote/renewalSeedFlatDeltas.ts+466
apps/server/src/trpc/router/pricingQuote/buildEngagementRenewalSeed.ts+40/-1
packages/types/v2/pricingSpecData.ts+54
Tests
renewalSeedFlatDeltas.test.ts+606
buildEngagementRenewalSeed.test.ts+323
pricingEngineService.spec.ts+56
Rollout + UX + docs
packages/feature-flags/flags.ts+18
PeriodTabs.tsx / periodUtils.ts+19/-2
knowledge/concepts/renewal-seed-flat-delta-coalescing.md+138
Mode Input shape Output shape Safety rule
off Any delta replay rows Same rows Caller does not invoke the coalescer.
samePrice 25 @ $720 + 5 @ $720 30 @ $720 Whole remaining payload must match; same currency, same price, same window.
latestAmendmentPrice 25 @ $720 + 343 @ $600 368 @ $600 Rows are repriced in chain order before assembly, then merged by the same coalescer.

3. How it works

Coalescing eligibility

describeFlatDeltaRow returns a candidate only for flat, counted, dated rows with currency prices.

Can merge
  • Same payloadKey: all fields except id, commitment_id, quotePriceFlat, and volumeFlat.
  • Same currency and price, rounded to PRICE_EQUALITY_DECIMALS = 10.
  • Commitment links match, or one row is unlinked.
Declines
  • Commitment-tier ladders.
  • tiered / ramped prices.
  • ramped volumes.
  • Undated rows or rows whose remaining payload differs.
if (flatDeltaCoalesce !== 'off') {
  seed.products = coalesceSamePriceFlatDeltas(seed.products);
}
Commitment wildcard without bridging

A land row may be unlinked while its amendment is remapped onto the root commitment. That pair can merge. Two concrete, different commitments cannot merge.

Allowed
land
commitment_id: undefined
+
amendment
commitment_id: c1
one row
Blocked
row A
commitment_id: c1
+
row B
commitment_id: c2
two rows

The survivor’s emitted commitment_id stays unchanged; only volumeFlat.value changes. Internally, the tracked commitment narrows to the first concrete id so an unlinked row cannot bridge c1 and c2.

The ordering invariant for latestAmendmentPrice

1
Replay contract state

accumulateChainProducts emits head first, amendments later.

2
Reprice in chain order

Latest means the last row of the line.

3
Assemble renewal seed

Rows are realigned to the renewal window.

4
Product rules

Substitution finalizes spec ids and prices.

5
Coalesce rows

Rows now share the amendment price.

Do not move the reprice after assembly. replicateActiveCommitmentLevel emits commitment-linked rows before unlinked rows. In the Merge shape, the amendment is commitment-linked and the land row is unlinked, so the assembled seed reverses their order. A post-assembly “last wins” read would pick the land’s old price.

4. Tests and rollout guards

Unit coverage
  • coalesceSamePriceFlatDeltas: merge, idempotence, purity, no mutation.
  • repriceFlatDeltasToLatest: latest price, overlapping windows, no cross-currency adoption.
  • getRenewalSeedFlatDeltaCoalesce: default off and explicit opt-ins.
Pipeline coverage
  • Replay → reprice → assemble → product rules → coalesce fixtures for Merge ECM scenarios.
  • Same-price case: 25 + 5 = 30 @ $720.
  • Reprice case: 25 + 343 = 368 @ $600, TCV $320,800.
ARR characterization
  • Two coincident same-spec rows are read as sequential by computeArrAtScale.
  • Coalesced row returns the full summed run rate.
  • netNewArr follows the corrected ARR.
ECM gate
  • --expect-exposed=<crmId,...> added to the hierarchy health script.
  • Fails on both unexpected exposure and missing approved exposure.
  • Report is written before the gate exits so failed audits leave evidence.

5. What it doesn't change

6. Risks / rollback / open questions

Primary risk: the correctness of latestAmendmentPrice depends on the chain-order invariant from accumulateChainProducts. The PR documents that invariant and pins it with tests that compare contract-state order against assembled-seed order.
Rollback path: set pricingEngineSpec.renewalSeedFlatDeltaCoalesce back to off for the org. The caller then skips reprice and coalesce, restoring today’s row shape.
Follow-up noted in the PR: the OpenAI production ECM pilot dealops-jdo7.10.2 stacks on this and carries the account-scoped regression for the production shape.