Skip to content

feat(ux): UX-COPY-01 — listening guidance: question, volume, balance, camera/mic (#142) - #206

Merged
nicoechaniz merged 6 commits into
mainfrom
feat/ux-copy-01-session-guidance
Aug 6, 2026
Merged

feat(ux): UX-COPY-01 — listening guidance: question, volume, balance, camera/mic (#142)#206
nicoechaniz merged 6 commits into
mainfrom
feat/ux-copy-01-session-guidance

Conversation

@AnnieScigliano

Copy link
Copy Markdown
Collaborator

feat(ux): UX-COPY-01 — listening guidance: question, volume, balance, camera/mic (#142)

Closes #142. Builds on main@d547e96 (post PR #187/#192). Prepares the guidance surface that the human acceptance battery #204 will evaluate.

What ships

A brief, bilingual, accessible listening guide — SessionGuidance — that explains:

  1. The experience invites you to look for a question, not an answer.
  2. What the overall volume controls (everything you hear in the room).
  3. What the Beacon / Session balance controls.
  4. That moving the balance fully toward Beacon lets you hear only the Beacon and bring the session voice to zero.
  5. That turning off the camera does not turn off the microphone — each control works independently.
  6. That camera and microphone always remain under the person's control.

Where it lives (per state)

  • WAITING (pre-room): the same component below the waiting event-card, deliberately outside the role="status" live region so disclosure toggling is never announced as a door-state change.
  • In-room: directly above the Volume + Mix controls it explains, in normal flow — never overlaying the scene, tapestry, contributions, or controls. Closed by default so it doesn't compete with the scene or with SessionContributions.
  • No new route, no navigation, no remount of Room/audio/video/Beacon (purely presentational, local aria-expanded state only).

#98 explicitly NOT simulated

The facilitation mix override is not implemented and this PR does not pretend otherwise: verified there is no override signal anywhere in src/. No override copy appears in the interface; that part of #142 remains blocked by #98. No fictional state, no anticipatory acoustic logic.

Copy (final, ES/EN — natural, not literal)

ES: "La experiencia te invita a buscar una pregunta, no una respuesta." · "El volumen general controla todo lo que escuchás en la sala." · "El balance elige cuánto escuchás del Beacon y cuánto de la sesión." · "Si llevás el balance completamente hacia Beacon, podés quedarte solo con su sonido y dejar la voz de la sesión en cero." · "Apagar la cámara no apaga tu micrófono. Cada control funciona por separado." · "Tu cámara y tu micrófono permanecen siempre bajo tu control." · Etiqueta: "Cómo funciona la escucha".

EN: "The experience invites you to look for a question, not an answer." · "Overall volume controls everything you hear in the room." · "The balance chooses how much of the Beacon and how much of the session you hear." · "Move the balance fully toward Beacon to hear only the Beacon and bring the session voice to zero." · "Turning off your camera does not turn off your microphone. Each control works independently." · "Your camera and microphone always remain under your control." · Label: "How listening works".

Wording adjustments from the issue's base are minimal and tone-only; meaning is unchanged.

Accessibility

  • button + aria-expanded + aria-controls; panel toggles via the hidden attribute.
  • Always-visible text label (never icon-only); chevron is aria-hidden.
  • Keyboard (Enter/Space) and touch; focus stays on the toggle; 44px min touch target.
  • prefers-reduced-motion: no JS animation at all; the only transition (chevron) is motion-safe with motion-reduce:transition-none.
  • Existing visual tokens/primitives (--border-subtle, --surface-alt, --gold, --cream) — no technical-documentation aesthetic.

Tests

  • Unit/component (SessionGuidance.test.tsx, 8 tests): full ES and EN copy; closed-by-default; aria wiring; keyboard + focus; readable label; reduced-motion classes; 44px target; long copy never truncated.
  • Room integration: existing page + media-continuity jsdom suites stay green (34/34) — opening/closing doesn't remount Room, calls no volume/camera/mic handler.
  • E2E (session-guidance.spec.ts, 2 tests): waiting surface readability + keyboard; in-room bounding-box placement above the volume controls without overlap; media-probe continuity across open/read/close (connections, tracks, media DOM, play calls, AudioContext unchanged; canonical Firefox autoplay-resume exception).
  • Local gates: 925 unit tests pass (only the 4 pre-existing macOS-only livekit-target-monitor failures), tsc, eslint, next build all clean.

Visual baselines

The closed disclosure legitimately adds one quiet row above the volume controls in the attendee room, so attendee-audio-prompt baselines may drift. Per the issue's governance: evidence first (CI diff), review of the diff, then regenerate only the affected images on the canonical Linux runner using the proven TEMP-step method from #187, and remove every TEMP step before requesting review. No baseline is regenerated preemptively.

Governance and risks

  • Label audio-touching included: the PR touches src/app/session/[id]/page.tsx, which is path-governance only — no acoustic change (no volume equations, gain, crossfader, AudioContext, codec/bitrate/sample-rate, buffers, LiveKit rooms/tokens, publish/subscribe, camera/mic lifecycle, setCameraEnabled/setMicrophoneEnabled, camera switching, Beacon connection, roles/capabilities, contributions, Prisma, EarlyBirds, or payments were touched).
  • Risk: none to media continuity (presentational component; proven by probe e2e).
  • Rollback: revert the two mounts and the component; no state, schema, or API changes to unwind.

Out of scope (untouched)

#134, #126, #131, #98 (documented above as the blocker for override copy), PR #203 EarlyBirds lane, and everything in the guardrail list.

Reviewer: @nicoechaniz — audio-adjacent surface per governance.

New session.guidance namespace: intention (a question, not an answer),
master volume, Beacon/Session balance, full-Beacon listening, camera/mic
independence, and personal control. The facilitation mix override (#98)
is deliberately absent: no real override signal exists in the codebase
yet, so no interface copy may imply one.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
Isolated, presentational disclosure: text-labeled button with
aria-expanded/aria-controls driving a hidden panel. Closed by default so
it never competes with the scene; no JS animation (motion-safe classes
only); 44px touch target; owns no media, network, or room state, so
toggling it can never remount the Room or touch an AudioContext.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
…142)

Two minimal mounts of the same component: below the WAITING event-card
(outside the status live region, so disclosure toggling is never
announced as a door-state change) and directly above the Volume + Mix
controls it explains. No handlers, state, or layout refactors touched;
the guidance never overlays the scene, tapestry, contributions, or
controls.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
Waiting surface: disclosure present and readable before doors open,
keyboard toggle with focus retention. In-room: bounding-box proof that
the disclosure sits above the volume controls without overlap, plus the
media-probe continuity guard (open/read/close leaves connections,
tracks, media DOM, play calls and AudioContext untouched), with the
canonical Firefox autoplay-resume exception.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
@AnnieScigliano AnnieScigliano added enhancement New feature or request ws2-session-room audio-touching Touches frozen audio behavior and requires Nico approval labels Aug 6, 2026
…ce runner (#142)

Evidence first: the only e2e failure is attendee-audio-prompt at w390
(3542 px, ratio 0.02), and the report's actual-vs-expected diff is a
single ~44px row insertion at the controls area — the guidance toggle,
exactly as scoped. All other surfaces and widths pass unchanged.

This TEMP step pair regenerates snapshots before the gates so this same
run validates the new baseline, and uploads them as an artifact. Both
steps are gated to this branch and will be reverted once the affected
PNG is committed, before requesting review.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
#142)

The reference-runner artifact differed from the repo in exactly one
file: attendee-audio-prompt-w390-linux.png (390x844) — the legitimate
guidance-toggle row above the volume controls, already validated as the
only diff band in the failing run's evidence. The TEMP regeneration and
upload steps in e2e.yml are fully reverted; the workflow is back to its
canonical form before review.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
@AnnieScigliano

Copy link
Copy Markdown
Collaborator Author

Ciclo de baseline visual completado (para la review):

  1. Run 1 (ac8bb36): único fallo = attendee-audio-prompt w390, 3542 px (ratio 0.02). Evidencia del reporte: el actual estable difiere del esperado solo en la banda y 744-840 del viewport 390×844 — la fila del toggle del guidance sobre los controles de volumen. w1440/w1024/w320 pasaron sin cambios.
  2. Run 2 (4a5e9ad): pasos TEMP (regen + artifact) regeneraron los snapshots en el runner de referencia y el gate completo pasó verde contra ellos (e2e 14m5s pass).
  3. Verificación del artifact: difiere del repo en exactamente UN archivo — attendee-audio-prompt-w390-linux.png (390×844). Ese PNG quedó commiteado en 2df84bf.
  4. TEMP revertidos: e2e.yml tiene diff cero contra main. La PR contiene solo los 6 archivos de alcance.

Corrida final en curso sobre 2df84bf (workflow canónico, sin TEMP). Cuando salga verde, la PR queda lista para review — sin despliegue ni merge sin aprobación, como siempre.

@AnnieScigliano
AnnieScigliano requested review from compaii and removed request for compaii August 6, 2026 08:50
@AnnieScigliano

Copy link
Copy Markdown
Collaborator Author

Hola @compaii — te pido la review de esta PR junto con @nicoechaniz. 🌿

Contexto breve para tu lectura: es la guía de escucha de UX-COPY-01 (#142) — un disclosure presentacional (SessionGuidance) con el copy bilingüe sobre la pregunta, el volumen general, el balance Beacon/Sesión y la independencia cámara/micrófono. Está montado en el estado WAITING (pre-sala) y junto a los controles de volumen dentro de la sala. No toca nada acústico: el label audio-touching es solo por path-governance de la página de sesión.

Puntos donde tu mirada suma especialmente:

  1. El tono del copy (ES/EN en src/lib/i18n.ts, namespace session.guidance) — coherencia con la voz del Beacon y con lo que HUMAN-QA-02 — Regresión humana integral posterior al evento del 2 de agosto #204 va a evaluar en la batería humana.
  2. La decisión RTC-02 — Mezcla compartida dirigida por facilitación con handoff suave #98: el override de mezcla por facilitación aún no existe como señal real, así que dejé ese copy FUERA de la interfaz y lo declaré bloqueado por RTC-02 — Mezcla compartida dirigida por facilitación con handoff suave #98. Si ves una forma mejor de encuadrarlo, bienvenida.
  3. La integración discreta: la guía no compite con la escena ni con contribuciones; si sentís que en algún estado se hace demasiado presente (o demasiado invisible), es el momento de ajustarlo.

Gates: CI verde completo (test, lint-and-build, e2e con baseline w390 bendecido en el runner de referencia, frozen-audio-paths). Todo el contexto está en el body de la PR y en #142.

@nicoechaniz nicoechaniz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aprobada. Revisé el diff exacto contra main, la ubicación WAITING/in-room, accesibilidad, i18n, continuidad de media y el baseline w390. No hay cambios en gain, crossfader, AudioContext, LiveKit ni lifecycle de cámara/micrófono; frozen-audio-paths está verde. Verificación adicional local: 8/8 tests focalizados, ESLint de archivos modificados y TypeScript verdes; CI completo también verde.

Observaciones no bloqueantes:

  • El test unitario de teclado termina disparando click manualmente, pero el E2E sí prueba Enter real y foco, por lo que la conducta nativa queda cubierta.
  • El cuerpo usa Closes #142 mientras documenta que el copy de override/“Volver” queda pendiente de #98. Al mergear, preservemos ese remanente en #98 o en un follow-up explícito para que el autocierre de #142 no lo pierda.

@nicoechaniz
nicoechaniz merged commit 341c15c into main Aug 6, 2026
4 checks passed
AnnieScigliano added a commit that referenced this pull request Aug 6, 2026
Additive, dated execution sheet that consumes WEEKEND_REHEARSAL.md as
the canonical protocol and adds only the post-August-2 surfaces:
NAMED/ANONYMOUS contributions, the cockpit contributions drawer, the
second-session A->B leakage check, and the bilingual SessionGuidance.

Status PREPARED - NOT EXECUTED; decision PENDING DEPLOYED SHA + HUMAN
EXECUTION. Fail-closed rule: every row is BLOCKED unless /api/health
shows a candidate containing PRs #187, #192 and #206 (verified today:
deployed 3473397 contains #187/#192 but not #206/341c15c). All 34
journey rows start NOT RUN; roles use synthetic codes only; closure
requires human evidence and a go/no-go signature.

No code, schema, workflow, snapshot or E2E changes. No tickets or
sessions created. EarlyBirds lane untouched.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
AnnieScigliano added a commit that referenced this pull request Aug 6, 2026
…#204)

The initial verification conflated the PR #161 backend merge (89f7799,
which IS an ancestor of deployed 3473397) with the chat feature being
live. Re-verified with explicit merge-base probes (exit 1 = not
contained): production contains the #161 contract/backend only; #187
(388fe8f), hardening 671cde8, #192 (d547e96) and #206 (341c15c) are all
absent, and main is 19 commits ahead of the deployed SHA (rev-list
0 19). Fail-closed wording updated accordingly. No other content,
status or NOT RUN rows changed.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
AnnieScigliano added a commit that referenced this pull request Aug 7, 2026
Additive, dated execution sheet that consumes WEEKEND_REHEARSAL.md as
the canonical protocol and adds only the post-August-2 surfaces:
NAMED/ANONYMOUS contributions, the cockpit contributions drawer, the
second-session A->B leakage check, and the bilingual SessionGuidance.

Status PREPARED - NOT EXECUTED; decision PENDING DEPLOYED SHA + HUMAN
EXECUTION. Fail-closed rule: every row is BLOCKED unless /api/health
shows a candidate containing PRs #187, #192 and #206 (verified today:
deployed 3473397 contains #187/#192 but not #206/341c15c). All 34
journey rows start NOT RUN; roles use synthetic codes only; closure
requires human evidence and a go/no-go signature.

No code, schema, workflow, snapshot or E2E changes. No tickets or
sessions created. EarlyBirds lane untouched.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
AnnieScigliano added a commit that referenced this pull request Aug 7, 2026
…#204)

The initial verification conflated the PR #161 backend merge (89f7799,
which IS an ancestor of deployed 3473397) with the chat feature being
live. Re-verified with explicit merge-base probes (exit 1 = not
contained): production contains the #161 contract/backend only; #187
(388fe8f), hardening 671cde8, #192 (d547e96) and #206 (341c15c) are all
absent, and main is 19 commits ahead of the deployed SHA (rev-list
0 19). Fail-closed wording updated accordingly. No other content,
status or NOT RUN rows changed.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
AnnieScigliano added a commit that referenced this pull request Aug 7, 2026
Deployed is now 64634e9 (= origin/release, build 2026-08-07T00:17:59Z,
schema 20260806233000_add_logos_private_session). Re-probed ancestry
against the new SHA: #161 backend exit 0; #187, 671cde8, #192 and #206
all exit 1 - production still lacks the chat UI, its hardening/fixes and
SessionGuidance. The 2 21 branch comparison is explained as divergent
branches carrying their own LOGOS integration commits (release #209,
main #208), not as 'main 21 ahead'. Fail-closed unchanged: battery
blocked, all rows NOT RUN.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
nicoechaniz pushed a commit that referenced this pull request Aug 7, 2026
* docs(qa): prepare post-August-2 human acceptance sheet (#204)

Additive, dated execution sheet that consumes WEEKEND_REHEARSAL.md as
the canonical protocol and adds only the post-August-2 surfaces:
NAMED/ANONYMOUS contributions, the cockpit contributions drawer, the
second-session A->B leakage check, and the bilingual SessionGuidance.

Status PREPARED - NOT EXECUTED; decision PENDING DEPLOYED SHA + HUMAN
EXECUTION. Fail-closed rule: every row is BLOCKED unless /api/health
shows a candidate containing PRs #187, #192 and #206 (verified today:
deployed 3473397 contains #187/#192 but not #206/341c15c). All 34
journey rows start NOT RUN; roles use synthetic codes only; closure
requires human evidence and a go/no-go signature.

No code, schema, workflow, snapshot or E2E changes. No tickets or
sessions created. EarlyBirds lane untouched.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>

* docs(qa): correct the deployed-candidate facts in the execution sheet (#204)

The initial verification conflated the PR #161 backend merge (89f7799,
which IS an ancestor of deployed 3473397) with the chat feature being
live. Re-verified with explicit merge-base probes (exit 1 = not
contained): production contains the #161 contract/backend only; #187
(388fe8f), hardening 671cde8, #192 (d547e96) and #206 (341c15c) are all
absent, and main is 19 commits ahead of the deployed SHA (rev-list
0 19). Fail-closed wording updated accordingly. No other content,
status or NOT RUN rows changed.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>

* docs(qa): correct the #98 fact in the scope separation (#204)

Blocking review fix: #98 (RTC-02 - facilitation-driven shared mix with
soft handoff) exists and is OPEN and unimplemented; the sheet wrongly
claimed the card does not exist. Scope separation preserved: HUMAN-QA-02
neither executes nor certifies that work, which stays under
audio-touching governance and requires explicit acoustic approval. No
other content changed.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>

* docs(qa): refresh deploy evidence after the LOGOS release (#204)

Deployed is now 64634e9 (= origin/release, build 2026-08-07T00:17:59Z,
schema 20260806233000_add_logos_private_session). Re-probed ancestry
against the new SHA: #161 backend exit 0; #187, 671cde8, #192 and #206
all exit 1 - production still lacks the chat UI, its hardening/fixes and
SessionGuidance. The 2 21 branch comparison is explained as divergent
branches carrying their own LOGOS integration commits (release #209,
main #208), not as 'main 21 ahead'. Fail-closed unchanged: battery
blocked, all rows NOT RUN.

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>

---------

Signed-off-by: AnnieScigliano <anyscigliano@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

audio-touching Touches frozen audio behavior and requires Nico approval enhancement New feature or request ws2-session-room

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UX-COPY-01 — Pregunta, retorno y guía de mezcla

2 participants