File: 2026.10.23 - Kestrel Medical - 04 Stakeholder Brief Coverage Check.md
Kestrel Medical: Stakeholder Brief Coverage Check
Test case, Sample data. In test mode the "brief" is Sharon's own words in the Meeting Script (01 Meeting Script.md), never the Stakeholder Brief file. Checked against04 Dashboard.html(Jennifer's finished first draft, rebuilt from Experimental A on 24-Oct-26 at Adam's choice) and Business Requirements v1.2. Ovy proposes next steps only: nothing here has been changed.
Author: Ovy. Date: 23-Oct-26, refreshed 24-Oct-26. Result: 12 Addressed, 8 Partly, 2 Not addressed (22 items).
Refresh, 24-Oct-26: all 22 items re-checked against the Experimental A build. Every result is unchanged: the numbers, story, tiles and actions are the same. The only change is where items 2, 3 and 7 are answered: the ranked bar of biggest gaps is now one circle of all 25 lost tenders, coloured by biggest scoring gap, with the 3 big losses ringed. The 5 tenders with no scoring table now show in grey instead of being left out.
On Adam's instruction (23-Oct-26), every open question belongs to Phase 2, a separate project after Stage 5. Where a gap is an open question, the proposed next step says so.
1. Item by item
| # | Sharon's words (Meeting Script) | Result | Where the output answers it |
|---|---|---|---|
| 1 | Problem as stated: "we've lost three of the last five big tenders" | ✓ Addressed | Headline: "Kestrel lost 3 of its last 5 big tenders"; Big tender win rate tile "2 of 5" |
| 2 | "my reps keep telling me we're being undercut on price everywhere, 10 and 15 per cent off" | ! Partly | Why section circle: price was the biggest gap on only 3 of 20 scored losses (3 orange dots of 25); Highlands Ambulance price gap −0.90 (Kestrel cheaper). No view tests the reps' "10 and 15 per cent" claim directly, because winning prices exist on only 5 of 25 lost tenders |
| 3 | "What I need is a proper win-loss view" | ✓ Addressed | Big tender win rate tile, the last 5 tenders by close date, calendar-year counts, and "Big tender win rate: the last 5 tenders and the size line" in Detail |
| 4 | "something that shows our pricing against the competition" | ! Partly | "Our price against the winning price on lost tenders" is a Phase 2 placeholder; stand-in "price score gap" in Detail. Dollar price against competitors is not shown |
| 5 | "go to global with evidence and argue for more discount room" | ✓ Addressed | Headline and Why section give the evidence; it points away from more discount ("service and support, not price"). Real problem as understood: the evidence to prove or disprove price |
| 6 | "get me out of Excel. I've got thirty monthly reports and half of them say different things" | ! Partly | Monthly reports tile is a Phase 2 placeholder; stand-in "Reports on the draft agreed set: 3 of 30, 17 different combinations in use". The dashboard itself is one set of numbers, but the reports are not yet replaced or checked |
| 7 | "If we don't understand why we're losing, we'll keep discounting blind" | ✓ Addressed | Why section: "Service and support was the biggest gap on all 3 big losses; price was never the biggest" |
| 8 | Tender detail: Southern Metropolitan (price), Highlands ("about the stretcher as much as anything"), Western Plains (distributor that bundles) | ✓ Addressed | The three big losses shown side by side with their scoring gaps and winners; "one a distributor that bundles brands" |
| 9 | Margin: "43 per cent gross margin in 2027" | ! Partly | Gross margin per cent tile is a Phase 2 placeholder ("Target: 43% for 2027", "Needs cost of sales (finance)"); stand-in Net price realisation 87.36%, labelled "not gross margin" |
| 10 | "4 per cent revenue growth" | ✓ Addressed | Revenue growth on the year tile: −6.8%, target +4% in 2027, needs +0.72 pts a month, Off track |
| 11 | Success: "we stop losing tenders" | ✓ Addressed | Win rate tile and the first of the top 3 actions (bid manager reviews the debriefs, the sales leader sets the response) |
| 12 | Success: "I stop spending three days a month reconciling spreadsheets" | × Not addressed | No measure of reconciliation time; the Monthly reports measure is a Phase 2 placeholder |
| 13 | "Deb Harlow would know what a realistic win rate looks like" (no target from Sharon) | ✓ Addressed | Win rate tile: "Target set in Phase 2", "Not rated: target open", no status colour; Gary's starting proposal marked "Proposed" |
| 14 | Decisions: "pricing calls on big deals within my authority", "where the reps focus", "headcount asks", "how we respond to tenders" | ! Partly | Pricing, rep focus and tender response are the top 3 actions. Headcount asks to global are not shown on the page |
| 15 | "I want to know where the margin is leaking, especially on the big deals" | ! Partly | Average discount off list price on big deals (17.03% and its trend; target set in Phase 2 since Business Requirements v1.3) shows the price side of leakage; margin by product group is a Phase 2 placeholder |
| 16 | "which reps and which product groups are growing and which are going backwards" | ✓ Addressed | Detail: "Revenue growth on the year, by month, product group and rep" (10 groups, 14 reps); "Only Beds is growing (+2.6%)" |
| 17 | "which ones we're losing, who's winning them, and on what price" | ! Partly | Which and who: "The 3 big losses went to 3 different winners". On what price: Phase 2 placeholder, as item 4 |
| 18 | Format: "a pack for global matters most", "pull it up in a meeting with the reps", "I wouldn't be looking at it on my phone" | ! Partly (see note) | Screen version checked at 14 widths with no sideways scroll. Jennifer flagged that the dark default would print dark: there is no print-ready pack for global yet |
| 19 | Rhythm: "the dashboard would follow that rhythm" (monthly) | ✓ Addressed | Business Requirements v1.2 review rhythm monthly; dashboard shows "Data to 30-Sep-26" |
| 20 | "global's dashboards don't understand our market ... has to speak to how our business actually works" | ✓ Addressed | Built around Kestrel's tenders, debrief scoring areas, product groups and competitors by name |
| 21 | "I also want the reports automated and consistent" | × Not addressed | The dashboard is built from re-runnable scripts on Sample data; no automated refresh from SAP or the tender register exists yet |
| 22 | Playback correction: "I believe it's price ... What I want is the evidence to prove or disprove it" | ✓ Addressed | Headline answers it directly, labelled Strong Inference (debrief scores, Sample data) |
Note on item 18: counted as Partly, because the main use is the pack, and the pack is not built.
↑ Back to top2. Proposed next steps (propose only, not made)
| # | Gap | Proposed next step | Owner (stage) | When |
|---|---|---|---|---|
| 2, 4, 17 | Price against competitors in dollars | Back-fill winning prices from the debrief letters; switch on "Our price against the winning price on lost tenders" | Bid manager with Kewpie and the data engineer | Phase 2 project |
| 6, 12 | Thirty reports still disagree; reconciling time not measured | Agree the sales definitions; build the governed sales table and the monthly report check. Ask Sharon at the walk-through whether to log reconciliation days as a sub-KPI | Finance report owner, Kewpie, data engineer; Gary for any new KPI | Phase 2 project; the question at Stage 5 |
| 9, 15 | Margin can't be calculated | Source cost of sales per order line and reconcile to finance's 41%; switch on Gross margin per cent and Gross margin by product group | Finance report owner, Kewpie, data engineer | Phase 2 project |
| 14 | Headcount asks not shown | Ask Sharon at the walk-through whether headcount needs a view, or stays a decision she takes from the revenue growth view | Gary (with SME sign-off) | Stage 5 walk-through |
| 18 | No print-ready pack for global | Add a print-always-light version or a PDF pack in the format global expects (format is an open question) | Jennifer, after Sharon confirms the format | Stage 5 decision; build in Phase 2 if global's format is needed |
| 21 | Not automated | Automate the refresh from SAP and the tender register | Data engineer with Kewpie | Phase 2 project |
| All | Gary's proposals not yet confirmed (discount path to 14%, 3 of the last 5) | Asked at the walk-through: Sharon left the discount target open (removed from the dashboard in Business Requirements v1.3, 24-Oct-26) and kept 3 of the last 5 as a proposal for Deb | Gary (with SME sign-off) | Done, 24-Oct-26 |
File: 2026.10.23 - Kestrel Medical - 04 Standards and Validation.md
Kestrel Medical: Standards and Validation (Stage 4)
Re-run 24-Oct-26 for Business Requirements v1.3 (Adam approved Sharon's change): Average discount off list price on big deals shows 17.03%, its trend, "Target set in Phase 2" and a neutral "Not rated: target open". No target, path to 14%, gap, pace or status colour. Jennifer's fixes were re-applied to Viktor's rebuilt page; three of her exact text replacements were adjusted to Viktor's new wording (item 1 below), with the same shortening.
Test case, Sample data. This report now covers Experimental A (the dot swarm circle of lost tenders), chosen by Adam on 24-Oct-26. It replaces the Standard version's report. Built by Jennifer (Stage 4) from Viktor's Experimental A dashboard, Business Requirements v1.3, Calculation Pack v1.2 and the saved Monochrome blue and Charcoal and teal palettes. No story line, KPI, number or chart was changed.
Date: 24-Oct-26 (re-run) · Output: 02 - Deliverables/2026.10.23 - Kestrel Medical - 04 Dashboard.html · Re-run: 03 - Working Files/jennifer_finish.py (fixes), jennifer_checks.py (widths, errors), jennifer_screenshots.py (screenshots)
1. Verdict
- Both standards: all clear-cut items fixed, and Adam's 4 items approved on 24-Oct-26 and applied (section 5). Still failing: 9 long caption and definition lines (not in the main flow), and core content drawn by script (accepted)
- Validation checklist: 5 of 5 pass, with the four Phase 2 KPIs recorded as "Phase 2 placeholder, as documented"
- Width sweep: 56 checks (14 widths from 375 to 1600, dark and light, sections closed and open): 0 sideways scrolling, 0 elements poking out, 0 controls under 44px, 0 script errors
- Nothing published
2. Palette
- Monochrome blue throughout (default). Accent, surfaces, lines and the growing and going backwards bars are the saved values, dark and light
- Charcoal and teal on the six scoring areas (3 or more categories), in fixed slots: service and support teal, price coral, then clinical fit, supply reliability, training, sustainability. Same colour on every chart they appear in, including the circle of 25 lost tenders (legend underneath names each colour with its count)
- Status colours (green, amber, red) only on the one rated tile (Revenue growth on the year, Off track), always with an icon and a word
- Checked in both modes: lowest text contrast 5.07 to 1 dark, 4.80 to 1 light (target 4.5 to 1)
3. What Jennifer fixed (clear-cut, all in jennifer_finish.py)
| # | Fix | Why (standard) |
|---|---|---|
| 1 | Phones: tiles now sit one per row. Before, the number and sparkline on tiles 2, 3 and 4 ran past the tile edge and were clipped at 375px | UX 1 and 2: fits without clipping on phones |
| 2 | Value labels on long bars (for example +4.35) stay inside their card; the three boxes in the reports detail wrap instead of overflowing at tablet width (768px, 40px over) | Web 3: no horizontal overflow |
| 3 | Smallest text raised from 9.6px to 11.2px (tags, owner lines, axis labels, table headings) | UX 3: readability |
| 4 | Light mode: "service and support" in the headline was 3.0 to 1; now 4.5 or better | Web 2: text contrast 4.5 to 1 |
| 5 | Page follows the system light or dark setting until the reader picks one (their pick is remembered) | UX 4: follow prefers-color-scheme |
| 6 | The five big tender dots in the What changed chart can be focused with the keyboard but had no name; each now reads "Won or Lost, customer, closed date" | Web 2: screen readers |
| 7 | "Skip to main content" link; "On this page" jump links in the header (wide screens); "Back to top" at the bottom of each section (desktop) | UX 3 and Web 1 |
| 8 | noindex added (customer names and tender values must not reach Google) | Web 6 |
| 9 | First screen kept inside 800px at 1280 to 1600 wide: tiles end at 785 to 791px (they would have run to 805 to 811px after fix 3) | 30-second test |
| 10 | Circle (new): each of the 25 dots now has a name for screen readers, for example "Lost tender, Highlands Ambulance, closed 19/09/2025, $11.80m, biggest gap: Service and support, one of the 3 big losses" | Web 2: names for focusable items |
| 11 | Circle (new): the numbers 1 to 3 on the ringed dots were white (about 2.9 to 1 on teal). They now sit on a small disc in the page colour with text at 14.6 to 1 dark, 17.5 to 1 light | Web 2: text contrast 4.5 to 1 |
| 12 | Circle (new): dots were drawn at 90% and 45% strength, so light-mode teal was 2.85 to 1 and the grey "no scoring table" dots 1.8 to 1 against the card. Now full strength: lowest dot is 3.2 to 1 light, 3.6 to 1 dark (3 to 1 needed for a graphic). The legend swatches match. Colours, counts and sizes are unchanged | UX 4 / Web 2: graphics visible in both modes |
| 13 | Stage label "Stage 4 · Finished first draft · Experimental A" and footer credit; Business Requirements v1.3 and Calculation Pack v1.2 in the header and footer | Change control |
4. Standards results
UX Standards Reference (and the UXPin principles)
| Area | Check | Result | Evidence |
|---|---|---|---|
| Layout | No sideways scroll, 375 upright, 568 × 320 and 740 × 360 sideways, 768, 1100+ | Pass | Width sweep, 0 of 56 |
| Layout | Layout changes live across 900px and 640px without reload | Pass | Charts redraw on resize; sweep loads each width fresh |
| Layout | Phone bottom tab bar, tablet and desktop top tabs | Not applicable | One scrolling page with no tabs. Sharon: "Not phone" (a screen and a pack) |
| Layout | Tables become cards on phones | Pass | The few tables are "See data" tables, fixed layout, wrap at 375px |
| Layout | Safe areas | Pass | Side padding uses env(safe-area-inset) |
| Touch | Controls under 44px on phones | Pass | 0 buttons, links or summaries under 44px at every width |
| Touch | Inputs 16px | Not applicable | No text inputs |
| Readability | Headings front-loaded, sections by use | Pass | What changed, Why, What to do, Detail. Answer first, working behind "See data" and collapsed sections |
| Readability | Bullets within the word limit | Pass for the main flow; 9 lines over 30 words in captions and definitions remain | The three in the main flow were shortened (item 1, approved and applied). The rest are captions and definitions Adam did not ask to change |
| Readability | One term per idea | Pass, one note | Headings say "Discount on big deals"; the tile uses the full name "Average discount off list price on big deals" |
| Visual | Dark and light | Pass | Both screenshotted and measured |
| Visual | Reduced motion | Pass | Charts and count-up numbers switch off |
| Visual | Colour never the only signal | Pass | Status chips have icon and word; won or lost tenders are filled or hollow; bars carry signed values; area colours have a legend, labels and counts; the circle legend gives each area's name and count, big losses are ringed and numbered, and the See data table lists every tender |
| Visual | Secondary links low weight, buttons not underlined | Pass | Jump and Back to top links grey and thin; buttons plain |
| Trust | Shared output shows only what the audience needs | Pass | No weights or internal codes; plain names; Sample data label on the page |
| Trust | No silent failures | Pass | Storage wrapped in try/catch; no script errors |
| UXPin | Consistency, scannability, visual grammar, hierarchy, plain language, familiar patterns | Pass | Same tile, bar and table forms throughout |
| UXPin | Progressive disclosure, whitespace | Pass | Detail sections open by default at 1100px and wider, closed on phones (item 2, approved and applied) |
| UXPin | User control | Pass | Colour mode toggle works; replay removed, so nothing is mouse only except the hover detail, which the See data tables repeat |
| UXPin | User at the centre, define the problem first, iterate on evidence | Not tested | Build process, not page |
| UXPin | Accessibility (#10) | Covered below | Web Build Standards |
Web Build Standards
| Section | Check | Result | Evidence |
|---|---|---|---|
| HTML | doctype, lang="en-AU", charset, viewport, 4-word title | Pass | "Kestrel Medical Tender Dashboard" |
| HTML | One h1, headings in order, unique ids, semantic elements, details and summary | Pass | h1 then h2, h3, h4, no skipped levels. 0 duplicate ids. WHATWG §4.3 and §4.11.1 |
| HTML | No clickable divs | Pass | Click-to-replay removed (item 3, approved and applied). Charts still play once on first view |
| Accessibility | Contrast 4.5 to 1, both modes | Pass | 5.07 dark, 4.80 light, after fix 4 |
| Accessibility | Keyboard: focus ring, everything reachable | Pass | Focus ring on every control; skip link added. Chart rows, bars and the 25 circle dots are no longer tab stops (item 4, approved and applied): 5 KPI tile stops remain, plus the real controls. Not walked through by hand: structure and CSS checked |
| Accessibility | Names for focusable items, charts with text summary | Pass | 0 unnamed focusable items (the 25 circle dots checked in the Browser pane); each chart has a summary and a "See data" table |
| Accessibility | Reduced motion, 200% zoom | Pass | 200% on 1280 is 640px: no overflow |
| CSS | Colour tokens with dark mode, relative units | Pass | :root tokens, JS swaps the set per mode |
| JavaScript | 0 console errors on load, in both modes, all widths | Pass | 0 in the Browser pane and in headless Chrome |
| JavaScript | Storage in try/catch, no popups, pinned libraries | Pass | No libraries; only Google Fonts (see note) |
| JavaScript | Core content shows if script fails | Fail, accepted | Tiles and charts are drawn by script. Same as every Kestrel build; a pack for global would be printed from a working browser. Not proposed for change |
| Performance | Page weight, fonts | Note | 73 KB page. Six font files from Google Fonts (Lexend 300, 400, 500, 600; IBM Plex Mono 400, 500). Core Web Vitals: not measured |
| Security | No keys or tokens, no personal data in URLs, noindex, no external links | Pass | No links out; no secrets. Customer names are in the page: see the privacy open question in the Business Requirements (section 10) |
| Security | HTTPS | Not applicable | Not published |
| PWA | Manifest and service worker | Not applicable | None |
| Release | 7-step list | Steps 1 to 6 done; step 7 respected | Nothing published |
5. Before/After items: all four approved by Adam, 24-Oct-26, and applied (jennifer_finish.py)
| # | Where | Before | After | Why (standard) | Status |
|---|---|---|---|---|---|
| 1 | Three long lines in the main flow (these are Viktor's words, so I'd like your yes) | a. "The axis starts at 12% so the step can be read. No target in the first pass: it is set in Phase 2. Big deal means tender contract orders until the sales leader sets a size rule. Click the chart to replay." (v1.3 wording, 38 words) b. "Average discount off list price on tender contract orders, by year of order (2026 is Jan to Sep). Below: the last 5 tenders of $5m or more, by close date." (v1.3 wording, 31) c. First action note: "2 of the last 5 now. Gary's starting proposal, 3 of the last 5 by Dec-27, means winning the next 2 big tenders (Working Hypothesis). A service measure is a Phase 2 question for the sales leader." (37) | a. "The axis starts at 12% so the step can be read. No target yet: it is set in Phase 2. Big deal means tender contract orders for now." b. "Discount on tender contract orders by order year (2026 is Jan to Sep). Below: the last 5 tenders of $5m or more." c. "2 of the last 5 now. A target of 3 of 5 by Dec-27 means winning the next 2 (Working Hypothesis)." The service measure question stays in the open questions for Phase 2 | UX 3: about 20 words per line, 30 at most | Approved by Adam, 24-Oct-26, applied |
| 2 | Detail section, desktop | All five sections closed; reader taps each | Open by default at 1100px and wider, closed on phones. The page gets longer on a big screen | UX 3: on desktop, keep everything open with jump links (jump links are done). Viktor closed them to keep the walk-through short, so it is your call | Approved by Adam, 24-Oct-26, applied |
| 3 | "What changed" and the other charts | Clicking a chart replays its animation. Mouse only, and the caption says "Click the chart to replay" | Remove the click and the caption; charts still animate once on first view | Web 1 and 2: no clickable divs; keyboard users cannot replay. A "Replay" button is the alternative, but it adds 8 buttons | Approved by Adam, 24-Oct-26, applied |
| 4 | Chart rows and circle dots (about 115 tab stops) | Every bar, row and circle dot can be tabbed to, to show its hover detail (the dots are named, so a screen reader reads each one) | Rows and dots stop being tab stops; the "See data" tables carry the same figures for keyboard and screen reader users | Web 2: keyboard pass in reasonable steps. The detail on hover then stays mouse only | Approved by Adam, 24-Oct-26, applied |
Also for Adam (no change proposed): in the circle, dot size shows contract value only roughly (Viktor's caption says so; the See data table has the exact values). Six area colours on small dots need the legend, so the legend sits directly underneath and carries names and counts. Hovering or focusing a dot also names its area. Also: the pack for global is the main use, and the page is dark by default when a reader has no system setting. Printing a dark page uses a lot of ink. I'd suggest a print version that is always light, but that is a new feature, so I've left it for Stage 5.
↑ Back to top6. Validation checklist
| # | Check | Result | Evidence |
|---|---|---|---|
| 1 | Every Must Have KPI is on the dashboard, calculated as documented | Pass | Built (7): Average discount off list price on big deals 17.03%; Revenue growth on the year -6.8%; Big tender win rate 2 of 5; Revenue growth by product group and by rep (detail); Why we lost, from the debriefs (the three big losses by scoring area, and the circle of all 25 lost tenders by biggest gap); Who is winning the tenders we lose. Numbers match the Calculation Pack: discount 17.03% with trend flat (no pace, as no target), growth -6.8% with +0.72 needed and +0.27 trend, 5 tenders, Net price realisation 87.36%, reports 3 of 30 with 17 combinations. Phase 2 placeholder, as documented (4): Gross margin per cent, Gross margin by product group, Monthly reports that match the agreed set of numbers, Our price against the winning price on lost tenders. Each placeholder shows its exact name, owner, "Phase 2: waiting for data", and no number, status colour, sparkline, gap or pace. Each stand-in carries "Stand-in, not the KPI" and "Sample data", and never takes the KPI's name, target or status colour. The stated 41% appears only as a note on the margin placeholder, not on the stand-in |
| 2 | Every business objective shows its progress (actual, target, gap, pace needed) | Pass | Lift gross margin: discount tile shows actual 17.03% and its trend (flat, 0.00 points a month) with "Target set in Phase 2": no target number, gap, pace, path or status colour (Phase 2, as documented, per v1.3); the 43% margin target shows as text with "Phase 2: waiting for data" (as documented). Grow revenue: -6.8% against +4%, gap -10.8 points, needs +0.72 a month. Stop losing the big tenders: 2 of 5 with "Target set in Phase 2", no colour, gap or pace (Phase 2, as documented). One agreed set of numbers: "Phase 2: waiting for data" (Phase 2, as documented) |
| 3 | Every action owner can see their KPI's status at a glance | Pass | Sales leader: Not rated Phase 2 (margin), Not rated: target open (discount, neutral grey chip and icon, no green, amber or red; no dashed target line on its sparkline; no "On track" or "Amber from" wording anywhere on the page: checked in the finished page), Off track (revenue). Bid manager: Not rated, target open. Finance report owner: Not rated Phase 2. Owner named on every tile. A KPI with an open target shows no status colour: checked |
| 4 | The 30-second test passes | Pass | At 1280 to 1600 wide, the headline (3 of 5 lost, service and support, not price), the three actions with owners and dates, and all five tiles with status end at 785 to 791px, inside an 800px screen. On a phone the same order scrolls: headline, actions, tiles |
| 5 | The Business Requirements version in the footer matches the latest | Pass | Header and footer say Business Requirements v1.3 and Calculation Pack v1.2; the files are v1.3 and v1.2 |
7. Screenshots (in 02 - Deliverables/)
2026.10.23 - Kestrel Medical - 04 Screenshot Desktop dark.pngand... Desktop light.png(1440 wide, full page, Detail sections open as they now are by default)2026.10.23 - Kestrel Medical - 04 Screenshot Phone dark.pngand... Phone light.png(375 wide, full page; the page sits in a 500px frame because headless Chrome will not go narrower)- Screenshots are taken with motion off so every chart and number is in its finished state
8. How the checks were run
- Browser pane (Edge-based): at 375 confirmed the circle fits (310px wide, legend ends at 335px of 375, no sideways scroll, 25 of 25 dots named); opened the page at 375 and 1280, measured contrast in both modes, focusable items, names, ids, console (no errors), touch targets and sideways scroll, and looked at the phone layout
- Headless Chrome:
jennifer_checks.pyfor the 14-width sweep in both modes with sections closed and open;jennifer_screenshots.pyfor the four screenshots - Not done: a hand keyboard walk-through, Core Web Vitals, the slowest action in seconds. They are marked "Not tested" above, not guessed