# Independent questionnaire contract: breakfast grains tracker Version 1.0. Fictional research universe: adults aged 18+ who buy or jointly buy household groceries and bought breakfast cereal, porridge oats or another grain breakfast product in the past four weeks. Bread is outside this category. One interview describes one household buyer, not every household member. Approximate intended length 10–12 minutes; untested estimate. Question IDs are data identities. Numbered requirements below define the measurement and routes. Respondent answers must not be inferred from display order. The script implementations must satisfy the requirements independently. | No. | Measurement / QSS ID | ODIN | Response contract | |---|---|---:|---| | 1 | Participation `s_consent` | 5 | Yes=1/No=2; No ends before screening | | 2 | Age `s_age` | 10 | Whole years 0–120; below 18 ends immediately, 121 blocks as invalid | | 3 | Grocery role `s_grocery_role` | 20 | Sole=1/shared=2/little or none=3; shared does not require equal responsibility | | 4 | Four-week category purchase `s_category_purchase` | 30 | Yes=1/No=2; role 3 or purchase 2 ends after the screening group | | 5 | First unaided brand `q_unaided_brand` | 40 | Open recall; None recalled is acceptable; do not auto-code to aided brands | | 6 | Additional unaided brands `q_unaided_other` | 41 | Optional open recall, captured separately | | 7 | Aided awareness `q_aided_awareness` | 50 | Multi; stable codes 1–6, Other=98 with text, exclusive None=99 | | 8 | Four-week brand purchase `q_purchase_p4w` | 60 | Multi; only named aware brands plus Other/None fallback | | 9 | Most often purchased `q_most_often` | 70 | Single from brands selected as purchased; exclude None | | 10 | Purchased-brand satisfaction `q_rep_satisfaction` | 71 | Repeat named purchased brands only; 1 Very dissatisfied…5 Very satisfied; Cannot judge=9 | | 11 | Four-week repurchase likelihood `q_rep_repurchase` | 72 | Same repeat; 1 Definitely will not…5 Definitely will | | 12 | Brand value rating `q_rep_value` | 73 | Same repeat; 1 Very poor…5 Excellent plus Cannot judge=9; separate construct from satisfaction | | 13 | Next-purchase consideration `q_consideration` | 80 | Multi; only named aware brands plus Other/None fallback; ask aware nonusers too | | 14 | Category consumption frequency `q_frequency` | 140 | Ordered six frequency bands plus Never personally eat=7; eligible buyers may buy only for others | | 15 | Consumption occasions `q_occasions` | 150 | Multi weekday breakfast/weekend/snack/evening/cooking; exclusive None=99 | | 16 | Used retail channels `q_channels` | 160 | Multi supermarket/discount/local/online/specialist; Other=98 with text | | 17 | Primary channel `q_primary_channel` | 170 | Single restricted to channels selected at 16, including Other only when selected | | 18 | Category purchase barriers `q_barriers` | 180 | Multi sugar/processing/price/alternative breakfast/satiety; exclusive no barrier=99 | | 19 | Taste importance `q_rate_taste` | 190 | 1 Not at all important…5 Extremely important; Cannot judge=9 | | 20 | Whole grain content importance `q_rate_health` | 191 | Same importance scale plus Cannot judge=9; does not assert health benefit | | 21 | Satiety importance `q_rate_satiety` | 192 | Same importance scale plus Cannot judge=9 | | 22 | Price importance `q_rate_value` | 193 | Same importance scale plus Cannot judge=9 | | 23 | Preferred pack format `q_pack_format` | 200 | Single carton/pouch/bulk/sachet/Other=98 with text | | 24 | Interest in grain alternatives `q_innovation_interest` | 210 | 1 Not at all interested…5 Extremely interested; named ingredient examples are context | | 25 | Household size `d_household_size` | 220 | Integer 1–15; reject 0/16, do not save rejected response | | 26 | Children in household `d_children` | 230 | Yes=1/No=2; no children's personal details | | 27 | Broad settlement type `d_settlement` | 240 | Five general settlement categories, no actual geographic IDs | | 28 | Household income band `d_income` | 250 | Four £ bands; Prefer not to say=99; optional disclosure through refusal code | Named brands are Reedmere=1, Alderfen=2, Sunwick=3, Mornvale=4, Grainridge=5 and Highfield=6. All are invented for this fixture. Aided named-brand presentation varies per case, with Other and None at the end. Persist offered order as provenance. Do not assume the two engines use identical random algorithms or seeds. Repeat evaluation uses code order, not the awareness display order. Retail channels keep their declared order; the primary-channel subset retains that order. Behavioral contracts: 1. No consent collects no age or main-study data. Age 17 is a valid answer with an ineligible outcome; 121 is an invalid answer with no state commit. Nonbuyers end without brand questions. 2. Awareness None bypasses all brand stages and repeats. Purchase None bypasses most-often and repetitions but still asks consideration. Awareness and purchase are separate measures; buying the category does not imply buying a listed brand. 3. With awareness {1,3}, purchase and consideration offer {1,3,98,99}. With purchase {1,3}, most-often offers {1,3}; exactly two brand occurrences collect satisfaction, repurchase and value, with the displayed stable brand identity retained. Their independently supplied ratings differ by brand and remain distinct after native replay. Other has open text but does not enter named-brand evaluation or named-brand base sizes. 4. At every multi item, a mixed exclusive/ordinary response is rejected atomically. Other text is retained. Primary channel choices carry membership from used channels, rather than relying on an instruction alone. 5. Buyers for others remain eligible without reporting personal consumption. Never personally eat and Cannot judge are explicit responses; they are not recoded as low ratings. 6. Completion occurs only after the remaining category and demographic questions. Local completion is not proof of uploaded or stored collection. Engine-specific display continuations/Exit are presentation steps, not additional measurements. `fixtures.json` predeclares eight independent scenarios and expected collected-question sequences: two-brand buyer, unaware buyer, aware nonuser, Other channel, refusal, underage, nonbuyer and buyer for others. Both engines execute these scenarios, with invalid age and mixed-exclusive proposals, carried-domain checks, repeated identity, provenance and replay checks. The fixtures contain no real respondent data. QSS uses `domain.select(answers.question.ids())` to carry brand and channel membership, adding explicit Other/None fallbacks where specified. Selected named-brand repetitions exclude codes 98 and 99. The source routes guard missing predecessor answers before any selector runs. Answered scalar selectors use their payload; unavailable selectors refuse explicitly instead of silently producing an empty domain. Direct physical Answer-to-options coercion is not assumed. ODIN uses CONTROL filters, independent text piping and repeat context. Both preserve repeat answers in runtime context; fixed-width legacy U-file repeat export and real legacy DLL acceptance are not qualified here. Text lengths differ between QSS and legacy alpha fields; the fixture asserts supplied short verbatims, not unbounded text equivalence. Before actual research: cognitive-test category meaning, recall periods, None behavior and price/health wording; include ineligible adults in screener tests. Then time a small browser/mobile pilot, review unprompted confusion and revise the frozen contract before publishing another immutable version. These examples remain human-review and marketing candidates.