From c223a435571c0c8e51849c80e9a774bc386adf37 Mon Sep 17 00:00:00 2001 From: Sourav P Bijoy <71513365+Phloraxx@users.noreply.github.com> Date: Sat, 25 Jul 2026 09:13:39 +0530 Subject: [PATCH 1/4] polish: preserve motion preference across judge presets --- apps/browser/src/shared/recompose.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/browser/src/shared/recompose.ts b/apps/browser/src/shared/recompose.ts index 45267df..e0beca1 100644 --- a/apps/browser/src/shared/recompose.ts +++ b/apps/browser/src/shared/recompose.ts @@ -122,13 +122,16 @@ export function profileForRecomposePreset( if (preset === 'personalized') return structuredClone(profile); const next = structuredClone(profile); + // Judge presets demonstrate layout/information differences. They deliberately + // preserve the person's existing motion preference instead of silently + // forcing reduced motion, so the progressive Recompose transition remains + // visible unless the person has actually asked AURA to reduce motion. if (preset === 'clear_calm') { next.capabilities.attention = 'important'; next.preferences.explanationStyle = 'concise'; next.preferences.informationDensity = 'calm'; next.preferences.lineSpacing = Math.max(next.preferences.lineSpacing, 1.55); next.preferences.readingWidth = 'narrow'; - next.preferences.reduceMotion = true; next.preferences.targetSizePx = Math.max(next.preferences.targetSizePx, 52); next.preferences.textScale = Math.max(next.preferences.textScale, 1.1); next.summary = @@ -148,7 +151,6 @@ export function profileForRecomposePreset( if (preset === 'easy_to_control') { next.capabilities.motor = 'important'; next.preferences.informationDensity = 'calm'; - next.preferences.reduceMotion = true; next.preferences.strongFocus = true; next.preferences.targetSizePx = 60; next.preferences.textScale = Math.max(next.preferences.textScale, 1.08); @@ -161,7 +163,6 @@ export function profileForRecomposePreset( next.preferences.explanationStyle = 'concise'; next.preferences.informationDensity = 'step_by_step'; next.preferences.readingWidth = 'narrow'; - next.preferences.reduceMotion = true; next.preferences.strongFocus = true; next.preferences.targetSizePx = Math.max(next.preferences.targetSizePx, 52); next.preferences.textScale = Math.max(next.preferences.textScale, 1.1); From a889d2eddefe684f7bb95d706fc76c4d97c2ac45 Mon Sep 17 00:00:00 2001 From: Sourav P Bijoy <71513365+Phloraxx@users.noreply.github.com> Date: Sat, 25 Jul 2026 09:14:04 +0530 Subject: [PATCH 2/4] test: preserve reduced-motion preference in judge presets --- apps/browser/src/shared/recompose.test.ts | 33 ++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/apps/browser/src/shared/recompose.test.ts b/apps/browser/src/shared/recompose.test.ts index 93680b2..c0330c8 100644 --- a/apps/browser/src/shared/recompose.test.ts +++ b/apps/browser/src/shared/recompose.test.ts @@ -31,7 +31,6 @@ describe('Recompose judge profiles', () => { const steps = profileForRecomposePreset(original, 'step_by_step'); expect(calm.preferences.informationDensity).toBe('calm'); - expect(calm.preferences.reduceMotion).toBe(true); expect(visual.preferences.textScale).toBeGreaterThanOrEqual(1.35); expect(visual.preferences.targetSizePx).toBe(60); expect(motor.capabilities.motor).toBe('important'); @@ -40,6 +39,38 @@ describe('Recompose judge profiles', () => { expect(steps.capabilities.cognitive).toBe('important'); }); + it('preserves the actual reduced-motion preference across demo presets', () => { + const motionAllowed = createDefaultBrowserProfile( + '2026-07-24T00:00:00.000Z', + 'profile-motion', + ); + motionAllowed.preferences.reduceMotion = false; + + for (const preset of [ + 'clear_calm', + 'easier_to_see', + 'easy_to_control', + 'step_by_step', + ] as const) { + expect(profileForRecomposePreset(motionAllowed, preset).preferences.reduceMotion).toBe( + false, + ); + } + + const reduced = structuredClone(motionAllowed); + reduced.preferences.reduceMotion = true; + for (const preset of [ + 'clear_calm', + 'easier_to_see', + 'easy_to_control', + 'step_by_step', + ] as const) { + expect(profileForRecomposePreset(reduced, preset).preferences.reduceMotion).toBe( + true, + ); + } + }); + it('keeps the personalized option identical in behavior but cloned', () => { const original = createDefaultBrowserProfile( '2026-07-24T00:00:00.000Z', From 829d26ba09109bad00f9f7dcfc33d5cd9098f3a8 Mon Sep 17 00:00:00 2001 From: Sourav P Bijoy <71513365+Phloraxx@users.noreply.github.com> Date: Sat, 25 Jul 2026 09:14:55 +0530 Subject: [PATCH 3/4] fix: report local Recompose fallback honestly --- apps/browser/src/main/feature-bridge.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/browser/src/main/feature-bridge.ts b/apps/browser/src/main/feature-bridge.ts index 29d281e..fc55de2 100644 --- a/apps/browser/src/main/feature-bridge.ts +++ b/apps/browser/src/main/feature-bridge.ts @@ -165,8 +165,10 @@ ipcMain.handle(IPC_CHANNELS.applyLocalRecompose, async (_event, untrusted) => { if (result.output === null) { return localRecomposeResultSchema.parse({ ...result, - // The deterministic interface is already active even when Qwen is not. - applied: true, + // `applied` describes the local-model refinement only. The deterministic + // Recompose surface remains active, but the UI must not claim Qwen + // successfully personalized the page when the local model failed. + applied: false, }); } From c67640a733ec27524b6180eb235019c5389a8f9a Mon Sep 17 00:00:00 2001 From: Sourav P Bijoy <71513365+Phloraxx@users.noreply.github.com> Date: Sat, 25 Jul 2026 09:16:20 +0530 Subject: [PATCH 4/4] docs: clarify demo motion and dictation behavior --- docs/browser/12-RECOMPOSE-VOICE.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/browser/12-RECOMPOSE-VOICE.md b/docs/browser/12-RECOMPOSE-VOICE.md index 5cd0448..ac69fd3 100644 --- a/docs/browser/12-RECOMPOSE-VOICE.md +++ b/docs/browser/12-RECOMPOSE-VOICE.md @@ -21,6 +21,8 @@ The event build exposes four non-diagnostic example profiles alongside the perso These are demonstrations of needs, not medical modes. The fifth option is **My profile**, which uses Learn Me. +Judge presets change layout, density, target size, and information hierarchy, but they do not silently change the person's motion preference. Progressive Recompose transitions remain visible when motion is allowed; a Learn Me/system reduced-motion preference still removes spatial motion across every preset. + ## Recompose architecture ```text @@ -157,12 +159,12 @@ MediaRecorder ↓ OpenAI transcription ↓ -transcript in composer +validated transcript ↓ existing Talk to AURA request ``` -The baseline implementation uses `gpt-4o-mini-transcribe` after the person stops recording because it is simple, low-cost, and uses the existing OpenAI key. A future enhancement may replace it with `gpt-realtime-whisper` transcript deltas without changing Talk to AURA. +The baseline implementation uses `gpt-4o-mini-transcribe` after the person stops recording because it is simple, low-cost, and uses the existing OpenAI key. The finalized transcript is submitted directly into the same Talk to AURA path as typed text, so the judge gets an immediate page/action response rather than an extra confirmation click. The transcribed text remains visible as the user's conversation message. A future enhancement may replace it with `gpt-realtime-whisper` transcript deltas without changing Talk to AURA. Primary OpenAI references: @@ -201,11 +203,11 @@ AURA is ready when all of the following are true: - the same arbitrary page looks materially different under at least three judge presets; - Fiverr/search/listing pages no longer remain a lightly restyled grid; - the first useful visible change begins immediately after `Make This Mine`; -- local Qwen failure still leaves a convincing deterministic Recompose interface; +- local Qwen failure still leaves a convincing deterministic Recompose interface and is reported as a local fallback, not as a successful Qwen refinement; - cloud failure still leaves the local/deterministic interface usable; - `Original` restores the real website without reload and without losing form state; - every Recompose action maps to a real current-page target; -- push-to-talk fills the existing Talk to AURA composer and can submit normally; +- push-to-talk submits the finalized transcript through the existing Talk to AURA path and exposes that transcript in conversation history; - AURA can speak a short assistant reply and can be interrupted; -- reduced-motion preferences disable spatial Recompose transitions; +- reduced-motion preferences disable spatial Recompose transitions while motion-enabled profiles retain the progressive transition across judge presets; - CI remains green for lint, typecheck, tests, build, and Electron E2E.