Skip to content

feat(rate): add bounded club explorer camera - #4444

Draft
d-sorgcodexagent[bot] wants to merge 6 commits into
codex/4433-putting-sample-inspectorfrom
codex/4433-club-explorer-camera
Draft

feat(rate): add bounded club explorer camera#4444
d-sorgcodexagent[bot] wants to merge 6 commits into
codex/4433-putting-sample-inspectorfrom
codex/4433-club-explorer-camera

Conversation

@d-sorgcodexagent

Copy link
Copy Markdown
Contributor

Summary

  • add a matched keyboard/pointer camera contract for the React Explorer and PyQt 3D Clubhead visual surfaces
  • make STL import bounded, immutable, provenance-aware, and generation-safe while preserving prior accepted evidence on failure
  • align camera/source state semantics, diagnostic rendered evidence, workflow authority, and visualization manifest contracts

Scientific and interaction contract

  • imported STL: 2 MiB and 2,048 raw-triangle limits; generated/rendered meshes: 4,096-triangle limit (covers the 2,176-triangle Mallet Putter)
  • camera changes are presentation-only and reuse one solved scenario snapshot
  • Arrow keys orbit, +/- zoom, Home/Reset restores the canonical camera; pointer drag/wheel use the same state without stealing focus
  • imported meshes are display-normalized only; no physical face, density, hosel, or mass-CG inference
  • async React imports are exact-source/epoch bound; PyQt synchronous adoption is transactional with honest stale-image errors if rollback rendering also fails

Evidence

  • Python adjacent Club/mesh/units/GUI: 601 passed, 2 optional build123d skips
  • React focused: 31/31; TypeScript and ESLint green
  • Playwright: 3/3 at 1440x900, 1280x720, and 390x844
  • PyQt rendered lifecycle: DPI 1.0 and 1.5, exact DPR and retained-canvas hashes
  • production build, Ruff lint/format, MyPy, workflow governance, cumulative diff, and <=400 changed source/test limits green

Artifacts remain diagnostic, not approved goldens. Portable mesh archive identity, formal AT validation, approved baselines, and remaining #4433 tabs stay open.

Depends on #4443. Advances #4433; does not close it.

dieterolson pushed a commit that referenced this pull request Aug 14, 2026
The web build was broken and two React tests failed once the whole family
was integrated. Both are genuine cross-slice defects that no individual PR
could expose, because each slice only ever ran against its own parent.

1. `npm run build` (tsc) failed, which is why "Rate web production Worker E2E"
   could not even start its preview server. #4431 made `executionMetadata`
   required on `VariationExecutionRequest`/`VariationExecutionResult`, but four
   test fixtures introduced by the #4444 chain construct those objects without
   it. Supplied it the way the already-updated fixtures in the same file do --
   from the request under test, which also satisfies `validateResult`'s
   request/result metadata equality check. For the two unsupported-flight-model
   cases the request is now spread from `jointRequest()` with only the plan
   overridden; `validateExecutionRequest` runs `validatePlan` before the
   metadata comparison, so the assertion still exercises the flight-model
   rejection it was written for.

2. A real behavioural regression. `importPlan` sets the plan, clears results,
   then reports provenance -- either "resolves against the current variable
   registry ... not evidence of historical reproducibility" for a raw plan, or
   "Execution sidecar verified against the current registry" for a signed
   document. The #4444 chain added an effect that calls `invalidateResults` on
   every configuration-identity change. Changing the plan changes that
   identity, so the effect ran after commit and overwrote the provenance
   message with the generic "Ready: configuration changed; run again." The
   user was silently denied the one message that tells them a loaded plan was
   re-resolved against today's registry rather than its recorded one.

   `invalidateResults` now announces only a discard that actually happened,
   decided from refs so the callback identity stays stable and the effect
   cannot re-trigger itself. Nothing else references that string, and the
   invalidation tests assert visual state and heading removal rather than
   status text, so they are unaffected -- they invalidate with results present,
   where the message still appears.

Verified in the web workspace: tsc clean, eslint clean (--max-warnings 0),
vite build succeeds, and vitest is 1084/1084 across 126 files (was 1082/1084).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants