# Consultation AI suggestion — logic spec **Version 1.1.0.** Generated from `rules-source.json`. Do not edit this file by hand — change the JSON and re-run `node build-docs.js`. The prototype (`hairstylist-form-full-prototype.html`) carries the same version stamp. If the two disagree, run `node verify-sync.js` — it fails loudly rather than letting them drift. --- ## 1. Questions to add Impact = how often the suggestion changes when that question is varied, measured across 669 real men's consultations. | Question | Section | Required | Impact | Maps to | |---|---|---|---|---| | **Length Wanted On Top** | Hair & Scalp Assessment | yes | 100% | `hairLength` | | **Thickness Of Remaining Hair** | Hair & Scalp Assessment | yes | 76% | `q4` | | **Does The Client Wear The Front Pushed Back?** | Hair & Scalp Assessment | yes | 66% | `q2` | | **Hair At The Sides And Back** | Hair & Scalp Assessment | optional | 39% | `sideStyle` | | **Coverage Area — Palm Test** | Measurements | optional | — | `areaSize` | ### Length Wanted On Top Over 6 inches is a custom order; below about 1.5 inches the base shows. Without it every consultation silently assumes 3-6 inches. `Short — 1.5–2″` · `3″–6″ (standard)` · `Longer than 6″` · `Very long — 12″+` Maps to engine input `hairLength` as `[0,1,2,3]`. ### Thickness Of Remaining Hair Volume, not haircut. Baldness level says how much is gone; this says what the system blends into. `Still thick and full` · `Average` · `Fine, or thinning too` Maps to engine input `q4` as `[0,1,2]`. ### Does The Client Wear The Front Pushed Back? Decides whether a base with a visible front edge is viable. Often the difference between three months of wear and one. `Pushed back, forehead exposed` · `Sometimes` · `Falls forward` · `Not settled yet` Maps to engine input `q2` as `[0,1,2,3]`. ### Hair At The Sides And Back Under 1 inch there is nothing for clips to grip, and a thick poly edge would show. Geeta's rule, Aug 2026. `Shaved, faded or under 1″` · `1″ or more` Maps to engine input `sideStyle` as `[0,1]`. ### Coverage Area — Palm Test *(online only)* Online consultants cannot measure — 49% of online consultations have no measurement at all. This substitutes for it. `Palm alone covers it` · `Whole hand, fingers spread` · `Spreads past the hand` · `Well past — most of the top` Maps to engine input `areaSize` as `["small","standard","large","large"]`. ## 2. Rules Every rule the suggestion applies, and where it came from. ### R-SWEAT — Sweaty scalp excludes skin bases **Source:** Team ruling - **When:** sweats_from_scalp_often = 1 OR scalp_condition includes 'sweaty' - **Then:** Remove every SKIN-family product from the suggestion. If all picks were skin, substitute the hybrid fallback set. 47% of men's consultations record sweating. Skin traps heat and the bond fails early. ### R-BASE — A known base type constrains the family **Source:** Mehmet, Sept 2026 - **When:** base_type answered and not 'not sure' - **Then:** Suggest only within that family. Clients arriving from another company often already know what worked. 'not sure' is the most common answer and is ignored. ### R-CONFLICT — Sweat beats stated preference **Source:** Derived from R-SWEAT + R-BASE - **When:** base_type = 'poly/skin' AND client sweats - **Then:** R-SWEAT wins — suggest lace or hybrid, and say why in the basis line. Honouring the request would sell a bond that fails. Change this only if the team decides otherwise. ### R-EXPERIENCE — Experience tier gates the delicate bases **Source:** Quiz engine (Cindy, Geeta) - **When:** has_worn_hair_system_before = 1 - **Then:** previous_hair_system_experience = 'By Myself' -> tier 2 (experienced, unlocks delicate). Anything else -> tier 1 (still gated). BUG FIXED Sept 2026: every returning client was previously mapped to tier 1 and never saw the delicate tier. Changes the answer in 47% of cases. ### R-SIZE — Order of trust for sizing **Source:** Engine - **When:** always - **Then:** Measured base width+length > palm test > inferred from baldness level. So the palm test only applies when no measurement was taken — which is the online case. ### R-INCOMPLETE — Refuse to guess on a thin form **Source:** Design decision - **When:** any of: priority, density, hairpiece_type, baldness_level, hair_texture, top_length, remaining_thickness missing - **Then:** Show no suggestion. Name the missing fields instead. Half of men's consultations are missing a core field. A confident suggestion on a half-filled form is worse than none. ### R-THREE — Always suggest three, never one **Source:** Measured - **When:** always - **Then:** Return up to 3 ranked products. Never a single confident pick. Consultants agree with each other only ~20% of the time on identical client profiles. Cross-validated ceiling is 19% top-1, 36% top-3. ### R-LOG — Log every acceptance and override **Source:** Design decision - **When:** stylist adds a suggestion, removes one, searches the catalogue, rates the suggestions up or down, or saves - **Then:** POST the entry. Actions: accepted, unaccepted, picked_manually, searched_manually, opened_catalogue, rated (up/down with optional reason chip and comment), saved (with suggested vs chosen and what was overridden). A thumbs-up is recorded too — agreement is signal the override log alone cannot show. The disagreement between suggestion and final choice is the most valuable output of this feature. ## 3. Channel behaviour Driven by the `location` already chosen on the welcome screen. ### Online (`location = Online`) - **Hide:** base_measure_width, base_measure_length - **Show:** area_size - **Require:** photos Base measurement fill is 49% online vs 80% in store — consultants are being asked for something they cannot take. ### In store (`location = any branch address`) - **Hide:** area_size - **Show:** base_measure_width, base_measure_length - **Require:** base_measure_width, base_measure_length, baldness_level, hairstylist_internal_note In store fills measurement and baldness level well. The internal note is filled 35% in store vs 76% online — that knowledge is being lost. ## 4. Fields already collected and used | Field | Fill | Used as | |---|---|---| | `hairpiece_type` | 100% | q8 (coverage route) | | `baldness_level` | 67% | areaSize fallback | | `density` | 95% | qDensity | | `hair_texture` | 95% | texture | | `scalp_condition` | 85% | q3 (heat) + sweat rule | | `sweats_from_scalp_often` | 94% | hard rule: no skin bases | | `priority` | 80% | q1 — highest weighted input (x3) | | `preferred_maintenance_location` | 95% | q6 | | `has_worn_hair_system_before` | 99% | q5 with previous_hair_system_experience | | `previous_hair_system_experience` | 30% | q5 tier — 'By Myself' unlocks delicate bases | | `base_measure_width` | 69% | areaSize (preferred over palm test) | | `base_measure_length` | 69% | areaSize | | `base_type` | 3.2% | hard constraint on base family when answered | ## 5. Fields collected and thrown away These are already in your database. Wiring them up costs nothing. | Field | Fill | Opportunity | |---|---|---| | `company_and_product_from_previous_hair_system` | 25% | What a switching client wore before — the strongest signal available for competitor switchers. | | `wants_similar_product_to_worn_before` | 23% | A direct statement of intent the suggestion never sees. | | `hairstylist_internal_note` | 50% | The stylist's actual reasoning, in their own words. | | `wants_patch_test` | 16% | Implies suspected adhesive sensitivity. | ## 6. Integration **Module:** `shp-suggest-core.js` — same engine as the customer quiz. **Adapter:** SHP_FIELDS at the top of the module — one line per field, mapping form values to the engine. **API:** - `shpSuggest(formValues) -> { ok, picks[3] | custom, missing[], why }` - `shpRenderBlock(mountEl, formValues, onAdd) — renders the panel` - `shpLogFinalChoice(formValues, chosenSkus) -> log entry to POST` - `shpSetGallery(fn) — optional, supply full product image sets by SKU` Same engine as the customer quiz, so the portal and the storefront cannot contradict each other. ## 7. Known gaps - Colour and stock: the suggestion can recommend a product unavailable in the client's shade. Needs an inventory feed, not a question. - Custom orders: the tool says THAT something is custom, not what to build. No workshop rules are encoded. - Women's: the matrix is men's only. ~15% of consultations are not. - Baldness level is a TWO-STEP picker: 3 groups (Advanced/Noticeable/Early Thinning) opening 7 Norwood levels (assets 1- to 7-.png). The artwork currently served is the WOMEN'S set; the men's files should replace it at the same paths.