File: 2026.10.23 - Kestrel Medical - 02 KPI Calculation Pack.md
Kestrel Medical: KPI Calculation Pack
Sample data. Every number below is calculated from the Sample data in03 - Working Files/data/by03 - Working Files/calc_kpis.py(results inkpi_results.json) and03 - Working Files/kewpie_substitutes.py(stand-ins, results insubstitutes_results.json). Data runs to 2026-09-30. Nothing here is real Kestrel data: check it against real data before go-live.
Version: Calculation Pack v1.1 for Business Requirements v1.1. Date: 23-Oct-26. Author: Kewpie, KPI Creator Stage 2. Replaces v1.0.
What changed from v1.0
- Four KPIs are Phase 2 placeholders, as Adam decided: Gross margin per cent (K1), Gross margin by product group (K1.1), Monthly reports that match the agreed set of numbers (K5), Our price against the winning price on lost tenders (K4.1). Each shows 'Phase 2: waiting for data', with a labelled stand-in beside it. The calculation is still documented, and a named Phase 2 data source is recorded (section 4).
- Average discount off list price on big deals (K2): the target is now a straight-line path from 17.03% (Sep-26) to 14% (Dec-27), so pace needed moves from 0.00 to -0.20 points a month. Baseline unchanged at 17.03%. Status is Green today, but the run rate is flat, so it goes Amber from Oct-26 and Red from Feb-27 if nothing changes.
- Big tender win rate (K4): now a count over the last 5 big tenders: 2 of 5 (the same five tenders as before). The target is open (Deb sets it). Against Gary's starting proposal of 3 of the last 5, the next 2 big tenders must both be won.
- Revenue growth on the year (K3): numbers unchanged (-6.8%, pace +0.72, run rate +0.27). The 4% is now measured on 2026 full-year actuals: about $203.5m in 2027 (estimate), still 3.1% below 2025.
- Challenge notes are marked resolved or still open as Business Requirements v1.1 records them (section 5).
1. Summary: the Top 5
| Measure | Baseline | Target | Pace needed | Run rate | Status |
|---|---|---|---|---|---|
| Gross margin per cent (K1) | Phase 2 placeholder: waiting for cost of sales | 43% for 2027 (text only) | Not shown | Not shown | Phase 2 placeholder, no colour |
| Average discount off list price on big deals (K2) | 17.03% (Jan to Sep 2026) | Path from 17.03% (Sep-26) to 14% (Dec-27) | -0.20 pts a month | 0.000 pts a month (flat) | Green today; off pace (Amber from Oct-26 if flat) |
| Revenue growth on the year (K3) | -6.8% (Jan to Sep 2026 on 2025) | +4% in 2027 on 2026 actuals | +0.72 pts a month | +0.27 pts a month | Red (below 0%), off pace |
| Big tender win rate (K4) | 2 of the last 5 big tenders | Open (Deb sets it); starting proposal 3 of the last 5 by Dec-27 | Next 2 big tenders both won (if 3 of 5) | Not meaningful | Not rated (target open) |
| Monthly reports that match the agreed set of numbers (K5) | Phase 2 placeholder: waiting for finance's agreed definitions | Open until switch-on | Not shown | Not shown | Phase 2 placeholder, no colour |
Status uses Gary's thresholds. Pace needed is (target - current) / months remaining, with months remaining counted from Sep-26 to Dec-27 (15). A Phase 2 placeholder shows no number, status colour, sparkline or pace needed.
Stand-ins beside the placeholders (not KPIs)
Each stand-in is labelled 'Stand-in, not the KPI' and 'Sample data'. It has no target and no status colour, and never uses the KPI's name or finance's stated 41%.
| Placeholder for | Stand-in | Baseline (Sample data) |
|---|---|---|
| Gross margin per cent (K1) | Net price realisation | 87.36% (Jan to Sep 2026), against 87.67% in 2025 |
| Gross margin by product group (K1.1) | Net price realisation by product group | Equipment groups 82.9% to 84.5%; Defibrillator consumables 95.0%; Parts and Service 100.0% |
| Monthly reports that match the agreed set of numbers (K5) | Reports on the draft agreed set | 3 of 30 reports; 17 combinations in use |
| Our price against the winning price on lost tenders (K4.1) | Price score gap on lost tenders | Behind on price in 11 of 20 scored losses; average -0.03 points of 30 |
2. The calculations
Gross margin per cent (K1)
- Result of the check on Gary's draft: Confirmed (Phase 2 KPI: placeholder tile on the dashboard)
- Plain English: Net sales less cost of sales, over net sales.
- Calculation:
(SUM(net_value_aud) - SUM(cost_of_sales)) / SUM(net_value_aud) - Sources and why:
sales_order_lines.net_value_aud(the sales system of record). Cost of sales: no field found. Phase 2: cost of sales per shipped order line from SAP product costing and billing documents, joined on order and line number. - Grain: Order line (each order has one line)
- Filters: Shipped lines, January to December. Must reconcile to finance's 41% before use. Placeholder tile until then; the stated 41% may appear only as a text note on the placeholder, never in the headline slot and never on the stand-in.
- Baseline: Phase 2 placeholder: waiting for cost of sales from finance. No baseline can be calculated from the Sample data: no cost of sales field exists in any of the 11 files. Finance's stated figure of about 41% is a text note on the placeholder only, not calculated. Period: Phase 2 (the stated figure is the current year, from the sales leader). Evidence: Working Hypothesis (a stated figure, not reproducible)
- Pace needed: Not applicable until Phase 2: the placeholder shows no pace needed
- Run rate: Not available: no history without cost of sales
- Reading it: Phase 2: waiting for data. Cannot say whether on pace until cost of sales is supplied
- Counter-metric: Net sales value year to date (Revenue growth on the year, K3), read alongside: a margin lift bought by dropping low-margin sales shows as falling net sales. Net sales Jan to Sep 2026 are $149.36m, -6.8% on the same months of 2025
- Notes: Phase 2 KPI. Formula confirmed as the right shape. Data mapping NOT confirmed: no cost field (checked every column in all 11 files; challenge note C1). Phase 2 needs cost of sales per shipped order line from SAP product costing, joined on order and line number, reconciled to finance's 41% before switch-on. First pass: placeholder tile plus the stand-in Net price realisation (Adam's choice), which never carries this KPI's name, target or status colour.
- Stand-in (first pass only, not the KPI): 87.36% of list price kept on shipped lines (net sales $149.36m), against 87.67% in the same months of 2025. By full year: 2021 89.72%, 2022 89.28%, 2023 89.28%, 2024 87.61%, 2025 87.22%. Excluding warranty replacement lines: 87.26% against 87.58%. Price side only: this is not gross margin. Period: January to September 2026 against the same months of 2025, ship date (Sample data). Evidence: Observed Fact for the calculation; Working Hypothesis that it moves with gross margin (no cost data to test the link). Calculation:
SUM(net_value_aud) / SUM(list_price * qty), shipped lines, ship date
Average discount off list price on big deals (K2)
- Result of the check on Gary's draft: Corrected
- Plain English: One minus net value over list value, across big-deal lines, weighted by value.
- Calculation:
1 - SUM(net_value_aud) / SUM(list_price * qty), order_type = tender_contract - Sources and why:
sales_order_lines.list_price,.qty,.net_value_aud,.order_type,.order_date.discount_pctused as a cross-check only. - Grain: Order line
- Filters: Order type tender_contract (placeholder until Sharon sets a size rule); period by order date; no lines excluded for missing list price (none).
- Baseline: 17.03% value-weighted discount off list on tender contract order lines (5,485 lines). Placeholder big-deal definition. Period: January to September 2026, order date. Evidence: Observed Fact (calculation); Working Hypothesis for which orders count as big deals
- Pace needed: -0.20 points a month: a straight-line path from 17.03% (Sep-26) to 14.0% (Dec-27) over 15 months. Path: Dec-26 16.42%, Jun-27 15.21%, Dec-27 14.00%
- Run rate: 0.000 points a month over the last 3 months (flat)
- Reading it: Green today (on the path at its starting point) but off pace: a flat discount goes Amber from Oct-26 and Red from Feb-27 (more than 1 point above the path). It has to fall about 0.20 points a month
- Counter-metric: Tender contract net sales and the Big tender win rate (K4): pulling back discount can simply lose the deals. Tender contract net sales Jan to Sep: $86.7m in 2026 against $95.1m in 2025
- Notes: Corrected (C4, accepted in v1.1): the draft placeholder 'orders linked to a contract_id' picks up service contract lines, not tenders. No order reaches $5m, so an order-total rule gives nothing. v1.1 changes the target to a path back towards about 14% (2023 level) by Dec-27, Gary's proposal for Sharon to confirm (C5). Discount recalculated from list_price, qty and net_value_aud agrees with discount_pct (99.9% of lines within 0.002 points). The 2026 reference is Jan to Sep until the year closes.
Target path (v1.1, Gary's proposal, for Sharon to confirm): straight line from 17.03% (Sep-26) to 14.0% (Dec-27), -0.20 points a month: Sep-26 17.03%, Dec-26 16.42%, Mar-27 15.82%, Jun-27 15.21%, Sep-27 14.61%, Dec-27 14.00%. Green at or below the path, Amber up to 1 point above, Red more than 1 point above. If the discount stays flat it is Amber from Oct-26 and Red from Feb-27.
Average discount on tender contract lines by year (order date): 2021: 14.04%, 2022: 14.04%, 2023: 14.05%, 2024: 17.03%, 2025: 17.03%, Jan to Sep 2026: 17.03%.
If 'big deal' meant something else (Jan to Sep 2026): tender contract and distributor lines 16.78%; the biggest 1% of lines by value ($87,101 or more) 4.14%. The baseline depends heavily on the definition, so Sharon's size rule (open question) matters.
Revenue growth on the year (K3)
- Result of the check on Gary's draft: Confirmed
- Plain English: Net sales shipped this year to date over net sales shipped in the same months last year, minus one.
- Calculation:
SUM(net_value_aud, ship month 1..m, 2026) / SUM(net_value_aud, ship month 1..m, 2025) - 1 - Sources and why:
sales_order_lines.net_value_audand.actual_ship_date(the draft rule, until finance confirms its revenue rule);.order_typechecked. - Grain: Order line
- Filters: Shipped lines only; year to date against year to date.
- Baseline: -6.8% ($149.36m against $160.26m). Full year 2025 on 2024 was +0.4%, which matches 'flat last year'. Period: January to September 2026 against January to September 2025, ship date. Evidence: Observed Fact
- Pace needed: +0.72 points a month: from -6.8% to +4.0% over 15 months (Sep-26 to Dec-27). In v1.1 the 4% is measured on 2026 full-year actuals: about $203.5m in 2027 ($16.96m a month) against $16.6m a month so far in 2026
- Run rate: +0.27 points a month over the last 3 months (year-to-date growth moved from -7.6% in Jun to -6.8% in Sep)
- Reading it: Off pace: the run rate is about 2.7 times too slow. Even on the 2026 base, 2027 would be about 3.1% below 2025
- Counter-metric: Value-weighted average discount across all lines (Average discount, K2 context): growth bought with price shows here. All lines Jan to Sep 2026: 12.52%, against 12.84% for the full year 2025
- Notes: Confirmed on ship date. Numbers are unchanged from v1.0. Checked order types: there are no credit or return types; warranty replacement lines carry full list value at 0% discount ($1.8m in 2025) and removing them changes the baseline to -6.9%, so it is immaterial. On order date the baseline is -9.9%. 1,517 lines (1.26%, all 2026) have no ship date yet and are not counted. The 2027 measure cannot exist before 2027, so the 2026 year-to-date figure is the baseline. v1.1 sets the base for the 4% as 2026 full-year actuals (estimate $195.68m until the year closes); the base is still an open question for Sharon and finance (C6).
Year-to-date growth by month in 2026 (ship date): Jan -12.5%, Feb -9.1%, Mar -8.7%, Apr -7.8%, May -8.2%, Jun -7.6%, Jul -7.8%, Aug -7.3%, Sep -6.8%.
What 4% means on the v1.1 base (2026 full-year actuals; estimate, Working Hypothesis): full-year 2026 is estimated at $195.68m (Jan to Sep actual plus Q4 2025 moved by the year-to-date rate). 4% on that is $203.5m for 2027, which is -3.1% against full-year 2025 ($209.95m).
Big tender win rate (K4)
- Result of the check on Gary's draft: Corrected
- Plain English: Tenders won out of the last 5 decided tenders with a contract value of $5m or more (rolling five-tender window), with the calendar-year count alongside.
- Calculation:
COUNT(outcome = won) over the last 5 tenders with outcome IN (won, lost) and contract value >= 5,000,000, ordered by close_date - Sources and why:
tender_register.outcome,.estimated_value,.contract_length,.close_date,.tender_reference. The bid manager's file, because the sales leader does not trust the CRM for win-loss. - Grain: Tender
- Filters: Contract value $5m or more (annual amounts times years); exclude undecided, partial and cancelled; show the count next to the rate.
- Baseline: 2 of the last 5 big tenders (40%). Calendar year alongside: 2024 1 of 2, 2025 0 of 2, 2026 to Sep 1 of 1. Won Coastal Ambulance Service ($14.0m) and Capital Region Health ($5.6m); lost Southern Metro Health Network ($6.5m), Western Plains LHD ($7.2m) and Highlands Ambulance ($11.8m). Period: The last five tenders of $5m or more in the register, closing March 2024 to February 2026. Evidence: Observed Fact (small numbers)
- Pace needed: Target open (Q-1): Deb Harlow sets it. Against Gary's starting proposal of at least 3 of the last 5 by Dec-27, the next 2 big tenders must both be won: after one win the window still reads 2 of 5, after two it reads 3 of 5. At about 2 big tenders a year, about 2.5 are expected by Dec-27
- Run rate: Not meaningful: only 5 events, so no run rate over 3 periods
- Reading it: Not rated until Deb sets the target. If 3 of 5 is accepted it is reachable only if both of the next two big tenders are won, with little room for a loss
- Counter-metric: Number and value of big tenders bid, and the discount on tender contract orders (Average discount, K2): a count can be lifted by bidding only on easy tenders or cutting price. Big tenders bid: 2 (2024), 2 (2025), 1 (2026 to Sep)
- Notes: Corrected (C7, accepted in v1.1): 24 of 64 estimated values are stored as annual amounts ('$2.4m pa'), which must be multiplied by the contract length to compare with $5m. The same five tenders qualify either way. No partial or cancelled tender is $5m or more. v1.1 measures it as a count over the last 5 big tenders, not a yearly percentage (C2). At $4m or more the count is 5 of 10; across all sizes 28 of 53, so the result depends on the size line. Customer names vary in the register (Southern Metro and Southern Metropolitan; Western Plains LHD and Western Plains Health District).
| Tender | Customer (as in the register) | Closed | Value | Outcome | Winner |
|---|---|---|---|---|---|
| TND-2024-03 | Coastal Ambulance Service | 22/03/2024 | $14.0m | won | Kestrel Medical |
| TND-2024-07 | Southern Metro Health Network | 12/07/2024 | $6.5m | lost | Vantage Medical |
| TND-2025-02 | Western Plains LHD | 30/04/2025 | $7.2m | lost | Allied Clinical Supply |
| TND-2025-06 | Highlands Ambulance | 19/09/2025 | $11.8m | lost | Norland Rescue Systems |
| TND-2026-01 | Capital Region Health | 27/02/2026 | $5.6m | won | Kestrel Medical |
What the count needs (Working Hypothesis, Gary's starting proposal of at least 3 of the last 5 by Dec-27): the next 2 big tenders both won. After the next win the window reads 2 of 5 (the March 2024 win drops out), and after the next two it reads 3 of 5. About 2.5 big tenders are expected by Dec-27 at the recent pace of 2 a year.
Size line sensitivity (won of decided): $5m 2 of 5, $4m 5 of 10, $3m 8 of 13, $2m 13 of 20, $1m 19 of 35, $0m 28 of 53
Monthly reports that match the agreed set of numbers (K5)
- Result of the check on Gary's draft: Confirmed (Phase 2 KPI: placeholder tile on the dashboard)
- Plain English: Phase 2: reports that carry a sales number and whose monthly net sales check against the governed sales table, over all reports that carry a sales number.
- Calculation:
COUNT(reports whose month net sales agree with the governed sales table within tolerance) / COUNT(reports that carry a sales number) - Sources and why: Phase 2: the monthly check results (report, month, report net sales, governed net sales, pass or fail), built by the data engineer from the 30 workbooks and the governed sales table. First pass stand-in only:
monthly_reports_index.workbook,.sales_definition,.customer_grouping,.last_refreshed. - Grain: Report, month
- Filters: Agreed definition and match tolerance set by finance (open); reports marked n/a reviewed one by one to see whether they carry a sales number. Placeholder tile until one full month's check has run.
- Baseline: Phase 2 placeholder: waiting for the agreed definitions from finance and the first monthly number check. No baseline can be calculated yet: the index records what owners say they use, not whether their numbers agree. Period: Phase 2. Evidence: Working Hypothesis (the agreed set is open)
- Pace needed: Not applicable until Phase 2: the placeholder shows no pace needed. Target open (C3), set by the finance report owner with the sales leader once the agreed definitions exist
- Run rate: Not available: the index holds one snapshot, no history
- Reading it: Phase 2: waiting for data
- Counter-metric: Reports refreshed in the last 30 days, and the total number of reports that carry a sales number: the rate could be lifted by retiring reports or relabelling the index. 22 of 30 were refreshed in the 30 days to 30-Sep-26; 8 were last refreshed in March 2026 or earlier
- Notes: Phase 2 KPI. v1.1 changes the measure from the self-reported index to Tom's check of each report's monthly net sales against a governed sales table (C3 resolved by the change; target still open). First pass: placeholder tile plus the stand-in Reports on the draft agreed set. Index facts (Sample data): sales definitions ship date 14, invoice date 5, order date 5, n/a 6; customer grouping n/a 9, parent where known 6, ship-to 6, manual mapping tab 5, sold-to 4. 12 reports have n/a in at least one column; 17 different combinations are in use.
- Stand-in (first pass only, not the KPI): 3 of 30 reports (10%) say they use the draft rule (ship date, customers grouped by parent where known); 17 different combinations of sales definition and customer grouping are in use. Shows what reports say they use, not whether their numbers agree. Period: Report index at 30-Sep-26 (Sample data). Evidence: Working Hypothesis (the agreed set is open and the index is self-reported). Calculation:
COUNT(sales_definition = ship date AND customer_grouping = parent where known) / COUNT(reports), plus COUNT(DISTINCT sales_definition, customer_grouping)
Stand-in detail (Sample data): reports matching each candidate set (with parent where known): invoice date + parent where known 1, ship date + parent where known 3, order date + parent where known 1. Most common combinations: ship date with ship-to: 5; ship date with n/a: 4; n/a with n/a: 3. Reports on the draft set: 08 Work orders by tech, 12 Tender pipeline, 25 Rep targets. Reports last refreshed more than 30 days before the cutoff: 02 Sales by product group, 05 Open quotes, 09 Overdue PMs, 10 Service revenue, 13 Ambulance accounts, 23 Installed base (service), 25 Rep targets, 29 Quarterly review pack.
Sub-KPIs
Gross margin by product group (K1.1)
- Result of the check on Gary's draft: Confirmed (Phase 2 KPI: placeholder tile on the dashboard)
- Plain English: Gross margin per cent, split by product group.
- Calculation:
K1 grouped by material_group - Sources and why: As Gross margin per cent (K1), plus
sales_order_lines.material_group - Grain: Order line by product group
- Filters: As K1. Placeholder tile until the cost feed switches on; the groups must add up to the total.
- Baseline: Phase 2 placeholder: waiting for cost of sales from finance. No baseline can be calculated: no cost of sales field. Period: Phase 2. Evidence: Working Hypothesis
- Pace needed: Not applicable until Phase 2: the placeholder shows no pace needed
- Run rate: Not available
- Reading it: Phase 2: waiting for data. Switches on with Gross margin per cent (K1)
- Counter-metric: As Gross margin per cent (K1)
- Notes: Phase 2 KPI. Formula confirmed; data mapping blocked by the same missing cost of sales field (C1). First pass: placeholder tile plus the stand-in Net price realisation by product group.
- Stand-in (first pass only, not the KPI): Loading systems 82.91% (+0.06 pts on 2025, 8.4% of net sales); Powered stretchers 82.95% (+0.01 pts on 2025, 9.1% of net sales); Stair chairs 83.10% (-0.08 pts on 2025, 2.8% of net sales); Manual stretchers 83.12% (-0.15 pts on 2025, 3.8% of net sales); Defibrillators 84.17% (+0.12 pts on 2025, 19.6% of net sales); Beds 84.33% (-0.34 pts on 2025, 21.8% of net sales); ED stretchers 84.45% (+0.30 pts on 2025, 7.1% of net sales); Defibrillator consumables 95.00% (-0.00 pts on 2025, 8.7% of net sales); Parts 100.00% (+0.00 pts on 2025, 4.4% of net sales); Service 100.00% (+0.00 pts on 2025, 14.2% of net sales). Service and Parts show 100% because they are not discounted: that says nothing about their margin. Groups are not ranked best or worst. Period: January to September 2026 against the same months of 2025, ship date (Sample data). Evidence: Observed Fact for the calculation; Working Hypothesis that group margin follows group realisation. Calculation:
Net price realisation grouped by material_group, with each group's share of net sales
Stand-in detail: Net price realisation by product group, Jan to Sep 2026 (Sample data, not gross margin):
| Product group | Realisation 2026 | Realisation 2025 | Change (pts) | Share of net sales 2026 |
|---|---|---|---|---|
| Loading systems | 82.91% | 82.85% | +0.06 | 8.4% |
| Powered stretchers | 82.95% | 82.94% | +0.01 | 9.1% |
| Stair chairs | 83.10% | 83.19% | -0.08 | 2.8% |
| Manual stretchers | 83.12% | 83.27% | -0.15 | 3.8% |
| Defibrillators | 84.17% | 84.05% | +0.12 | 19.6% |
| Beds | 84.33% | 84.68% | -0.34 | 21.8% |
| ED stretchers | 84.45% | 84.15% | +0.30 | 7.1% |
| Defibrillator consumables | 95.00% | 95.00% | -0.00 | 8.7% |
| Parts | 100.00% | 100.00% | +0.00 | 4.4% |
| Service | 100.00% | 100.00% | +0.00 | 14.2% |
Revenue growth by product group (K3.1)
- Result of the check on Gary's draft: Confirmed
- Plain English: Revenue growth, split by product group.
- Calculation:
K3 grouped by material_group - Sources and why:
sales_order_lines.material_group,.net_value_aud,.actual_ship_date - Grain: Order line by product group
- Filters: As K3
- Baseline: Service -20.8%; Defibrillators -9.2%; ED stretchers -7.4%; Stair chairs -7.1%; Powered stretchers -6.3%; Loading systems -5.0%; Parts -4.3%; Manual stretchers -2.3%; Defibrillator consumables -0.1%; Beds +2.6%. Period: January to September 2026 against 2025, ship date. Evidence: Observed Fact
- Pace needed: Service +1.65; Defibrillators +0.88; ED stretchers +0.76; Stair chairs +0.74; Powered stretchers +0.69; Loading systems +0.60; Parts +0.56; Manual stretchers +0.42; Defibrillator consumables +0.28; Beds +0.09 points a month to reach +4.0% in 15 months
- Run rate: Service +0.31; Defibrillators +0.04; ED stretchers +0.65; Stair chairs +0.89; Powered stretchers +2.54; Loading systems +0.31; Parts -0.64; Manual stretchers +0.86; Defibrillator consumables +0.45; Beds -0.89 points a month
- Reading it: Only Beds is growing (above 0%). Service is lumpy: 64% of its 2025 ship-date sales fall in January and July, so its year-to-date swings are mostly billing timing
- Counter-metric: Rolls up to Revenue growth on the year (K3); watch the Average discount counter-metric
- Notes: Confirmed. Group names are tidied from the material_group codes.
| Product group | Growth Jan to Sep 2026 | Run rate (pts a month) | Pace needed (pts a month) |
|---|---|---|---|
| Service | -20.8% | +0.31 | +1.65 |
| Defibrillators | -9.2% | +0.04 | +0.88 |
| ED stretchers | -7.4% | +0.65 | +0.76 |
| Stair chairs | -7.1% | +0.89 | +0.74 |
| Powered stretchers | -6.3% | +2.54 | +0.69 |
| Loading systems | -5.0% | +0.31 | +0.60 |
| Parts | -4.3% | -0.64 | +0.56 |
| Manual stretchers | -2.3% | +0.86 | +0.42 |
| Defibrillator consumables | -0.1% | +0.45 | +0.28 |
| Beds | +2.6% | -0.89 | +0.09 |
Revenue growth by rep (K3.2)
- Result of the check on Gary's draft: Confirmed
- Plain English: Revenue growth, split by rep.
- Calculation:
K3 grouped by rep_id - Sources and why:
sales_order_lines.rep_id,.net_value_aud,.actual_ship_date - Grain: Order line by rep
- Filters: As K3 (parent grouping makes no difference to a split by rep)
- Baseline: R10 -17.5%; R07 -10.6%; R05 -9.8%; R01 -9.2%; R14 -8.7%; R09 -8.0%; R02 -6.8%; R06 -6.1%; R08 -5.5%; R04 -4.8%; R13 -4.5%; R11 -1.5%; R12 +0.1%; R03 +35.4%. Period: January to September 2026 against 2025, ship date. Evidence: Observed Fact
- Pace needed: R10 +1.44; R07 +0.97; R05 +0.92; R01 +0.88; R14 +0.85; R09 +0.80; R02 +0.72; R06 +0.68; R08 +0.63; R04 +0.58; R13 +0.56; R11 +0.36; R12 +0.26; R03 -2.09 points a month to reach +4.0% in 15 months
- Run rate: R10 +0.36; R07 -0.89; R05 +0.58; R01 +2.05; R14 +0.07; R09 +3.85; R02 -1.11; R06 -0.83; R08 +0.29; R04 -4.76; R13 +0.08; R11 +1.28; R12 -3.17; R03 +21.20 points a month
- Reading it: Only R03 (small base) and R12 (flat) are at or above 0%
- Counter-metric: Rolls up to Revenue growth on the year (K3)
- Notes: Confirmed on rep_id. Gary's parent-grouping filter does not change a split by rep, because the rep sits on the order line. Reps are not tied to accounts in the data (median 4 different reps per sold-to customer). R03's +35% is on a small base ($1.5m in 2025).
| Rep | Growth Jan to Sep 2026 | Run rate (pts a month) | Pace needed (pts a month) |
|---|---|---|---|
| R10 | -17.5% | +0.36 | +1.44 |
| R07 | -10.6% | -0.89 | +0.97 |
| R05 | -9.8% | +0.58 | +0.92 |
| R01 | -9.2% | +2.05 | +0.88 |
| R14 | -8.7% | +0.07 | +0.85 |
| R09 | -8.0% | +3.85 | +0.80 |
| R02 | -6.8% | -1.11 | +0.72 |
| R06 | -6.1% | -0.83 | +0.68 |
| R08 | -5.5% | +0.29 | +0.63 |
| R04 | -4.8% | -4.76 | +0.58 |
| R13 | -4.5% | +0.08 | +0.56 |
| R11 | -1.5% | +1.28 | +0.36 |
| R12 | +0.1% | -3.17 | +0.26 |
| R03 | +35.4% | +21.20 | -2.09 |
Our price against the winning price on lost tenders (K4.1)
- Result of the check on Gary's draft: Corrected (Phase 2 KPI: placeholder tile on the dashboard)
- Plain English: Our submitted price over the winning price, minus one, for lost tenders.
- Calculation:
our_submitted_price / winning_price - 1, outcome = lost - Sources and why:
tender_register.our_submitted_price,.winning_price,.outcome - Grain: Tender
- Filters: Lost tenders with a known winning price; annual amounts converted to contract totals. Placeholder tile until winning prices are back-filled; show the count with a known winning price beside the result.
- Baseline: Phase 2 placeholder: waiting for winning prices from the debrief letters. Winning price is recorded on only 5 of 25 lost tenders (2 of the 3 big losses), too few to show as a baseline. Period: Phase 2. Evidence: Working Hypothesis (winning price missing on 80% of lost tenders)
- Pace needed: Not applicable until Phase 2: the placeholder shows no pace needed (evidence measure, no target)
- Run rate: Not applicable
- Reading it: Phase 2: waiting for data
- Counter-metric: Price score gap from the debrief scoring table, as a second source (see Why we lost, K4.2): on the 3 big losses our price score was behind by 0.6 and 1.2 points of 30 and ahead by 0.9
- Notes: Phase 2 KPI. Corrected (C7, accepted in v1.1): values stored as annual amounts are converted to contract totals. Winning price is missing on 20 of 25 lost tenders (C8). What the register holds today (not shown on the tile): Southern Metro Health Network +2.1%, Highlands Ambulance -1.5%, Western Plains LHD not recorded; average +0.9% across the 5. First pass: placeholder tile plus the stand-in Price score gap on lost tenders.
- Stand-in (first pass only, not the KPI): Behind on price in 11 of 20 lost tenders with a scoring table; average gap -0.03 points of 30, median +0.45. Big losses: Southern Metro Health Network +0.60, Western Plains LHD +1.20, Highlands Ambulance -0.90. Positive means the preferred supplier scored higher on price. Price score, not price. Period: Lost tenders, whole register (Sample data). Evidence: Strong Inference (scores parsed from debrief text; only 3 tenders to cross-check against real prices). Calculation:
Weighted price points (out of 30) the preferred supplier scored above Kestrel, lost tenders with a scoring table; positive = behind on price
What the register holds today (documented, not shown on the dashboard):
| Lost tender | Our price against the winning price |
|---|---|
| TND-2021-22 | +1.9% |
| TND-2024-07 (big) | +2.1% |
| TND-2025-25 | +1.0% |
| TND-2025-06 (big) | -1.5% |
| TND-2026-22 | +1.0% |
Stand-in detail: Price score gap on lost tenders (Sample data): weighted points out of 30 that the preferred supplier scored above Kestrel on price (positive means we were behind). | Big loss | Price score gap (points of 30) | Gap across the other five areas (points of 70) |
| --- | --- | --- |
|---|---|---|
| Southern Metro Health Network (TND-2024-07) | +0.60 | +5.25 |
| Western Plains LHD (TND-2025-02) | +1.20 | +2.85 |
| Highlands Ambulance (TND-2025-06) | -0.90 | +8.40 |
Across 20 scored losses: behind on price in 11, level or ahead in 9, behind by 1 point or more in 5; average gap on the other five areas +1.32 points.
Why we lost, from the debriefs (K4.2)
- Result of the check on Gary's draft: Corrected
- Plain English: For each lost tender, the scoring area with the biggest gap to the preferred supplier, counted by area.
- Calculation:
argmax over areas of weighted points (preferred - ours), outcome = lost - Sources and why:
tender_register.scoring_table,.debrief_notes,.debrief_received - Grain: Tender
- Filters: Lost tenders with a scoring table; text parsed into six areas.
- Baseline: Biggest gap to the preferred supplier, of 20 lost tenders with a scoring table: Service and support 7, Clinical fit 5, Price 3, Sustainability 3, Supply reliability 2. All 3 big losses: Service and support. Price was the biggest gap in only 3 of 20. Period: Lost tenders, whole register. Evidence: Strong Inference (scores from the buyer's debrief, parsed from text)
- Pace needed: No target (evidence measure)
- Run rate: Not applicable
- Reading it: Debrief received on all 25 lost tenders: Green on Gary's coverage threshold
- Counter-metric: Debrief coverage: debrief received on 25 of 25 lost tenders; scoring table present on 20 of 25
- Notes: Corrected: the scoring text comes in three layouts and scales, so gaps are compared in weighted points out of 100 (weights 30, 25, 15, 10, 10, 10), not raw scores (C9). Five lost tenders have no scoring table and are excluded and counted.
| Big loss | Price | Clinical fit | Service and support | Supply reliability | Training | Sustainability |
|---|---|---|---|---|---|---|
| Southern Metro Health Network (TND-2024-07) | +0.60 | +0.50 | +2.85 | +1.00 | +0.30 | +0.60 |
| Western Plains LHD (TND-2025-02) | +1.20 | -0.50 | +1.95 | +0.60 | +0.40 | +0.40 |
| Highlands Ambulance (TND-2025-06) | -0.90 | -0.25 | +4.35 | +3.50 | +0.20 | +0.60 |
Gaps are weighted points out of 100 that the preferred supplier scored above us (negative means we scored higher).
Who is winning the tenders we lose (K4.3)
- Result of the check on Gary's draft: Confirmed
- Plain English: Count and value of lost tenders by winning supplier.
- Calculation:
COUNT, SUM(contract value) grouped by winning_supplier, outcome = lost - Sources and why:
tender_register.winning_supplier,.estimated_value,.contract_length - Grain: Tender
- Filters: Lost tenders.
- Baseline: Lost tenders by winner: Allied Clinical Supply 7 ($15.2m); Meridian Biomedical 6 ($7.5m); Helix Healthcare 5 ($13.2m); Vantage Medical 4 ($10.6m); Norland Rescue Systems 3 ($13.9m). Big losses: Vantage Medical, Allied Clinical Supply (a distributor bundling brands), Norland Rescue Systems. Period: Lost tenders, whole register. Evidence: Observed Fact
- Pace needed: No target (evidence measure)
- Run rate: Not applicable
- Reading it: Not applicable
- Counter-metric: Rolls up to Big tender win rate (K4)
- Notes: Confirmed. Supplier names are consistent in the register (5 names, none missing on lost tenders). Values are contract totals (annual amounts multiplied by term). The big losses went to three different winners, so no single competitor explains them.
3. KPI tree
Gross margin per cent (K1)
Gross margin by product group (K1.1)
Average discount off list price on big deals (K2)
Revenue growth on the year (K3)
Revenue growth by product group (K3.1)
Revenue growth by rep (K3.2)
Big tender win rate (K4)
Our price against the winning price on lost tenders (K4.1)
Why we lost, from the debriefs (K4.2)
Who is winning the tenders we lose (K4.3)
Monthly reports that match the agreed set of numbers (K5)
↑ Back to top4. What Phase 2 needs
Each Phase 2 KPI stays Must Have with its name, target and owner. Kewpie works with a data engineer to source the data. All four are placeholders until the switch-on test passes.
| KPI | Data to source | System | Owner | What the data engineer does | Switch-on test |
|---|---|---|---|---|---|
| Gross margin per cent (K1) | Kewpie with a data engineer sources cost of sales per shipped order line (standard or actual), with the same order and line numbers as the sales data | SAP (product costing and billing documents) | Finance report owner (Tom Nguyen), with the sales leader as the customer of the number | Locates the cost source with finance; extracts cost per order line and joins on order and line number; handles returns, rebates, freight and warranty lines; loads it with the sales data; adds a daily refresh and a reconciliation check | The calculated figure reconciles to finance's reported 41 per cent, within a tolerance finance sets |
| Monthly reports that match the agreed set of numbers (K5) | Kewpie with a data engineer builds one governed sales table to finance's agreed sales date rule and customer grouping, then pulls each report's monthly net sales and checks it against that table | The 30 Excel workbooks on the shared drive, and the governed table in the new data store | Finance report owner (Tom Nguyen) sets the agreed definitions and owns the report list | Builds the governed table and customer parent mapping; runs the monthly number check with a tolerance; records each result so there is history and a run rate; replaces the self-reported index | Finance has agreed the definitions and the tolerance, and one full month's check has run |
| Gross margin by product group (K1.1) | The same cost of sales feed as Gross margin per cent (K1), mapped to the product group codes (material_group) | SAP | Finance report owner (Tom Nguyen); sales leader uses it | As Gross margin per cent (K1) | Switches on with Gross margin per cent (K1), and the groups add up to the total |
| Our price against the winning price on lost tenders (K4.1) | Kewpie with a data engineer sources the winning price and our price for each lost tender, as numbers in total contract value (not annual amounts) | The bid manager's tender register, or the CRM if tenders move there | Bid manager (Deb Harlow) | With the bid manager, back-fills the 20 missing winning prices from the debrief letters, big losses first (Western Plains first); makes winning price and our price required number fields with a total-contract-value rule; cleans customer name variants; adds a completeness check | Winning price recorded on all three big losses and on enough lost tenders for the count to be shown beside the result |
5. Challenge notes
No KPI has been added, dropped or reprioritised. Corrections to Gary's draft measures are marked. 'Status in v1.1' follows the Business Requirements change log.
| # | KPI | Issue | Evidence | Suggested fix | Status in v1.1 |
|---|---|---|---|---|---|
| C1 | Gross margin per cent (K1) and Gross margin by product group (K1.1) | No cost of sales field, so gross margin cannot be calculated. | Checked every column in all 11 Sample data files: no cost, COGS, margin or standard cost field. Only the monthly report index mentions a margin report ('04 Margin by customer.xlsx'), with no data behind it. | Finance (Tom Nguyen) to name the SAP cost of sales source and supply it by order line; then reconcile to the stated 41%. Until then, report the stated 41% as a Working Hypothesis only. | Open for Phase 2. v1.1 marks the two margin KPIs Phase 2 placeholders; finance must name the cost of sales source (switch-on needs it to reconcile to the stated 41%) |
| C2 | Big tender win rate (K4) | Target is open (needed before Stage 2 finishes). Raised for Adam; Kewpie cannot set it. | Baseline 2 of 5 (40%). About 2 big tenders a year (2024: 2, 2025: 2, 2026 to Sep: 1), so a one-year percentage can only be 0%, 50% or 100%. On a rolling five-tender window, from the current mix: 60% needs the next 2 big tenders won, 80% needs 3, 100% needs 4. The result also moves with the size line: 5 of 10 at $4m or more. | Ask the bid manager (Deb Harlow) for a rolling five-tender target, or a count rule such as 'win at least 1 of the next 2'. Decision for Adam at this gate. | Resolved in v1.1 by the measure change: a count over the last 5 big tenders. Target still open for the bid manager, needed before Stage 4 is approved |
| C3 | Monthly reports that match the agreed set of numbers (K5) | Target is open, and the measure is a proxy. | No agreed set exists yet. On one candidate (ship date and parent where known) 3 of 30 reports match. The index records what owners say they use, not whether the numbers agree. 12 reports show n/a in at least one column, 17 different combinations are in use, and 8 reports were last refreshed in March 2026 or earlier. | Finance (Tom) to set the agreed sales definition and customer grouping and say how the n/a reports are treated (not a sales report, or to be fixed). Then set a target such as 'every report that carries a sales number uses the agreed set by Dec-27'. Adding a real number check (each report's net sales for one month against the agreed set) would turn the proxy into a test. Decision for Adam. | Resolved in v1.1 by the measure change: Tom's number check against a governed sales table, a Phase 2 placeholder. Target still open until switch-on |
| C4 | Average discount off list price on big deals (K2) | Correction to Gary's draft filter: the big-deal placeholder picks up the wrong orders, and an order-total rule finds none. | 3,153 lines carry a contract_id; all start with 'SC' (service contracts), all are Service product group and standard order type. None are tenders. The largest order total is $2,278,217, so no order reaches $5m (each order is one line). | Before: 'Big deal = order total at or above a size Sharon sets (open); placeholder: orders linked to a contract.' After: 'Big deal = order type tender_contract, as a placeholder until Sharon sets a size.' Applied in the pack and spec. Sharon's size rule is still open. | Resolved: accepted in v1.1 (tender contract orders as the big-deal placeholder). Sharon's size rule still open |
| C5 | Average discount off list price on big deals (K2) | Target does not connect to the margin target, and the baseline depends on the definition. | Tender contract discount was 14.1% in 2023, 17.0% in 2024 and 17.0% in 2025, then 17.0% in 2026 to Sep. 'At or below the 2026 average' therefore means holding the post-2024 level (pace needed zero), while Gross margin per cent (K1) must rise about 2 points. The same measure on the top 1% of lines by value reads 4.1%. | For Gary and Adam to consider: whether the reference year should be 2023 (14.1%) rather than 2026, and which big-deal definition applies. No change made here. | Resolved by a target change in v1.1 (path back towards about 14% by Dec-27). Sharon to confirm at next contact |
| C6 | Revenue growth on the year (K3) | Baseline is a decline, and the base for 4% is open (Q-2). | Year to date -6.8% (order date basis -9.9%). 4% on a 2026 base gives about $203.5m for 2027, still -3.1% against 2025. Pace needed +0.72 points a month against a run rate of +0.27. SMART 'A' check: the pace needed is about 2.7 times the run rate, with no plan to close it. | Confirm with the sales leader and finance whether the 4% is on 2026 actuals or on 2025. No change made here. Ship date stays as the draft rule until finance confirms. | Resolved in v1.1 for now: measured against 2026 full-year actuals. The base is still open for Sharon and finance |
| C7 | Big tender win rate (K4) and Our price against the winning price on lost tenders (K4.1) | Correction to Gary's draft filter: annual amounts in estimated_value. | 24 of 64 values read like '$2.4m pa' with a contract length of 2 to 5 years. Treated as $2.4m they understate the contract value (for example $4.8m over 2 years). The same five tenders qualify at $5m, but the draft would misread lower size lines and future tenders. | Before: 'estimated_value at or above $5m (text like $2.21m converted to dollars)'. After: 'Contract value at or above $5m: text like $2.21m is the total; text like $2.4m pa is multiplied by the contract length in years.' Applied in the pack and spec. | Resolved: accepted in v1.1 |
| C8 | Our price against the winning price on lost tenders (K4.1) | Evidence gap: winning price is missing on most lost tenders. | 5 of 25 lost tenders have a winning price (20%); 2 of the 3 big losses. Over 5% missing, so the baseline is a Working Hypothesis. What there is: Southern Metro +2.1%, Highlands -1.5%; Western Plains not recorded. The scoring tables point the same way: price was a small gap on the big losses and service the largest (see Why we lost, K4.2). | Ask Deb Harlow for winning prices from the debrief letters, starting with Western Plains LHD. Use the price score from the scoring table as a second source until then. | Open for Phase 2. v1.1 marks the KPI a Phase 2 placeholder; winning prices to be back-filled from the debrief letters (bid manager) |
| C9 | Why we lost, from the debriefs (K4.2) | Correction to Gary's draft formula: scoring text is in three layouts and scales. | Layouts: points out of area weight ('25.5/30'), scores out of 100 ('PRICE=88/PREF=90'), and a percentage table. Raw 'biggest gap' would compare unlike scales. Five lost tenders have no scoring table. | Before: 'argmax(preferred_score - our_score) per tender from scoring_table'. After: 'argmax over areas of the gap in weighted points out of 100 (weights 30, 25, 15, 10, 10, 10).' Applied in the pack and spec. | Resolved: accepted in v1.1 |
| C10 | Sales leader's belief about the big losses | Not a change to any measure: the calculations do not support 'we lost on price' for the three big losses. | Southern Metro: our price +2.1% above the winner, price score 0.6 points behind, service 2.9 behind. Western Plains: price 1.2 behind, service 2.0 behind, winner a distributor. Highlands: our price 1.5% below the winner, price score 0.9 ahead, service 4.4 and supply reliability 3.5 behind. Strong Inference, from three tenders. | For Gary and the sales leader to weigh. No KPI is changed. | For information, no change |
| C11 | Revenue growth by rep (K3.2) | Gary's parent-grouping filter does not affect a split by rep. | The rep sits on the order line; the data shows a median of 4 different reps per customer, so reps are not tied to accounts. | No change made. For Gary: confirm how reps are credited if the aim is account ownership. | Resolved: accepted in v1.1 (rep credited from the order line). How reps should be credited for account ownership is a question for Sharon |
6. Data quality log
| Source | Check | Result |
|---|---|---|
| sales_order_lines | Lines with no ship date | 1,517 (1.26%), all 2026 orders not yet shipped: excluded from ship-date measures |
| sales_order_lines | Missing or zero list price | 0 |
| sales_order_lines | Duplicate order lines | 0 |
| sales_order_lines | Negative discounts (price above list) | 2 lines, kept |
| sales_order_lines | contract_id populated | 3,153 lines, all service contracts (C4) |
| sales_order_lines | Cost of sales | No field (C1) |
| tender_register | Values stored as annual amounts | 24 of 64 (C7) |
| tender_register | Lost tenders with no winning price | 20 of 25 (C8) |
| tender_register | Lost tenders with no scoring table | 5 of 25 (C9) |
| tender_register | Customer name variants | Southern Metro Health Network; Southern Metropolitan Health Network; Western Plains Health District; Western Plains LHD |
| monthly_reports_index | n/a in sales definition or customer grouping | 12 of 30 |
| monthly_reports_index | Only a snapshot, no history | No run rate possible |
7. Open questions that stay with Gary and the stakeholders
- Big-deal size rule (sales leader). Confirm the discount path towards 14% (sales leader). Base for the 4% (sales leader and finance). Win-rate count target, needed before Stage 4 is approved (bid manager). Cost of sales source and reconciliation tolerance, needed to start Phase 2 (finance). Agreed definitions, tolerance and target for the reports check, needed before the Phase 2 switch-on (finance, with the sales leader). Who is the data engineer, and when can they start (Adam).
File: 2026.10.23 - Kestrel Medical - 01 Business Requirements.md
Kestrel Medical: Business Requirements
Test case, Sample data. Kestrel Medical is a test case. Sharon was played by the case's stakeholder agent. Data named here is mapped to the Sample data in 03 - Working Files/data/, which must be checked against real data before go-live.
1. Document control
| Field | Detail |
|---|---|
| Version | 1.1 |
| Date | 23-Oct-26 |
| Status | Approved at the Stage 2 gate, 23-Oct-26 |
| Author | Gary, KPI Creator Stage 1 |
| Stakeholder | Sharon, sales leader (exact title to confirm) |
| Sign-off | Sharon confirmed the playback on 23-Oct-26, with three corrections (all made). Adam (acting subject matter expert, test mode) approved v1.0 at the Stage 1 gate, 23-Oct-26, and v1.1 at the Stage 2 gate, 23-Oct-26. Sharon has not yet seen the v1.1 changes; the ones marked "for Sharon to confirm" go to her at the next contact |
2. Problem Statement
Kestrel has lost three of its last five big tenders, each over five million dollars, and believes price is the reason but can't yet prove or disprove it. With gross margin at about 41 per cent against global's 43 per cent target for 2027, and thirty monthly reports that give different answers, the business needs one set of evidence before it asks global for more discount room.
The problem as stated
Sharon, in her words: lost three of the last five big tenders, each over five million dollars, "never happened to me in 22 years". Reps say Kestrel is being undercut 10 to 15 per cent. She wants a win-loss view and pricing against the competition, so she can take evidence to global and argue for more discount room. And she wants out of Excel: thirty monthly reports, and half of them say different things.
The problem as Gary understands it
- The ask and the target pull against each other. The ask is evidence for more discount. Global's target is more margin (about 41 to 43 per cent in 2027) and 4 per cent revenue growth, after a flat year
- The loss reasons are belief, not yet evidence. They come from reps and one procurement person. Sharon's own account of the three losses: one "was price" (Southern Metropolitan Health Network), one was "about the stretcher as much as anything" (Highlands Ambulance, a 15-year customer), and one went to a distributor that bundles several brands (Western Plains Health District, won by Allied Clinical Supply)
- The evidence exists but hasn't been used. Deb Harlow, the bid manager, keeps the tender file and the debrief letters
- Nobody agrees on the base numbers. Thirty monthly reports from ERP extracts disagree, and Sharon spends three days a month reconciling them
Gary's note: the question I'd put to Sharon is "What decision changes if this number moves?" Here, the answer is the discount case to global. If the debriefs say Kestrel lost on product fit or bundling, more discount won't win the next tender and will cost the margin target. That's my reading, not Sharon's words, and Sharon has not confirmed it.
↑ Back to top3. Objectives
| ID | Objective | Sub-objective |
|---|---|---|
| O1 | Lift gross margin to 43 per cent in 2027 (about 41 per cent now) | Know where margin is leaking, especially on big deals (O1.1) |
| O2 | Grow revenue 4 per cent in 2027 (flat last year) | Know which reps and product groups are growing and which are going backwards (O2.1) |
| O3 | Stop losing the big tenders (over five million dollars) | Know which tenders we lose, who wins them, on what price, and the real reasons from the debriefs (O3.1) |
| O4 | One agreed set of numbers instead of thirty monthly reports that disagree, automated and consistent |
Each objective helps solve the Problem Statement: margin and growth are global's tests (O1, O2), the tender losses are the trigger (O3), and one agreed set of numbers makes the evidence credible (O4).
↑ Back to top4. Audience and decisions
| Who | Decisions | How often | Where |
|---|---|---|---|
| Sales leader (Sharon) | Pricing on big deals within her authority; where reps focus; headcount asks to global; how Kestrel responds to tenders | Monthly (her expectation, "don't hold me to it") | A pack for global (main use); on screen in meetings with the reps. Not phone |
| Global group | Whether to give more discount room; headcount | Unknown | Pack, format unknown |
| Reps | Where to focus | In meetings with the sales leader | Screen |
| Others | Unknown: Sharon to check with the team | Unknown | Unknown |
5. Business Requirements with Data Mapping
All measures, data mappings and filters below were drafted by Gary and confirmed or corrected by Kewpie at Stage 2 (Calculation Pack v1.0). Targets and thresholds marked "Gary's proposal" were not said by Sharon. Four KPIs are Phase 2 KPIs: see "Phase for each KPI" below.
Top 5
| Measure | Type | Objective | What do we want to know? | Why? | Action if outside threshold | Action owner | Target (SMART) | Thresholds |
|---|---|---|---|---|---|---|---|---|
| Gross margin per cent (K1) (Phase 2) | Lagging | O1 | What gross margin we earn on sales, against global's 43 per cent | Global's headline target; any discount case has to square with it | Sales leader tightens pricing on big deals within her authority; anything beyond goes to global with the discount evidence | Sales leader | 43% for the 2027 financial year (January to December). Global's target. Observed Fact | Gary's proposal: Green 43% or more year to date; Amber 42% to under 43%; Red under 42%. Applied from Phase 2 only |
| Average discount off list price on big deals (K2) | Leading | O1, O1.1 | How much discount we give off list on big deals, and where it's growing | Shows margin leaking before year end; the evidence for or against more discount room | Sales leader reviews big-deal pricing within her authority and pulls back discounts that aren't winning business | Sales leader | Back down from 17.0 per cent towards the 2023 level of about 14 per cent on tender contract orders by Dec-27. Gary's proposal, for Sharon to confirm. Working Hypothesis. Read with Big tender win rate (K4) as the counter-metric | Green at or below a straight-line path from 17.0 per cent (Sep-26) to 14 per cent (Dec-27); Amber up to 1 point above the path; Red more than 1 point above. Gary's proposal |
| Revenue growth on the year (K3) | Lagging | O2 | Whether revenue grows 4 per cent in 2027 after a flat year | Global's growth target; drives rep focus and headcount asks | Sales leader moves rep focus to growing product groups and customers; makes a headcount ask to global if the gap is capacity | Sales leader | 4% growth in 2027. Global's target. Observed Fact. Measured against 2026 full-year actuals on ship date until finance confirms the base. Note: 2026 is tracking -6.8 per cent, so 4 per cent on 2026 still leaves 2027 about 3 per cent below 2025 | Gary's proposal: Green 4% or more; Amber 0% to under 4%; Red below 0% |
| Big tender win rate (K4) | Lagging | O3 | How many tenders over five million dollars we win | Three of the last five lost; decides how Kestrel responds to the next tenders | Bid manager reviews the debriefs and scoring of lost bids; sales leader decides how the response changes | Bid manager (response decided by the sales leader) | To be set by the bid manager as a count out of the last 5 big tenders. Gary's starting proposal for Deb: at least 3 of the last 5 by Dec-27, which means winning the next 2 big tenders. Working Hypothesis. Open question, needed before Stage 4 is approved. Starting point: won 2 of the last 5 (Observed Fact) | Follow the count Deb sets |
| Monthly reports that match the agreed set of numbers (K5) (Phase 2) | Leading | O4 | Whether the monthly reports agree with one agreed set of numbers | Three days a month reconciling; every other measure depends on agreed numbers | Finance report owner fixes or retires any report that doesn't match | Finance report owner | Open question, needed before the Phase 2 switch-on: Sharon wants one agreed set of numbers with Tom checking the reports against it, and has not agreed a target. Set by the finance report owner with the sales leader, once the agreed definitions exist | Open, with the target |
SME sign-off (all rows): Sharon (stakeholder) confirmed the playback with corrections, 23-Oct-26. Adam (acting subject matter expert, test mode) approved at the Stage 1 gate, 23-Oct-26, and approved the v1.1 changes at the Stage 2 gate, 23-Oct-26.
Measures for the Top 5 (confirmed or corrected by Kewpie)
| Measure | How measured | Data source and fields | Filters and conditions |
|---|---|---|---|
| Gross margin per cent (K1) (Phase 2) | (Net sales minus cost of sales) divided by net sales. (SUM(net_value_aud) - SUM(cost_of_sales)) / SUM(net_value_aud) | SAP sales orders: sales_order_lines.net_value_aud, sales_order_lines.actual_ship_date. Cost of sales: no field in the Sample data. Phase 2: cost of sales per shipped order line from SAP product costing and billing documents, joined on order and line number, sourced by the data engineer with the finance report owner | Shipped lines only; financial year January to December; must reconcile to finance's 41 per cent before use. Phase 2 KPI: until the cost of sales feed reconciles, the tile is a placeholder showing 'Phase 2: waiting for data. Waiting for cost of sales from finance'. Finance's stated 41 per cent may appear only as a text note on the placeholder, 'Finance's stated figure, not calculated', Working Hypothesis, with no status colour, never in the headline slot and never on the stand-in |
| Average discount off list price on big deals (K2) | 1 minus net value over list value, value-weighted. 1 - SUM(net_value_aud) / SUM(list_price * qty) | SAP sales orders: sales_order_lines.list_price, .qty, .net_value_aud, .discount_pct (cross-check), .order_id, .contract_id, .material_group, .order_type | Big deal = order total at or above a size Sharon sets (open); placeholder: tender contract orders (order_type tender_contract). The earlier placeholder, orders linked to a contract, picked up service contracts and is replaced (Kewpie's correction C4). Exclude lines with no list price. Period by order date |
| Revenue growth on the year (K3) | Net sales year to date over the same period last year, minus 1. SUM(net_value_aud, YTD 2027) / SUM(net_value_aud, same period 2026) - 1 | SAP sales orders: sales_order_lines.net_value_aud, .actual_ship_date, .order_type | Year to date vs year to date; ship date until finance confirms its revenue rule; Kewpie to check order types for credits and returns |
| Big tender win rate (K4) | Tenders won out of the last 5 decided tenders with a contract value of $5m or more (rolling five-tender window), shown as a count (for example '2 of 5'), with the calendar-year count alongside | Bid manager's tender spreadsheet: tender_register.outcome, .estimated_value, .contract_length, .close_date, .tender_reference. Chosen over the CRM, which Sharon doesn't trust for win-loss | $5m or more (values stored as text like "$2.21m"; values marked "pa" are annual amounts, multiplied by the contract length in years, Kewpie's correction C7); dates as dd/mm/yyyy text; exclude undecided; show the count (for example 2 of 5) next to the rate, as numbers are small |
| Monthly reports that match the agreed set of numbers (K5) (Phase 2) | Phase 2 KPI. Reports that carry a sales number and whose net sales for the month check against the governed sales table (within a tolerance finance sets), divided by all reports that carry a sales number. Run automatically each month by the data engineer's check, reviewed by the finance report owner. Reports that carry no sales number are listed but not counted. First pass: placeholder tile, with the stand-in Reports on the draft agreed set | Phase 2: the monthly check results (report, month, report net sales, governed net sales, pass or fail), built by the data engineer from the 30 workbooks and the governed sales table. First pass stand-in only: monthly reports index: monthly_reports_index.workbook, .owner, .sales_definition, .customer_grouping, .last_refreshed | Agreed definition and match tolerance set by finance (open); reports marked "n/a" reviewed one by one to see whether they carry a sales number |
Sub-KPIs (Must Have, explain a Top 5 measure)
| Sub-KPI | Under | Objective | What it explains | How measured | Data | Owner |
|---|---|---|---|---|---|---|
| Gross margin by product group (K1.1) (Phase 2) | Gross margin per cent (K1) | O1.1 | Where the margin leaks | Gross margin split by product group | sales_order_lines.material_group, .net_value_aud, cost of sales (Phase 2: same feed as Gross margin per cent (K1)) | Sales leader |
| Revenue growth by product group (K3.1) | Revenue growth on the year (K3) | O2.1 | Which product groups grow or go backwards | Revenue growth by material_group | sales_order_lines.material_group, .net_value_aud | Sales leader |
| Revenue growth by rep (K3.2) | Revenue growth on the year (K3) | O2.1 | Which reps grow or go backwards | As Revenue growth on the year (K3). Rep credited from the order line (rep_id). How reps should be credited for account ownership is an open question for Sharon (Kewpie's correction C11) | sales_order_lines.rep_id, .net_value_aud | Sales leader |
| Our price against the winning price on lost tenders (K4.1) (Phase 2) | Big tender win rate (K4) | O3.1 | "On what price" we lost: proves or disproves the price story | Phase 2 KPI. our_submitted_price / winning_price - 1, lost tenders, values as total contract value (annual amounts multiplied by the contract length). Gary's proposed thresholds, applied from Phase 2 only: Green within 2%; Amber 2% to 5% above; Red more than 5% above. Show the count of tenders with a known winning price beside the result. First pass: placeholder tile, with the stand-in Price score gap on lost tenders | tender_register.our_submitted_price, .winning_price, .outcome, .contract_length. Phase 2: winning price back-filled from the debrief letters and made a required number field | Bid manager |
| Why we lost, from the debriefs (K4.2) | Big tender win rate (K4) | O3.1 | Price, product fit, service or something else | For each lost tender, the scoring area with the biggest gap to the preferred supplier, compared in weighted points out of 100 across the three scoring layouts (Kewpie's correction C9); losses counted by area | tender_register.scoring_table, .debrief_notes, .debrief_received | Bid manager |
| Who is winning the tenders we lose (K4.3) | Big tender win rate (K4) | O3.1 | One competitor's product, or bundled distributor bids | Count and value of lost tenders by winning supplier | tender_register.winning_supplier, .estimated_value | Bid manager |
Phase for each KPI
This first pass builds every Top 5 KPI and sub-KPI that the data supports today. Four can't be built yet because the data doesn't exist or isn't complete. They stay Must Have, keep their name, target and owner, and show as placeholder tiles until Phase 2, when Kewpie works with a data engineer to source the data. Every other KPI is marked 'First pass: built': Average discount off list price on big deals (K2), Revenue growth on the year (K3), Revenue growth by product group (K3.1), Revenue growth by rep (K3.2), Big tender win rate (K4), Why we lost, from the debriefs (K4.2) and Who is winning the tenders we lose (K4.3).
| KPI | Phase marking |
|---|---|
| Gross margin per cent (K1) | First pass: placeholder tile plus the stand-in Net price realisation. Phase 2: Kewpie with a data engineer sources cost of sales per shipped order line (standard or actual), with the same order and line numbers as the sales data. System: SAP (product costing and billing documents). Owner: finance report owner (Tom Nguyen), with the sales leader as the customer of the number. Data engineer: locates the cost source with finance; extracts cost per order line and joins on order and line number; handles returns, rebates, freight and warranty lines; loads it with the sales data; adds a daily refresh and a reconciliation check. Switch-on test: the calculated figure reconciles to finance's reported 41 per cent, within a tolerance finance sets |
| Gross margin by product group (K1.1) | First pass: placeholder tile plus the stand-in Net price realisation by product group. Phase 2: the same cost of sales feed as Gross margin per cent (K1), mapped to the product group codes (material_group). System: SAP. Owner: finance report owner (Tom Nguyen); sales leader uses it. Switch-on test: switches on with Gross margin per cent (K1), and the groups add up to the total |
| Monthly reports that match the agreed set of numbers (K5) | First pass: placeholder tile plus the stand-in Reports on the draft agreed set. Phase 2: Kewpie with a data engineer builds one governed sales table to finance's agreed sales date rule and customer grouping, then pulls each report's monthly net sales and checks it against that table. System: the 30 Excel workbooks on the shared drive, and the governed table in the new data store. Owner: finance report owner (Tom Nguyen) sets the agreed definitions and owns the report list. Data engineer: builds the governed table and customer parent mapping; runs the monthly number check with a tolerance; records each result so there is history and a run rate; replaces the self-reported index. Switch-on test: finance has agreed the definitions and the tolerance, and one full month's check has run |
| Our price against the winning price on lost tenders (K4.1) | First pass: placeholder tile plus the stand-in Price score gap on lost tenders. Phase 2: Kewpie with a data engineer sources the winning price and our price for each lost tender, as numbers in total contract value (not annual amounts). System: the bid manager's tender register, or the CRM if tenders move there. Owner: bid manager (Deb Harlow). Data engineer: with the bid manager, back-fills the 20 missing winning prices from the debrief letters, big losses first (Western Plains first); makes winning price and our price required number fields with a total-contract-value rule; cleans customer name variants; adds a completeness check. Switch-on test: winning price recorded on all three big losses and on enough lost tenders for the count to be shown beside the result |
Stand-ins for the first pass (not KPIs)
A stand-in is a small, separate panel beside a placeholder tile. It carries its own plain name and the labels 'Stand-in, not the KPI' and 'Sample data' (until real data is loaded). It never takes the KPI's name, target, thresholds, pace needed, status colour or finance's stated 41 per cent. It has no target and no status colour of its own. It is removed, or moved to a context note, when its KPI switches on in Phase 2.
Adam chose, at the Stage 2 gate on 23-Oct-26, to show the Net price realisation stand-in beside the Gross margin per cent (K1) placeholder, with its labels, rather than the placeholder alone.
| Stand-in for | Stand-in |
|---|---|
| Gross margin per cent (K1) | Name: Net price realisation. What it shows: how much of list price Kestrel keeps after discounting, on shipped lines: net value over list value. Baseline 87.36 per cent, January to September 2026, against 87.67 per cent in the same months of 2025 (Sample data). Evidence label: Observed Fact for the calculation; Working Hypothesis that it moves with gross margin, because there's no cost data to test the link. On the panel: 'Price side only. This is not gross margin and can't be compared with the 43 per cent target.' Never shows the KPI's name, target or status colour |
| Gross margin by product group (K1.1) | Name: Net price realisation by product group, with each group's share of net sales. What it shows: which product groups carry the deepest discounts (equipment groups keep about 83 to 84 per cent of list; Sample data). Evidence label: Observed Fact for the calculation; Working Hypothesis that group margin follows group realisation. On the panel: 'Service and Parts show 100 per cent because they aren't discounted. That says nothing about their margin.' Groups not ranked as best or worst. Never shows the KPI's name, target or status colour |
| Monthly reports that match the agreed set of numbers (K5) | Name: Reports on the draft agreed set, with the number of different combinations in use. What it shows: how many reports say they use the draft rule (ship date, customers grouped by parent where known): 3 of 30, with 17 different combinations in use (index at 30-Sep-26, Sample data). Evidence label: Working Hypothesis (the agreed set is open and the index is self-reported). On the panel: 'Against a draft set. Shows what reports say they use, not whether their numbers agree.' Never shows the KPI's name, target or status colour |
| Our price against the winning price on lost tenders (K4.1) | Name: Price score gap on lost tenders. What it shows: for each lost tender with a buyer's scoring table, the preferred supplier's price score minus ours, in weighted points out of 30 (positive means we were behind on price). Behind on price in 11 of 20 scored losses; big losses: Southern Metropolitan Health Network +0.60, Western Plains Health District +1.20, Highlands Ambulance -0.90 (Sample data). Evidence label: Strong Inference (scores parsed from debrief text; only 3 tenders to cross-check against real prices). On the panel: 'Price score, not price. The buyer's view of price, not our price against the winner's.' Never shows the KPI's name, target or status colour |
Placeholder tiles
A placeholder tile uses the KPI's exact name from these Business Requirements, its owner's role, and the text 'Phase 2: waiting for data', with one line on what's missing (for example 'Waiting for cost of sales from finance'). The headline slot shows no number, no status colour, no sparkline, no gap and no pace needed. The target may be shown as text ('Target: 43 per cent for 2027') so the reader knows what's coming. A placeholder tile sits in the same place the real tile will take, so the layout doesn't change at switch-on.
How validation treats Phase 2 KPIs
For Jennifer's validation checklist in this first pass:
- A Phase 2 KPI counts as 'on the dashboard, calculated as documented' when its placeholder tile and stand-in are shown exactly as these Business Requirements document them, and is recorded as 'Phase 2 placeholder, as documented', not a fail
- For Lift gross margin (O1), progress shows Average discount off list price on big deals (K2) with actual, target, gap and pace, and the margin target as text with 'Phase 2: waiting for data'. For One agreed set of numbers (O4), progress shows 'Phase 2: waiting for data'. Neither is a fail
- Each Phase 2 owner can see 'Phase 2: waiting for data' at a glance, which counts as their status
It is a fail if a placeholder shows a number, a status colour, a sparkline or a pace needed, or if a stand-in takes the KPI's name, target, status colour or the stated 41 per cent. Kewpie's Stage 2 check, 'documented calculation that runs on the data', is met for these four by a documented calculation plus a named Phase 2 data source. Gary's proposal, approved by Adam; the process file itself is unchanged, which is Adam's call.
↑ Back to top6. Backlog (Nice to Have)
| Item | Reason parked |
|---|---|
| CRM opportunity win rate | Sharon doesn't trust the CRM for win-loss: only some reps use it properly |
| Reps' reported competitor price cuts (10 to 15 per cent) | Anecdote, not evidence. Replaced by our price against the winning price on lost tenders (K4.1) |
| Service and field measures (work orders, contracts, parts) | The field service system was named, but no objective or action was raised for it. The debrief analysis shows service and support was the biggest scoring gap on all three big losses: ask Sharon whether to add a service measure under Big tender win rate (K4) in the next release |
7. Data inventory (as named in the interview)
| Source | Holds | Mapped Sample data | Grain | History | Refresh | Quality notes |
|---|---|---|---|---|---|---|
| SAP ERP | Sales orders, customers | sales_order_lines, sales_order_change_log, customers | Order line | Unknown | Unknown | Monthly reports come from ERP extracts. Cost of sales field not yet named. Phase 2: data engineer to source cost per order line from SAP product costing with the finance report owner |
| Tender spreadsheet (bid manager) | Bids, outcomes, debriefs | tender_register | Tender | Unknown | Manual | Debrief letters held by Deb Harlow. Values and dates stored as text. Winning price recorded on 5 of 25 lost tenders. Phase 2: back-fill from debrief letters and make it a required number field |
| CRM | Opportunities | crm_opportunities | Opportunity | Unknown | Unknown | Not trusted for win-loss. Not used in the Top 5 |
| Monthly Excel reports | Thirty reports | monthly_reports_index | Report | Monthly | Monthly | Half disagree. Owned by Tom Nguyen (finance). Cause unknown |
| Field service system | Technician work | work_orders, asset_register, site_customer_map, service_contracts | Work order, asset | Unknown | Unknown | No measure in this release |
Sharon said she isn't the one to ask about the data itself. Tom Nguyen (finance) and Deb Harlow (bid manager) hold the detail.
↑ Back to top8. Constraints and chart preferences
- Must speak to how Kestrel's market actually works, not global's standard view
- Reports automated and consistent
- A pack for global first, then a screen in meetings with the reps. Not designed for phone
- Privacy and customer confidentiality: unknown, Sharon to check
- Chart likes and dislikes: none given. Sharon will react to a draft
9. Assumptions
| Assumption | Evidence label |
|---|---|
| The financial year is January to December, set by global; 2027 is both calendar and financial year | Observed Fact |
| Kestrel won 2 of its last 5 big tenders | Observed Fact |
| Revenue counts on ship date in the draft measures, until finance confirms its rule | Working Hypothesis |
| The tender file and debrief letters are a better source of loss reasons than the CRM or rep reports | Strong Inference |
| The Sample data reflects the shape of the real systems | Working Hypothesis |
| The four stand-ins point the same way as the KPIs they sit beside, but can't be used to judge them against target | Working Hypothesis |
10. Open questions
| Question | For |
|---|---|
| What count out of the last 5 big tenders is a realistic target for Big tender win rate (K4)? Gary's starting proposal: at least 3 of the last 5 by Dec-27. Needed before Stage 4 is approved | Bid manager (Deb Harlow) |
| Can you back-fill winning prices from the debrief letters, starting with Western Plains, and should they move into the CRM or stay in the tender file? | Bid manager (Deb Harlow) |
| Is the 4 per cent revenue growth for 2027 measured against 2026 actuals? | Sales leader, with finance |
| Where does cost of sales come from for gross margin, how does finance get to 41 per cent, and what tolerance counts as reconciled? Needed to start Phase 2 | Finance report owner (Tom Nguyen) |
| Why do the thirty monthly reports disagree (how sales is counted, how customers are grouped, or both), and which is right? What is the agreed sales definition and customer grouping, which reports carry a sales number, and what tolerance counts as a match? | Finance report owner (Tom Nguyen) |
| Who is the data engineer for Phase 2, and when can they start? | Adam |
| Outside tenders, what order size counts as a big deal? | Sales leader (Sharon) |
| Is the tighter discount target right for Average discount off list price on big deals (K2): back from 17.0 per cent towards about 14 per cent by Dec-27? | Sales leader (Sharon) |
| How should reps be credited for Revenue growth by rep (K3.2): the rep on the order line, or account ownership? | Sales leader (Sharon) |
| The debriefs point to service and support. Do you want a service measure under Big tender win rate (K4) in the next release? | Sales leader (Sharon) |
| When does evidence next go to global, and in what pack format? | Sales leader (Sharon) |
| What privacy or customer confidentiality rules apply, for example showing competitor prices or customer names in a pack for global? | Sales leader (Sharon) |
| Who else will open the dashboard, and how often? | Sales leader (Sharon) |
| What target should the monthly reports match against, and how will Tom check them in practice? Target for Monthly reports that match the agreed set of numbers (K5): needed before the Phase 2 switch-on | Finance report owner, with the sales leader |
| How far back does each system go, and how often does each refresh? | Finance report owner and bid manager |
11. Change log
| Version | Date | Change | Reason | Approved by |
|---|---|---|---|---|
| 1.0 | 23-Oct-26 | First version. Playback corrections made: (1) Before "discount and tender decisions are being made blind", After "believes price is the reason but can't yet prove or disprove it"; (2) Before "my proposed target is better than half in 2027", After "target left for the bid manager"; (3) Before "Target all of them", After "one agreed set of numbers, with Tom checking the reports against it; target open" | Stage 1 interview and playback | Adam, 23-Oct-26 |
| 1.0 | 23-Oct-26 | Stage 1 approved. Gary's proposed thresholds, big-deal discount target, owners and due dates accepted. Targets for Big tender win rate (K4) and Monthly reports that match the agreed set of numbers (K5) logged as open questions, needed before Kewpie finishes Stage 2 | Sharon asked that both targets be set later by the bid manager and the finance report owner | Adam, 23-Oct-26 |
| 1.1 | 23-Oct-26 | Four KPIs marked Phase 2 with placeholder tiles and labelled stand-ins: Gross margin per cent (K1), Gross margin by product group (K1.1), Monthly reports that match the agreed set of numbers (K5), Our price against the winning price on lost tenders (K4.1). Placeholder display rule and validation rule added. Net price realisation stand-in shown beside the margin placeholder with its labels (Adam's choice). Data source notes and open questions updated | Data for these four can't be sourced in the first pass (Kewpie's Stage 2 findings); Adam asked for placeholders, 23-Oct-26 | Adam, 23-Oct-26 |
| 1.1 | 23-Oct-26 | Stage 2 challenge responses applied: Big tender win rate (K4) measured as a count out of the last 5 big tenders, with Gary's starting target proposal for Deb; Average discount off list price on big deals (K2) target and thresholds changed to a path back towards about 14 per cent (for Sharon to confirm); Revenue growth on the year (K3) target measured against 2026 full-year actuals; service measure question added to the backlog; Revenue growth by rep (K3.2) credited from the order line. Kewpie's corrections C4 (tender contract orders as the big-deal placeholder), C7 (annual tender values multiplied by contract length), C9 (weighted points out of 100) and C11 (rep on the order line) accepted. The deadline for the Big tender win rate (K4) target moves from "before Kewpie finishes Stage 2" to "before Stage 4 is approved", as recommended at the Stage 2 gate | Kewpie's challenge notes in Calculation Pack v1.0 and Gary's response | Adam, 23-Oct-26 |
| 1.1 | 23-Oct-26 | Stage 2 approved | Stage 2 gate | Adam, 23-Oct-26 |
File: 2026.10.23 - Kestrel Medical - 01 Project Plan.md
Kestrel Medical: Project Plan
Test case, Sample data. Built from Business Requirements v1.1 (approved at the Stage 2 gate, 23-Oct-26). Dates and effort are Gary's proposals. The first pass covers phases 1 to 5; Phase 2, Source missing data, follows it.
1. Goal and scope
- Goal: a first trusted dashboard Sharon can take to global as evidence and use in rep meetings, covering gross margin, revenue growth, big tender wins and one agreed set of numbers
- In scope: the Top 5 measures and their six sub-KPIs in Business Requirements v1.1. First pass: built where the data supports it, placeholder tiles with labelled stand-ins for Gross margin per cent, Gross margin by product group, Monthly reports that match the agreed set of numbers, and Our price against the winning price on lost tenders. Phase 2: source the missing data and switch those four on
- Out of scope this time: CRM win rate, reps' reported competitor price cuts, service and field measures
2. Phases and sprints
| Phase | Dates (proposed) | Deliverables | Owner (role) |
|---|---|---|---|
| 1. Discover | 23-Oct-26 to 30-Oct-26 | Business Requirements v1.0, open questions answered by the bid manager and finance | Gary; sales leader |
| 2. Build KPIs | 2-Nov-26 to 27-Nov-26 (2 sprints) | Calculation Pack: measures confirmed on the data, baselines, pace needed, challenge notes | Kewpie; finance report owner |
| 3. Visualise | 30-Nov-26 to 11-Dec-26 (1 sprint) | Story, Standard dashboard (pack-first layout), Experimental options | Viktor |
| 4. Harden | 14-Dec-26 to 22-Jan-27 (1 sprint, plus the holiday break) | Standards and validation, stakeholder review, fixes | Jennifer |
| 5. Embed | 25-Jan-27 to 5-Feb-27 | Handover, owner walk-through, monthly review rhythm agreed | Adam; sales leader |
| Phase 2: Source missing data | 8-Feb-27 to 19-Mar-27 (3 sprints) | Cost of sales feed reconciled; governed sales table and monthly report check; winning prices back-filled and required; four placeholder tiles switched to real KPIs and revalidated | Kewpie with a data engineer; finance report owner; bid manager |
The data adds a sprint to Build KPIs: cost of sales isn't named yet, the reports disagree, and the tender file stores values as text. Four KPIs can't be sourced in the first pass and move to Phase 2. The finance report owner and bid manager can start their parts (naming the cost source, agreeing definitions, back-filling winning prices) during the first pass, so Phase 2 starts ready.
Phase 2 tasks
| Task | Owner (role) | Person-days | Depends on |
|---|---|---|---|
| (a) Name the cost of sales source and the reconciliation tolerance | Finance report owner | 1 | Data engineer named |
| (b) Extract cost per shipped order line from SAP and join to sales, with returns, rebates, freight and warranty handled | Data engineer, with Kewpie | 6 | (a) |
| (c) Reconcile to finance's 41 per cent and switch on Gross margin per cent and Gross margin by product group | Kewpie, with finance report owner | 3 | (b) |
| (d) Agree the sales date rule, customer grouping and match tolerance | Finance report owner, with sales leader | 1 | None |
| (e) Build the governed sales table and customer parent mapping | Data engineer | 5 | (d) |
| (f) Automated monthly check of each report against the governed table, with history; switch on Monthly reports that match the agreed set of numbers | Data engineer, with Kewpie | 3 | (e); target set |
| (g) Back-fill winning prices from debrief letters, big losses first | Bid manager | 2 | None |
| (h) Make winning price and our price required number fields, total contract value rule, completeness check; switch on Our price against the winning price on lost tenders | Data engineer, with bid manager and Kewpie | 2 | (g) |
| (i) Rerun validation on the four switched-on tiles; remove or move the stand-ins | Jennifer | 2 | (c), (f), (h) |
| (j) Phase 2 walk-through with the sales leader | Adam | 1 | (i) |
3. MoSCoW
| Priority | Items |
|---|---|
| Must | Gross margin per cent (placeholder in the first pass, Phase 2); Average discount off list price on big deals; Revenue growth on the year; Big tender win rate; Monthly reports that match the agreed set of numbers (placeholder in the first pass, Phase 2) |
| Should | Gross margin by product group (placeholder in the first pass, Phase 2); Revenue growth by product group; Revenue growth by rep; Our price against the winning price on lost tenders (placeholder in the first pass, Phase 2); Why we lost, from the debriefs; Who is winning the tenders we lose |
| Could | Experimental dashboard options |
| Won't (this time) | CRM win rate; reps' reported competitor price cuts; service and field measures |
4. Effort estimate
| Phase | Person-days | Assumptions |
|---|---|---|
| Discover | 3 | Bid manager and finance answer the open questions within a week |
| Build KPIs | 10 | Includes agreeing the sales definition with finance and parsing the tender file |
| Visualise | 5 | One Standard version, up to two Experimental |
| Harden | 4 | One round of stakeholder fixes |
| Embed | 2 | One walk-through session |
| Phase 2: Source missing data | 26 | A data engineer is named and starts 8-Feb-27; finance names the cost source and agrees definitions before then; the bid manager back-fills during the first pass |
| Total | 50 (first pass 24, Phase 2 26) |
5. RAID log
| ID | Type | Description | Impact | Owner (role) | Action | Status |
|---|---|---|---|---|---|---|
| R1 | Risk | Cost of sales isn't named, so gross margin per cent can't be calculated | H | Finance report owner | Placeholder tile and stand-in in the first pass; name the SAP source before Phase 2 starts; reconcile to 41 per cent in Phase 2 | Open, mitigated for the first pass |
| R2 | Risk | The evidence may show losses weren't mainly price, which changes the discount case to global | H | Sales leader | Agree up front that the dashboard shows the evidence either way | Open |
| R3 | Risk | Only a handful of big tenders a year, so the win rate swings on one result | M | Bid manager | Show counts next to rates; use a rolling window | Open |
| R4 | Risk | Phase 2 data doesn't reconcile: the cost feed doesn't reach finance's 41 per cent, report numbers don't check against the governed table, or back-filled winning prices are too few | H | Finance report owner (margin, reports); bid manager (winning prices) | Agree each tolerance before the data engineer starts; a tile switches on only when it passes its reconciliation; if it fails, the placeholder stays, the gap is written up, and Adam decides whether to accept, extend Phase 2 or go back to the sales leader | Open |
| R5 | Risk | A stand-in is read as the real KPI, for example price realisation read as margin in the pack for global | M | Sales leader | Stand-in labels fixed by the Business Requirements; Jennifer's validation fails any stand-in that takes a KPI's name, target or status colour; Adam explains it at the walk-through | Open |
| I1 | Issue | Thirty monthly reports disagree; cause unknown | H | Finance report owner | Agree one sales definition and customer grouping | Open |
| I2 | Issue | CRM not trusted for win-loss | M | Sales leader | Use the tender file instead | Closed (designed out) |
| A1 | Assumption | Revenue counts on ship date until finance confirms | M | Finance report owner | Confirm the rule | Open |
| A2 | Assumption | Sample data reflects the real systems' shape | M | Kewpie | Check against real extracts before go-live | Open |
| D1 | Dependency | Bid manager supplies the win-rate target and debrief letters | H | Bid manager | Answer before Build KPIs ends | Open |
| D2 | Dependency | Global's pack format and the next date evidence goes to global | M | Sales leader | Confirm before Visualise | Open |
| D3 | Dependency | Privacy and customer confidentiality rules for competitor prices and customer names | M | Sales leader | Confirm before Visualise | Open |
| D4 | Dependency | A data engineer is named and booked for Phase 2 | H | Adam | Name before Stage 4 is approved | Open |
6. Milestones and approval gates
| Milestone | Gate | Proposed date |
|---|---|---|
| Business Requirements v1.0 approved | Stage 1 gate (Adam) | 30-Oct-26 |
| Calculation Pack approved | Stage 2 gate (Adam) | 27-Nov-26 |
| Standard dashboard chosen | Stage 3 gate (Adam) | 11-Dec-26 |
| Finished first draft validated | Stage 4 gate (Adam) | 22-Jan-27 |
| Stakeholder brief coverage check | Ovy, before Stage 5 | 23-Jan-27 |
| Walk-through, sign-off and go-live date set | Stage 5 (Sharon and Adam) | 5-Feb-27 |
| Phase 2 data sources named (cost of sales, agreed definitions, back-fill under way) | Ovy check | 5-Feb-27 |
| Phase 2 KPIs switched on and revalidated | Phase 2 gate (Adam) | 19-Mar-27 |
| Phase 2 walk-through | Sales leader and Adam | 26-Mar-27 |
7. Review rhythm after go-live
- Monthly: sales leader reviews the Top 5, in line with today's monthly reports (Sharon's expectation, to confirm)
- After each big tender decision: bid manager updates the outcome, winning price and debrief
- Before each global review: pack produced from the dashboard (date and format open)
- Monthly, from Phase 2: the data engineer's automated check runs each report against the governed sales table; the finance report owner reviews the failures. Until then, quarterly: the finance report owner checks the monthly reports against the agreed set of numbers
File: 2026.10.23 - Kestrel Medical - 02 Kewpie Substitutes for Missing KPIs.md
Kestrel Medical: Substitutes for KPIs That Can't Be Built Yet
Sample data. Every number is calculated from the Sample data in03 - Working Files/data/by03 - Working Files/kewpie_substitutes.py(results insubstitutes_results.json). Data runs to 2026-09-30. Nothing here is real Kestrel data. Nothing in the Calculation Pack,calc_kpis.py,spec.jsonor the Business Requirements has been changed. No KPI is added, dropped or reprioritised: each real KPI stays in the Top 5 and gets a placeholder tile marked for Phase 2. The substitute sits beside the placeholder as a clearly labelled stand-in, never in place of the real KPI's name or target.
Author: Kewpie, KPI Creator Stage 2. Date: 23-Oct-26.
Summary
| KPI | Why it can't be built now | Substitute for the first pass | Substitute baseline | Phase 2 need |
|---|---|---|---|---|
| Gross margin per cent (K1) | No cost of sales field in any of the 11 files (C1). Finance's 41% is a stated figure only | Net price realisation (net value as a share of list value, shipped lines) | 87.36% (Jan to Sep 2026), against 87.67% in the same months of 2025 | Cost of sales per order line from the SAP product costing, owned by the Finance lead |
| Gross margin by product group (K1.1) | Same missing cost of sales | Net price realisation by product group, with each group's share of net sales | Beds 84.33%, Defibrillators 84.17%, Defibrillator consumables 95.00%, ED stretchers 84.45%, Loading systems 82.91%, Stair chairs 83.10%, Manual stretchers 83.12%, Powered stretchers 82.95%, Parts and Service 100% (Jan to Sep 2026) | Same cost feed, mapped to the product group codes |
| Monthly reports that match the agreed set of numbers (K5) | No agreed set exists yet; the index records what owners say they use, not whether numbers agree (C3) | Reports on the draft agreed set (ship date and parent where known), shown with the count of different combinations in use | 3 of 30 reports (10%); 17 different combinations in use | Agreed definitions from Finance, then an automated number check against one governed sales table, run by the data engineer |
| Our price against the winning price on lost tenders (K4.1) | Winning price recorded on only 5 of 25 lost tenders (C8) | Price score gap on lost tenders (weighted points behind the preferred supplier, from the buyer's debrief scoring tables) | 11 of 20 lost tenders with a scoring table were behind on price; average gap -0.03 points of 30 (median +0.45); 3 big losses: +0.60, +1.20, -0.90 | Winning price captured at debrief, made a required field in the tender register or CRM, owned by the Bid manager |
Everything else in the Top 5 and the sub-KPIs can be built now (section 3), so no placeholder is proposed for them.
↑ Back to top1. What I propose
- Placeholder tile for each of the four KPIs above, named exactly as in the Business Requirements, with the text "Phase 2: waiting for data" and the owner's role. No status colour, no number in the headline slot.
- Substitute shown as a small, separate stand-in, titled with its own plain name, labelled "Sample data" and "Stand-in, not the KPI". It must never carry the real KPI's name, target, status colour or the sales leader's stated 41%.
- Honest limits up front. For Gross margin per cent (K1) and Gross margin by product group (K1.1) the substitute is a price-side signal only. For the other two it is a closer relative of the real KPI.
- Phase 2 gate. Each placeholder turns into the real KPI only when the data engineer's feed reconciles to the owner's figure (for K1, to finance's 41%).
2. The four KPIs, one by one
Gross margin per cent (K1)
- Why it can't be built now: no cost, COGS, margin or standard cost field in any of the 11 files. The stated 41% can't be reproduced.
- Substitute (plain name): Net price realisation.
- Calculation:
SUM(net_value_aud) / SUM(list_price * qty), shipped lines, by ship date, January to September. - Source fields:
sales_order_lines.net_value_aud,.list_price,.qty,.actual_ship_date. - Baseline (Sample data): 87.36% for January to September 2026 (net sales $149.36m). Same months of 2025: 87.67%. By full year: 2021 89.72%, 2022 89.28%, 2023 89.28%, 2024 87.61%, 2025 87.22%. Excluding warranty replacement lines (full list value, $1.39m in 2026 to date): 87.26% against 87.58%. Monthly 2026: Jan 89.70, Feb 85.52, Mar 87.37, Apr 85.62, May 86.14, Jun 87.37, Jul 89.35, Aug 86.02, Sep 86.89.
- Evidence label: Observed Fact for the calculation. Working Hypothesis that it moves with gross margin, because there is no cost data to test the link.
- What it tells Adam: how much of list price Kestrel keeps after discounting. The step down in 2024 (89.28% to 87.61%) lines up with the 3-point rise in tender discount in the Calculation Pack (challenge note C5). A fall in realisation will pull margin down unless cost falls too.
- What it doesn't tell Adam: gross margin. It ignores cost of sales entirely, so it can't say whether margin is 41%, 43% or anything else, and it can't be set against the 43% target or given a pace needed.
- How it could mislead: (1) List prices can rise or fall, so realisation can move with no change in margin. (2) Product mix: Service, Parts and consumables carry little or no discount, so a shift in mix moves the total (Service fell from 16.7% to 14.2% of net sales, which alone nudges realisation down) without any price decision. (3) Realisation can be flat while cost rises. (4) Reading a rise as a margin gain would be wrong.
- Recommendation: show it as a stand-in beside the placeholder. Never as a margin proxy with a target.
Gross margin by product group (K1.1)
- Why it can't be built now: same missing cost of sales.
- Substitute (plain name): Net price realisation by product group, with each group's share of net sales.
- Calculation: as above, grouped by
material_group. - Source fields: as above plus
sales_order_lines.material_group. - Baseline (Sample data, Jan to Sep 2026, change from the same months of 2025 in points, share of net sales in brackets): Beds 84.33% (-0.34, 21.8%); Defibrillators 84.17% (+0.12, 19.6%); Defibrillator consumables 95.00% (0.00, 8.7%); ED stretchers 84.45% (+0.30, 7.1%); Loading systems 82.91% (+0.06, 8.4%); Stair chairs 83.10% (-0.08, 2.8%); Manual stretchers 83.12% (-0.15, 3.8%); Powered stretchers 82.95% (+0.01, 9.1%); Parts 100.00% (0.00, 4.4%); Service 100.00% (0.00, 14.2%).
- Evidence label: Observed Fact for the calculation. Working Hypothesis that group margin follows group realisation.
- What it tells Adam: which groups carry deep discounts. The equipment groups all keep about 83% to 84% of list, so no single group stands out on price. Within-group realisation barely moved (all within 0.4 points), so the small fall in total realisation is mostly mix, not price.
- What it doesn't tell Adam: which groups make money. Service and Parts at 100% of list say nothing about their margin (service cost is labour, parts cost is purchase price), and equipment groups differ in cost.
- How it could mislead: the 100% for Service and Parts looks like "best" but is only "no discounting". Ranking groups by realisation would send attention to the wrong place.
- Recommendation: show as a stand-in table beside the placeholder, with the note on Service and Parts.
Monthly reports that match the agreed set of numbers (K5)
- Why it can't be built now: finance hasn't defined the agreed set, so "match" has no test. The index holds what each owner says the report uses, one snapshot, no history, so no run rate.
- Substitute (plain name): Reports on the draft agreed set, with the number of different combinations in use.
- Calculation:
COUNT(sales_definition = ship date AND customer_grouping = parent where known) / COUNT(reports), plusCOUNT(DISTINCT sales_definition, customer_grouping). The draft set is the rule used for Revenue growth on the year (K3), labelled "draft" on the tile. - Source fields:
monthly_reports_index.workbook,.sales_definition,.customer_grouping,.last_refreshed. - Baseline (Sample data, index at 30-Sep-26): 3 of 30 reports (10%): 08 Work orders by tech, 12 Tender pipeline, 25 Rep targets. 17 different combinations in use. 12 reports have n/a in at least one field. 14 of 30 use ship date at all. 22 of 30 refreshed in the last 30 days.
- Evidence label: Working Hypothesis (the agreed set is open, and the index is self-reported).
- What it tells Adam: how far the reports are from one rule, if the draft rule is chosen. It shows the scale of the clean-up: 17 combinations is nowhere near one agreed set.
- What it doesn't tell Adam: whether any report's numbers actually agree. A report can say "ship date" and still be wrong.
- How it could mislead: (1) If finance picks a different agreed set (for example invoice date), the 3 changes. Each alternative candidate gives 1 of 30. (2) n/a reports might not carry sales numbers at all, so 3 of 30 may understate the real position. (3) Retiring reports lifts the percentage without fixing anything. (4) Owners can relabel the index.
- Recommendation: show as a stand-in labelled "against a draft set". Don't set a target until finance defines the set.
Our price against the winning price on lost tenders (K4.1)
- Why it can't be built now: winning price is recorded on 5 of 25 lost tenders (20%), and 2 of the 3 big losses.
- Substitute (plain name): Price score gap on lost tenders.
- Calculation: for each lost tender with a scoring table,
(preferred supplier's price score - Kestrel's price score)in weighted points out of 30, across the three scoring layouts (same parser as the debrief KPI, Why we lost K4.2). Positive means Kestrel was behind on price. - Source fields:
tender_register.scoring_table,.outcome,.estimated_value,.contract_length. - Baseline (Sample data, whole register): 20 of 25 lost tenders have a scoring table. Kestrel was behind on price in 11 of 20 and level or ahead in 9. Behind by 1 point or more in 5. Average gap -0.03 points, median +0.45, range -2.4 to +2.1. Big losses: Southern Metro Health Network +0.60, Western Plains LHD +1.20, Highlands Ambulance -0.90. On the same lost tenders the average gap across the other five areas is +1.32 points.
- Cross-check against the real KPI: the 3 tenders that have both a winning price and a scoring table agree in direction (our price +1.9% and +2.1% above the winner with price score behind by 0.9 and 0.6; our price 1.5% below with the price score ahead by 0.9). Three points is too few to call it a validation.
- Evidence label: Strong Inference (scores come from the buyer's debrief, parsed from text; the cross-check has only 3 tenders).
- What it tells Adam: whether price was where we lost ground in the buyer's own scoring. It supports the Calculation Pack note that the three big losses were not mainly on price (challenge note C10).
- What it doesn't tell Adam: the dollar price gap. A score is the buyer's view of price, shaped by its scoring formula, not our price against the winner's price.
- How it could mislead: a small score gap can hide a large dollar gap, and the reverse. Five lost tenders have no table. Buyers differ in how they score price.
- Recommendation: use as the first-pass substitute. It is a stronger stand-in than the 5 known winning prices, which would show an average of +0.9% from a sample too small to trust.
3. Checked and buildable now (no placeholder proposed)
| KPI | Position |
|---|---|
| Average discount off list price on big deals (K2) | Built on a placeholder big-deal rule (tender contract lines). 17.03% baseline. Sharon's size rule is still open, but the KPI runs |
| Revenue growth on the year (K3), by product group (K3.1) and by rep (K3.2) | Built, Observed Fact. Reps aren't tied to accounts, noted in C11 |
| Big tender win rate (K4) | Built: 2 of 5 (40%), small numbers. Target still open (C2). Not a Phase 2 data gap |
| Why we lost (K4.2) and Who is winning the tenders we lose (K4.3) | Built. K4.2 uses parsed text (Strong Inference). Winner is named on all 25 lost tenders |
4. What Phase 2 needs
| KPI | Data to source | Likely system | Owner (role) | What the data engineer does |
|---|---|---|---|---|
| Gross margin per cent (K1) and by product group (K1.1) | Cost of sales per shipped order line (standard or actual), with the same order and line numbers as the sales data | SAP (product costing and billing documents; the sales order lines already come from SAP) | Finance lead (Tom Nguyen in the test case), with the Sales leader as the customer of the number | Locate the cost source with finance; extract cost per order line and join on order and line number; handle returns, rebates, freight and warranty lines; reconcile the total to finance's reported 41% before use; load to the same store as sales; add a daily refresh and a reconciliation check |
| Monthly reports that match the agreed set of numbers (K5) | One governed sales table (agreed sales date rule and customer grouping), plus each report's monthly net sales | The 30 Excel workbooks and the shared drive, with the governed table in the new data store | Finance lead sets the agreed definitions; Sales Operations owns the report list | Build the governed sales table to Finance's rules; add the customer parent mapping; for each report pull one month's net sales and compare to the governed table with a tolerance; record the result monthly so there is history and a run rate; replace the self-reported index |
| Our price against the winning price on lost tenders (K4.1) | Winning price (and our price) per lost tender from the debrief letters or buyer notice, as numbers with a clear unit (total contract value, not annual) | Tender register (bid manager's file), or the CRM if tenders move there | Bid manager (Deb Harlow in the test case) | Back-fill the 20 missing winning prices from debrief letters, starting with the big losses; add required numeric fields and a total-contract-value rule to the register or CRM form; clean customer name variants; add a completeness check to the data pipeline |
5. Assumptions and open points
- I assumed "build properly" means calculated from a source Adam can trace and defend, so a stated figure (finance's 41%) or a self-reported index doesn't qualify.
- I treated the real KPI's name, target and status colour as untouchable. A substitute only fills the space beside a placeholder.
- Gary needs to draft the Business Requirements change for Adam's yes (placeholder display rule, Phase 2 mark, the stand-in text). I haven't touched them.
- If Adam prefers no stand-in for Gross margin per cent (K1) and by product group (K1.1), because the price-side signal risks being read as margin, the alternative is the placeholder only. I lean to show it with the labels above: it gives the sales leader something real about discount pressure, and it is the part of margin the team can influence.
File: 2026.10.23 - Kestrel Medical - 02 Gary Phase 2 Changes.md
Kestrel Medical: Gary's Phase 2 Changes
Test case, Sample data. Proposals only, for Adam's yes. Nothing in the Business Requirements v1.0, the Project Plan or spec.json has been changed, and Sharon hasn't been contacted.
Adam asked for placeholders for the KPIs that can't be built in this first pass, marked for Phase 2, where Kewpie works with a data engineer to source the data. Four KPIs are affected: Gross margin per cent (K1), Gross margin by product group (K1.1), Monthly reports that match the agreed set of numbers (K5) and Our price against the winning price on lost tenders (K4.1). None is dropped or reprioritised: each keeps its name, target and owner, and gets a placeholder tile now and the real calculation in Phase 2. Each placeholder sits beside a small stand-in that Kewpie calculated. A stand-in is labelled "Stand-in, not the KPI" and never takes the KPI's name, target, status colour or finance's stated 41 per cent. This file merges four of my earlier 11 rows (rows 1, 4, 5 and 9 in "02 Gary Response to Challenge Notes"), so Adam reads one consistent set. My other seven earlier rows (2, 3, 6, 7, 8, 10, 11) stand as written.
1. Business Requirements: Before and After (proposed v1.1)
"(none)" in Before means a new item. Quotes in Before are from Business Requirements v1.0, word for word.
| # | Item | Before | After | ||||
|---|---|---|---|---|---|---|---|
| 1 | Document control, Version and Status | "1.0" / "Approved at the Stage 1 gate, 23-Oct-26" | "1.1" / "Draft v1.1 for Adam's yes: Phase 2 placeholders and Stage 2 challenge responses. v1.0 approved at the Stage 1 gate, 23-Oct-26" | ||||
| 2 | Section 5, new subsection "Phase for each KPI", introduction | (none) | "This first pass builds every Top 5 KPI and sub-KPI that the data supports today. Four can't be built yet because the data doesn't exist or isn't complete. They stay Must Have, keep their name, target and owner, and show as placeholder tiles until Phase 2, when Kewpie works with a data engineer to source the data. Every other KPI is marked 'First pass: built': Average discount off list price on big deals (K2), Revenue growth on the year (K3), Revenue growth by product group (K3.1), Revenue growth by rep (K3.2), Big tender win rate (K4), Why we lost, from the debriefs (K4.2) and Who is winning the tenders we lose (K4.3)" | ||||
| 3 | Phase for Gross margin per cent (K1) | (none) | "First pass: placeholder tile plus the stand-in Net price realisation. Phase 2: Kewpie with a data engineer sources cost of sales per shipped order line (standard or actual), with the same order and line numbers as the sales data. System: SAP (product costing and billing documents). Owner: finance report owner (Tom Nguyen), with the sales leader as the customer of the number. Data engineer: locates the cost source with finance; extracts cost per order line and joins on order and line number; handles returns, rebates, freight and warranty lines; loads it with the sales data; adds a daily refresh and a reconciliation check. Switch-on test: the calculated figure reconciles to finance's reported 41 per cent, within a tolerance finance sets" | ||||
| 4 | Phase for Gross margin by product group (K1.1) | (none) | "First pass: placeholder tile plus the stand-in Net price realisation by product group. Phase 2: the same cost of sales feed as Gross margin per cent (K1), mapped to the product group codes (material_group). System: SAP. Owner: finance report owner (Tom Nguyen); sales leader uses it. Switch-on test: switches on with Gross margin per cent (K1), and the groups add up to the total" | ||||
| 5 | Phase for Monthly reports that match the agreed set of numbers (K5) | (none) | "First pass: placeholder tile plus the stand-in Reports on the draft agreed set. Phase 2: Kewpie with a data engineer builds one governed sales table to finance's agreed sales date rule and customer grouping, then pulls each report's monthly net sales and checks it against that table. System: the 30 Excel workbooks on the shared drive, and the governed table in the new data store. Owner: finance report owner (Tom Nguyen) sets the agreed definitions and owns the report list. Data engineer: builds the governed table and customer parent mapping; runs the monthly number check with a tolerance; records each result so there is history and a run rate; replaces the self-reported index. Switch-on test: finance has agreed the definitions and the tolerance, and one full month's check has run" | ||||
| 6 | Phase for Our price against the winning price on lost tenders (K4.1) | (none) | "First pass: placeholder tile plus the stand-in Price score gap on lost tenders. Phase 2: Kewpie with a data engineer sources the winning price and our price for each lost tender, as numbers in total contract value (not annual amounts). System: the bid manager's tender register, or the CRM if tenders move there. Owner: bid manager (Deb Harlow). Data engineer: with the bid manager, back-fills the 20 missing winning prices from the debrief letters, big losses first (Western Plains first); makes winning price and our price required number fields with a total-contract-value rule; cleans customer name variants; adds a completeness check. Switch-on test: winning price recorded on all three big losses and on enough lost tenders for the count to be shown beside the result" | ||||
| 7 | Section 5, new subsection "Stand-ins for the first pass (not KPIs)", rule | (none) | "A stand-in is a small, separate panel beside a placeholder tile. It carries its own plain name and the labels 'Stand-in, not the KPI' and 'Sample data' (until real data is loaded). It never takes the KPI's name, target, thresholds, pace needed, status colour or finance's stated 41 per cent. It has no target and no status colour of its own. It is removed, or moved to a context note, when its KPI switches on in Phase 2" | ||||
| 8 | Stand-in for Gross margin per cent (K1) | (none) | "Name: Net price realisation. What it shows: how much of list price Kestrel keeps after discounting, on shipped lines: net value over list value. Baseline 87.36 per cent, January to September 2026, against 87.67 per cent in the same months of 2025 (Sample data). Evidence label: Observed Fact for the calculation; Working Hypothesis that it moves with gross margin, because there's no cost data to test the link. On the panel: 'Price side only. This is not gross margin and can't be compared with the 43 per cent target.' Never shows the KPI's name, target or status colour" | ||||
| 9 | Stand-in for Gross margin by product group (K1.1) | (none) | "Name: Net price realisation by product group, with each group's share of net sales. What it shows: which product groups carry the deepest discounts (equipment groups keep about 83 to 84 per cent of list; Sample data). Evidence label: Observed Fact for the calculation; Working Hypothesis that group margin follows group realisation. On the panel: 'Service and Parts show 100 per cent because they aren't discounted. That says nothing about their margin.' Groups not ranked as best or worst. Never shows the KPI's name, target or status colour" | ||||
| 10 | Stand-in for Monthly reports that match the agreed set of numbers (K5) | (none) | "Name: Reports on the draft agreed set, with the number of different combinations in use. What it shows: how many reports say they use the draft rule (ship date, customers grouped by parent where known): 3 of 30, with 17 different combinations in use (index at 30-Sep-26, Sample data). Evidence label: Working Hypothesis (the agreed set is open and the index is self-reported). On the panel: 'Against a draft set. Shows what reports say they use, not whether their numbers agree.' Never shows the KPI's name, target or status colour" | ||||
| 11 | Stand-in for Our price against the winning price on lost tenders (K4.1) (replaces my earlier row 9) | My earlier row 9 proposed the price score gap as a second source inside this sub-KPI. Its Before quoted a "filters and conditions" text that isn't in v1.0 | "Name: Price score gap on lost tenders. What it shows: for each lost tender with a buyer's scoring table, the preferred supplier's price score minus ours, in weighted points out of 30 (positive means we were behind on price). Behind on price in 11 of 20 scored losses; big losses: Southern Metropolitan Health Network +0.60, Western Plains Health District +1.20, Highlands Ambulance -0.90 (Sample data). Evidence label: Strong Inference (scores parsed from debrief text; only 3 tenders to cross-check against real prices). On the panel: 'Price score, not price. The buyer's view of price, not our price against the winner's.' Never shows the KPI's name, target or status colour" | ||||
| 12 | Section 5, new subsection "Placeholder tiles", display rule | (none) | "A placeholder tile uses the KPI's exact name from these Business Requirements, its owner's role, and the text 'Phase 2: waiting for data', with one line on what's missing (for example 'Waiting for cost of sales from finance'). The headline slot shows no number, no status colour, no sparkline, no gap and no pace needed. The target may be shown as text ('Target: 43 per cent for 2027') so the reader knows what's coming. A placeholder tile sits in the same place the real tile will take, so the layout doesn't change at switch-on" | ||||
| 13 | Gross margin per cent (K1), filters and conditions (replaces my earlier row 1) | "Shipped lines only; financial year January to December; must reconcile to finance's 41 per cent before use" | "Shipped lines only; financial year January to December; must reconcile to finance's 41 per cent before use. Phase 2 KPI: until the cost of sales feed reconciles, the tile is a placeholder showing 'Phase 2: waiting for data. Waiting for cost of sales from finance'. Finance's stated 41 per cent may appear only as a text note on the placeholder, 'Finance's stated figure, not calculated', Working Hypothesis, with no status colour, never in the headline slot and never on the stand-in" | ||||
| 14 | Gross margin per cent (K1), data source and fields | "SAP sales orders: sales_order_lines.net_value_aud, sales_order_lines.actual_ship_date. Cost of sales: no field in the Sample data; finance to name the SAP source" | "SAP sales orders: sales_order_lines.net_value_aud, sales_order_lines.actual_ship_date. Cost of sales: no field in the Sample data. Phase 2: cost of sales per shipped order line from SAP product costing and billing documents, joined on order and line number, sourced by the data engineer with the finance report owner" | ||||
| 15 | Gross margin by product group (K1.1), data | "sales_order_lines.material_group, .net_value_aud, cost of sales (open)" | "sales_order_lines.material_group, .net_value_aud, cost of sales (Phase 2: same feed as Gross margin per cent (K1))" | ||||
| 16 | Monthly reports that match the agreed set of numbers (K5), how measured (replaces my earlier row 4) | "Reports using the agreed sales definition and customer grouping, over all reports" | "Phase 2 KPI. Reports that carry a sales number and whose net sales for the month check against the governed sales table (within a tolerance finance sets), divided by all reports that carry a sales number. Run automatically each month by the data engineer's check, reviewed by the finance report owner. Reports that carry no sales number are listed but not counted. First pass: placeholder tile, with the stand-in Reports on the draft agreed set" | ||||
| 17 | Monthly reports that match the agreed set of numbers (K5), data source and fields (replaces my earlier row 5) | "Monthly reports index: monthly_reports_index.workbook, .owner, .sales_definition, .customer_grouping, .last_refreshed" | "Phase 2: the monthly check results (report, month, report net sales, governed net sales, pass or fail), built by the data engineer from the 30 workbooks and the governed sales table. First pass stand-in only: monthly reports index: monthly_reports_index.workbook, .owner, .sales_definition, .customer_grouping, .last_refreshed" | ||||
| 18 | Monthly reports that match the agreed set of numbers (K5), filters and conditions | "Agreed definition set by finance (open); reports marked "n/a" reviewed one by one" | "Agreed definition and match tolerance set by finance (open); reports marked "n/a" reviewed one by one to see whether they carry a sales number" | ||||
| 19 | Monthly reports that match the agreed set of numbers (K5), target (Top 5) | "Open question, needed before Kewpie finishes Stage 2 (Adam, 23-Oct-26): Sharon wants one agreed set of numbers with Tom checking the reports against it, and has not agreed a target" | "Open question, needed before the Phase 2 switch-on: Sharon wants one agreed set of numbers with Tom checking the reports against it, and has not agreed a target. Set by the finance report owner with the sales leader, once the agreed definitions exist" | ||||
| 20 | Our price against the winning price on lost tenders (K4.1), how measured (merges my earlier row 9) | "our_submitted_price / winning_price - 1, lost tenders. Gary's proposed thresholds: Green within 2%; Amber 2% to 5% above; Red more than 5% above" | "Phase 2 KPI. our_submitted_price / winning_price - 1, lost tenders, values as total contract value (annual amounts multiplied by the contract length). Gary's proposed thresholds, applied from Phase 2 only: Green within 2%; Amber 2% to 5% above; Red more than 5% above. Show the count of tenders with a known winning price beside the result. First pass: placeholder tile, with the stand-in Price score gap on lost tenders" | ||||
| 21 | Our price against the winning price on lost tenders (K4.1), data | "tender_register.our_submitted_price, .winning_price, .outcome" | "tender_register.our_submitted_price, .winning_price, .outcome, .contract_length. Phase 2: winning price back-filled from the debrief letters and made a required number field" | ||||
| 22 | Section 5, new subsection "How validation treats Phase 2 KPIs" | (none) | "For Jennifer's validation checklist in this first pass: (1) a Phase 2 KPI counts as 'on the dashboard, calculated as documented' when its placeholder tile and stand-in are shown exactly as these Business Requirements document them, and is recorded as 'Phase 2 placeholder, as documented', not a fail; (2) for Lift gross margin (O1), progress shows Average discount off list price on big deals (K2) with actual, target, gap and pace, and the margin target as text with 'Phase 2: waiting for data'; for One agreed set of numbers (O4), progress shows 'Phase 2: waiting for data'; neither is a fail; (3) each Phase 2 owner can see 'Phase 2: waiting for data' at a glance, which counts as their status. It is a fail if a placeholder shows a number, a status colour, a sparkline or a pace needed, or if a stand-in takes the KPI's name, target, status colour or the stated 41 per cent. Kewpie's Stage 2 check, 'documented calculation that runs on the data', is met for these four by a documented calculation plus a named Phase 2 data source. Gary's proposal; the process file itself is unchanged, which is Adam's call" | ||||
| 23 | Section 7, Data inventory, SAP ERP, quality notes | "Monthly reports come from ERP extracts. Cost of sales field not yet named" | "Monthly reports come from ERP extracts. Cost of sales field not yet named. Phase 2: data engineer to source cost per order line from SAP product costing with the finance report owner" | ||||
| 24 | Section 7, Data inventory, Tender spreadsheet, quality notes | "Debrief letters held by Deb Harlow. Values and dates stored as text" | "Debrief letters held by Deb Harlow. Values and dates stored as text. Winning price recorded on 5 of 25 lost tenders. Phase 2: back-fill from debrief letters and make it a required number field" | ||||
| 25 | Section 9, Assumptions, new row | (none) | "The four stand-ins point the same way as the KPIs they sit beside, but can't be used to judge them against target. Working Hypothesis" | ||||
| 26 | Section 10, Open questions, cost of sales | "Where does cost of sales come from for gross margin, and how does finance get to 41 per cent? \ | Finance report owner (Tom Nguyen)" | "Where does cost of sales come from for gross margin, how does finance get to 41 per cent, and what tolerance counts as reconciled? Needed to start Phase 2 \ | Finance report owner (Tom Nguyen)" | ||
| 27 | Section 10, Open questions, new | (none) | "Who is the data engineer for Phase 2, and when can they start? \ | Adam" | |||
| 28 | Section 10, Open questions, new | (none) | "Can you back-fill winning prices from the debrief letters, starting with Western Plains, and should they move into the CRM or stay in the tender file? \ | Bid manager (Deb Harlow)" | |||
| 29 | Section 11, Change log, new row | (none) | "1.1 \ | [date of Adam's yes] \ | Four KPIs marked Phase 2 with placeholder tiles and labelled stand-ins: Gross margin per cent (K1), Gross margin by product group (K1.1), Monthly reports that match the agreed set of numbers (K5), Our price against the winning price on lost tenders (K4.1). Placeholder display rule and validation rule added. Stage 2 challenge responses applied \ | Data for these four can't be sourced in the first pass (Kewpie's Stage 2 findings); Adam asked for placeholders, 23-Oct-26 \ | Adam" |
How my earlier 11 rows fit:
| Earlier row | What happens |
|---|---|
| 1, Gross margin per cent (K1) tile rule | Replaced by rows 12 and 13 here. Change: the stated 41 per cent moves out of the headline into a text note, so it can't be read as calculated |
| 4, Monthly reports (K5) how measured | Replaced by row 16. Same measure, now marked Phase 2 and run by the data engineer's check |
| 5, Monthly reports (K5) data source | Replaced by row 17. The index becomes the first-pass stand-in only |
| 9, Our price against the winning price (K4.1) interim source | Replaced by rows 11, 20 and 21. The price score gap becomes a separate stand-in, not a second source inside the KPI |
| 2, 3, 6, 7, 8, 10, 11 | Stand as written. One correction when I apply them: their Before text paraphrases v1.0 rather than quoting it word for word. I'll quote v1.0 exactly in the final v1.1 |
2. Project Plan: Before and After
| # | Item | Before | After | |||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Header note | "Built from Business Requirements v1.0 (23-Oct-26). Dates and effort are Gary's proposals." | "Built from Business Requirements v1.1 (draft). Dates and effort are Gary's proposals. The first pass covers phases 1 to 5; Phase 2, Source missing data, follows it" | |||||||||||||||||||||||||||||||||
| 2 | Goal and scope, In scope | "the Top 5 measures and their six sub-KPIs in Business Requirements v1.0" | "the Top 5 measures and their six sub-KPIs in Business Requirements v1.1. First pass: built where the data supports it, placeholder tiles with labelled stand-ins for Gross margin per cent, Gross margin by product group, Monthly reports that match the agreed set of numbers, and Our price against the winning price on lost tenders. Phase 2: source the missing data and switch those four on" | |||||||||||||||||||||||||||||||||
| 3 | Phases and sprints, new row after "5. Embed" | (none) | "Phase 2: Source missing data \ | 8-Feb-27 to 19-Mar-27 (3 sprints) \ | Cost of sales feed reconciled; governed sales table and monthly report check; winning prices back-filled and required; four placeholder tiles switched to real KPIs and revalidated \ | Kewpie with a data engineer; finance report owner; bid manager" | ||||||||||||||||||||||||||||||
| 4 | Phases and sprints, note | "The data adds a sprint to Build KPIs: cost of sales isn't named yet, the reports disagree, and the tender file stores values as text." | "The data adds a sprint to Build KPIs: cost of sales isn't named yet, the reports disagree, and the tender file stores values as text. Four KPIs can't be sourced in the first pass and move to Phase 2. The finance report owner and bid manager can start their parts (naming the cost source, agreeing definitions, back-filling winning prices) during the first pass, so Phase 2 starts ready" | |||||||||||||||||||||||||||||||||
| 5 | New section "Phase 2 tasks" | (none) | Table: Task \ | Owner (role) \ | Person-days \ | Depends on. (a) Name the cost of sales source and the reconciliation tolerance \ | Finance report owner \ | 1 \ | Data engineer named. (b) Extract cost per shipped order line from SAP and join to sales, with returns, rebates, freight and warranty handled \ | Data engineer, with Kewpie \ | 6 \ | (a). (c) Reconcile to finance's 41 per cent and switch on Gross margin per cent and Gross margin by product group \ | Kewpie, with finance report owner \ | 3 \ | (b). (d) Agree the sales date rule, customer grouping and match tolerance \ | Finance report owner, with sales leader \ | 1 \ | none. (e) Build the governed sales table and customer parent mapping \ | Data engineer \ | 5 \ | (d). (f) Automated monthly check of each report against the governed table, with history; switch on Monthly reports that match the agreed set of numbers \ | Data engineer, with Kewpie \ | 3 \ | (e); target set. (g) Back-fill winning prices from debrief letters, big losses first \ | Bid manager \ | 2 \ | none. (h) Make winning price and our price required number fields, total contract value rule, completeness check; switch on Our price against the winning price on lost tenders \ | Data engineer, with bid manager and Kewpie \ | 2 \ | (g). (i) Rerun validation on the four switched-on tiles; remove or move the stand-ins \ | Jennifer \ | 2 \ | (c), (f), (h). (j) Phase 2 walk-through with the sales leader \ | Adam \ | 1 \ | (i) |
| 6 | MoSCoW, Must | "Gross margin per cent; Average discount off list price on big deals; Revenue growth on the year; Big tender win rate; Monthly reports that match the agreed set of numbers" | "Gross margin per cent (placeholder in the first pass, Phase 2); Average discount off list price on big deals; Revenue growth on the year; Big tender win rate; Monthly reports that match the agreed set of numbers (placeholder in the first pass, Phase 2)" | |||||||||||||||||||||||||||||||||
| 7 | MoSCoW, Should | "Gross margin by product group; Revenue growth by product group; Revenue growth by rep; Our price against the winning price on lost tenders; Why we lost, from the debriefs; Who is winning the tenders we lose" | "Gross margin by product group (placeholder in the first pass, Phase 2); Revenue growth by product group; Revenue growth by rep; Our price against the winning price on lost tenders (placeholder in the first pass, Phase 2); Why we lost, from the debriefs; Who is winning the tenders we lose" | |||||||||||||||||||||||||||||||||
| 8 | Effort estimate, new row and total | "Total \ | 24" | "Phase 2: Source missing data \ | 26 \ | A data engineer is named and starts 8-Feb-27; finance names the cost source and agrees definitions before then; the bid manager back-fills during the first pass. Total \ | 50 (first pass 24, Phase 2 26)" | |||||||||||||||||||||||||||||
| 9 | RAID log, R1 | "Cost of sales isn't named, so gross margin per cent can't be calculated \ | H \ | Finance report owner \ | Name the SAP field and reconcile to 41 per cent \ | Open" | "Cost of sales isn't named, so gross margin per cent can't be calculated \ | H \ | Finance report owner \ | Placeholder tile and stand-in in the first pass; name the SAP source before Phase 2 starts; reconcile to 41 per cent in Phase 2 \ | Open, mitigated for the first pass" | |||||||||||||||||||||||||
| 10 | RAID log, new risk R4 | (none) | "R4 \ | Risk \ | Phase 2 data doesn't reconcile: the cost feed doesn't reach finance's 41 per cent, report numbers don't check against the governed table, or back-filled winning prices are too few \ | H \ | Finance report owner (margin, reports); bid manager (winning prices) \ | Agree each tolerance before the data engineer starts; a tile switches on only when it passes its reconciliation; if it fails, the placeholder stays, the gap is written up, and Adam decides whether to accept, extend Phase 2 or go back to the sales leader \ | Open" | |||||||||||||||||||||||||||
| 11 | RAID log, new risk R5 | (none) | "R5 \ | Risk \ | A stand-in is read as the real KPI, for example price realisation read as margin in the pack for global \ | M \ | Sales leader \ | Stand-in labels fixed by the Business Requirements; Jennifer's validation fails any stand-in that takes a KPI's name, target or status colour; Adam explains it at the walk-through \ | Open" | |||||||||||||||||||||||||||
| 12 | RAID log, new dependency D4 | (none) | "D4 \ | Dependency \ | A data engineer is named and booked for Phase 2 \ | H \ | Adam \ | Name before Stage 4 is approved \ | Open" | |||||||||||||||||||||||||||
| 13 | Milestones and approval gates, new rows after "Walk-through, sign-off and go-live date set" | (none) | "Phase 2 data sources named (cost of sales, agreed definitions, back-fill under way) \ | Ovy check \ | 5-Feb-27" and "Phase 2 KPIs switched on and revalidated \ | Phase 2 gate (Adam) \ | 19-Mar-27" and "Phase 2 walk-through \ | Sales leader and Adam \ | 26-Mar-27" | |||||||||||||||||||||||||||
| 14 | Review rhythm after go-live, Quarterly | "Quarterly: finance report owner checks the monthly reports against the agreed set of numbers" | "Monthly, from Phase 2: the data engineer's automated check runs each report against the governed sales table; the finance report owner reviews the failures. Until then, quarterly: the finance report owner checks the monthly reports against the agreed set of numbers" |
3. Decisions for Adam
- Yes to the Business Requirements rows (1 to 29) and Project Plan rows (1 to 14) above, so I can write v1.1 and update
spec.json? - Kewpie's option: show the margin stand-in (Net price realisation) or the placeholder only. I lean to showing it with the labels in row 8, because it's the part of margin the sales team can move. If the pack for global is the main use, the risk in R5 is real, so it's your call.
File: 2026.10.23 - Kestrel Medical - 02 Gary Response to Challenge Notes.md
Kestrel Medical: Gary's Response to Kewpie's Challenge Notes
Test case, Sample data. Gary's recommendations for Adam's SME sign-off on the 11 challenge notes in Calculation Pack v1.0. Nothing has been changed yet, and Sharon hasn't been contacted. Every Before and After below is a proposal, applied to Business Requirements v1.1 and spec.json only once Adam says yes.
Recommendation on approving Stage 2
Approve Stage 2 with conditions. Gross margin per cent (K1) and Gross margin by product group (K1.1) are documented but can't be run. The targets for Big tender win rate (K4) and Monthly reports that match the agreed set of numbers (K5) are still open. None of these stops Viktor building the story and the tiles. They do stop Jennifer's validation ("calculated as documented") and go-live. So:
- Close all three before Stage 4 is approved, not before Stage 3 starts
- Until then, the Gross margin per cent (K1) tile shows "Waiting for cost of sales from finance". The stated 41 per cent appears as a Working Hypothesis, with no status colour and never as a calculated number
One line per note
| Note | Recommendation | Gary's reason |
|---|---|---|
| Missing cost of sales (C1), Gross margin per cent (K1) and Gross margin by product group (K1.1) | Open question, plus a Business Requirements change to the display rule (row 1 below) | Margin is global's headline. We can't invent a cost source. Tom Nguyen names it |
| Win-rate target (C2), Big tender win rate (K4) | Business Requirements change: measure it as a count over the last 5 big tenders, not a yearly percentage (rows 2 and 3). The number stays with Deb Harlow | At about 2 big tenders a year, a yearly rate can only read 0, 50 or 100 per cent, which is noise. Sharon asked that Deb set the target, so I give Deb the form and a starting proposal, not a decision |
| Can the reports measure work as specified (C3), Monthly reports that match the agreed set of numbers (K5) | Business Requirements change: no, not as specified. Change it to Tom's check of each report's numbers against the agreed set (rows 4 and 5). Target stays open | The index records what each report says it uses, not whether its numbers agree. Sharon's own words were "one agreed set of numbers, with Tom checking the reports against it". The After matches that |
| Big-deal filter (C4), Average discount off list price on big deals (K2) | Accept Kewpie's correction (tender contract orders as the placeholder). Sharon's size rule stays an open question | The contract_id placeholder picked up service contracts. My draft was wrong |
| Discount target (C5), Average discount off list price on big deals (K2) | Business Requirements change to the target and thresholds (rows 6 and 7), for Sharon to confirm at the next contact | Holding 17 per cent is green by definition and does nothing for a 2-point margin rise. The tender discount jumped 3 points in 2024. Pulling back towards the 2023 level is the action Sharon described ("tighten pricing on big deals") |
| Base for 4 per cent growth (C6), Revenue growth on the year (K3) | Business Requirements change to the rationale (row 8). The base stays an open question for Sharon and Tom | Sharon said "don't take my word on the base". Until Tom confirms, I measure against 2026 actuals and show what that means in dollars: still about 3 per cent below 2025 |
| Annual amounts in tender values (C7), Big tender win rate (K4) and Our price against the winning price on lost tenders (K4.1) | Accept Kewpie's correction | Values marked "pa" are annual amounts. Multiplying by the contract length is right |
| Missing winning prices (C8), Our price against the winning price on lost tenders (K4.1) | Open question for Deb Harlow (winning prices from the debrief letters, Western Plains first), plus a Business Requirements change for the interim second source (row 9) | Winning prices are recorded for only 5 of 25 lost tenders. The price score from the buyer's scoring is a fair stand-in, if it's labelled |
| Scoring layouts (C9), Why we lost, from the debriefs (K4.2) | Accept Kewpie's correction | Comparing weighted points out of 100 is the only fair way to compare three different layouts |
| Evidence on "lost on price" (C10) | No change to the KPI list or the Problem Statement. One Business Requirements change to the backlog reason (row 10), and a new open question for Sharon | See the C10 note below |
| Rep credit (C11), Revenue growth by rep (K3.2) | Accept. Remove my parent-grouping filter (row 11). Ask Sharon how reps should be credited | Sharon asked "which reps are growing". The rep on the order line answers that. Account ownership is a different question |
C10: the data doesn't support "lost on price"
- What it shows (Strong Inference, Sample data, 3 tenders): service and support was the biggest scoring gap on all three big losses. On Highlands Ambulance we were 1.5 per cent cheaper than the winner. Across 20 scored losses, price was the biggest gap in only 3
- Does it change the requirements? No. Sharon's confirmed words were that she wants "the evidence to prove or disprove it". The Problem Statement and the tender measures were built to answer exactly that, and they have. Changing the statement now would put words in her mouth
- What it does change:
- Viktor's story should lead with it, because it's the answer Sharon asked for, even though it isn't the answer she expected
- It backs the tighter discount target proposed for C5. More discount room may cost margin and still not win the tender
- The Project Plan risk "The evidence may show losses weren't mainly price" (R2) has now happened. Sharon needs to hear it from Adam at the walk-through, not find it on a tile
- New open question for Sharon: "The debriefs point to service and support. Do you want a service measure under Big tender win rate (K4) in the next release?" I wouldn't add one without her. She raised no service objective, and that's her call to make
Before and After (proposed Business Requirements v1.1)
| # | Item | Before | After |
|---|---|---|---|
| 1 | Gross margin per cent (K1), filters and conditions | "Shipped lines only; financial year January to December; must reconcile to finance's 41 per cent before use" | "Shipped lines only; financial year January to December; must reconcile to finance's 41 per cent before use. Until finance supplies cost of sales, the tile shows 'Waiting for cost of sales from finance' and the stated 41 per cent as a Working Hypothesis, with no status colour" |
| 2 | Big tender win rate (K4), how measured | "Tenders won divided by tenders decided (won plus lost), over five million dollars, rolling" | "Tenders won out of the last 5 decided tenders with a contract value of $5m or more (rolling five-tender window), shown as a count (for example '2 of 5'), with the calendar-year count alongside" |
| 3 | Big tender win rate (K4), target | "To be set by the bid manager (Q-1)" | "To be set by the bid manager as a count out of the last 5 big tenders (Q-1). Gary's starting proposal for Deb: at least 3 of the last 5 by Dec-27, which means winning the next 2 big tenders. Working Hypothesis. Thresholds follow the count Deb sets" |
| 4 | Monthly reports that match the agreed set of numbers (K5), how measured | "Reports that use the agreed sales definition and customer grouping, divided by all monthly reports" | "Reports that carry a sales number and whose net sales for the month check against the agreed set of numbers (within a tolerance finance sets), divided by all reports that carry a sales number. Checked by the finance report owner each month. Reports that carry no sales number are listed but not counted" |
| 5 | Monthly reports that match the agreed set of numbers (K5), data source and fields | "monthly_reports_index.workbook, .owner, .sales_definition, .customer_grouping, .last_refreshed" | "The finance report owner's monthly check log (to be set up: report, month, report net sales, agreed net sales, pass or fail). Until it exists, monthly_reports_index.sales_definition and .customer_grouping are used as a labelled proxy (currently 3 of 30 on one candidate set)" |
| 6 | Average discount off list price on big deals (K2), target | "At or below the 2026 big-deal average (Kewpie to set the baseline). Working Hypothesis" | "Back down from 17.0 per cent towards the 2023 level of about 14 per cent on tender contract orders by Dec-27. Gary's proposal, for Sharon to confirm. Working Hypothesis. Read with Big tender win rate (K4) as the counter-metric" |
| 7 | Average discount off list price on big deals (K2), thresholds | "Green at or below the 2026 average; Amber up to 1 percentage point above; Red more than 1 percentage point above" | "Green at or below a straight-line path from 17.0 per cent (Sep-26) to 14 per cent (Dec-27); Amber up to 1 point above the path; Red more than 1 point above. Gary's proposal" |
| 8 | Revenue growth on the year (K3), target rationale | "Global's target for 2027. Base (2026 actuals?) to confirm (Q-2)" | "Global's target for 2027, measured against 2026 full-year actuals on ship date until finance confirms the base (Q-2). Note: 2026 is tracking -6.8 per cent, so 4 per cent on 2026 still leaves 2027 about 3 per cent below 2025" |
| 9 | Our price against the winning price on lost tenders (K4.1), filters and conditions | "Lost tenders with a known winning price; text values like $2.12m converted to dollars; same tender size filter as K4, with all sizes shown for context" | "Lost tenders with a known winning price; values converted to contract totals. Where the winning price is missing, show the price score gap from the buyer's scoring, labelled 'price score, not price'. Same tender size filter as Big tender win rate (K4), with all sizes shown for context" |
| 10 | Backlog: Service and field measures, reason | "Systems named, but no objective or action raised in the interview" | "Systems named, but no objective or action raised in the interview. The debrief analysis shows service and support was the biggest scoring gap on all three big losses: ask Sharon whether to add a service measure under Big tender win rate (K4) in the next release" |
| 11 | Revenue growth by rep (K3.2), filters and conditions | "As K3. Customer grouping by parent where known (customers.parent_id), to match the agreed definition" | "As Revenue growth on the year (K3). Rep credited from the order line (rep_id). How reps should be credited for account ownership is an open question for Sharon" |
New or updated open questions
- For the bid manager (Deb Harlow): What count out of the last 5 big tenders is a realistic target? Can you add winning prices from the debrief letters, starting with Western Plains?
- For finance (Tom Nguyen): Where does cost of sales come from? What is the agreed sales definition and customer grouping? Which reports carry a sales number? What tolerance counts as a match?
- For Sharon: Is the tighter discount target right (back towards about 14 per cent)? Is the 4 per cent on 2026 actuals? How should reps be credited? Do you want a service measure, given what the debriefs show?
File: dataset_description.md
Dataset description (Sample data)
Sample data for Kestrel Medical, copied unchanged from the test bank. Data to 2026-09-30. Not real company data.
| File | Rows | Used for |
|---|---|---|
| sales_order_lines.csv | 120,391 | K2, K3, K3.1, K3.2 (one line per order; order dates Jan-2018 to Sep-2026) |
| tender_register.csv | 64 | K4, K4.1, K4.2, K4.3 (values and dates stored as text) |
| monthly_reports_index.csv | 30 | K5 (note: 'n/a' is a real value, not missing) |
| customers.csv, sales_order_change_log.csv | not used for the Top 5 | context |
| crm_opportunities.csv | backlog | not trusted for win-loss |
| work_orders, asset_register, site_customer_map, service_contracts, parts_inventory_daily | backlog | no objective in this release |
No file has a cost of sales field. Re-run: python calc_kpis.py then python build_pack.py (needs pandas).