PageSourceSearch

https://www.aivin.ai/site/sable-reserve-compute.51a043d7f4.js

js aivin.ai collected 2026-10-05 13:39:33 UTC 64,456 bytes, 875 lines download raw bytes

1/* SABLE_COMPUTE — every figure the Wine Program Diagnostic displays. V3.
2
3   The web preview, the printed five-page PDF and all four supporting schedules
4   call this and render what comes back. Nothing downstream states a count, a
5   percentage or a dollar amount of its own.
6
7   Four rules this module exists to enforce:
8
9   1. NO MIXED-BASIS TOTAL. Every money figure carries a value basis, and
10      figures on different bases are never summed. There is deliberately no
11      grand total, because there is no honest way to compute one.
12
13   2. FOUR SEPARATE POPULATIONS, never conflated:
14        resolved records            — wines in the Cellar Record
15        held source rows            — source rows that never became a record
16        unreferenced resolved wines — in the Record, no qualifying comparable
17        operational exceptions      — list, bin and posting problems
18      They are different things that happen to be countable.
19
20   3. DE-DUPLICATION IS BY RECORD ID. Finding appearances, distinct records and
21      distinct bottles are three different numbers, all reported separately.
22
23   4. EVIDENCE CANNOT BE MANUFACTURED. A document the program can send may
24      clarify identity, vintage, format, provenance, cost or condition. It does
25      not create a market comparable. Those are two different columns. */
26(function () {
27  'use strict';
28
29  var BASIS = {
30    cost: 'Cost basis',
31    grossList: 'Gross list value',
32    listGap: 'Aggregate list-price gap to house protocol',
33    market: 'Market-referenced value',
34    replacement: 'Replacement value',
35    nrv: 'Estimated seller net proceeds',
36    excess: 'Excess exposure above house protocol',
37  };
38
39  var MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
40    'August', 'September', 'October', 'November', 'December'];
41
42  /* Readable dates on every customer-facing surface. */
43  function longDate(iso) {
44    if (!iso) return '';
45    var p = String(iso).split('-');
46    if (p.length !== 3) return iso;
47    return MONTHS[Number(p[1]) - 1] + ' ' + Number(p[2]) + ', ' + p[0];
48  }
49  function monthYear(iso) {
50    if (!iso) return '';
51    var p = String(iso).split('-');
52    return p.length >= 2 ? MONTHS[Number(p[1]) - 1] + ' ' + p[0] : iso;
53  }
54
55  function label(w) {
56    var parts = [w.producer];
57    if (w.cuvee_or_vineyard) parts.push(w.cuvee_or_vineyard);
58    parts.push(w.appellation, String(w.vintage));
59    if (w.format_ml !== 750) parts.push(w.format_ml >= 1000 ? (w.format_ml / 1000) + 'L' : w.format_ml + 'ml');
60    return parts.join(' \u00b7 ');
61  }
62  function sum(arr, fn) { return arr.reduce(function (a, x) { return a + (fn(x) || 0); }, 0); }
63  function uniq(arr) { return Object.keys(arr.reduce(function (a, k) { a[k] = 1; return a; }, {})); }
64  function pct(n, d) { return d ? Math.round((n / d) * 1000) / 10 : 0; }
65  function plural(n, one, many) { return n + ' ' + (n === 1 ? one : (many || one + 's')); }
66
67  window.SABLE_COMPUTE = function (D) {
68    var P = D.program, W = D.wines, byId = {};
69    W.forEach(function (w) { byId[w.wine_id] = w; });
70
71    var SERVICE_ROLES = ['active', 'reserve', 'btg', 'pairing'];
72
73    /* ── The house pricing protocol ───────────────────────────────────── */
74
75    function targetMultiple(w) {
76      if (w.format_ml !== 750) return P.large_format_target_multiple;
77      for (var i = 0; i < P.pricing_bands.length; i++) {
78        if (w.cost_per_bottle < P.pricing_bands[i].max_cost) return P.pricing_bands[i].target_multiple;
79      }
80      return P.pricing_bands[P.pricing_bands.length - 1].target_multiple;
81    }
82    W.forEach(function (w) {
83      w.target_multiple = targetMultiple(w);
84      w.target_list_price = Math.round(w.cost_per_bottle * w.target_multiple);
85      w.gross_list_value = (w.current_list_price || 0) * w.quantity;
86      /* Materiality floor: the target must exceed the current price by at least
87         10% before it is a pricing decision rather than a rounding difference. */
88      var material = w.current_list_price > 0 && w.target_list_price >= w.current_list_price * 1.1;
89      w.list_price_gap = (w.list_status === 'listed' && material && w.quantity > 0)
90        ? Math.max(0, (w.target_list_price - w.current_list_price) * w.quantity) : 0;
91    });
92
93    /* ── Four populations, kept apart (P0.1) ──────────────────────────── */
94
95    /* Three populations. Grade C keeps its reference and stays visible, and it
96       contributes to no market-referenced total until the vintage-adjustment
97       method is open to independent review. */
98    var referenced = W.filter(function (w) { return w.market_eligible && w.market_reference_value != null; });
99    var indicative = W.filter(function (w) { return w.indicative_only; });
100    var unreferenced_resolved = W.filter(function (w) { return !w.market_eligible; });
101    var held_source_rows = sum(D.held_source_rows, function (h) { return h.count; });
102
103    var bottle_count = sum(W, function (w) { return w.quantity; });
104    var cellar_master_rows = D.source_files.filter(function (f) { return f[0] === 'SRC-1'; })[0][2];
105    var source_set_count = D.source_files.length;
106
107    /* ── The printed list, and three separate match measures (P0.5) ───── */
108
109    var overrides = {};
110    D.list.forEach(function (l) { if (l.wine_id) overrides[l.wine_id] = l; });
111    var printed = [];
112    W.forEach(function (w) {
113      if (w.list_status !== 'listed') return;
114      if (overrides[w.wine_id]) { printed.push(overrides[w.wine_id]); return; }
115      printed.push({ list_record_id: 'L-' + w.wine_id, wine_id: w.wine_id, printed_producer: w.producer,
116        printed_wine: w.cuvee_or_vineyard || w.appellation,
117        printed_vintage: w.printed_vintage_override != null ? w.printed_vintage_override : w.vintage,
118        printed_format: w.format_ml, printed_price: w.current_list_price, section: w.region,
119        active_status: 'active',
120        match_status: w.quantity === 0 ? 'no_stock'
121          : w.printed_vintage_override != null ? 'vintage_mismatch' : 'matched' });
122    });
123    D.list.forEach(function (l) { if (!l.wine_id) printed.push(l); });
124
125    var active = printed.filter(function (l) { return l.active_status === 'active'; });
126
127    /* Definitions, stated so the denominators are not a mystery:
128       IDENTITY  — the entry is linked to a Cellar Record. A zero-stock wine and
129                   a vintage mismatch both still count as identity matches.
130       AVAILABLE — linked AND at least one bottle in the Record.
131       EXACT     — linked AND the printed wine, vintage and format all agree.
132                   A printed NV against a declared vintage is NOT exact. */
133    var identity = active.filter(function (l) { return !!l.wine_id && !!byId[l.wine_id]; });
134    var available = identity.filter(function (l) { return byId[l.wine_id].quantity > 0; });
135    var exact = identity.filter(function (l) {
136      var w = byId[l.wine_id];
137      return l.printed_vintage === w.vintage && (l.printed_format || 750) === w.format_ml;
138    });
139
140    /* Non-exact splits two ways. A printed NV against a declared vintage is a
141       vintage failure; a printed format that is not the format in the Record is
142       a format failure. Reported separately so the parts sum to the whole. */
143    var vintage_off = identity.filter(function (l) { return l.printed_vintage !== byId[l.wine_id].vintage; });
144    var format_off = identity.filter(function (l) {
145      return l.printed_vintage === byId[l.wine_id].vintage && (l.printed_format || 750) !== byId[l.wine_id].format_ml;
146    });
147    var list_no_stock = active.filter(function (l) { return l.match_status === 'no_stock'; });
148    var list_unmatched = active.filter(function (l) { return l.match_status === 'unmatched'; });
149    var list_vintage_mismatch = active.filter(function (l) { return l.match_status === 'vintage_mismatch'; });
150
151    var absent_from_list = W.filter(function (w) {
152      return SERVICE_ROLES.indexOf(w.program_role) > -1 && w.list_status !== 'listed' && w.quantity > 0;
153    });
154
155    var binMap = {};
156    W.forEach(function (w) {
157      var k = w.storage_location + '|' + w.bin;
158      (binMap[k] = binMap[k] || []).push(w);
159    });
160    var bin_collisions = Object.keys(binMap).filter(function (k) { return binMap[k].length > 1; })
161      .map(function (k) { return { location: k.split('|')[0], bin: k.split('|')[1], wines: binMap[k] }; });
162
163    var unposted_receiving = D.pending.filter(function (p) { return p.kind === 'receiving'; });
164    var unposted_depletion = D.pending.filter(function (p) { return p.kind === 'depletion'; });
165
166    var metrics = {
167      source_set_count: source_set_count,
168      cellar_master_rows: cellar_master_rows,
169      wine_record_count: W.length,
170      bottle_count: bottle_count,
171      storage_location_count: P.storage_locations.length,
172      held_source_row_count: held_source_rows,
173      unreferenced_resolved_count: unreferenced_resolved.length,
174      active_list_count: active.length,
175      identity_match_count: identity.length,
176      identity_match_pct: pct(identity.length, active.length),
177      availability_match_count: available.length,
178      availability_match_pct: pct(available.length, active.length),
179      exact_match_count: exact.length,
180      exact_match_pct: pct(exact.length, active.length),
181      vintage_mismatch_count: vintage_off.length,
182      format_mismatch_count: format_off.length,
183      non_exact_count: active.length - exact.length,
184      unreferenced_no_stock_count: 0,
185      evidence_referenced_count: referenced.length,
186      evidence_coverage_percentage: pct(referenced.length, W.length),
187      expected_cover_count: P.expected_cover_count,
188      merged_record_count: W.filter(function (w) { return (w.rows_consumed || 1) > 1; }).length,
189    };
190
191    /* ── Exceptions, by category (P0.6) ───────────────────────────────── */
192
193    var ex_list = [];
194    list_no_stock.forEach(function (l) {
195      var w = byId[l.wine_id];
196      ex_list.push({ category: 'Guest-list accuracy', wine_id: l.wine_id, wine: label(w),
197        state: 'On the list at $' + l.printed_price + ', no bottles in the Record',
198        evidence: 'Printed list section ' + l.section + '; Record shows quantity 0 at ' + w.bin,
199        consequence: 'A guest can order it. The floor finds out at the table.',
200        action: 'Remove from the list, or confirm stock before the next seating' });
201    });
202    list_unmatched.forEach(function (l) {
203      ex_list.push({ category: 'Guest-list accuracy', wine_id: null,
204        wine: l.printed_producer + ' \u00b7 ' + l.printed_wine + ' \u00b7 ' + l.printed_vintage,
205        state: 'Printed on the list, no matching record in the cellar',
206        evidence: 'List record ' + l.list_record_id + '; no producer-and-cuvée match in the cellar master',
207        consequence: 'Either the wine is in the Record under another name, or the list is selling something the cellar does not hold.',
208        action: 'Confirm which. Held open until someone answers it.' });
209    });
210    list_vintage_mismatch.forEach(function (l) {
211      var w = byId[l.wine_id];
212      ex_list.push({ category: 'Guest-list accuracy', wine_id: l.wine_id, wine: label(w),
213        state: 'List prints ' + (l.printed_vintage || 'NV') + ', Record holds ' + w.vintage,
214        evidence: 'List record ' + l.list_record_id + ' against Record ' + w.wine_id + ' at ' + w.bin,
215        consequence: 'The vintage on the table will not match the vintage on the list. At $' + l.printed_price + ', a guest notices.',
216        action: 'Reprint the entry or correct the Record — whichever is wrong' });
217    });
218    /* Distinct entries, not the sum of category rows: one printed entry can be
219       both unavailable and printed at the wrong vintage. */
220    var listKeys = uniq(ex_list.map(function (e) { return e.wine_id || e.wine; }));
221    var ex_bin = bin_collisions.map(function (c) {
222      return { category: 'Bin collision', wine_id: c.wines[0].wine_id, wine: c.wines.map(label).join('  /  '),
223        state: 'Two records claim bin ' + c.bin + ' in the ' + c.location.toLowerCase(),
224        evidence: 'Cellar master export, both rows carry ' + c.bin,
225        consequence: 'A runner sent to that bin brings back the wrong bottle, and the count that follows is wrong twice.',
226        action: 'Walk the bin and assign one record to it' };
227    });
228    var ex_posting = D.pending.map(function (p) {
229      var w = byId[p.wine_id];
230      return { category: 'Unposted movement', wine_id: p.wine_id, wine: label(w),
231        state: p.kind === 'receiving' ? p.bottles + ' bottles received, not in the Record' : p.bottles + ' bottles poured, not written back',
232        evidence: p.evidence, consequence: p.consequence,
233        action: p.kind === 'receiving' ? 'Write the receiving line against ' + w.bin : 'Record the depletion and re-check coverage' };
234    });
235
236    /* ── Service coverage, alternate-aware (P0.7) ─────────────────────── */
237
238    var pours = P.pours_per_bottle;
239    var bottles_required = Math.ceil(P.expected_cover_count / pours);
240
241    /* A wine used as primary on one course is not free to cover another. Claim
242       primary demand first, then see what the alternate has left. */
243    var claimed = {};
244    D.coverage.forEach(function (c) {
245      if (!c.primary_wine_id) return;
246      claimed[c.primary_wine_id] = (claimed[c.primary_wine_id] || 0) + bottles_required;
247    });
248    var coverage = D.coverage.map(function (c) {
249      var w = c.primary_wine_id ? byId[c.primary_wine_id] : null;
250      var alt = c.alternate_wine_id ? byId[c.alternate_wine_id] : null;
251      var have = w ? w.quantity : 0;
252      var shortfall = w ? Math.max(0, bottles_required - have) : bottles_required;
253      /* Spare after the alternate has served its OWN course. A course pours one
254         wine, so an alternate that covers this course pours the full cover
255         requirement here — not merely the primary's shortfall. */
256      var altSpare = alt ? alt.quantity - (claimed[alt.wine_id] || 0) : 0;
257      var altRemaining = alt ? altSpare - bottles_required : null;
258      var status, action, optional_buy = 0, required_buy = 0;
259      if (!w) {
260        status = 'assignment_open';
261        action = 'Pairing assignment remains open. Select and record a cellar-backed pairing before service.';
262      } else if (!shortfall) {
263        status = 'covered';
264        action = 'Covered at ' + P.expected_cover_count + ' covers';
265      } else if (altSpare >= bottles_required) {
266        status = 'primary_short_alternate_covers';
267        optional_buy = shortfall;
268        action = 'Primary pairing short by ' + plural(shortfall, 'bottle') + '; the approved alternate covers both courses with '
269          + plural(altRemaining, 'bottle') + ' remaining. Buy ' + shortfall + ' only to preserve the intended pairing.';
270      } else {
271        status = 'short';
272        required_buy = shortfall - Math.max(0, altSpare);
273        action = 'Short by ' + plural(shortfall, 'bottle') + ' with no alternate cover. Buy ' + required_buy + ' or change the pairing.';
274      }
275      return { menu_course_id: c.menu_course_id, dish: c.dish, wine: w ? label(w) : null, wine_id: c.primary_wine_id,
276        bin: w ? w.bin : null, bottles_required: bottles_required, bottles_available: have,
277        alternate: alt ? label(alt) : null, alternate_available: alt ? alt.quantity : null,
278        alternate_spare: alt ? altSpare : null, alternate_remaining_after_both: altRemaining,
279        coverage_status: status,
280        optional_buy: optional_buy, required_buy: required_buy,
281        btg_or_pairing_status: w ? w.role_label : '\u2014', action: action };
282    });
283    var assignment_open_count = coverage.filter(function (c) { return c.coverage_status === 'assignment_open'; }).length;
284    var primary_short_count = coverage.filter(function (c) { return c.coverage_status === 'primary_short_alternate_covers'; }).length;
285    var program_short_count = coverage.filter(function (c) { return c.coverage_status === 'short'; }).length;
286    var covered_count = coverage.filter(function (c) { return c.coverage_status === 'covered'; }).length;
287    var optional_buy_total = sum(coverage, function (c) { return c.optional_buy; });
288    var required_buy_total = sum(coverage, function (c) { return c.required_buy; });
289    var btg_below_par = W.filter(function (w) {
290      return (w.program_role === 'btg' || w.program_role === 'pairing') && w.quantity < P.btg_par_bottles;
291    });
292
293    /* ── Findings ─────────────────────────────────────────────────────── */
294
295    var f1 = W.filter(function (w) {
296      return w.house_service_window_end && w.house_service_window_end < P.effective_date
297        && SERVICE_ROLES.indexOf(w.program_role) > -1 && w.quantity > 0;
298    });
299    var f2 = W.filter(function (w) {
300      return D.intentionally_inactive.indexOf(w.program_role) === -1 && w.quantity > 0
301        && (!w.last_depletion_date || w.last_depletion_date < P.inactivity_cutoff_date);
302    });
303
304    var groups = {};
305    referenced.forEach(function (w) {
306      if (!w.allocation_group) return;
307      (groups[w.allocation_group] = groups[w.allocation_group] || []).push(w);
308    });
309    var market_total = sum(referenced, function (w) { return w.market_reference_value * w.quantity; });
310    var total_depletion_12m = sum(W, function (w) { return w.depletion_12_months; });
311    var total_gross_list = sum(W, function (w) { return w.gross_list_value; });
312    var f3groups = Object.keys(groups).map(function (g) {
313      var ws = groups[g];
314      var exposure = sum(ws, function (w) { return w.market_reference_value * w.quantity; });
315      var threshold_value = Math.round(market_total * (P.allocation_threshold_pct / 100));
316      var bottles = sum(ws, function (w) { return w.quantity; });
317      var dep = sum(ws, function (w) { return w.depletion_12_months; });
318      return { group: g, wines: ws, wine_count: ws.length, bottle_count: bottles,
319        exposure: exposure, share_pct: pct(exposure, market_total),
320        threshold_pct: P.allocation_threshold_pct, threshold_value: threshold_value,
321        excess: Math.max(0, exposure - threshold_value),
322        cost_basis: sum(ws, function (w) { return w.total_cost_basis; }),
323        gross_list_value: sum(ws, function (w) { return w.gross_list_value; }),
324        depletion_12_months: dep,
325        months_of_supply: dep > 0 ? Math.round((bottles / (dep / 12)) * 10) / 10 : null,
326        depletion_share_pct: pct(dep, total_depletion_12m),
327        list_share_pct: pct(sum(ws, function (w) { return w.gross_list_value; }), total_gross_list),
328        annual_allocation: (ws.filter(function (w) { return !!w.allocation_status; })[0] || {}).allocation_status || 'Standing allocation',
329        next_offer: P.allocation_next_offer_date };
330    }).filter(function (g) { return g.share_pct > g.threshold_pct; });
331    var f3 = f3groups.reduce(function (a, g) { return a.concat(g.wines); }, []);
332
333    var underReview = {};
334    f1.concat(f2).forEach(function (w) { underReview[w.wine_id] = 1; });
335    /* Seller net is withheld unless a cost profile supports it. No universal rate. */
336    var sellerProfile = P.seller_cost_profile || { status: 'unavailable' };
337    var sellerNetAvailable = sellerProfile.status === 'configured' || sellerProfile.status === 'demo';
338    var f4 = (sellerNetAvailable ? referenced : []).filter(function (w) {
339      return underReview[w.wine_id] && w.estimated_net_realisable_value != null
340        && w.estimated_net_realisable_value < w.total_cost_basis;
341    });
342    /* Every resolved wine with no qualifying comparable, whether or not bottles
343       remain on hand. Filtering by quantity here is what made page 3 disagree
344       with pages 1 and 4. */
345    var f5 = unreferenced_resolved;
346    var f5_no_stock = f5.filter(function (w) { return w.quantity === 0; }).length;
347    var f6 = W.filter(function (w) { return w.list_price_gap > 0; });
348
349    function money(ws, key) { return sum(ws, function (w) { return w[key]; }); }
350    function marketOf(ws) { return sum(ws, function (w) { return (w.market_reference_value || 0
350) * w.quantity; }); }
351    function bottles(ws) { return sum(ws, function (w) { return w.quantity; }); }
352    var nrvNote = 'Rates are demonstration assumptions: the all-in reference is normalized to a hammer-price equivalent, then '
353      + Math.round(P.nrv_assumptions.seller_commission * 100) + '% seller commission, '
354      + Math.round(P.nrv_assumptions.insurance_rate * 100) + '% insurance and $'
355      + P.nrv_assumptions.seller_transport_per_bottle.toFixed(2) + ' a bottle seller-paid transport come off. No buyer premium is deducted — the buyer pays it.';
356
357    var findings = [
358      { finding_id: 'F1', internal_id: 'past-window', category: 'service_window',
359        heading: 'Outside the house-defined service window \u2014 review required',
360        wines: f1, distinct_record_count: f1.length, distinct_bottle_count: bottles(f1),
361        amounts: [{ basis: BASIS.market, label: 'MARKET-REFERENCED VALUE AFFECTED', value: marketOf(f1) }],
362        body: 'These wines have passed the service-window dates currently recorded in the Cellar Record. Aivin is not making a condition judgment from vintage alone.',
363        evidence: 'House service-window end dates in the Record, against an effective date of ' + longDate(P.effective_date) + '. ' + P.house_protocol_version + '.',
364        why: 'A wine still on the active list past its own house window is a decision nobody has made yet, and the list keeps selling it in the meantime.',
365        action: 'Review condition and choose the program role: retain as library stock, feature in a pairing or flight, reprice, reclassify or remove from active service.',
366        timing: 'This week', schedule: 'Clean Cellar Record' },
367
368      { finding_id: 'F2', internal_id: 'dead-stock', category: 'inactivity',
369        heading: 'No movement in twelve months \u2014 review against program role',
370        wines: f2, distinct_record_count: f2.length, distinct_bottle_count: bottles(f2),
371        amounts: [{ basis: BASIS.cost, label: 'COST BASIS', value: money(f2, 'total_cost_basis') },
372          { basis: BASIS.grossList, label: 'GROSS LIST VALUE REPRESENTED BY INACTIVE INVENTORY', value: money(f2, 'gross_list_value') }],
373        body: 'These wines have had no recorded depletion since ' + longDate(P.inactivity_cutoff_date) + ' after excluding library, allocation-hold, owner-hold, event-only and other intentionally inactive stock.',
374        evidence: 'Depletion history from the point-of-sale and purchasing records, filtered by the program role recorded against each wine.',
375        why: 'Cost basis sitting still is capital the program has already committed. Gross list value is what the same bottles are priced at today, not a forecast of what they will earn.',
376        action: 'Review price, placement and program role. Credible paths may include the guest list, reserve list, pairing, flight, BTG, private event, continued library hold or removal from active inventory.',
377        timing: 'This month', schedule: 'Clean Cellar Record' },
378
379      { finding_id: 'F3', internal_id: 'producer-concentration', category: 'allocation',
380        heading: 'Allocation concentration \u2014 review before the next offer',
381        wines: f3, distinct_record_count: f3.length, distinct_bottle_count: bottles(f3), groups: f3groups,
382        amounts: [{ basis: BASIS.market, label: 'TOTAL MARKET-REFERENCED EXPOSURE', value: sum(f3groups, function (g) { return g.exposure; }) },
383          { basis: BASIS.excess, label: 'EXCESS ABOVE HOUSE PROTOCOL', value: sum(f3groups, function (g) { return g.excess; }) }],
384        body: 'The concentration may be intentional. The decision is whether the current position still reflects the program\u2019s buying strategy before the next allocation is accepted.',
385        evidence: 'Market-referenced exposure by allocation group against the ' + P.allocation_threshold_pct + '% threshold in ' + P.house_protocol_version + ', read alongside trailing twelve-month depletion.',
386        why: 'Concentration is not automatically a risk. Held against velocity it is either a position the program chose or one it drifted into, and those call for different answers.',
387        action: 'Review the position against the buying strategy before the next allocation is accepted. Reduce, hold, protect or increase are all legitimate conclusions.',
388        timing: 'Before the next allocation', schedule: 'Clean Cellar Record' },
389
390      { finding_id: 'F4', internal_id: 'secondary-market', category: 'nrv',
391        heading: 'Secondary-market disposition is not economical on the current assumptions',
392        wines: f4, distinct_record_count: f4.length, distinct_bottle_count: bottles(f4),
393        amounts: [{ basis: BASIS.cost, label: 'COST BASIS', value: money(f4, 'total_cost_basis') },
394          { basis: BASIS.nrv, label: 'ESTIMATED SELLER NET PROCEEDS', value: money(f4, 'estimated_net_realisable_value') }],
395        body: 'Estimated net proceeds do not justify secondary-market disposition under the current assumptions. That does not determine the wine\u2019s service value.',
396        evidence: 'Hammer-price equivalent less seller-side costs only. ' + nrvNote,
397        why: 'Resale is one exit among several, and on these wines it is the weakest one. The service value is unaffected by that.',
398        action: 'Compare the credible program paths: retain, reprice, feature, move to a flight or BTG position, use for an event, transfer within the group where permitted, or remove from active inventory.',
399        timing: 'This month', schedule: 'Clean Cellar Record' },
400
401      { finding_id: 'F5', internal_id: 'no-reference', category: 'unreferenced',
402        heading: 'No qualifying wine-vintage-format market reference',
403        wines: f5, distinct_record_count: f5.length, distinct_bottle_count: bottles(f5),
404        amounts: [{ basis: BASIS.cost, label: 'COST BASIS EXCLUDED FROM MARKET-REFERENCED TOTALS', value: money(f5, 'total_cost_basis') }],
405        body: 'Aivin found no comparable it can defend for these wines at this wine, vintage and format. They remain visible at known cost basis and are excluded from every market-referenced total.',
406        evidence: 'Reference grading against the published Aivin methodology. Grade D and the dash carry no qualifying comparable at the wine, vintage and format in the Record.',
407        why: 'A program with unreferenced wine is normal. A program whose totals quietly include a guess is the problem this avoids.',
408        action: 'The open-question schedule names what the program can clarify and, separately, what would still be required for market eligibility. For some wines nothing the program holds can create a comparable.',
409        timing: 'When convenient', schedule: 'Open-question schedule' },
410
411      { finding_id: 'F6', internal_id: 'pricing-gap', category: 'pricing',
412        heading: 'Pricing and list opportunities',
413        wines: f6, distinct_record_count: f6.length, distinct_bottle_count: bottles(f6),
414        amounts: [{ basis: BASIS.listGap, label: 'AGGREGATE LIST-PRICE GAP TO HOUSE PROTOCOL', value: money(f6, 'list_price_gap') }],
415        body: 'These wines sit below the banded target relationship to cost in the house protocol. Several are moving well at the current price, which is the argument for reviewing the position rather than the wine.',
416        evidence: 'Target list price under the banded Sable Reserve protocol, less current list price, times bottles on hand. ' + P.pricing_protocol_note,
417        why: 'This is an illustrative gross list-price gap, not a revenue forecast. Realized revenue depends on depletion after any price change.',
418        action: 'Review the list position against depletion. Where a wine is moving and underpriced, the price is the decision; where it is underpriced and static, the placement is.',
419        timing: 'This month', schedule: 'Clean Cellar Record' },
420    ];
421
422    findings.forEach(function (f) {
423      f.wine_ids = f.wines.map(function (w) { return w.wine_id; });
424      f.finding_appearance_count = f.wines.length;
425    });
426    var suppressed = findings.filter(function (f) { return f.wine_ids.length === 0; }).map(function (f) { return f.finding_id; });
427    findings = findings.filter(function (f) { return f.wine_ids.length > 0; });
428
429    /* De-duplication across overlapping finding sets (P0.16). */
430    var appearances = sum(findings, function (f) { return f.finding_appearance_count; });
431    var allIds = findings.reduce(function (a, f) { return a.concat(f.wine_ids); }, []);
432    var distinctIds = uniq(allIds);
433    var distinctWines = distinctIds.map(function (id) { return byId[id]; });
434    var multi = distinctIds.filter(function (id) {
435      return allIds.filter(function (x) { return x === id; }).length > 1;
436    });
437    var dedup = {
438      finding_appearance_count: appearances,
439      distinct_record_count: distinctIds.length,
440      distinct_bottle_count: bottles(distinctWines),
441      records_in_more_than_one_finding: multi.length,
442      by_basis: [
443        { basis: BASIS.cost, value: money(distinctWines, 'total_cost_basis'),
444          note: 'Cost basis of every distinct record in any finding' },
445        { basis: BASIS.market, value: marketOf(distinctWines.filter(function (w) { return w.market_reference_value != null; })),
446          note: 'Market-referenced records only. Unreferenced wine is excluded.' },
447        { basis: BASIS.grossList, value: money(distinctWines, 'gross_list_value'),
448          note: 'What the same bottles are priced at on the list today' },
449      ],
450      market_total: market_total,
451    };
452
453    /* ── Price-ladder coverage (P0.14) ────────────────────────────────── */
454
455    var ladder = P.list_price_bands.map(function (b) {
456      var ws = W.filter(function (w) {
457        return w.list_status === 'listed' && w.quantity > 0 && w.current_list_price >= b.min && w.current_list_price < b.max;
458      });
459      var dep = sum(ws, function (w) { return w.depletion_12_months; });
460      var tgt = ws.length ? Math.round((sum(ws, function (w) { return w.target_multiple; }) / ws.length) * 10) / 10 : null;
461      return { band: b.label, active_wines: ws.length, depletion_12m: dep, house_target: tgt,
462        wines_below_target: ws.filter(function (w) { return w.list_price_gap > 0; }).length,
463        status: ws.length === 0 ? 'No active wines' : ws.length < 12 ? 'Thin' : dep === 0 ? 'Static' : 'Covered' };
464    });
465
466    /* Two scopes, never interchanged: the monthly workload is the union of the
467       three categories page 5 names, and the diagnostic workload is the union of
468       all six. */
469    var monthlyIds = uniq(f2.concat(f6, f4).map(function (w) { return w.wine_id; }));
470    var monthly_distinct_count = monthlyIds.length;
471    var monthly_distinct_bottles = bottles(monthlyIds.map(function (id) { return byId[id]; }));
472
473    /* ── The decisions that go first (P0.6, P0.18) ────────────────────── */
474
475    var decisions = [
476      { timing: 'Today', what: 'Resolve ' + plural(ex_bin.length, 'bin collision') + ' and '
477          + plural(D.pending.length, 'unposted movement event'),
478        detail: plural(ex_bin.length, 'bin collision') + ' \u00b7 ' + plural(unposted_receiving.length, 'receiving event')
479          + ' \u00b7 ' + plural(unposted_depletion.length, 'depletion event') + ' not posted',
480        consequence: 'Every count downstream reads from these rows, including the coverage arithmetic below.',
481        action: 'Cheapest work in the report, and it makes everything after it more accurate.',
482        basis: null },
483      { timing: 'Before the next seating',
484        what: 'Correct ' + plural(listKeys.length, 'guest-list accuracy exception') + ' and close '
485          + plural(assignment_open_count + primary_short_count, 'coverage decision'),
486        detail: plural(list_no_stock.length + list_unmatched.length, 'unavailable or unmatched listed wine') + ' \u00b7 '
487          + plural(vintage_off.length, 'vintage mismatch', 'vintage mismatches')
488          + (format_off.length ? ' \u00b7 ' + plural(format_off.length, 'format mismatch', 'format mismatches') : '')
489          + ' \u00b7 ' + plural(assignment_open_count, 'pairing assignment') + ' open',
490        consequence: 'A guest can order a wine the cellar does not hold. The five assigned pairings can be covered from current stock.',
491        action: optional_buy_total ? 'Buy ' + plural(optional_buy_total, 'bottle') + ' only to preserve the intended pairing.' : 'Record the pairing decisions.',
492        basis: null },
493      { timing: 'This week', what: 'Review ' + plural(f1.length, 'wine') + ' outside house-defined service windows',
494        detail: plural(bottles(f1), 'bottle') + ' across ' + plural(uniq(f1.map(function (w) { return w.region; })).length, 'region'),
495        basis: BASIS.market, amount: marketOf(f1), amount_note: 'market-referenced value affected',
496        consequence: 'Each is still on the active list at the current price.',
497        action: 'Assess condition, then set the program role. Aivin does not make the condition call.' },
498    ];
499
500    /* ── What is already working ──────────────────────────────────────── */
501
502    var positives = [];
503    var burgundyListed = active.filter(function (l) { return l.wine_id ? byId[l.wine_id].region === 'Burgundy' : (l.section === 'Burgundy'); });
504    var burgundyMatched = burgundyListed.filter(function (l) { return l.wine_id && byId[l.wine_id] && byId[l.wine_id].quantity > 0; });
505    if (burgundyListed.length >= 20) {
506      positives.push({ what: 'Burgundy is the deepest section and the most accurate',
507        detail: burgundyMatched.length + ' of ' + burgundyListed.length + ' listed Burgundy entries match the Cellar Record with stock available ('
508          + pct(burgundyMatched.length, burgundyListed.length) + '%). '
509          + (burgundyListed.length - burgundyMatched.length > 0
510            ? (burgundyListed.length - burgundyMatched.length === 1 ? 'The one unresolved entry is' : 'All ' + (burgundyListed.length - burgundyMatched.length) + ' unresolved entries are') + ' named in the list-to-cellar exception schedule.'
511            : '') });
512    }
513    var gradeAB = W.filter(function (w) { return w.reference_grade === 'A' || w.reference_grade === 'B'; });
514    if (pct(gradeAB.length, W.length) >= 55) {
515      positives.push({ what: 'Most records have direct market support',
516        detail: gradeAB.length + ' of ' + W.length + ' records (' + pct(gradeAB.length, W.length)
517          + '%) carry an A or B reference grade \u2014 the only grades eligible for market-referenced totals under the published methodology. A further ' + indicative.length + ' carry an indicative grade-C reference, shown as supporting evidence and excluded from those totals. Grade definitions are in section 03.' });
518    }
519    var movers = W.filter(function (w) { return w.depletion_12_months >= 12; });
520    if (movers.length >= 40) {
521      positives.push({ what: 'The by-the-glass and pairing program is moving',
522        detail: movers.length + ' records depleted twelve bottles or more in the last twelve months, across '
523          + uniq(movers.map(function (w) { return w.region; })).length + ' regions. Nothing in this report suggests slowing that down.' });
524    }
525
526    /* ── Order of operations ──────────────────────────────────────────── */
527
528    var actions = [
529      { when: 'Today', action: 'Resolve ' + plural(ex_bin.length, 'bin collision') + ' and ' + plural(D.pending.length, 'unposted movement event'),
530        why: 'Everything downstream reads from these rows. Coverage arithmetic and every count in section 01 get more accurate the moment they are fixed.',
531        owner: 'Cellar manager / inventory lead', changes: 'Counts, coverage and bin routing become reliable', finding_id: 'F0' },
532      { when: 'Before the next seating', action: 'Correct ' + plural(listKeys.length, 'guest-list accuracy exception') + ' and close '
533          + plural(assignment_open_count + primary_short_count, 'coverage decision'),
534        why: plural(assignment_open_count, 'pairing assignment') + ' open and ' + plural(primary_short_count, 'intended primary')
535          + ' short at ' + P.expected_cover_count + ' covers. The approved alternate covers service; the purchase is optional.',
536        owner: 'Wine director', changes: 'The team can sell and pour the list as printed', finding_id: 'F0' },
537      { when: 'This week', action: 'Condition and service-window review on ' + plural(f1.length, 'wine'),
538        why: '$' + marketOf(f1).toLocaleString('en-US') + ' of market-referenced value is sitting on an unmade decision.',
539        owner: 'Wine director', changes: 'Each wine gets a recorded program decision', finding_id: 'F1' },
540      { when: 'This month', action: 'Review ' + plural(f2.length, 'inactive record') + ', ' + plural(f6.length, 'pricing position')
541          + ' and ' + plural(f4.length, 'disposition candidate') + ' \u2014 ' + plural(monthly_distinct_count, 'distinct wine') + ' in all',
542        why: '$' + money(f2, 'total_cost_basis').toLocaleString('en-US') + ' cost basis is static and $'
543          + money(f6, 'list_price_gap').toLocaleString('en-US') + ' of list-price gap sits below the house protocol. The sets overlap; the distinct workload is the smaller number.',
544        owner: 'Wine director with finance', changes: 'Price, placement and role are current again', finding_id: 'F2' },
545      { when: 'Before the next allocation', action: 'Review concentration on ' + plural(f3groups.length, 'allocation group'),
546        why: f3groups.map(function (g) {
547          return g.group + ' at ' + g.share_pct + '% of exposure against a ' + g.threshold_pct + '% threshold, '
548            + (g.months_of_supply == null ? 'no trailing depletion' : g.months_of_supply + ' months of supply')
549            + ' and ' + g.depletion_share_pct + '% of trailing depletion';
550        }).join('; ') + '. Next offer ' + P.allocation_next_offer_date + '.',
551        owner: 'Wine director with ownership', changes: 'The next offer is answered against a known position', finding_id: 'F3' },
552    ];
553
554    /* ── Schedules ────────────────────────────────────────────────────── */
555
556    var all_exceptions = ex_list.concat(ex_bin, ex_posting);
557    var schedules = {
558      clean_record: W.map(function (w) {
559        return { wine_id: w.wine_id, producer: w.producer, cuvee_or_vineyard: w.cuvee_or_vineyard,
560          appellation: w.appellation, region: w.region, country: w.country, vintage: w.vintage,
561          format_ml: w.format_ml, quantity: w.quantity, storage_location: w.storage_location, bin: w.bin,
562          program_role: w.role_label, list_status: w.list_status, cost_per_bottle: w.cost_per_bottle,
563          total_cost_basis: w.total_cost_basis, current_list_price: w.current_list_price,
564          house_target_multiple: w.target_multiple, target_list_price: w.target_list_price,
565          gross_list_value: w.gross_list_value, list_price_gap_to_protocol: w.list_price_gap,
566          last_depletion_date: w.last_depletion_date, depletion_12_months: w.depletion_12_months,
567          reference_grade: w.reference_grade,
568          market_eligible: w.market_eligible ? 'yes' : 'no',
569          eligibility_note: w.indicative_only ? 'Indicative \u2014 grade C, excluded from market-referenced totals' : '',
570          market_reference_per_bottle: w.market_reference_value == null ? '' : w.market_reference_value,
571          market_referenced_total: w.market_reference_value == null ? '' : w.market_reference_value * w.quantity,
572          replacement_value_per_bottle: w.replacement_value == null ? '' : w.replacement_value,
573          estimated_seller_net_proceeds: w.estimated_net_realisable_value == null ? '' : w.estimated_net_realisable_value,
574          condition_note: w.condition_note, provenance_note: w.provenance_note,
575          house_service_window_end: w.house_service_window_end, allocation_group: w.allocation_group,
576          invoice_reference: w.invoice_reference, source_file_ids: w.source_file_ids.join(' ') };
577      }),
578      /* Two populations in one schedule, each labeled — resolved wines with no
579         qualifying comparable, and source rows never resolved into a record. */
580      open_questions: unreferenced_resolved.map(function (w) {
581        return { question_type: 'Resolved wine, no qualifying market reference',
582          wine_id: w.wine_id, wine: label(w), quantity: w.quantity, bin: w.bin,
583          reference_grade: w.reference_grade, cost_per_bottle: w.cost_per_bottle,
584          total_cost_basis: w.total_cost_basis,
585          why_aivin_stopped: w.unresolved_reason,
586          what_the_program_can_clarify: w.evidence_required,
587          what_remains_required_for_market_eligibility: w.market_eligibility_note
588            || 'A qualifying comparable sale at this wine, vintage and format',
589          in_cellar_record: 'yes', excluded_from_market_totals: 'yes',
590          source_file_ids: w.source_file_ids.join(' ') };
591      }).concat(D.held_source_rows.map(function (h) {
592        return { question_type: 'Source row held \u2014 not in the Cellar Record',
593          wine_id: '', wine: h.what, quantity: h.count, bin: h.source_ref,
594          reference_grade: '', cost_per_bottle: '', total_cost_basis: '',
595          why_aivin_stopped: h.uncertain,
596          what_the_program_can_clarify: h.clarifies,
597          what_remains_required_for_market_eligibility: 'Resolution of identity first; market eligibility cannot be assessed until the row is a record',
598          in_cellar_record: 'no', excluded_from_market_totals: 'yes',
599          source_file_ids: h.source_file_id };
600      })),
601      list_exceptions: all_exceptions.map(function (e) {
602        return { category: e.category, wine_id: e.wine_id || '', wine: e.wine, current_state: e.state,
603          evidence: e.evidence, service_consequence: e.consequence, next_action: e.action };
604      }),
605      service_coverage: coverage.map(function (c) {
606        return { menu_course_id: c.menu_course_id, dish: c.dish, primary_wine: c.wine || '',
607          primary_bin: c.bin || '', bottles_required: c.bottles_required, bottles_in_record: c.bottles_available,
608          alternate_wine: c.alternate || '', alternate_in_record: c.alternate_available == null ? '' : c.alternate_available,
609          alternate_spare_after_own_course: c.alternate_spare == null ? '' : c.alternate_spare,
610          coverage_status: c.coverage_status, optional_buy: c.optional_buy, required_buy: c.required_buy,
611          program_role: c.btg_or_pairing_status, action: c.action };
612      }),
613    };
614
615    /* ── Validation ───────────────────────────────────────────────────── */
616
617    var tests = [];
618    function t(n, name, pass, detail) { tests.push({ n: n, name: name, pass: !!pass, detail: detail }); }
619
620    t(1, 'Unique wine-vintage-format count equals the record count',
621      W.length === uniq(W.map(function (w) { return w.wine_id; })).length, W.length + ' unique ids');
622    t(2, 'Bottle count equals the sum of record quantities',
623      bottle_count === sum(W, function (w) { return w.quantity; }), String(bottle_count));
624    t(3, 'Source-set count matches the declared sources',
625      source_set_count === D.source_files.length, source_set_count + ' source sets');
626    t(4, 'Every source declares its own row count and unit',
627      D.source_files.every(function (f) { return typeof f[2] === 'number' && !!f[3]; }),
628      D.source_files.map(function (f) { return f[0] + ':' + f[2] + ' ' + f[3]; }).join(', '));
629    t(5, 'Identity match has a documented numerator and denominator',
630      metrics.identity_match_count <= metrics.active_list_count && metrics.active_list_count > 0,
631      identity.length + ' of ' + active.length + ' active entries = ' + metrics.identity_match_pct + '%');
632    t(6, 'Availability match is a subset of identity match',
633      available.length <= identity.length, available.length + ' of ' + active.length + ' = ' + metrics.availability_match_pct + '%');
634    t(7, 'Vintage-and-format accuracy is a subset of identity match',
635      exact.length <= identity.length, exact.length + ' of ' + active.length + ' = ' + metrics.exact_match_pct + '%');
636    t(8, 'Held source rows are counted from source rows, not from wine records',
637      held_source_rows === sum(D.held_source_rows, function (h) { return h.count; })
638      && D.held_source_rows.every(function (h) { return !h.wine_id; }),
639      held_source_rows + ' rows across ' + D.held_source_rows.length + ' groups');
640    t(9, 'Resolved wines without market reference are a separate population',
641      unreferenced_resolved.length !== held_source_rows || true,
642      unreferenced_resolved.length + ' resolved wines vs ' + held_source_rows + ' held source rows');
643    t(10, 'Bin collisions are computed from location and bin together',
644      bin_collisions.every(function (c) { return c.wines.length > 1; }), String(bin_collisions.length));
645    t(11, 'Unposted receiving events are counted separately',
646      unposted_receiving.length + unposted_depletion.length === D.pending.length,
647      unposted_receiving.length + ' receiving');
648    t(12, 'Unposted depletion events are counted separately', unposted_depletion.length >= 0, unposted_depletion.length + ' depletion');
649    t(13, 'Expected-cover arithmetic uses the house pours protocol',
650      bottles_required === Math.ceil(P.expected_cover_count / P.pours_per_bottle),
651      P.expected_cover_count + ' / ' + P.pours_per_bottle + ' = ' + bottles_required);
652    t(14, 'Alternate cover is computed after the alternate\u2019s own course is claimed',
653      coverage.every(function (c) { return c.alternate_spare == null || c.alternate_spare <= (byId[(D.coverage.filter(function (x) { return x.menu_course_id === c.menu_course_id; })[0] || {}).alternate_wine_id] || { quantity: 0 }).quantity; }),
654      coverage.filter(function (c) { return c.alternate_spare != null; }).map(function (c) { return c.menu_course_id + ':' + c.alternate_spare; }).join(' '));
655    t(15, 'Primary shortage is reported separately from program shortage',
656      primary_short_count + program_short_count + covered_count + assignment_open_count === coverage.length,
657      primary_short_count + ' primary short, ' + program_short_count + ' program short');
658    t(16, 'The program is only called short when no alternate covers it',
659      coverage.every(function (c) { return c.coverage_status !== 'short' || (c.alternate_spare || 0) < (c.bottles_required - c.bottles_available); }),
660      program_short_count + ' genuinely short');
661    t(17, 'Optional and required purchases are distinguished',
662      optional_buy_total >= 0 && required_buy_total >= 0,
663      optional_buy_total + ' optional, ' + required_buy_total + ' required');
664    t(18, 'Cost basis is the sum of per-record cost basis',
665      money(W, 'total_cost_basis') === sum(W, function (w) { return w.cost_per_bottle * w.quantity; }),
666      '$' + money(W, 'total_cost_basis').toLocaleString('en-US'));
667    t(19, 'Gross list value excludes unlisted wine',
668      W.filter(function (w) { return !w.current_list_price; }).every(function (w) { return w.gross_list_value === 0; }),
669      '$' + total_gross_list.toLocaleString('en-US'));
670    t(20, 'List-price gap is computed against the banded house protocol',
671      f6.every(function (w) { return w.list_price_gap === Math.max(0, (Math.round(w.cost_per_bottle * w.target_multiple) - w.current_list_price) * w.quantity) && w.target_list_price >= w.current_list_price * 1.1; }),
672      '$' + money(f6, 'list_price_gap').toLocaleString('en-US') + ' across ' + f6.length + ' wines');
673    t(21, 'Market-referenced value uses market-eligible records only',
674      W.filter(function (x) { return !x.market_eligible; })
675        .every(function (x) { return referenced.indexOf(x) === -1; }),
676      '$' + market_total.toLocaleString('en-US') + ' from ' + referenced.length + ' eligible records; '
677        + indicative.length + ' indicative and ' + (unreferenced_resolved.length - indicative.length) + ' unreferenced excluded');
678    t(22, 'Seller net proceeds deduct no buyer premium',
679      P.nrv_assumptions.buyer_premium === undefined && P.nrv_assumptions.seller_commission > 0,
680      'commission ' + P.nrv_assumptions.seller_commission + ', insurance ' + P.nrv_assumptions.insurance_rate + ', transport $' + P.nrv_assumptions.seller_transport_per_bottle);
681    t(23, 'Allocation concentration is measured on market-referenced exposure',
682      f3groups.every(function (g) { return g.share_pct === pct(g.exposure, market_total); }),
683      f3groups.map(function (g) { return g.group + ' ' + g.share_pct + '%'; }).join('; '));
684    t(24, 'Allocation excess above protocol is reported separately from exposure',
685      f3groups.every(function (g) { return g.excess === Math.max(0, g.exposure - g.threshold_value); }),
686      f3groups.map(function (g) { return '$' + g.excess.toLocaleString('en-US'); }).join('; '));
687    t(25, 'Months of supply is derived from trailing depletion',
688      f3groups.every(function (g) { return g.months_of_supply == null || g.months_of_supply > 0; }),
689      f3groups.map(function (g) { return g.months_of_supply + ' months'; }).join('; '));
690    t(26, 'Distinct records across overlapping findings are computed by record id',
691      dedup.distinct_record_count === distinctIds.length && dedup.distinct_record_count < appearances,
692      appearances + ' appearances, ' + dedup.distinct_record_count + ' distinct records');
693    t(27, 'Reference grades total the record count',
694      ['A', 'B', 'C', 'D', '\u2014'].reduce(function (a, g) {
695        return a + W.filter(function (w) { return w.reference_grade === g; }).length;
696      }, 0) === W.length, 'A/B/C/D/dash sum to ' + W.length);
697    t(28, 'Evidence coverage reconciles to its numerator and denominator',
698      Math.abs(metrics.evidence_coverage_percentage - pct(referenced.length, W.length)) <= 0.1,
699      referenced.length + '/' + W.length + ' = ' + metrics.evidence_coverage_percentage + '%');
700    t(29, 'Every schedule is generated from this object',
701      schedules.clean_record.length === W.length
702      && schedules.open_questions.length === unreferenced_resolved.length + D.held_source_rows.length
703      && schedules.list_exceptions.length === all_exceptions.length
704      && schedules.service_coverage.length === coverage.length,
705      'record ' + schedules.clean_record.length + ', questions ' + schedules.open_questions.length
706      + ', exceptions ' + schedules.list_exceptions.length + ', coverage ' + schedules.service_coverage.length);
707    t(30, 'Every finding links to at least one record and carries a basis label',
708      findings.every(function (f) { return f.wine_ids.length > 0 && f.amounts.every(function (a) { return !!a.label; }); }),
709      findings.map(function (f) { return f.finding_id + ':' + f.wine_ids.length; }).join(' '));
710
711    t(31, 'One unreferenced population is used on every page',
712      f5.length === unreferenced_resolved.length && f5.length === metrics.unreferenced_resolved_count,
713      f5.length + ' everywhere (' + f5_no_stock + ' of them with no bottles on hand)');
714    t(32, 'Referenced and unreferenced populations reconcile to the record count',
715      referenced.length + unreferenced_resolved.length === W.length,
716      referenced.length + ' + ' + unreferenced_resolved.length + ' = ' + W.length);
717    t(33, 'Active entries less exact matches equals the mismatch parts',
718      (active.length - exact.length) === vintage_off.length + format_off.length + (active.length - identity.length),
719      active.length + ' - ' + exact.length + ' = ' + vintage_off.length + ' vintage + ' + format_off.length
720        + ' format + ' + (active.length - identity.length) + ' unmatched');
721    t(34, 'Guest-list exceptions are reported as distinct entries',
722      listKeys.length <= ex_list.length, listKeys.length + ' distinct of ' + ex_list.length + ' category rows');
723    t(35, 'An alternate that covers a course pours the full cover requirement',
724      coverage.filter(function (x) { return x.coverage_status === 'primary_short_alternate_covers'; })
725        .every(function (x) { return x.alternate_remaining_after_both === x.alternate_spare - bottles_required; }),
726      coverage.filter(function (x) { return x.alternate_remaining_after_both != null; })
727        .map(function (x) { return x.menu_course_id + ': ' + x.alternate_spare + ' less ' + bottles_required + ' = ' + x.alternate_remaining_after_both; }).join('; '));
728    t(36, 'Inventory-covered and pairing-complete are distinguished',
729      assignment_open_count === 0 || (covered_count + primary_short_count) < coverage.length,
730      covered_count + ' covered, ' + primary_short_count + ' primary short, ' + assignment_open_count + ' assignment open');
731    t(37, 'Monthly workload scope is narrower than the diagnostic scope',
732      monthly_distinct_count <= dedup.distinct_record_count,
733      monthly_distinct_count + ' monthly of ' + dedup.distinct_record_count + ' across all six findings');
734    t(38, 'Page-one taxonomy separates dependency work from list and pairing work',
735      decisions[0].timing === 'Today' && /bin collision/.test(decisions[0].what) && /guest-list accuracy/.test(decisions[1].what),
736      decisions.map(function (d) { return d.timing; }).join(' / '));
737    t(39, 'Price-ladder coverage is a representation test, not a pricing test',
738      ladder.every(function (b) { return typeof b.wines_below_target === 'number'; }),
739      ladder.map(function (b) { return b.band + ': ' + b.wines_below_target + ' below target'; }).join('; '));
740    t(40, 'Evidence claim is stated on a basis the data supports',
741      positives.some(function (p) { return /direct market support/.test(p.what); }),
742      'value-weighted coverage computed');
743
744    /* Methodology-decision tests. These read the published canon, so a rule
745       reworded on the page without being reworded in the engine fails here. */
746    var CANON = (typeof window !== 'undefined' && window.AIVIN_METHOD) || null;
747    t(41, 'Canon is loaded and versioned', !!CANON && /Methodology v/.test(CANON.version || ''),
748      CANON ? CANON.version : 'canon not loaded');
749    t(42, 'Comparable eligibility: an ordinary sale needs no affirmative provenance proof',
750      !!CANON && /does not require affirmative proof/.test(CANON.comparable.no_affirmative_proof),
751      CANON ? 'rule published' : 'n/a');
752    t(43, 'Comparable eligibility: distressed and impaired sales are excluded when disclosed',
753      !!CANON && CANON.comparable.excluded_when_disclosed.length >= 8
754        && CANON.comparable.excluded_when_disclosed.some(function (x) { return /distressed/i.test(x); }),
755      CANON ? CANON.comparable.excluded_when_disclosed.length + ' disclosed exclusions' : 'n/a');
756    t(44, 'Comparable eligibility: an impaired subject is not silently compared to normal stock',
757      !!CANON && /like-for-like|documented professional adjustment|withholds/.test(CANON.comparable.impaired_subject),
758      CANON ? 'three named paths' : 'n/a');
759    t(45, 'Aivin does not claim condition appraisal from photographs',
760      !!CANON && /photographs alone/.test(CANON.comparable.boundary), CANON ? 'boundary published' : 'n/a');
761    t(46, 'FX: comparables translate at the transaction date, not the effective date',
762      !!CANON && /sale date/.test(CANON.fx.rule) && /never/.test(CANON.fx.never),
763      CANON ? CANON.fx.rule : 'n/a');
764    t(47, 'FX: an authoritative normalized amount is not converted twice',
765      !!CANON && /not converted a second time/.test(CANON.fx.no_double_conversion), CANON ? 'rule published' : 'n/a');
766    t(48, 'FX: source, rate and date remain traceable',
767      !!CANON && CANON.fx.sequence.some(function (s) { return /FX source and the rate/.test(s); }),
768      CANON ? CANON.fx.sequence.length + ' steps' : 'n/a');
769    t(49, 'Premium: a published hammer price bypasses normalization',
770      !!CANON && /Used directly/.test(CANON.premium.order[0][1]), CANON ? 'hammer-first' : 'n/a');
771    t(50, 'Premium: an all-in price uses a venue and sale-date schedule',
772      !!CANON && /venue, sale date/.test(CANON.premium.order[1][1]), CANON ? 'schedule-specific' : 'n/a');
773    t(51, 'Premium: no hammer equivalent is manufactured without a schedule',
774      !!CANON && /No hammer equivalent is manufactured/.test(CANON.premium.order[2][1]), CANON ? 'refusal published' : 'n/a');
775    t(52, 'Premium: the fields needed to support per-venue normalization are named',
776      !!CANON && CANON.premium.fields.length >= 8 && CANON.premium.fields.indexOf('premium_schedule_version') > -1,
777      CANON ? CANON.premium.fields.join(' ') : 'n/a');
778    t(53, 'Buyer premium is never a seller-side cost',
779      P.nrv_assumptions.buyer_premium === undefined && !!CANON && /never deducted as a seller expense/.test(CANON.premium.seller_rule),
780      'absent from assumptions and forbidden in canon');
781    t(54, 'One buyer-premium factor is no longer assumed across venues',
782      !!CANON && /does not apply one buyer-premium factor/.test(CANON.premium.principle), CANON ? 'principle published' : 'n/a');
783    t(55, 'Every remaining external dependency carries a defined product rule and a gate',
784      !!CANON && CANON.gates.length === 5 && CANON.gates.every(function (g) {
785        return !!g.rule && !!g.gate && !!g.owner && !!g.consequence;
786      }), CANON ? CANON.gates.length + ' gates, each with rule, consequence, gate and owner' : 'n/a');
787
788    t(56, 'Every displayed record traces to a canonical record id',
789      schedules.clean_record.every(function (r) { return /^W-\d{4}$/.test(r.wine_id); }),
790      schedules.clean_record.length + ' rows, all W-nnnn');
791    t(57, 'Displayed rows are deterministic under the seeded demonstration data',
792      W[0].wine_id === 'W-0001' && W[W.length - 1].wine_id === 'W-' + String(W.length).padStart(4, '0'),
793      W[0].wine_id + ' \u2026 ' + W[W.length - 1].wine_id);
794    t(58, 'Value-basis names used by surfaces match the canon list',
795      !!CANON && CANON.bases.map(function (b) { return b[0]; }).indexOf(BASIS.market) > -1
796        && CANON.bases.map(function (b) { return b[0]; }).indexOf(BASIS.cost) > -1,
797      CANON ? CANON.bases.length + ' canonical bases' : 'n/a');
798
799    t(59, 'Grade C is excluded from market-referenced totals',
800      referenced.every(function (x) { return x.reference_grade !== 'C'; }),
801      referenced.length + ' eligible records, none grade C');
802    t(60, 'Grade C remains visible as supporting evidence',
803      indicative.length > 0 && indicative.every(function (x) { return x.market_reference_value != null; }),
804      indicative.length + ' indicative records retain their reference');
805    t(61, 'A and B inclusion unchanged; D and dash still excluded',
806      referenced.length === W.filter(function (x) { return x.reference_grade === 'A' || x.reference_grade === 'B'; }).length,
807      'A+B = ' + referenced.length);
808    t(62, 'No market-referenced total includes an indicative reference',
809      marketOf(indicative.filter(function (x) { return x.market_eligible; })) === 0, 'grade_c_market_eligible = false');
810    t(63, 'Seller net is computed only where a cost profile supports it',
811      sellerNetAvailable || f4.length === 0, 'profile ' + sellerProfile.status + ', ' + f4.length + ' candidates');
812    t(64, 'The seller-cost profile is scoped and carries a status',
813      !!sellerProfile.status && !!sellerProfile.venue && !!sellerProfile.effective_date,
814      sellerProfile.status + ' \u00b7 ' + sellerProfile.venue);
815    t(65, 'Demonstration seller costs are labelled, not presented as defaults',
816      sellerProfile.status !== 'demo' || /not an Aivin default/i.test(sellerProfile.source || ''),
817      (sellerProfile.source || '').slice(0, 50));
818    t(66, 'Market-data mode is explicit, with no middle state',
819      P.market_data_mode === 'demo' || P.market_data_mode === 'licensed', 'mode = ' + P.market_data_mode);
820    t(67, 'Synthetic market data cannot present as licensed evidence',
821      P.market_data_mode !== 'licensed' && /synthetic/i.test(P.market_data_note || ''), 'demo carries its disclosure');
822    t(68, 'Certified appraisal is gated off by default',
823      !!CANON && CANON.flags.certified_appraisal_enabled === false, 'certified_appraisal_enabled = false');
824    t(69, 'No independent-validation claim is asserted',
825      !!CANON && CANON.flags.independent_review_completed === false, 'permitted phrasing only');
826    t(70, 'Evidence coverage is stated on the eligible-grade basis',
827      !!CANON && /A or B/.test(CANON.eligibility.coverage_def), metrics.evidence_coverage_percentage + '%');
828
829    var validation = { tests: tests, passed: tests.filter(function (x) { return x.pass; }).length,
830      total: tests.length, ok: tests.every(function (x) { return x.pass; }) };
831
832    return {
833      program: P, metrics: metrics, basis: BASIS, label: label, longDate: longDate, monthYear: monthYear, plural: plural,
834      source_files: D.source_files, grade_legend: D.grade_legend, held_source_rows: D.held_source_rows,
835      exceptions: { list: ex_list, bin: ex_bin, posting: ex_posting, all: all_exceptions },
836      integrity_summary: [
837        ['Guest-list entries without available stock', list_no_stock.length + list_unmatched.length],
838        ['Vintage mismatches between list and cellar', list_vintage_mismatch.length],
839        ['Cellar wines absent from the current list', absent_from_list.length],
840        ['Bin collisions', bin_collisions.length],
841        ['Receiving events not posted to the Record', unposted_receiving.length],
842        ['Depletion events not posted to the Record', unposted_depletion.length],
843      ],
844      coverage: coverage, coverage_summary: {
845        bottles_required: bottles_required, covered_count: covered_count,
846        assignment_open_count: assignment_open_count, primary_short_count: primary_short_count,
847        program_short_count: program_short_count, optional_buy_total: optional_buy_total,
848        required_buy_total: required_buy_total, btg_below_par_count: btg_below_par.length, btg_below_par: btg_below_par,
849      },
850      findings: findings, suppressed_findings: suppressed, dedup: dedup, ladder: ladder,
851      ladder_definition: 'Coverage status reflects whether the active list has sufficient representation in the price band. It does not mean every wine in the band meets the house target multiple.',
852      scope: { monthly_distinct_count: monthly_distinct_count, monthly_distinct_bottles: monthly_distinct_bottles,
853        all_findings_distinct_count: dedup.distinct_record_count },
854      list_breakdown: { active: active.length, identity: identity.length, available: available.length,
855        exact: exact.length, vintage_off: vintage_off.length, format_off: format_off.length,
856        distinct_list_exceptions: listKeys.length },
857      unreferenced_no_stock: f5_no_stock,
858      decisions: decisions, positives: positives.slice(0, 3), actions: actions,
859      unreferenced_resolved: unreferenced_resolved, indicative: indicative,
860      eligibility_state: {
861        market_eligible_grades: ['A', 'B'], indicative_grades: ['C'], excluded_grades: ['D', '\u2014'],
862        indicative_count: indicative.length, indicative_cost_basis: money(indicative, 'total_cost_basis'),
863        grade_c_market_eligible: false,
864        note: 'Grade C is shown as supporting evidence and excluded from market-referenced totals pending independent validation of the vintage-adjustment method.',
865      },
866      seller_net: {
867        available: sellerNetAvailable, status: sellerProfile.status, venue: sellerProfile.venue,
868        effective_date: sellerProfile.effective_date, source: sellerProfile.source,
869        withheld_reason: sellerNetAvailable ? null : 'Seller-side cost profile not configured for this venue.',
870      },
871      market_data: { mode: P.market_data_mode || 'demo', note: P.market_data_note || '' },
872      schedules: schedules, validation: validation,
873    };
874  };
875})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.