{
 "slug": "pos-service-buttons",
 "collected_utc": "2026-09-04T04:15Z",
 "surface_driven": [
  "unauthenticated GET https://jlk5auefmk.execute-api.us-east-1.amazonaws.com/dev/restaurants/<RID>/menu",
  "real chromium browser (390x844, hasTouch) against https://dcgmji73h6qel.cloudfront.net/menu?id=<RID>&table=<T>&layout=mosaic_v2"
 ],
 "menu_json_pos_experience": {
  "pos-gate 02d14028-2788-5e77-98e5-5cbd14880566": {
   "http": 200,
   "restaurant.pos_experience": {
    "service_buttons_hidden": true,
    "order_status_hidden": true,
    "dish_ratings_hidden": true,
    "auto_close_on_payment": true
   },
   "categories": 0,
   "items": 0
  },
  "pos-push baa315c1-2fa6-570c-bfc2-efb14cecf121": {
   "http": 200,
   "restaurant.pos_experience": {
    "service_buttons_hidden": false,
    "order_status_hidden": false,
    "dish_ratings_hidden": false,
    "auto_close_on_payment": false
   },
   "categories": 5,
   "items": 14
  },
  "canary-mosaic 28ae37ab-706c-4e20-83d7-52f5d2dff747": {
   "http": 200,
   "restaurant.pos_experience": {
    "service_buttons_hidden": false,
    "order_status_hidden": false,
    "dish_ratings_hidden": false,
    "auto_close_on_payment": false
   },
   "categories": 5,
   "items": 15
  }
 },
 "browser_observations": {
  "POS-GATE 02d14028 (service_buttons_hidden=true)": {
   "table": 9991,
   "rendered": "layout-empty-state \u2014 heading 'Canary Mosaic V2 POS Gate \u2014 dev', body 'The menu is being prepared. Please check back in a moment or ask your server.'",
   "all_data_testids_on_screen": [
    "layout-empty-state",
    "m2-layout",
    "table-session-active"
   ],
   "layout-service-button count": 0,
   "service_drawer": "absent",
   "browser_saw_menu_payload_pos_experience": {
    "service_buttons_hidden": true,
    "order_status_hidden": true,
    "dish_ratings_hidden": true,
    "auto_close_on_payment": true
   },
   "screenshots": [
    "/workspace/uat/lane-pos/shots/psb-POS-GATE-02d14028.png",
    "/workspace/uat/lane-pos/shots/svc-POS-GATE-02d14028-nobutton.png"
   ],
   "CONFOUND": "this fixture has 0 menu items, so the whole menu chrome (dock, m2-* tiles, subcat nav) is absent too. The absence of the service button here is NOT attributable to the pos_experience gate \u2014 nothing renders at all."
  },
  "POS-PUSH baa315c1 (service_buttons_hidden=false)": {
   "table": 9992,
   "layout-service-button count": 1,
   "initial_state": {
    "opacity": "0",
    "pointerEvents": "none",
    "w": 17,
    "h": 17,
    "x": 330,
    "y": 794
   },
   "after_scroll_600px": {
    "opacity": "1",
    "pointerEvents": "auto",
    "w": 48,
    "h": 48,
    "x": 208,
    "y": 782,
    "aria-label": "Call staff or request the check"
   },
   "drawer_after_click_testids": [
    "service-bubble",
    "service-bubble-attend_table",
    "service-bubble-cutlery",
    "service-bubble-ready_for_bill"
   ],
   "screenshots": [
    "/workspace/uat/lane-pos/shots/psb-POS-PUSH-baa315c1.png",
    "/workspace/uat/lane-pos/shots/svc-POS-PUSH-baa315c1-drawer.png"
   ]
  },
  "CONTROL 28ae37ab (service_buttons_hidden=false)": {
   "table": 9993,
   "layout-service-button count": 1,
   "initial_state": {
    "opacity": "0",
    "pointerEvents": "none",
    "w": 17,
    "h": 17,
    "x": 330,
    "y": 794
   },
   "after_scroll_600px": {
    "opacity": "1",
    "pointerEvents": "auto",
    "w": 48,
    "h": 48,
    "x": 208,
    "y": 782,
    "aria-label": "Call staff or request the check"
   },
   "drawer_after_click_onscreen_text": [
    "TABLE 9913 \u00b7 SERVICE",
    "How can we help?",
    "Call Waiter / Someone will stop by",
    "Silverware / A fresh set",
    "Check Please / Ready to settle up",
    "Your server is nearby \u2014 we'll be right with you."
   ],
   "drawer_after_click_testids": [
    "service-bubble",
    "service-bubble-attend_table",
    "service-bubble-cutlery",
    "service-bubble-ready_for_bill"
   ],
   "screenshots": [
    "/workspace/uat/lane-pos/shots/psb-CONTROL-28ae37ab.png",
    "/workspace/uat/lane-pos/shots/svc-CONTROL-28ae37ab-drawer.png",
    "/workspace/uat/lane-pos/shots/dock-CONTROL-28ae37ab-scrolled.png"
   ]
  }
 },
 "what_i_could_establish": [
  "step 1 (Menu payload carries pos_experience) \u2014 WITNESSED. All 3 fixtures return the 4-key object at restaurant.pos_experience on an unauthenticated GET.",
  "step 3 (all four keys gate together) \u2014 WITNESSED at the payload level: pos-gate is all-true, the two non-POS fixtures are all-false. No fixture shows a mixed set.",
  "step 4 (non-POS restaurant keeps its service buttons) \u2014 WITNESSED IN THE BROWSER on both non-POS fixtures: dock button appears on scroll and opens the Call Waiter / Silverware / Check Please drawer."
 ],
 "what_i_could_not_establish": [
  "step 2 (Service buttons hidden on the POS fixture) \u2014 NOT WITNESSABLE as a gate effect. The only dev fixture with service_buttons_hidden=true (pos-gate 02d14028) has 0 menu items and renders layout-empty-state, so no menu chrome of any kind renders. Absence of the service button there is fully explained by the empty menu; the gate is never exercised on a rendered menu.",
  "I did not mutate any restaurant config to create a POS-gated fixture with a menu."
 ],
 "fixture_sweep_all_26_dev_fixtures": {
  "method": "unauthenticated GET /dev/restaurants/<RID>/menu for every id in runs/wave0/fixtures.json",
  "service_buttons_hidden=true count": 1,
  "the only one": "pos-gate 02d14028 'Canary Mosaic V2 POS Gate \u2014 dev'",
  "items on that one": 0,
  "every other fixture": "service_buttons_hidden=false, 6-24 items",
  "consequence": "there is NO non-POS empty-menu fixture in dev, so the empty-menu cause and the gate cause cannot be separated by fixture comparison. The confound is structural, not an omission on my part."
 },
 "payload_still_ships_the_buttons": {
  "observation": "On pos-gate 02d14028 the SAME payload that sets pos_experience.service_buttons_hidden=true also carries restaurant.service_buttons = [{action:attend_table,label:'Call Waiter',order:1},{action:cutlery,label:'Silverware',order:2},{action:ready_for_bill,label:'Check Please',order:3}].",
  "same on all 26 fixtures": "every dev fixture ships the identical 3-entry service_buttons array, gated or not. The server does not strip them; only the flag differs."
 },
 "service_button_is_scroll_gated_on_non_POS_fixtures": {
  "at first paint (t+0s and t+8s, no scroll)": "[data-testid=layout-service-button] exists but computed opacity=0, pointer-events=none, 17x17px at x=330,y=794",
  "after page.mouse.wheel(0,600)": "opacity=1, pointer-events=auto, 48x48px at x=208,y=782, aria-label='Call staff or request the check'",
  "outerHTML at that point": "<button type=\"button\" class=\"m2z-dock-btn\" aria-label=\"Call staff or request the check\" aria-hidden=\"false\" tabindex=\"0\" data-testid=\"layout-service-button\" style=\"transform: translateX(0px) scale(1); opacity: 1; transition-delay: 45ms; pointer-events: auto;\">",
  "note": "reported as literal observation only - I did not attempt to judge whether scroll-gating is intended."
 },
 "admin_surface_seen": {
  "login": "POST /dev/auth/login -> 200 {\"token\":\"<redacted>\",\"subject\":\"canary\"}",
  "GET /admin/integrations/clover/02d14028-.../proposals": "200, 2030 bytes, {\"items\":[{\"id\":\"0f848fa0-...\",\"clover_item_id\":\"MOCKITEM-1\",\"name\":\"Canary MOCKITEM-1\",\"price\":\"9.99\",...,\"is_active\":true,\"matched_menu_item_id\":...}]}",
  "GET /admin/integrations/clover/baa315c1-.../proposals": "200, 2030 bytes, same MOCKITEM-1 shape",
  "GET the same route for any NON-POS restaurant (28ae37ab, f469b191)": "403 {\"error\":\"canary_scope\",\"message\":\"The canary principal may only reach the POS integration routes.\"}",
  "GET /admin/health": "200 {\"status\":\"healthy\",\"db_available\":true,\"db_connected\":true,\"schema_compatible\":true,\"missing_columns\":[]}"
 }
}