# Playground behavior audit

Audit started 2026-10-28 (America/Los_Angeles) against the PR44 preview at `http://127.0.0.1:8879`, revision `079554c` through `60d905b` plus the subsequent journey fixes on `fix/sim-camera-reload`. The local interaction preview for the first completed fixes reported revision `66527a7`, asset digest `786c984b6609c0e125da`, built `2026-10-29T01:56:43.993Z`; it included edits later committed as `fe30898`, so that preview revision alone does not identify its full contents. The later geometry/audio preview reported revision `ba74584`, asset digest `da6899025d138d9668ec`, built `2026-10-29T02:08:31.849Z`, again including changes that were not all committed at build time. This inventory distinguishes an interaction working from the experience being enjoyable. Final commit and deployment verification must accompany this record; a passing local check is not a deployed-site claim.

## Expected behavior and findings

| Area | What it should do | Observed behavior / earlier defect | Status / verification |
| --- | --- | --- | --- |
| Wheel and pinch zoom | Small input should produce small, smoothly applied camera changes; pinch should work on touch screens. | Earlier wheel input changed radius immediately; a 120-pixel wheel event changed it about 6.35%. | Existing camera suite measures eased 1.55% notch changes, fine input, real Chromium touch pinch and WebKit wheel behavior. |
| Machine stats fold | Expand/collapse the information card without moving the 3D camera or its projection. | Earlier fold changed projection offset from 25 to -3.42 pixels at 1440×1000. | Existing camera suite records `statsStable: true`. |
| Aiming guide | A visible curved guide should start at the muzzle and show the predicted flight path. | A faint yellow dashed trajectory competed with a brighter straight laser. | New 60-segment guide is visible, has 0.150 m sampled bend and zero muzzle-origin error in the interaction receipt; straight reference defaults off. It is a nominal trajectory, not a guarantee that every spread-affected shot hits its endpoint. |
| Reload | Be obvious, animate flap/jar/pour, prevent repeat overfill or firing during reload, and end at capacity. | Reload previously filled immediately. | Formal Chromium/WebKit receipts show open flap (1.920 rad), jar and pouring balls; exact 30-ball completion, spam/fire/journey gates, hardware reentry, preserved conversation content, full-hopper rejection and reduced motion pass. |
| Native keyboard controls | Space should activate a focused checkbox/button; arrows should adjust a focused slider. Global shortcuts should work when interacting with the scene. | Space on the curved-guide checkbox left it unchanged. ArrowRight on the rate slider left its value unchanged. Global shortcuts intercepted these events. | Fixed in `fe30898`. Formal Chromium/WebKit interaction runs pass checkbox/slider ownership, focused ARM/FIRE activation, key release and blur cleanup. |
| Journey pause | PAUSE should freeze the ball/mechanism and progression while allowing inspection; Play should resume. | With `auto=false`, a paused step's elapsed time, ball position and feed-dial angle continued changing. | Fixed in `fe30898`. Formal Chromium/WebKit runs confirm elapsed time, ball position, feed dial and wheels stay fixed while paused; manual Next repositions the ball; Play resumes. |
| Journey after an exploded view | The demonstration ball and barrel should share the assembled mechanical frame; starting the journey should restore the mechanism before feeding. | Independent review found that the Exploded slider could remain at 1 during a journey, lifting the rendered barrel about 149 mm and separating the demonstrated path from its mouth by about 155 mm. The assembled muzzle/path matched the STL; the presentation state caused the mismatch. | Implemented and independently checked: assembled barrel mouth, muzzle and path agree within 0.000000608 mm at five pan/tilt poses, with 0° axis error; live fire waits for reassembly. Paused manual stage navigation also completes reassembly before placing the ball. |
| Manually advanced journey flight | A demo ball should leave the muzzle at the documented nominal speed regardless of pause/Next history. | Independent review found a paused, manually advanced journey launched at about 11.26 m/s because it reused partly spun-up flywheel RPM, instead of the nominal 15.85 m/s. | Implemented and independently checked: direct and previously exploded journeys, paused and advanced seven times, both launch at 15.85 m/s with age 0. Reassembly completes while paused before the queued Flight stage. |
| Master sound control | Mute should stop current speech and effects and prevent further audible output until enabled again. | User reported speech continuing after mute; the top-level sound toggle controlled effects separately from TTS. | Fixed in `60d905b`. Full Chromium/WebKit audio suites pass shared master mute/volume in robot, bench and talk demo, immediate browser/Piper cancellation, zero-volume silence, invalidated delayed replies and preserved voice-only preference. Audio quality itself was not judged. |
| Part picker | Every choice should identify/highlight the chosen component; the placeholder or close button should clear selection. | All 64 options selected matching parts and displayed cards. Closing cleared selection. Choosing the empty placeholder left `pan_spacer` selected. | Fixed and independently retested: the empty option clears selection. |
| Turret view modes | Solid, X-ray, cutaway and exploded views should change the matching geometry presentation. | All primary view controls selected the correct state; cutaway caps and transparent materials changed appropriately. | Observed working in browser. |
| Turret cameras | Range, turret, side and behind should move to distinct usable viewpoints. | All four produced distinct finite camera poses and targets. | Observed working in browser; human framing judgment still matters. |
| Visibility controls | Curved guide, straight reference, antennas, callouts and airflow should independently follow their toggles. | All five state transitions matched checked values in both directions. | Observed working in browser. |
| Unarmed fire | A fire attempt should not launch a ball and should explain ARM. | Shot count unchanged; toast explained ARM. | Observed working in browser. |
| Target reset and stage changes | Reset existing scene objects without recreating the renderer, robot or conversation. | Existing transition suite covers identity and scene continuity. | Independently retested: CLEAR BALLS cleared flying balls; RESET TARGETS restored cans using the same target arrays. All 15 recorded activities preserved the scene. Retain the dedicated transition suite for conversation identity. |
| Vehicle live/replay actions | Actions should be coherent in the selected mode; replay must not accumulate a latent live burst. | Source audit found FIRE/BURST could queue live gun input during replay; action consumption occurred after returning live. | Fixed. Committed robot suite passes Chromium/WebKit for both robot models, desktop/touch FIRE/BURST/RELOAD takeover, scene/conversation identity and six layouts. |
| Liveliness controls | The ALIVE pill and scene checkbox should show the same state. | Pill handler changed state without updating the checkbox. | Fixed and independently retested: pill and checkbox agree. |
| Portal navigation and downloads | Published navigation and visible internal links should resolve; layout should remain usable on phones. | 241 visible same-origin link targets returned HTTP200; no page JavaScript errors or horizontal overflow in the audited portal routes. | Portal audit passed at 320×568, 390×844, 568×320, 844×390 and 1440×900. HTTP200 alone does not validate each download's contents. |
| Build inclusion controls | Selecting build streams should change the included estimate and be reversible. | Checkbox toggled and restored. | Observed working in browser. |
| Progress reports | Selecting an FEA row should display its matching report. | Multiple rows changed the report to matching load cases. | Observed working in browser. |
| FEA inspector | Valid reports should render; field/load/playback controls and model inspection should remain reachable on phones. | Valid `thigh-T1.json` loaded; field, Design/Max load and Play/Pause controls worked. At 320×568, status/legend/panel obscured almost the entire model. | Fixed. Built-site Chromium/WebKit portal suite passes model/overlay bounds at 21 viewport sizes, reachable 44-pixel controls, field/load/playback controls and eased wheel zoom. |
| Generic CAD viewer | A bare utility route should show a useful model or an actionable empty state. | `/designer/kit/viewer.html` requested missing `exports/view/view.json`, leaving no canvas and an error. | Fixed. Bare route opens the real playground; explicit manifests still work. Built-site Chromium/WebKit checks cover a published STL via test manifest, part visibility/count and synchronized explode/section readouts. |
| Character demo/chat | Typed messages and presets should respond without destroying conversation on scene changes. | Curious changed mood; typed Hello produced a scripted reply and history. Service detection reported browser voice/ears and scripted brain. | Scripted behavior observed. Built-site Chromium/WebKit suite passes five layouts with chat forced open, exclusive phone chat/event trays and service-demo controls. Real microphone, voice quality and connected service responses remain outside this audit. |
| Recorded playback | All published activities should load; pause, scrub, speed and demo advance should be coherent. | All 15 v2 activities loaded; pause and play changed state; frame 10 mapped to 0.333 s at 30 fps; 1.5× playback selected; demo advanced Stand → Squat. | Independently observed working. |
| Live vehicle settings | Pose/drive controls, turret attachment, field of view, headlights and laser should affect their named functions. | Height 0.4 m, pitch 5°, leg difference 15 mm and speed 0.5 applied; visibility switches worked; laser OFF/ON/AUTO matched the rendered beam. | Independently observed working; laser requires a rendered frame before reading its visibility. |
| Character and sound controls | Expressions, typed chat, presets, mute, docking and sound should produce visible state feedback. | All nine expression buttons selected; chat, three presets, mute and dock worked; SOUND OFF/ON labels followed state. | UI behavior observed. Automated tests do not prove audio audibility or quality. |
| Lighting and background | Dimmer settings should change the whole scene, including empty sky, and survive model switches coherently. | Earlier scene lighting left the background bright. | Robot Chromium/WebKit suite checks dark sky, restored vehicle preference after the turret bench and bright sky on return to full daylight. |
| Phone part cards | A selected part card should remain readable without covering battle actions. | Independent review found the card overlapping the primary action bar on short phones. | Fixed in `fe30898`; Chromium reports no overlap and all ARM/FIRE/RELOAD buttons reachable at five sizes. Independent WebKit checks also pass at 320×568, 390×844 and 844×390. |
| Text chip alignment | Text-only chips should center their labels and remain easy to tap. | AUTO had inconsistent text treatment relative to icon chips. | Independently retested at 1280×900, 320×568 and 390×844: center error -0.008 px horizontally, 0 px vertically; target 56×44 px; selection works. |
| Phone simulator controls | Menu/drawer and ARM/FIRE/RELOAD should be reachable with useful touch targets and no horizontal overflow. | Menu/Escape, drawer open/close and all three main turret buttons passed at 320×568, 390×844 and 844×390. | Independently observed; dedicated suites add other representative sizes. |

## Follow-up audit status

The initial keyboard, pause, part-picker, text-centering and phone-card findings are fixed. The repository interaction test now uses the correct accessible-name/control selectors, initializes the rate before stepping it, waits for the current arc to render and opens the settled phone drawer before measuring its children. Chromium and WebKit completed the core interaction suite; Chromium additionally completed the newly added part-card overlap assertions. Receipts are `/tmp/gyropup-turret-interactions/chromium-report.json` and `webkit-report.json`.

A subsequent user report and independent review identified journey reassembly after explosion, nominal launch speed after manual navigation and TTS obeying master mute. All three fixes now have focused evidence: independent browser geometry/flight probes and full Chromium/WebKit audio runs. The geometry probes are `/tmp/gyropup-review-bore.mjs`, `gyropup-review-live-bore.mjs`, `gyropup-review-journey-speed.mjs` and `gyropup-review-reassembly.mjs`.

The phone regression waits for breakpoint-driven drawer state and animation frames before measuring controls. The earlier 100/200 ms wall-clock waits could inspect the old desktop drawer before the phone media-query callback ran, causing false overlap or hidden-control failures. Independent Chromium and WebKit checks confirm that the settled card stays clear of battle actions.

Current-head CI, independent review, final full-suite receipts and the deployed version are recorded on [PR44](https://github.com/Valpatel/gyropup/pull/44). Verify those release receipts before treating local evidence as a production claim.

## Current-model and landing follow-up (issue47)

The user requested a second validation pass after PR44: consistent current models across pages, a matching loading poster, a contrasting background, an alive/talking landing robot and label-free exploded inspection. The following inventory starts with observed gaps and is updated with measured results as the separate release is checked.

| Area | What it should do | Observed gap | Validation required |
| --- | --- | --- | --- |
| Poster handoff | Keep the same apparent pose, scale and framing until a real first frame is ready. | The previous hero showed a different full-CAD illustration and hid it before rendering. | Compare delayed loading and first-frame screenshots at narrow/wide aspect ratios and DPR1/2; retain useful fallback if WebGL or assets fail. |
| Hero contrast | Separate the yellow robot clearly from its background. | Warm yellow/cream field competed with yellow geometry. | Inspect the cool backdrop on phone and desktop, including labels, focus indicators and fallback. |
| Current model | Use the same approved full-detail turret and current robot in live play, landing and character demo. | Robotv2 used31 older turret parts, the bench used48 current turret parts, and the character demo used a stand-in. | Compare exported hashes, transformed parts, muzzle/laser and ownership across routes; validate current parts against independent CAD datums. |
| Default demo | Show the current robot while staying playful and continuous. | Autoplay cycled recorded physics with an older turret snapshot. | Exercise current live autoplay phases, manual takeover, pause, model changes and repeated toggles without scene or conversation replacement. |
| Recorded evidence | Preserve the model and trajectories actually used for recorded simulations. | Replacing only the turret would detach the recorded projectile origins from the visible barrel. | Keep matching historical geometry and an explicit recorded-snapshot label; check return to current live presentation. |
| Exploded inspection | Reveal components without labels, restore smoothly, and remain accessible by touch/keyboard. | Landing had no inspection control. | Rapid hover entry/exit, focused/pressed button, touch toggle, reduced motion, resize and return to assembled pose; reject pivot/frame drift. |
| Landing character | Offer occasional readable bubbles and optional speech without competing with the page. | Landing animated eyes but had no conversation/character behavior. | Verify hidden-tab/offscreen suppression, repeat cadence, manual interaction and shared master/voice mute before and during speech. |

Validation is staged: baseline reproduction, focused regression and negative controls, independent review, then hosted checks against the deployed version. Repeating an assertion does not replace testing a different state or input sequence. Historical simulation evidence and human play judgments remain distinct from presentation tests.

### Integrated results, 2026-10-29

The implementation for [PR48](https://github.com/Valpatel/gyropup/pull/48) closes the presentation gaps above. Local Chromium and WebKit checks passed on the integrated build; final current-head CI, independent review and production receipts belong on that PR.

| Area | Measured result | Remaining limit |
| --- | --- | --- |
| Poster, backdrop and inspection | Twelve viewport/DPR cases per browser compare actual rendered silhouettes: minimum overlap 0.9904 Chromium / 0.9807 WebKit, maximum mean RGB error 1.967 / 2.799 out of 255. Delayed imports, module/WebGL failure, hover, keyboard/touch controls and reduced motion pass. Phone and desktop screenshots show the cool background and complete robot. | A static fallback cannot reproduce later animation. |
| Current model | Same 48 current turret parts on landing, live robot and character demo; 46 independent required poses plus 90 operating frames pass with maximum landmark error 0.000010 mm. Wrong pivot, owner, axis sign, parent and units are rejected. Actual barrel-mouth and emitted-ball origins agree. | The committed v2 body remains an interim rig. No new full-body CAD, mass, collision-clearance or dynamics validation is implied. See [current-model evidence](current-model.md). |
| Default live demo | Both browsers observe real autonomous shots and target hits, pause, manual fire/reload/drive takeover, live slider feedback and preserved scene/conversation identity. Robot controls pass six layouts for v1/v2, desktop/touch and saved mute/URL overrides. | This is a kinematic showcase with browser projectile integration, not a new MuJoCo recording. Full-robot reload opens its flap and fills the existing counter; the bench retains the detailed jar/pour animation. |
| Recorded evidence | Explicit archived activities keep their original turret, muzzle and ball-speed frames. Repeated archive/current swaps, failed fetches and late-request cancellation pass. Recorded mass is labeled as such. | Older reports remain evidence of their original model and loads. |
| Landing character | Greeting screenshots caught low-contrast inherited speech text; corrected theme tokens now have a 4.5:1 text-contrast regression. Gesture-gated speech, master/voice mute, offscreen suppression and reduced-motion behavior pass. | Hidden-document behavior uses an explicit visibility adapter; these tests do not claim native tab-switch automation or judge voice quality. |
| Greetings and model visibility | A second screenshot pass caught readable bubbles obscuring the turret. Landing greetings now replace the caption in reserved space below the robot; Chromium and WebKit check actual projected model/control clearance at desktop and 320/390/844 px widths. Character-demo framing reserves room for speech. | A bubble fitting the viewport does not prove the robot is visible. Fresh navigation and resized views both need checking. |
| Fresh manual-play camera | Delayed talk styles previously left a stale bottom inset of about 836 px and clipped the robot above the canvas. The scene now ignores unstyled overlays and refreshes measured insets when the dock resizes or its stylesheet loads. The regression delays CSS, checks actual visible mesh bounds, then verifies stats folding leaves projection unchanged. | This is layout synchronization; it does not change user-driven camera controls or scene identity. |
| Product weight ceiling | Active product copy, requirements and D72 now specify 100 lb / 45.36 kg for the complete operating robot. The [weight budget](../design-weight-budget.md) distinguishes the current estimated mass from the new ceiling. | Historical 37 kg load gates and actual CAD masses remain unchanged. Full-ceiling structural and motion validation is open. |

Reproduce the new checks with `npm run test:hero`, `npm run test:models` and `npm run test:demo`, setting `SITE_URL` to the built site. Use `PLAYWRIGHT_BROWSER=webkit` for the second browser engine. CI runs the new suites alongside the existing mechanism, gameplay, portal, audio, cache and agent-markdown regressions in three parallel groups.

## Evidence and method

The prototype-warning follow-up ([PR52](https://github.com/Valpatel/gyropup/pull/52)) adds explicit first-entry acknowledgement, persistent warning text and the 100 lb / $10,000 design targets. Its dedicated Chromium and WebKit suites pass six phone/tablet/desktop layouts, direct simulator entry, keyboard containment, session revision and blocked-storage cases, scene/conversation preservation, held ARM/aim cleanup, temporary speech/SFX silence and static/agent warning content. The existing Chromium audio suite also passes. The first pass caught native reverse-Tab focus escape, a 320 px header control clipped despite no page overflow, and a greeting consumed behind the modal; all three now have regressions. Final CI and production receipts belong on PR52; acknowledgement does not establish training or hardware safety.

The independent broad probe `/tmp/gyropup-playground-audit.mjs` checks deliberate control groups, state changes and scene identity rather than clicking arbitrary buttons. The portal probe `/tmp/gyropup-portal-audit.mjs` and receipt `/tmp/gyropup-portal-audit.json` cover the landing page, progress, build, design notebook, FEA and character demo. Built-site portal receipts are `/tmp/gyropup-portal-chromium/report.json` and `/tmp/gyropup-portal-webkit/report.json`, both with no page errors or missing required resources. Scratch paths describe this session's evidence and are not durable repository dependencies.

The first broad probe used fixed wall-clock delays. On the shared software-rendered browser, those did not imply sufficient simulated time: a 700 ms wait advanced the scene by only about 0.1 simulated seconds. Such timeouts are not recorded as product failures. Wait for a state predicate or measure simulation time. Likewise, do not serialize a selected Three.js object graph in an assertion: capture small scalar properties such as its name instead.

During ongoing changes, one preview build imported `designer/robot_actions.js` before that file was included in the static output. The module returned HTTP404 and the simulator did not initialize. The owner staged the new files and rebuilt, resolving the missing import. Commit `ba74584` adds a static-build check rejecting missing relative modules before publication. Final verification must still use a coherent build and reject missing required resources.

Reproducible committed suites for the completed implementation:

```sh
npm run build
PORT=8879 node tools/serve-site.mjs
# In a second terminal, against that server:
SITE_URL=http://127.0.0.1:8879 npm run test:camera
SITE_URL=http://127.0.0.1:8879 npm run test:interactions
SITE_URL=http://127.0.0.1:8879 npm run test:sim
SITE_URL=http://127.0.0.1:8879 npm run test:web
SITE_URL=http://127.0.0.1:8879 npm run test:robot
SITE_URL=http://127.0.0.1:8879 npm run test:viewers
SITE_URL=http://127.0.0.1:8879 node tools/test-audio-settings.mjs
```

Use `SITE_URL=https://gyropup.com` for deployed checks and preserve the served `version.json` with results. A browser test should check console errors, failed required resources and `document.body.dataset.stageError`; catching a frame callback exception keeps the page alive but does not make that callback healthy.

## Experience judgment and limits

The bright curved guide and visible jar pour make the main battle loop easier to understand. The large ARM, RELOAD and FIRE controls communicate the central actions well. Inspection modes and the journey are useful demonstrations of the machine, while the portal exposes the project's progress and engineering evidence. Those are visual and interaction judgments, not proof that children will find the game fun.

A human play session should still assess aiming satisfaction, touch ergonomics while holding ARM and firing, pacing, audio balance, emotional appeal and whether the first minute explains itself. The automated checks do not establish hardware reliability, physical projectile behavior, collision safety, real microphone/voice quality, network-filter reputation, every possible phone/browser combination or accessibility conformance. Representative phone layouts are tested rather than claiming every phone resolution exists as a finite test set.
