Steven
Steven6 min de lectura

Tu app de Mac concede acceso al micrófono — y lo olvida en cada arranque

GeekBye pidió permiso de micrófono, se lo diste y funcionó. Al siguiente arranque: desaparecido. Y la app nunca llegaba a aparecer en Configuración del Sistema → Micrófono. La culpable era una función de seguridad de macOS ejecutando la app en silencio desde una ruta que se esfuma — aquí tienes el diagnóstico y el arreglo de un solo aviso.

macOS
Permisos
Ingeniería
Lanzamientos de GeekBye
Tu app de Mac concede acceso al micrófono — y lo olvida en cada arranque

Este es un fallo que te hace dudar de tus propios ojos. Instalas GeekBye, pide acceso al micrófono, haces clic en Permitir y la transcripción funciona. Perfecto. Cierras, lo reabres a la mañana siguiente — y te pide acceso al micrófono otra vez. Vas a comprobar Configuración del Sistema → Privacidad y seguridad → Micrófono para arreglarlo a mano, y GeekBye ni siquiera está en la lista. Ni denegado. Ni permitido. Simplemente ausente, como si nunca lo hubiera pedido.

Cada pieza por separado parecía correcta. El aviso era real. El permiso funcionaba en el momento. La app estaba correctamente firmada y notarizada, con las cadenas de uso adecuadas. Y aun así el permiso se evaporaba en cada arranque. GeekBye v2.0.6 lo corrigió — y la causa raíz es una de las cosas más taimadas que hace macOS para protegerte.

La función que escondía la app de sí misma

La culpable es App Translocation de macOS, una función de seguridad de Gatekeeper. Cuando descargas una app y la ejecutas directamente desde el DMG o desde tu carpeta ~/Downloads — en cualquier sitio donde siga estando "en cuarentena" — macOS no la ejecuta realmente desde donde tú la ves. La copia de forma transparente a una ruta aleatoria y de solo lectura enterrada bajo /private/var/folders/.../AppTranslocation/… y ejecuta esa copia. Es una buena defensa: impide que una descarga maliciosa manipule los archivos que tiene al lado.

Pero aquí está la colisión. El sistema de permisos de macOS (TCC — lo que lleva la cuenta de quién puede usar tu micrófono, cámara, pantalla) identifica una app por su ruta y su identidad de código. Cuando la app está translocada, esa ruta es aleatoria y temporal. Así que cuando concedes acceso al micrófono, macOS registra fielmente el permiso — contra una ruta que no existirá en el siguiente arranque. Reabres la app, macOS la transloca a una ruta aleatoria distinta, ve una app de la que no tiene registro alguno, y vuelve a preguntar. Y como esa ruta fantasma nunca es una ubicación estable, la app jamás se gana una fila permanente en Configuración del Sistema → Micrófono.

La app le estaba concediendo permiso a un fantasma.

Por eso también solo lo sufrían algunos. Si tu copia de GeekBye ya vivía en /Applications — porque la arrastraste ahí, o porque llegó ahí vía autoactualización — no hay cuarentena, ni translocación, la ruta es estable y todo persiste a la perfección. El fallo era invisible para nosotros y para cualquiera que hubiera pasado de su primera instalación, que es exactamente el tipo de fallo que sobrevive más tiempo.

El arreglo: darle a la app un hogar de verdad

Como el problema entero es una ruta inestable, el arreglo consiste en llevar la app a una estable. La v2.0.6 detecta cuándo GeekBye se está ejecutando translocada (o simplemente ejecutándose fuera de /Applications) y ofrece un "Mover a Aplicaciones" de un clic — usando la llamada de reubicación de macOS que copia el paquete a /Applications y lo relanza desde ahí. A partir de ese momento la app tiene una identidad fija: el permiso de micrófono se mantiene, la grabación de pantalla se mantiene, y GeekBye por fin aparece en Configuración del Sistema donde uno lo esperaría.

El aviso es educado al respecto. Ofrece Mover a Aplicaciones, Ahora no y No volver a preguntar — y recuerda la última elección, para que la app nunca dé la lata a alguien que tenga una razón deliberada para ejecutarla desde otro sitio. La decisión de si siquiera mostrar el aviso está aislada en funciones pequeñas y puras (¿esta compilación está translocada? ¿está fuera de /Applications? ¿el usuario la silenció?) para que la lógica se pruebe con tests unitarios sin necesidad de lanzar una compilación notarizada real en un volumen en cuarentena real.

El mismo lanzamiento también simplificó la propia experiencia de permisos. GeekBye solía abrir una ventana de permisos personalizada y a medida — unos cientos de líneas de interfaz tratando de reproducir algo que el sistema operativo ya hace bien. La v2.0.6 la eliminó y se apoyó en el aviso de permisos nativo de macOS, respaldado por un banner discreto y no bloqueante que aparece solo cuando falta de verdad un permiso requerido. Menos código, y un comportamiento que los usuarios ya reconocen porque cualquier otra app de Mac funciona igual.

De lo que estoy más orgulloso: lo demostramos antes de creerlo

Habría sido fácil adivinar la translocación y lanzar un arreglo. En vez de eso, el lanzamiento envió primero un diagnóstico de arranque: al iniciarse, GeekBye ahora reporta su propia ruta de ejecutable y si está translocada, si está dentro de /Applications, y el estado actual de los permisos de micrófono y pantalla. Esa telemetría convirtió una teoría plausible en una confirmada — los datos de producción mostraron que las sesiones afectadas estaban, de hecho, ejecutándose desde rutas translocadas fuera de /Applications, exactamente como se predijo.

Ese orden importa. "El aviso aparece pero el permiso no se mantiene" tiene varias explicaciones posibles — un problema de firma, una cadena de uso que falta, un asunto de entitlements, una rareza de la base de datos de TCC. Descartamos las causas a nivel de API (la ruta de la petición era demostrablemente correcta), y luego dejamos que los datos del mundo real señalaran la capa de identidad/ruta en vez de lanzar un arreglo esperanzado y cruzar los dedos para que pararan los tickets de soporte.

Tres cosas que enseña este fallo

  1. Un permiso que se pide pero no persiste es un problema de identidad, no de API. Si el código de la petición es correcto y el permiso aun así se esfuma, deja de reescribir la petición. Pregúntate a qué ruta e identidad de código está atando el sistema operativo el permiso — y si esa identidad es estable entre arranques.
  2. Lanza el diagnóstico con (o antes de) el arreglo. Unos pocos campos — desde dónde estoy ejecutándome, cuál es mi estado de permisos — convirtieron una conjetura fundada en una causa raíz verificada y nos dijeron exactamente qué usuarios estaban afectados. Instrumenta la frontera que sospechas antes de parchearla.
  3. Los fallos que se esconden de los desarrolladores son los que corren en el entorno "equivocado". El nuestro vivía en /Applications en cada máquina de desarrollo, así que el fallo era estructuralmente invisible para nosotros mientras golpeaba a los usuarios primerizos. Cuando un reporte no se reproduce, la primera pregunta es qué es distinto en dónde se ejecuta, no si el usuario se equivoca.

GeekBye v2.0.6 lanzó el aviso de reubicación y el diagnóstico juntos. Para el arco de fiabilidad más amplio en el que encaja, mira lo que de verdad cuesta una versión 2 (v2.0.0) y por qué la grabación de pantalla captura el monitor equivocado (v2.0.10) — otro fallo que solo aparecía en un entorno concreto. Para el lanzamiento de pequeños detalles de al lado, software tranquilo: el arreglo del parpadeo y el chip de modo de respuesta (v2.0.3 + v2.0.5).

Artículos Relacionados

La anatomía de lanzar software a la perfección: cómo la revisión de código detectó lo que las pruebas no podían
Steven
Steven7 min de lectura

La anatomía de lanzar software a la perfección: cómo la revisión de código detectó lo que las pruebas no podían

A lo largo de la serie GeekBye v2, pasa una y otra vez lo mismo: un arreglo pasa todas las pruebas en la máquina del desarrollador, y luego la revisión de código demuestra que habría fallado para casi todo el mundo. Este es el flujo de trabajo detrás de nueve lanzamientos — la puerta de revisión, las cazas del arreglo-primero y la disciplina de probar-antes-de-lanzar que convierte "en mi máquina funciona" en "funciona".

Ingeniería
Proceso
Revisión de código
Una variable CSS, cinco rondas de revisión y una cadena de herramientas de Swift que mintió
Steven
Steven8 min de lectura

Una variable CSS, cinco rondas de revisión y una cadena de herramientas de Swift que mintió

La v2.0.7 de GeekBye hizo todo el overlay translúcido de forma ajustable — lo que suena a un cambio de CSS de una línea y desde luego no lo fue. La historia de verdad es lo que cazó la revisión de código: dos superficies que se negaban a difuminarse, una barra de grabación que se veía mal con la misma opacidad y un binario compilado que oscilaba 672 bytes porque nuestra propia documentación le dijo a un revisor la versión de Swift equivocada.

Ingeniería
Diseño
Compilación
Software tranquilo: matar un interruptor que parpadea y enseñar al chat a decir en qué modo está
Steven
Steven7 min de lectura

Software tranquilo: matar un interruptor que parpadea y enseñar al chat a decir en qué modo está

Dos pequeños lanzamientos de GeekBye, sin funciones estrella — solo un interruptor de ajustes que dejó de parpadear y un asistente de chat que por fin te dice si respondió en modo reunión o en modo programación. Esto es lo que de verdad cuesta el "software tranquilo", un detalle cada vez.

Producto
Diseño
Ingeniería