@uwmd/core 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/browser.d.ts +10 -0
  2. package/dist/browser.d.ts.map +1 -1
  3. package/dist/browser.js +5 -0
  4. package/dist/browser.js.map +1 -1
  5. package/dist/calc/dated-flows.d.ts +26 -0
  6. package/dist/calc/dated-flows.d.ts.map +1 -0
  7. package/dist/calc/dated-flows.js +163 -0
  8. package/dist/calc/dated-flows.js.map +1 -0
  9. package/dist/calc/day-count.d.ts +27 -0
  10. package/dist/calc/day-count.d.ts.map +1 -0
  11. package/dist/calc/day-count.js +95 -0
  12. package/dist/calc/day-count.js.map +1 -0
  13. package/dist/calc/errors.d.ts +1 -1
  14. package/dist/calc/errors.d.ts.map +1 -1
  15. package/dist/calc/errors.js.map +1 -1
  16. package/dist/cash-flow-series.d.ts +106 -0
  17. package/dist/cash-flow-series.d.ts.map +1 -0
  18. package/dist/cash-flow-series.js +298 -0
  19. package/dist/cash-flow-series.js.map +1 -0
  20. package/dist/cli-portfolio.d.ts +7 -0
  21. package/dist/cli-portfolio.d.ts.map +1 -0
  22. package/dist/cli-portfolio.js +68 -0
  23. package/dist/cli-portfolio.js.map +1 -0
  24. package/dist/cli.js +25 -0
  25. package/dist/cli.js.map +1 -1
  26. package/dist/index.d.ts +10 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +5 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/parser.d.ts.map +1 -1
  31. package/dist/parser.js +2 -0
  32. package/dist/parser.js.map +1 -1
  33. package/dist/portfolio.d.ts +71 -0
  34. package/dist/portfolio.d.ts.map +1 -0
  35. package/dist/portfolio.js +174 -0
  36. package/dist/portfolio.js.map +1 -0
  37. package/dist/protocol.d.ts +8 -4
  38. package/dist/protocol.d.ts.map +1 -1
  39. package/dist/protocol.js +87 -2
  40. package/dist/protocol.js.map +1 -1
  41. package/dist/renderer.js +44 -1
  42. package/dist/renderer.js.map +1 -1
  43. package/dist/validator.d.ts.map +1 -1
  44. package/dist/validator.js +239 -0
  45. package/dist/validator.js.map +1 -1
  46. package/dist/version.d.ts +1 -1
  47. package/dist/version.js +1 -1
  48. package/dist/waterfall.d.ts +126 -0
  49. package/dist/waterfall.d.ts.map +1 -0
  50. package/dist/waterfall.js +384 -0
  51. package/dist/waterfall.js.map +1 -0
  52. package/package.json +2 -2
@@ -0,0 +1,126 @@
1
+ import { type CashFlowSeries } from './cash-flow-series.js';
2
+ export type WaterfallParty = 'lp' | 'gp';
3
+ export interface WaterfallTierReturnOfCapital {
4
+ type: 'return_of_capital';
5
+ }
6
+ export interface WaterfallTierPreferredReturn {
7
+ type: 'preferred_return';
8
+ /** Fraction in (0, 1). */
9
+ rate: number;
10
+ accrual: 'simple' | 'compound_annual';
11
+ }
12
+ export interface WaterfallTierCatchUp {
13
+ type: 'catch_up';
14
+ /** Share of this tier's cash going to the GP. MUST exceed target_promote. */
15
+ gp_share: number;
16
+ /** The GP profit share the catch-up fills toward. */
17
+ target_promote: number;
18
+ }
19
+ export interface WaterfallTierSplit {
20
+ type: 'split';
21
+ lp_share: number;
22
+ gp_share: number;
23
+ /** Caps the tier where cumulative LP distributions reach this multiple of LP contributions. */
24
+ until_lp_em?: number | null;
25
+ }
26
+ export type WaterfallTier = WaterfallTierReturnOfCapital | WaterfallTierPreferredReturn | WaterfallTierCatchUp | WaterfallTierSplit;
27
+ export interface WaterfallPartyOutcomes {
28
+ contributions?: number | null;
29
+ distributions?: number | null;
30
+ moic?: number | null;
31
+ xirr?: number | null;
32
+ }
33
+ export interface WaterfallStatedOutcomes {
34
+ lp?: WaterfallPartyOutcomes | null;
35
+ gp?: WaterfallPartyOutcomes | null;
36
+ promote_total?: number | null;
37
+ profit_total?: number | null;
38
+ }
39
+ export interface WaterfallScheduleCell {
40
+ tier: number;
41
+ lp?: number | null;
42
+ gp?: number | null;
43
+ }
44
+ export interface WaterfallScheduleRow {
45
+ date: string;
46
+ by_tier: WaterfallScheduleCell[];
47
+ }
48
+ /** The `distribution_waterfall` section content (UW_FORMAT_SPEC §4.27). */
49
+ export interface DistributionWaterfall {
50
+ cash_flow_ref: {
51
+ variant: string;
52
+ };
53
+ equity_split: {
54
+ lp: number;
55
+ gp: number;
56
+ };
57
+ tiers: WaterfallTier[];
58
+ stated_outcomes?: WaterfallStatedOutcomes | null;
59
+ stated_schedule?: WaterfallScheduleRow[] | null;
60
+ }
61
+ export interface WaterfallPartyResult {
62
+ contributions: number;
63
+ distributions: number;
64
+ roc_received: number;
65
+ pref_received: number;
66
+ /** Undefined ratio (zero contributions) reports null, never Infinity. */
67
+ moic: number | null;
68
+ /** The §VIII.9.3 root, or null when the procedure refuses (no sign change). */
69
+ xirr: number | null;
70
+ }
71
+ export interface WaterfallAllocation {
72
+ lp: WaterfallPartyResult;
73
+ gp: WaterfallPartyResult;
74
+ promote_total: number;
75
+ profit_total: number;
76
+ /** One row per distribution date; only tiers that paid appear. */
77
+ schedule: Array<{
78
+ date: string;
79
+ by_tier: Array<{
80
+ tier: number;
81
+ lp: number;
82
+ gp: number;
83
+ }>;
84
+ }>;
85
+ }
86
+ export type WaterfallVerdict = 'verified' | 'failed' | 'unverifiable';
87
+ export type WaterfallIssueCode = 'WF-OUTCOME-DISAGREES' | 'WF-SCHEDULE-DISAGREES' | 'WF-PROCEDURE-REFUSES' | 'WF-UNEVALUABLE';
88
+ export interface WaterfallIssue {
89
+ code: WaterfallIssueCode;
90
+ severity: 'failure' | 'indeterminate';
91
+ message: string;
92
+ /** Dotted path into stated_outcomes / stated_schedule this anchors to. */
93
+ field?: string;
94
+ expected?: string;
95
+ actual?: string;
96
+ }
97
+ export interface WaterfallVerification {
98
+ verdict: WaterfallVerdict;
99
+ issues: WaterfallIssue[];
100
+ }
101
+ export declare const WATERFALL_VERIFY_DECIMALS: Readonly<{
102
+ readonly currency: 2;
103
+ readonly rate: 6;
104
+ readonly ratio: 4;
105
+ }>;
106
+ /**
107
+ * Recompute the full allocation by the normative §VIII.10 walk. The caller
108
+ * supplies a structurally valid series and a WF-01-clean waterfall (structure
109
+ * is validation); this function still returns `null` rather than throwing
110
+ * when either is unusable, so the verifier can report `unverifiable`.
111
+ */
112
+ export declare function computeWaterfall(waterfall: DistributionWaterfall, series: CashFlowSeries): WaterfallAllocation | null;
113
+ /**
114
+ * Recompute the allocation and compare every stated figure, three-state:
115
+ * - a stated outcome or schedule cell disagrees beyond its quantum, or a
116
+ * stated xirr the §VIII.9.3 procedure refuses → `failed`
117
+ * - the referenced series is missing/invalid, or a stated ratio is
118
+ * undefined (zero contributions) → `unverifiable`
119
+ * - otherwise → `verified`
120
+ *
121
+ * `series` is the resolved §4.26 variant the waterfall's `cash_flow_ref`
122
+ * names; pass `null` when it does not resolve (the WF-02 situation reaching
123
+ * a verifier rather than the validator).
124
+ */
125
+ export declare function verifyWaterfall(waterfall: DistributionWaterfall, series: CashFlowSeries | null): WaterfallVerification;
126
+ //# sourceMappingURL=waterfall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waterfall.d.ts","sourceRoot":"","sources":["../src/waterfall.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,384 @@
1
+ // Distribution waterfall — state-and-verify LP/GP allocation (RFC 0035,
2
+ // UW_FORMAT_SPEC §4.27, protocol §VIII.10).
3
+ //
4
+ // The fourth state-and-verify structure: the document states a tier ladder
5
+ // (return of capital → preferred return → catch-up → promote splits) over a
6
+ // §4.26 dated series, and this module RECOMPUTES THE ENTIRE ALLOCATION —
7
+ // period by period, tier by tier — by the normative §VIII.10 walk, so two
8
+ // conforming engines agree on the promote. The verifier never trusts the
9
+ // stated splits; a verifier that did would verify nothing a spreadsheet
10
+ // didn't.
11
+ //
12
+ // This deliberately does NOT touch the Tier-3 calc engine, and it does not
13
+ // touch `capital_stack`: the stack is the liability side at one point in
14
+ // time (RFC 0033), this is the equity side over the hold, and the §4.24
15
+ // CS-WATERFALL-UNSUPPORTED boundary stays. Structural rules (`WF-01`…`WF-03`)
16
+ // are validator errors (validator.ts); arithmetic is verification here.
17
+ // Browser-safe; performs no I/O.
18
+ import { datedFlowsOf, xirrOf, } from './cash-flow-series.js';
19
+ import { DEFAULT_DAY_COUNT, isDayCountConvention, parseISODate, yearfrac, } from './calc/day-count.js';
20
+ // ─── Quantization (§VIII.9.4 quanta, the sibling verifiers' posture) ─────────
21
+ export const WATERFALL_VERIFY_DECIMALS = Object.freeze({
22
+ currency: 2,
23
+ rate: 6,
24
+ ratio: 4,
25
+ });
26
+ function roundTo(value, decimals) {
27
+ const f = 10 ** decimals;
28
+ const scaled = value * f;
29
+ return (scaled < 0 ? -Math.round(-scaled) : Math.round(scaled)) / f;
30
+ }
31
+ function isNum(v) {
32
+ return typeof v === 'number' && Number.isFinite(v);
33
+ }
34
+ function newParty() {
35
+ return {
36
+ unreturned: 0,
37
+ accrued_pref: 0,
38
+ contributions: 0,
39
+ distributions: 0,
40
+ roc_received: 0,
41
+ pref_received: 0,
42
+ flows: [],
43
+ };
44
+ }
45
+ /**
46
+ * Recompute the full allocation by the normative §VIII.10 walk. The caller
47
+ * supplies a structurally valid series and a WF-01-clean waterfall (structure
48
+ * is validation); this function still returns `null` rather than throwing
49
+ * when either is unusable, so the verifier can report `unverifiable`.
50
+ */
51
+ export function computeWaterfall(waterfall, series) {
52
+ const rows = series.series;
53
+ const flows = datedFlowsOf(series);
54
+ if (flows === null)
55
+ return null;
56
+ const convention = series.day_count ?? DEFAULT_DAY_COUNT;
57
+ if (!isDayCountConvention(convention))
58
+ return null;
59
+ const split = waterfall.equity_split;
60
+ if (!split || !isNum(split.lp) || !isNum(split.gp))
61
+ return null;
62
+ const tiers = waterfall.tiers;
63
+ if (!Array.isArray(tiers) || tiers.length === 0)
64
+ return null;
65
+ const pref = tiers.find((t) => t?.type === 'preferred_return');
66
+ const lp = newParty();
67
+ const gp = newParty();
68
+ const parties = [
69
+ ['lp', lp, split.lp],
70
+ ['gp', gp, split.gp],
71
+ ];
72
+ const schedule = [];
73
+ let prevDate = null;
74
+ for (let i = 0; i < rows.length; i++) {
75
+ const row = rows[i];
76
+ const date = parseISODate(row.date);
77
+ if (date === null)
78
+ return null;
79
+ // 1. Accrue first — pairwise yearfrac per §VIII.10, never differences of
80
+ // anchor fractions (30/360us is not additive).
81
+ if (pref && prevDate !== null) {
82
+ const dt = yearfrac(prevDate, date, convention);
83
+ for (const [, p] of parties.map(([n, s]) => [n, s])) {
84
+ if (dt > 0) {
85
+ if (pref.accrual === 'simple') {
86
+ p.accrued_pref += p.unreturned * pref.rate * dt;
87
+ }
88
+ else {
89
+ p.accrued_pref += (p.accrued_pref + p.unreturned) * ((1 + pref.rate) ** dt - 1);
90
+ }
91
+ }
92
+ }
93
+ }
94
+ prevDate = date;
95
+ const t = flows[i].t;
96
+ const amount = row.amount;
97
+ // 2. Contributions.
98
+ if (amount < 0) {
99
+ for (const [, p, share] of parties) {
100
+ const portion = -amount * share;
101
+ if (portion === 0)
102
+ continue;
103
+ p.unreturned += portion;
104
+ p.contributions += portion;
105
+ p.flows.push({ t, amount: -portion });
106
+ }
107
+ continue;
108
+ }
109
+ if (amount === 0)
110
+ continue;
111
+ // 3. Distributions fill the ladder.
112
+ let remaining = amount;
113
+ const byTier = [];
114
+ // Profit = distributions above returned capital. Pref receipts COUNT as
115
+ // profit — excluding them makes a catch-up that follows the pref tier
116
+ // have capacity zero forever (the RFC's original wording had exactly
117
+ // that bug; recorded as an erratum). `promote_total` still excludes the
118
+ // GP's own pref: the promote is what the GP earns beyond its co-invest
119
+ // return.
120
+ const profitSoFar = () => lp.distributions - lp.roc_received +
121
+ gp.distributions - gp.roc_received;
122
+ const gpProfit = () => gp.distributions - gp.roc_received;
123
+ for (let ti = 0; ti < tiers.length && remaining > 0; ti++) {
124
+ const tier = tiers[ti];
125
+ let lpPay = 0;
126
+ let gpPay = 0;
127
+ switch (tier.type) {
128
+ case 'return_of_capital': {
129
+ const cap = lp.unreturned + gp.unreturned;
130
+ const pay = Math.min(remaining, cap);
131
+ if (pay <= 0 || cap <= 0)
132
+ break;
133
+ lpPay = pay * (lp.unreturned / cap);
134
+ gpPay = pay - lpPay;
135
+ lp.unreturned -= lpPay;
136
+ gp.unreturned -= gpPay;
137
+ lp.roc_received += lpPay;
138
+ gp.roc_received += gpPay;
139
+ break;
140
+ }
141
+ case 'preferred_return': {
142
+ const cap = lp.accrued_pref + gp.accrued_pref;
143
+ const pay = Math.min(remaining, cap);
144
+ if (pay <= 0 || cap <= 0)
145
+ break;
146
+ lpPay = pay * (lp.accrued_pref / cap);
147
+ gpPay = pay - lpPay;
148
+ lp.accrued_pref -= lpPay;
149
+ gp.accrued_pref -= gpPay;
150
+ lp.pref_received += lpPay;
151
+ gp.pref_received += gpPay;
152
+ break;
153
+ }
154
+ case 'catch_up': {
155
+ const denom = tier.gp_share - tier.target_promote;
156
+ if (!(denom > 0))
157
+ return null; // WF-01 grammar; unreachable when validated
158
+ const cap = Math.max(0, (tier.target_promote * profitSoFar() - gpProfit()) / denom);
159
+ const pay = Math.min(remaining, cap);
160
+ if (pay <= 0)
161
+ break;
162
+ gpPay = pay * tier.gp_share;
163
+ lpPay = pay - gpPay;
164
+ break;
165
+ }
166
+ case 'split': {
167
+ let cap = Number.POSITIVE_INFINITY;
168
+ if (tier.until_lp_em != null) {
169
+ if (!(tier.lp_share > 0))
170
+ break; // capped tier paying LP nothing: cap 0
171
+ cap = Math.max(0, tier.until_lp_em * lp.contributions - lp.distributions) / tier.lp_share;
172
+ }
173
+ const pay = Math.min(remaining, cap);
174
+ if (pay <= 0)
175
+ break;
176
+ lpPay = pay * tier.lp_share;
177
+ gpPay = pay - lpPay;
178
+ break;
179
+ }
180
+ default:
181
+ return null;
182
+ }
183
+ const pay = lpPay + gpPay;
184
+ if (pay <= 0)
185
+ continue;
186
+ lp.distributions += lpPay;
187
+ gp.distributions += gpPay;
188
+ if (lpPay !== 0)
189
+ lp.flows.push({ t, amount: lpPay });
190
+ if (gpPay !== 0)
191
+ gp.flows.push({ t, amount: gpPay });
192
+ byTier.push({ tier: ti, lp: lpPay, gp: gpPay });
193
+ remaining -= pay;
194
+ }
195
+ if (remaining > 1e-9 * amount) {
196
+ // No uncapped terminal split absorbed the residue — WF-01 grammar;
197
+ // unreachable when validated, refused rather than silently dropped.
198
+ return null;
199
+ }
200
+ if (byTier.length > 0)
201
+ schedule.push({ date: row.date, by_tier: byTier });
202
+ }
203
+ const partyResult = (p) => {
204
+ let xirr = null;
205
+ try {
206
+ xirr = p.flows.length >= 2 ? xirrOf(p.flows) : null;
207
+ }
208
+ catch {
209
+ xirr = null; // §VIII.9.3 refusal — reported as null; the verifier decides severity
210
+ }
211
+ return {
212
+ contributions: p.contributions,
213
+ distributions: p.distributions,
214
+ roc_received: p.roc_received,
215
+ pref_received: p.pref_received,
216
+ moic: p.contributions > 0 ? p.distributions / p.contributions : null,
217
+ xirr,
218
+ };
219
+ };
220
+ return {
221
+ lp: partyResult(lp),
222
+ gp: partyResult(gp),
223
+ promote_total: gp.distributions - gp.roc_received - gp.pref_received,
224
+ profit_total: lp.distributions + gp.distributions - lp.contributions - gp.contributions,
225
+ schedule,
226
+ };
227
+ }
228
+ // ─── Verification ────────────────────────────────────────────────────────────
229
+ /**
230
+ * Recompute the allocation and compare every stated figure, three-state:
231
+ * - a stated outcome or schedule cell disagrees beyond its quantum, or a
232
+ * stated xirr the §VIII.9.3 procedure refuses → `failed`
233
+ * - the referenced series is missing/invalid, or a stated ratio is
234
+ * undefined (zero contributions) → `unverifiable`
235
+ * - otherwise → `verified`
236
+ *
237
+ * `series` is the resolved §4.26 variant the waterfall's `cash_flow_ref`
238
+ * names; pass `null` when it does not resolve (the WF-02 situation reaching
239
+ * a verifier rather than the validator).
240
+ */
241
+ export function verifyWaterfall(waterfall, series) {
242
+ const issues = [];
243
+ const stated = waterfall.stated_outcomes;
244
+ const statedSchedule = waterfall.stated_schedule;
245
+ const hasClaims = (stated != null && Object.keys(stated).length > 0) ||
246
+ (statedSchedule != null && statedSchedule.length > 0);
247
+ if (!hasClaims)
248
+ return { verdict: 'verified', issues };
249
+ const allocation = series ? computeWaterfall(waterfall, series) : null;
250
+ if (allocation === null) {
251
+ issues.push({
252
+ code: 'WF-UNEVALUABLE',
253
+ severity: 'indeterminate',
254
+ message: series
255
+ ? 'The waterfall or its referenced series is structurally unusable (WF-01/CF-01/CF-02), so stated figures cannot be verified.'
256
+ : 'cash_flow_ref does not resolve to a series (WF-02), so stated figures cannot be verified.',
257
+ });
258
+ return { verdict: 'unverifiable', issues };
259
+ }
260
+ const dp = WATERFALL_VERIFY_DECIMALS;
261
+ const checkCurrency = (field, claim, actual) => {
262
+ if (!isNum(claim))
263
+ return;
264
+ const want = roundTo(claim, dp.currency);
265
+ const got = roundTo(actual, dp.currency);
266
+ if (want !== got) {
267
+ issues.push({
268
+ code: 'WF-OUTCOME-DISAGREES',
269
+ severity: 'failure',
270
+ field,
271
+ message: `${field} states ${claim} but §VIII.10 recomputes to ${got}.`,
272
+ expected: String(want),
273
+ actual: String(got),
274
+ });
275
+ }
276
+ };
277
+ for (const party of ['lp', 'gp']) {
278
+ const claim = stated?.[party];
279
+ if (!claim)
280
+ continue;
281
+ const actual = allocation[party];
282
+ checkCurrency(`stated_outcomes.${party}.contributions`, claim.contributions, actual.contributions);
283
+ checkCurrency(`stated_outcomes.${party}.distributions`, claim.distributions, actual.distributions);
284
+ if (isNum(claim.moic)) {
285
+ if (actual.moic === null) {
286
+ issues.push({
287
+ code: 'WF-UNEVALUABLE',
288
+ severity: 'indeterminate',
289
+ field: `stated_outcomes.${party}.moic`,
290
+ message: `stated_outcomes.${party}.moic is stated but ${party} has no contributions, so the multiple is undefined and cannot be verified.`,
291
+ });
292
+ }
293
+ else {
294
+ const want = roundTo(claim.moic, dp.ratio);
295
+ const got = roundTo(actual.moic, dp.ratio);
296
+ if (want !== got) {
297
+ issues.push({
298
+ code: 'WF-OUTCOME-DISAGREES',
299
+ severity: 'failure',
300
+ field: `stated_outcomes.${party}.moic`,
301
+ message: `stated_outcomes.${party}.moic states ${claim.moic} but recomputes to ${got}.`,
302
+ expected: String(want),
303
+ actual: String(got),
304
+ });
305
+ }
306
+ }
307
+ }
308
+ if (isNum(claim.xirr)) {
309
+ if (actual.xirr === null) {
310
+ issues.push({
311
+ code: 'WF-PROCEDURE-REFUSES',
312
+ severity: 'failure',
313
+ field: `stated_outcomes.${party}.xirr`,
314
+ message: `stated_outcomes.${party}.xirr states a value but the §VIII.9.3 procedure refuses ${party}'s recomputed flows (no sign change or no bracketed root) — the document asserts a number the procedure cannot produce.`,
315
+ });
316
+ }
317
+ else {
318
+ const want = roundTo(claim.xirr, dp.rate);
319
+ const got = roundTo(actual.xirr, dp.rate);
320
+ if (want !== got) {
321
+ issues.push({
322
+ code: 'WF-OUTCOME-DISAGREES',
323
+ severity: 'failure',
324
+ field: `stated_outcomes.${party}.xirr`,
325
+ message: `stated_outcomes.${party}.xirr states ${claim.xirr} but §VIII.9.3 recomputes to ${got}.`,
326
+ expected: String(want),
327
+ actual: String(got),
328
+ });
329
+ }
330
+ }
331
+ }
332
+ }
333
+ checkCurrency('stated_outcomes.promote_total', stated?.promote_total, allocation.promote_total);
334
+ checkCurrency('stated_outcomes.profit_total', stated?.profit_total, allocation.profit_total);
335
+ // Schedule cells: an absent cell reads 0, both directions (§VIII.10.5).
336
+ if (statedSchedule != null && statedSchedule.length > 0) {
337
+ const recomputedByDate = new Map();
338
+ for (const row of allocation.schedule) {
339
+ const m = new Map();
340
+ for (const c of row.by_tier)
341
+ m.set(c.tier, { lp: c.lp, gp: c.gp });
342
+ recomputedByDate.set(row.date, m);
343
+ }
344
+ const tierCount = waterfall.tiers.length;
345
+ const dates = new Set([
346
+ ...statedSchedule.map((r) => r.date),
347
+ ...allocation.schedule.map((r) => r.date),
348
+ ]);
349
+ for (const date of [...dates].sort()) {
350
+ const statedRow = statedSchedule.find((r) => r.date === date);
351
+ const statedCells = new Map();
352
+ for (const c of statedRow?.by_tier ?? []) {
353
+ statedCells.set(c.tier, { lp: isNum(c.lp) ? c.lp : 0, gp: isNum(c.gp) ? c.gp : 0 });
354
+ }
355
+ const actualCells = recomputedByDate.get(date) ?? new Map();
356
+ for (let ti = 0; ti < tierCount; ti++) {
357
+ const want = statedCells.get(ti) ?? { lp: 0, gp: 0 };
358
+ const got = actualCells.get(ti) ?? { lp: 0, gp: 0 };
359
+ for (const party of ['lp', 'gp']) {
360
+ const w = roundTo(want[party], dp.currency);
361
+ const g = roundTo(got[party], dp.currency);
362
+ if (w !== g) {
363
+ issues.push({
364
+ code: 'WF-SCHEDULE-DISAGREES',
365
+ severity: 'failure',
366
+ field: `stated_schedule[${date}].tier[${ti}].${party}`,
367
+ message: `Schedule ${date} tier ${ti} ${party} states ${w} but §VIII.10 recomputes to ${g}.`,
368
+ expected: String(w),
369
+ actual: String(g),
370
+ });
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ if (issues.some((i) => i.severity === 'failure')) {
377
+ return { verdict: 'failed', issues };
378
+ }
379
+ if (issues.some((i) => i.severity === 'indeterminate')) {
380
+ return { verdict: 'unverifiable', issues };
381
+ }
382
+ return { verdict: 'verified', issues };
383
+ }
384
+ //# sourceMappingURL=waterfall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waterfall.js","sourceRoot":"","sources":["../src/waterfall.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uwmd/core",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Reference implementation of the UW Markdown standard — parser, validator, renderer, and CLI for .uw.md underwriting files.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@anthropic-ai/sdk": "^0.91.1",
61
- "@uwmd/signing": "0.2.2"
61
+ "@uwmd/signing": "0.2.4"
62
62
  },
63
63
  "peerDependenciesMeta": {
64
64
  "@anthropic-ai/sdk": {