claude-code-arcane 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +57 -55
  3. package/agents/audio/audio-director.md +90 -0
  4. package/agents/audio/audio-programmer.md +97 -0
  5. package/agents/audio/audio-qa.md +95 -0
  6. package/agents/audio/composer.md +88 -0
  7. package/agents/audio/technical-sound-designer.md +90 -0
  8. package/agents/audio/voice-director.md +96 -0
  9. package/agents/career/career-strategist.md +88 -0
  10. package/agents/career/cv-reviewer.md +81 -0
  11. package/agents/career/hiring-manager.md +68 -0
  12. package/agents/career/mock-interviewer.md +76 -0
  13. package/agents/freelance/client-screener.md +84 -0
  14. package/agents/freelance/discovery-call.md +65 -0
  15. package/agents/freelance/pipeline-strategist.md +99 -0
  16. package/agents/freelance/proposal-reviewer.md +82 -0
  17. package/dist/cli.js +52 -13
  18. package/docs/RELEASE-SETUP.md +1 -1
  19. package/docs/SKILLS-CATALOG.md +47 -3
  20. package/docs/USER-GUIDE.md +77 -72
  21. package/docs/agent-hierarchy.md +21 -1
  22. package/docs/presentations/build_arcane_deck.py +2 -2
  23. package/docs/presentations/build_arcane_deck_12.py +2 -2
  24. package/package.json +2 -2
  25. package/profiles/audio.yaml +45 -0
  26. package/profiles/freelance.yaml +43 -0
  27. package/profiles/job-hunt.yaml +5 -2
  28. package/rules/drafter-reviewer.md +16 -3
  29. package/rules/freelance-guardrails.md +53 -0
  30. package/rules/gamedev/audio-code.md +45 -0
  31. package/skills/adaptive-music/SKILL.md +171 -0
  32. package/skills/adaptive-music/references/anti-patterns.md +53 -0
  33. package/skills/audio-audit/SKILL.md +164 -0
  34. package/skills/audio-audit/references/anti-patterns.md +65 -0
  35. package/skills/audio-audit/scripts/check_assets.py +208 -0
  36. package/skills/audio-bible/SKILL.md +119 -0
  37. package/skills/audio-bible/references/anti-patterns.md +39 -0
  38. package/skills/audio-mix/SKILL.md +151 -0
  39. package/skills/audio-mix/references/anti-patterns.md +65 -0
  40. package/skills/audio-spec/SKILL.md +107 -0
  41. package/skills/audio-spec/references/anti-patterns.md +45 -0
  42. package/skills/career-registry/SKILL.md +95 -0
  43. package/skills/career-registry/scripts/career_registry.py +488 -0
  44. package/skills/client-screen/SKILL.md +83 -0
  45. package/skills/client-screen/references/red-flags.md +95 -0
  46. package/skills/cover-letter/SKILL.md +4 -3
  47. package/skills/cv-tailor/SKILL.md +11 -2
  48. package/skills/freelance-deliver/SKILL.md +90 -0
  49. package/skills/freelance-hunt/SKILL.md +126 -0
  50. package/skills/freelance-hunt/references/templates/Connects.md +39 -0
  51. package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
  52. package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
  53. package/skills/freelance-kickoff/SKILL.md +94 -0
  54. package/skills/freelance-pipeline/SKILL.md +109 -0
  55. package/skills/freelance-pipeline/scripts/import_history.py +425 -0
  56. package/skills/freelance-profile/SKILL.md +93 -0
  57. package/skills/freelance-proposal/SKILL.md +112 -0
  58. package/skills/freelance-scan/SKILL.md +196 -0
  59. package/skills/freelance-scan/references/dedup.md +35 -0
  60. package/skills/freelance-scan/references/platforms.md +167 -0
  61. package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
  62. package/skills/interview-prep/SKILL.md +11 -3
  63. package/skills/job-aplicar/SKILL.md +5 -1
  64. package/skills/job-hunt/SKILL.md +17 -0
  65. package/skills/job-outcome/SKILL.md +15 -1
  66. package/skills/job-upskill/SKILL.md +10 -2
  67. package/skills/middleware-integration/SKILL.md +186 -0
  68. package/skills/middleware-integration/references/anti-patterns.md +69 -0
  69. package/skills/midi-compose/SKILL.md +136 -0
  70. package/skills/midi-compose/references/smf-format.md +129 -0
  71. package/skills/midi-compose/scripts/compose_midi.py +326 -0
  72. package/skills/midi-compose/templates/example-composition.json +69 -0
  73. package/skills/music-composition/SKILL.md +106 -0
  74. package/skills/music-composition/references/form.md +57 -0
  75. package/skills/music-composition/references/game-music.md +82 -0
  76. package/skills/music-composition/references/harmony.md +82 -0
  77. package/skills/music-composition/references/melody.md +48 -0
  78. package/skills/music-composition/references/orchestration.md +69 -0
  79. package/skills/music-composition/references/rhythm-groove.md +49 -0
  80. package/skills/procedural-audio/SKILL.md +157 -0
  81. package/skills/procedural-audio/references/anti-patterns.md +45 -0
  82. package/skills/sfx-design/SKILL.md +130 -0
  83. package/skills/sfx-design/references/anti-patterns.md +53 -0
  84. package/skills/spatial-audio/SKILL.md +139 -0
  85. package/skills/spatial-audio/references/anti-patterns.md +53 -0
  86. package/skills/ui-sound-design/SKILL.md +133 -0
  87. package/skills/ui-sound-design/references/anti-patterns.md +57 -0
  88. package/skills/voice-pipeline/SKILL.md +150 -0
  89. package/skills/voice-pipeline/references/anti-patterns.md +69 -0
@@ -0,0 +1,53 @@
1
+ # Freelance Guardrails (marketplaces y clientes directos)
2
+
3
+ Buscar empleo es gratis: aplicás a 40 puestos y solo perdés tiempo. Freelancear no. Cada propuesta cuesta algo, cada contrato malo toca tu reputación, y cada "¿me agregás esto rapidito?" sin cobrar sale de tu bolsillo.
4
+
5
+ Estas cuatro reglas existen porque los tres recursos que se gastan (plata, reputación, tiempo no facturado) no se recuperan.
6
+
7
+ **El costo de postularse tiene nombre distinto en cada plataforma** y las reglas valen igual: Connects en Upwork, bids en Freelancer.com, y en outreach directo son las horas que ponés en escribir la propuesta. Donde abajo diga Connects, leé "lo que te cuesta postularte".
8
+
9
+ Las rutas son relativas al career workspace (`./career-workspace/` o env `CAREER_WORKSPACE`).
10
+
11
+ ## 1. Postularse cuesta plata: no se gasta sin screen
12
+
13
+ Nunca redactar una propuesta para una oferta cuyo cliente no pasó `/client-screen`, ni para una que quedó bajo el umbral de score.
14
+
15
+ Si el usuario quiere postularse igual a una que falló el screen, se puede - **pero se le dice qué falló y se registra en la nota**. Un pago sin verificar que nadie nombró es una postulación tirada, y peor: es la propuesta que sí te contestan y termina en disputa.
16
+
17
+ ## 2. La reputación se protege rechazando
18
+
19
+ Ganar un contrato no siempre es bueno. Casi toda plataforma calcula un puntaje sobre contratos cerrados (en Upwork es el Job Success Score) donde un cliente insatisfecho pesa más que dos contentos, y con clientes directos el equivalente son las referencias que no vas a poder pedir. Un contrato con alcance difuso, presupuesto irrealista o cliente sin historial es **riesgo de reputación**, no una oportunidad.
20
+
21
+ Cuando el screen marca riesgo alto, la recomendación por defecto es no postularse. Decir "no" es una acción del pipeline, no una ausencia de acción.
22
+
23
+ ## 3. Nada se cotiza abajo del piso
24
+
25
+ Todo bid pasa por el piso declarado en `01-Perfiles/` (tarifa mínima aceptable). El piso es **neto**, después de la comisión de la plataforma: si se queda un 10%, un piso de 40 USD/h exige bidear 45. Con cliente directo la comisión es cero, pero el piso sigue siendo neto de impuestos y de las horas no facturables.
26
+
27
+ Si el usuario todavía no fijó un piso, `/freelance-scan market` da la mediana de lo que cobran otros con su perfil. Es un punto de partida, no el piso: el piso lo define su costo de vida, no el mercado.
28
+
29
+ Alcance nuevo, precio nuevo. Ninguna propuesta ni contrato se amplía sin cotizarlo: si el trabajo extra no entra en un change order con número, no entra.
30
+
31
+ ## 4. El envío siempre lo hace el usuario
32
+
33
+ Ninguna skill de este perfil envía una propuesta, acepta un contrato ni gasta el presupuesto de postulaciones. Se redacta, se revisa, se muestra, y el usuario copia y manda.
34
+
35
+ Esto no es prudencia nuestra: **la API de Upwork no tiene mutation para postularse ni para gastar Connects**, justamente para frenar bots de auto-bidding, y las demás plataformas prohíben el envío automatizado en sus términos. Ninguna skill debe pretender lo contrario, y una que lo intentara estaría violando los ToS además de esta regla.
36
+
37
+ El corolario para las **fuentes**: ninguna skill del perfil puede depender de credenciales que cada usuario tenga que conseguir por su cuenta. Este perfil lo instala cualquiera, y una fuente con API key aprobada a mano funciona para uno y está rota para el resto. Las fuentes automáticas son públicas y sin key (ver `skills/freelance-scan/references/platforms.md`); lo demás se pega a mano.
38
+
39
+ ## La estructura no la sostiene este archivo
40
+
41
+ Una regla sin columna derecha es una intención.
42
+
43
+ | Regla | Qué la hace cumplir |
44
+ |---|---|
45
+ | Screen antes de gastar en postularse | `/freelance-proposal` exige la nota de screen; sin ella, pregunta y no redacta |
46
+ | Rechazar por riesgo de reputación | `/client-screen` emite veredicto explícito; el agente `client-screener` es adversarial por diseño |
47
+ | Piso de tarifa | `/freelance-proposal` lee el piso del perfil y falla ruidoso si el bid queda abajo; `/freelance-scan market` da la referencia de mercado |
48
+ | Alcance nuevo, precio nuevo | `/freelance-pipeline` detecta drift de alcance en contratos activos y pide change order |
49
+ | Envío manual | Ningún script del perfil escribe a una plataforma: `freelance_search.py` solo lee, y no hay otro |
50
+
51
+ ## Registro
52
+
53
+ Toda decisión de no postularse se registra igual que una postulación: nota en `03-Aplicaciones/` con `estado: descartado` y el motivo en `## Notas`. Los descartes son la mitad de los datos que `/freelance-pipeline` necesita para decirte si tu criterio de selección funciona.
@@ -0,0 +1,45 @@
1
+ ---
2
+ paths:
3
+ - "src/audio/**"
4
+ ---
5
+
6
+ # Audio Code Rules
7
+
8
+ - NEVER hardcode asset paths or clip references in gameplay code — post middleware events by name/ID
9
+ - Gameplay code MUST NOT call `Play()`/`PlayOneShot()` directly — raise an audio event, let the audio layer resolve it
10
+ - Concurrency limits (max instances, priority, cooldown) MUST be declared in data, never enforced with ad-hoc counters in gameplay
11
+ - Use delta time for ALL fades, ducking ramps and RTPC interpolation (frame-rate independence)
12
+ - NO static singletons for audio state — inject the audio service
13
+ - Every RTPC/parameter driven from gameplay must be normalized and clamped at the boundary before it reaches the middleware
14
+ - Voice budget is a hard limit: define max simultaneous voices per category and drop by priority, never let it grow unbounded
15
+ - Audio must degrade silently — a missing bank or failed event NEVER throws into the gameplay frame
16
+ - Keep the audio update off the render-critical path; audio work budget is 5-10% of frame time
17
+ - Reference the audio bible section each event implements in code comments
18
+
19
+ ## Examples
20
+
21
+ **Correct** (event-driven, data-declared):
22
+
23
+ ```csharp
24
+ // Gameplay raises intent; the audio layer owns resolution and limits.
25
+ audioService.Post(AudioEvent.PlayerFootstep, transform.position);
26
+
27
+ float wetness = Mathf.Clamp01(surface.Wetness); // clamped at the boundary
28
+ audioService.SetParameter(AudioParam.SurfaceWetness, wetness);
29
+
30
+ // Fade driven by delta time, not frame count.
31
+ currentVolume = Mathf.MoveTowards(currentVolume, targetVolume, fadeRate * Time.deltaTime);
32
+ ```
33
+
34
+ **Incorrect** (hardcoded, direct, frame-dependent):
35
+
36
+ ```csharp
37
+ AudioSource.PlayClipAtPoint(
38
+ Resources.Load<AudioClip>("SFX/footstep_concrete_01"), // VIOLATION: hardcoded path
39
+ transform.position); // VIOLATION: direct playback from gameplay
40
+
41
+ AudioManager.Instance.Play("footstep"); // VIOLATION: static singleton
42
+
43
+ currentVolume -= 0.02f; // VIOLATION: no delta time
44
+ audioService.SetParameter(AudioParam.SurfaceWetness, rawSensorValue); // VIOLATION: unclamped
45
+ ```
@@ -0,0 +1,171 @@
1
+ ---
2
+ name: adaptive-music
3
+ description: "Musica interactiva para juegos: layering vertical, re-secuenciacion horizontal, stingers, reglas de transicion con sync points, y mapeo de estados de gameplay a musica. Usar para: musica adaptativa, sistema de musica dinamica, transiciones musicales, combat music."
4
+ category: "audio"
5
+ argument-hint: "[design|layers|transitions|stingers|map]"
6
+ user-invocable: true
7
+ allowed-tools: Read, Glob, Grep, Write, Edit
8
+ ---
9
+ # adaptive-music — Sistemas de Música Interactiva
10
+
11
+ Diseña el sistema que decide **qué música suena cuándo** y **cómo pasa de un estado a otro sin que se escuche la costura**.
12
+
13
+ Esta skill diseña el sistema. El material musical lo escribe `/music-composition`; la implementación en middleware la baja `/middleware-integration`.
14
+
15
+ ## Cuándo usar
16
+
17
+ - Cuando la música tiene que responder a gameplay y no alcanza con reproducir un track
18
+ - Cuando las transiciones entre estados (exploración → combate → victoria) suenan a corte
19
+ - Cuando el loop fatiga y necesitás variación estructural, no otro track
20
+ - Antes de que el compositor escriba una nota: el sistema condiciona cómo se compone
21
+
22
+ ## Modos
23
+
24
+ | Modo | Qué hace |
25
+ |---|---|
26
+ | `design` | El sistema completo: eje dominante, capas/segmentos, matriz, stingers, parámetros |
27
+ | `layers` | Solo la arquitectura vertical: qué capas, qué rol, qué restricción compositiva |
28
+ | `transitions` | Solo la matriz de transiciones con sync points y segmentos de transición |
29
+ | `stingers` | Solo los stingers: armonía, sincronización, cooldown |
30
+ | `map` | Solo la tabla estado de gameplay → música, con triggers e histéresis |
31
+
32
+ ## Input
33
+
34
+ 1. Leer audio bible, sección 2 (emotional targets por game state) y 6 (music direction). Si no existe, avisar y ofrecer `/audio-bible`
35
+ 2. Listar los estados de gameplay reales — del código o del GDD, no inventados
36
+ 3. Preguntar al usuario: middleware target (Wwise / FMOD / engine nativo / sin definir), budget de memoria para música, y si hay material compuesto o se parte de cero
37
+
38
+ ---
39
+
40
+ ## Los dos ejes
41
+
42
+ Todo sistema de música adaptativa es una combinación de estos dos. Elegir cuál domina es la primera decisión.
43
+
44
+ ### Vertical — layering
45
+
46
+ Un mismo bloque temporal, capas que entran y salen. Todas suenan sincronizadas porque comparten grid y armonía.
47
+
48
+ - **Fuerte en:** respuesta inmediata a parámetros continuos (proximidad de enemigo, salud, intensidad de combate)
49
+ - **Débil en:** cambiar de material. Todo suena a la misma pieza
50
+ - **Costo:** memoria (N stems simultáneos) y una restricción compositiva real — cada capa debe funcionar sola y en toda combinación
51
+
52
+ ### Horizontal — re-secuenciación
53
+
54
+ Segmentos distintos que se concatenan según reglas, con transiciones en puntos musicalmente válidos.
55
+
56
+ - **Fuerte en:** cambiar de material y de forma; estructura no repetitiva
57
+ - **Débil en:** respuesta inmediata. La transición espera el sync point
58
+ - **Costo:** latencia de respuesta (hasta un compás o más) y complejidad de reglas
59
+
60
+ **Recomendación:** vertical para intensidad continua, horizontal para cambios de estado discretos. La mayoría de los juegos necesitan los dos: capas dentro de cada segmento, re-secuenciación entre segmentos.
61
+
62
+ ---
63
+
64
+ ## Sync points — dónde se puede cortar
65
+
66
+ Una transición suena bien o mal según **dónde** ocurre, no según el crossfade. De más responsivo a más musical:
67
+
68
+ | Sync point | Latencia | Cuándo usarlo |
69
+ |---|---|---|
70
+ | **Inmediato** | 0 | Emergencias (muerte del jugador). Suena a corte, y a veces eso está bien |
71
+ | **Siguiente beat** | hasta 1 beat | Reacción rápida que igual respeta el pulso |
72
+ | **Siguiente compás (bar)** | hasta 1 compás | El default sano para la mayoría de los casos |
73
+ | **Siguiente grid** | variable | Cuando definís una grilla más gruesa (2 o 4 compases) |
74
+ | **Exit cue** | hasta el fin del segmento | Máxima musicalidad, máxima latencia |
75
+ | **Entry cue del destino** | — | Define desde dónde arranca el segmento destino |
76
+
77
+ **Segmento de transición** — un fragmento corto que se inserta entre origen y destino. Resuelve los saltos que ningún sync point salva: cambio de tonalidad, de tempo o de métrica. Es la herramienta que más mejora un sistema y la que menos se usa.
78
+
79
+ En Wwise esto es la Transition Matrix del Music Switch Container: origen × destino, con Exit Cue del origen, Entry Cue del destino, fade in/out, y segmento de transición opcional. En FMOD el equivalente son transition regions y transition timelines. El concepto es el mismo; la nomenclatura cambia.
80
+
81
+ ---
82
+
83
+ ## Stingers
84
+
85
+ Frases cortas que se superponen sin interrumpir la música de fondo, sincronizadas al grid para que no suenen encima del tiempo equivocado.
86
+
87
+ - Uso: eventos puntuales que merecen puntuación musical — descubrimiento, kill, item raro, fallo
88
+ - **Deben compartir armonía con el material de fondo**, o sonar deliberadamente disonantes. Un stinger en la tonalidad equivocada es el error más audible del sistema
89
+ - Sincronizar a beat o compás, nunca inmediato
90
+ - Definir cooldown: dos stingers superpuestos suenan a error
91
+ - Si el fondo modula, el stinger necesita versiones por tonalidad o tiene que ser tonalmente neutro (percusión, cluster, ruido)
92
+
93
+ ---
94
+
95
+ ## Diseño del mapeo
96
+
97
+ El entregable central: la tabla estado → música.
98
+
99
+ | Estado de gameplay | Trigger | Segmento / capas | Sync point | Notas |
100
+ |---|---|---|---|---|
101
+ | Explore calm | default | bed + pulse | bar | loop indefinido |
102
+ | Explore alert | enemigo a <30 m | + harmony | beat | vuelve a calm con 5 s de histéresis |
103
+ | Combat | combate iniciado | segmento combat, todas las capas | bar | |
104
+ | Combat low health | HP < 25% | + intensity, filtro | beat | |
105
+ | Victory | combate resuelto | stinger + segmento victory | exit cue | one-shot, vuelve a explore |
106
+ | Death | HP = 0 | inmediato, corte | inmediato | |
107
+
108
+ **Parámetros continuos** aparte: qué RTPC/parámetro maneja qué, con rango normalizado y curva.
109
+
110
+ | Parámetro | Rango | Controla | Curva |
111
+ |---|---|---|---|
112
+ | `combat_intensity` | 0-1 | volumen de capa intensity | log |
113
+ | `player_health` | 0-1 | filtro low-pass sobre el bus música | lineal |
114
+
115
+ ---
116
+
117
+ ## Histéresis — el detalle que rompe los sistemas
118
+
119
+ Un estado que se calcula por umbral (`enemigo a <30 m`) va a oscilar cuando el jugador camine en el borde. El resultado es música entrando y saliendo cada segundo.
120
+
121
+ Toda transición basada en umbral necesita:
122
+ - **Umbrales distintos por dirección** — entra a 30 m, sale a 40 m
123
+ - **Tiempo mínimo en estado** — no se puede salir antes de N segundos
124
+ - **Debounce del trigger** — la condición tiene que sostenerse antes de contar
125
+
126
+ Sin esto, el sistema funciona en el editor y falla con un jugador real.
127
+
128
+ ---
129
+
130
+ ## Enfoques generativos
131
+
132
+ Cuando la variación por capas y segmentos no alcanza:
133
+
134
+ - **Selección estocástica de capas/segmentos** — la variación sale de qué combinación suena. El más barato y controlable; empezar acá siempre
135
+ - **Cadenas de Markov** — melodía estocástica entrenada sobre material propio. Preserva idioma, no genera estructura
136
+ - **L-systems / gramáticas recursivas** — generan estructura jerárquica por reescritura de reglas. Complemento de Markov, que no tiene forma
137
+ - **Restricciones armónicas** — capa de validación sobre lo generado: el generador propone, las reglas de función y voice leading filtran
138
+
139
+ La generación de notas en tiempo real tiene un techo de calidad y un riesgo de que suene mal en producción que la selección de material pregrabado no tiene. Justificar antes de ir por ahí.
140
+
141
+ ---
142
+
143
+ ## Proceso
144
+
145
+ 1. **Listar estados reales** del gameplay, con sus triggers exactos
146
+ 2. **Elegir el eje dominante** (vertical / horizontal / mixto) y justificarlo contra el budget
147
+ 3. **Definir capas o segmentos** y la restricción compositiva que impone al compositor
148
+ 4. **Llenar la matriz de transiciones** con sync points, y marcar dónde hace falta segmento de transición
149
+ 5. **Definir stingers** con su armonía y cooldown
150
+ 6. **Definir parámetros continuos** con rango y curva
151
+ 7. **Agregar histéresis** a toda transición por umbral
152
+ 8. **Presentar** al usuario y preguntar "¿Escribo el diseño a `<path>`?" antes de usar Write
153
+
154
+ ---
155
+
156
+ ## Verdict
157
+
158
+ - **READY** — la matriz está completa, todo umbral tiene histéresis, los stingers tienen armonía definida, y el compositor sabe qué restricción respetar
159
+ - **CONCERNS** — el diseño existe pero hay transiciones sin sync point, umbrales sin histéresis, o el budget de memoria no se verificó contra el número de stems
160
+ - **BLOCKED** — los estados de gameplay no están definidos, o no hay dirección musical de la cual derivar los emotional targets
161
+
162
+ ## Anti-patterns
163
+
164
+ > → Read references/anti-patterns.md
165
+
166
+ ## Next steps
167
+
168
+ - `/music-composition` para escribir el material respetando las restricciones de capas
169
+ - `/middleware-integration` para implementar la matriz en Wwise/FMOD
170
+ - `/audio-mix` para el ducking entre música y diálogo
171
+ - `/audio-audit` para verificar memoria y voice count del sistema en runtime
@@ -0,0 +1,53 @@
1
+ # Música Adaptativa — Anti-patterns
2
+
3
+ ## Crossfade como única transición
4
+
5
+ Fundir dos piezas en tonalidades o tempos distintos suena a error, no a transición. El crossfade solo funciona si el material comparte armonía y grid. Si no, hace falta sync point + segmento de transición.
6
+
7
+ ## Transiciones inmediatas por default
8
+
9
+ Cortar al instante es responsivo y musicalmente destructivo. Reservarlo para muerte del jugador y cortes deliberados. El default sano es siguiente compás.
10
+
11
+ ## Umbrales sin histéresis
12
+
13
+ El caso clásico: el jugador camina en el borde de un radio de detección y la música de combate entra y sale seis veces en diez segundos. Umbrales asimétricos + tiempo mínimo en estado + debounce. Siempre.
14
+
15
+ ## Capas que dependen entre sí
16
+
17
+ Si la capa de melodía se escribió asumiendo que la de armonía suena, al quitar la armonía la melodía queda flotando sin contexto. Cada capa tiene que funcionar sola y con cualquier subconjunto de las de abajo.
18
+
19
+ ## Stingers en la tonalidad equivocada
20
+
21
+ El error más audible del sistema. Si el fondo modula y el stinger es tonal y fijo, va a chocar. Versiones por tonalidad, o stingers tonalmente neutros.
22
+
23
+ ## Stingers sin cooldown
24
+
25
+ Cinco kills en dos segundos disparan cinco stingers superpuestos. Suena a bug.
26
+
27
+ ## Contar los stems y no la memoria
28
+
29
+ Ocho stems estéreo a 48 kHz sonando simultáneos es mucho más que "ocho archivos". Si van descomprimidos en memoria, el número crece rápido. Verificar el budget antes de comprometer la arquitectura vertical.
30
+
31
+ ## Diseñar el sistema después de componer
32
+
33
+ Si el compositor entregó una pieza lineal de tres minutos con clímax, convertirla en capas es imposible sin rehacerla. El sistema se diseña primero y define la restricción compositiva.
34
+
35
+ ## Un estado por situación
36
+
37
+ Veinte estados de música para veinte situaciones de gameplay produce una matriz de transiciones de 400 celdas que nadie va a autorear bien. Agrupar situaciones por emotional target: la mayoría de los juegos vive bien con 4-6 estados.
38
+
39
+ ## Loop que cierra con cadencia auténtica
40
+
41
+ Cada vuelta suena a arranque forzado. Cerrar abierto: semicadencia, pedal, cadencia plagal.
42
+
43
+ ## Música ocupando el rango del diálogo
44
+
45
+ Si el arreglo vive en 500 Hz-2 kHz y hay VO, uno de los dos pierde, y el ducking agresivo se escucha. Se resuelve en el arreglo, no en el mix.
46
+
47
+ ## Ignorar el estado inicial y el retorno
48
+
49
+ Se diseña explore → combat con cuidado y se olvida combat → explore. El retorno es la transición que el jugador escucha más veces.
50
+
51
+ ## Probar solo en el editor
52
+
53
+ El editor de middleware permite disparar estados a mano, en el orden correcto, sin ruido. El jugador real dispara transiciones en secuencias imposibles. Probar con gameplay, no con botones.
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: audio-audit
3
+ description: "Auditoria de audio: voice count, CPU, memoria, streaming, compliance de loudness (ASWG-R001), conformidad de assets contra spec y checklist por plataforma. Usar para: QA de audio, performance de audio, verificar loudness, revisar assets, pre-certificacion."
4
+ category: "audio"
5
+ argument-hint: "[full | perf | loudness | assets | platform]"
6
+ user-invocable: true
7
+ allowed-tools: Read, Glob, Grep, Write, Edit, Bash
8
+ ---
9
+ # audio-audit — QA y Compliance de Audio
10
+
11
+ Verifica que el audio del proyecto cumple: performance dentro del presupuesto, assets conformes al spec, y loudness dentro del target de plataforma.
12
+
13
+ ## Cuándo usar
14
+
15
+ - Antes de una milestone o de certificación
16
+ - El audio se corta, se satura o come demasiado CPU
17
+ - Verificar assets entregados por un contractor
18
+ - Auditar loudness para cumplir requisitos de plataforma
19
+ - Después de integrar un sistema nuevo, para medir su costo real
20
+
21
+ ## Input
22
+
23
+ 1. Leer audio bible (sección 8, standards) y los specs de `/audio-spec`
24
+ 2. Determinar plataformas target, y cuál es la más baja
25
+ 3. Preguntar al usuario: alcance (`full` / solo perf / solo loudness / solo assets) y si hay captura de profiler disponible
26
+
27
+ ---
28
+
29
+ ## 1. Performance
30
+
31
+ **Presupuesto:** el audio dispone del **5-10% del frame time**. A 60 fps el frame son 16.6 ms, así que el audio tiene ~0.8-1.7 ms. A 90 fps (VR) el frame son ~11 ms y el margen es menor.
32
+
33
+ | Métrica | Cómo se mide | Verdict |
34
+ |---|---|---|
35
+ | **CPU de audio** | Profiler del middleware, en gameplay real | FAIL si supera el 10% del frame sostenido |
36
+ | **Voces activas** | Pico vs límite configurado | CONCERNS si el pico toca el límite; FAIL si hay descartes de sonidos de prioridad alta |
37
+ | **Memoria de audio** | Por bank y total, vs budget del proyecto | FAIL si supera el budget en la plataforma más baja |
38
+ | **Accesos de streaming** | Contador de streaming del profiler | CONCERNS si hay starvation |
39
+ | **Game objects registrados** | Contador, medido a lo largo de una sesión larga | FAIL si crece monótonamente (leak) |
40
+
41
+ **Medir en gameplay real, no en el editor.** El editor dispara eventos en orden, uno por vez, sin ruido. El jugador produce combinaciones que nadie planificó. Y medir en la **plataforma más baja** del target: el presupuesto que cierra en PC no dice nada de un handheld.
42
+
43
+ **El leak de game objects es el hallazgo más frecuente.** Si el contador de objetos registrados crece durante una sesión de dos horas y nunca baja, hay des-registros faltantes. Se ve solo en sesiones largas.
44
+
45
+ ### Costos de referencia
46
+
47
+ Para saber si un número medido es razonable:
48
+
49
+ | Operación | Costo esperado por fuente |
50
+ |---|---|
51
+ | Convolución HRTF (512 taps) | ~2 ms |
52
+ | Encode ambisónico | ~0.1 ms |
53
+ | Decode ambisónico a binaural | ~1 ms total |
54
+ | Footstep procedural | ~1-2 ms |
55
+ | Síntesis de viento | ~0.5 ms/frame |
56
+ | Panning + atenuación | despreciable |
57
+
58
+ Si lo medido se desvía mucho del esperado, la causa suele ser configuración (más taps, más fuentes espacializadas de las previstas) antes que el motor.
59
+
60
+ ## 2. Loudness
61
+
62
+ Referencia de industria en juegos: **ASWG-R001** (Sony), la única especificación publicada por una plataforma mayor.
63
+
64
+ | Contexto | Loudness promedio | True peak máximo |
65
+ |---|---|---|
66
+ | Consola / home | **−23 LUFS** (±2) | **−1 dBTP** |
67
+ | Portable / handheld | **−18 LUFS** | −1 dBTP |
68
+
69
+ **Cómo medir bien:**
70
+
71
+ - Se mide el **programa completo en gameplay representativo**, no un asset aislado. Medir un `.wav` no dice nada sobre cumplimiento
72
+ - Sesión de duración suficiente para promediar: al menos varios minutos cubriendo exploración, combate y diálogo
73
+ - Medir el **true peak**, no el peak de sample: la codificación lossy puede generar picos por encima del valor medido en PCM
74
+ - **Confirmar el target vigente** de cada plataforma antes de certificación. Las recomendaciones se revisan — el promedio de ASWG también se citó como −24 LKFS, así que no confiar en un número memorizado
75
+
76
+ **Verdict:** COMPLIANT dentro del target con su tolerancia; NON-COMPLIANT fuera, o con true peak por encima de −1 dBTP.
77
+
78
+ ## 3. Conformidad de assets
79
+
80
+ Verificación mecánica contra los standards del bible. Esto se automatiza:
81
+
82
+ | Chequeo | Falla típica |
83
+ |---|---|
84
+ | Sample rate | Mezcla de 44.1 y 48 kHz en el mismo proyecto |
85
+ | Bit depth | 24-bit donde el pipeline espera 16 |
86
+ | Canales | Estéreo en un asset que se usa como fuente 3D mono |
87
+ | Naming | No sigue el patrón; rompe batch y automatización de banks |
88
+ | DC offset | Produce clicks al concatenar |
89
+ | Silencio al inicio | Retrasa el ataque; se percibe como lag |
90
+ | Clipping | Picos a 0 dBFS en el asset crudo |
91
+ | Duración vs spec | Fuera del rango especificado |
92
+ | Loudness por categoría | Assets de la misma categoría con niveles dispares |
93
+
94
+ **Fuente 3D en estéreo es el hallazgo más común y el más silencioso:** el middleware la trata distinto o la colapsa, y la localización espacial se degrada sin que nadie vea un error.
95
+
96
+ La skill trae el verificador: `scripts/check_assets.py`, stdlib-only (módulo `wave`), recursivo sobre una carpeta.
97
+
98
+ ```bash
99
+ python skills/audio-audit/scripts/check_assets.py assets/audio \
100
+ --rate 48000 --bits 16 --mono-3d --naming '^(sfx|vo|mus)_'
101
+ ```
102
+
103
+ Chequea sample rate, bit depth, canales, naming, clipping, DC offset, silencio inicial, archivos vacíos o silenciosos, y avisa cuando el sample rate obliga a un resampleo costoso. Emite `[FAIL]` / `[WARN]` / `[SKIP]` por hallazgo y cierra con COMPLIANT / CONCERNS / NON-COMPLIANT; exit code 1 solo si hay FAIL, para usarlo en CI.
104
+
105
+ Lo que necesita una herramienta externa (loudness integrado, análisis espectral) se reporta como `[SKIP]` en vez de abortar la corrida.
106
+
107
+ ## 4. Checklist por plataforma
108
+
109
+ | Ítem | Aplica a |
110
+ |---|---|
111
+ | Loudness dentro del target del contexto | Todas |
112
+ | True peak ≤ −1 dBTP | Todas |
113
+ | Manejo de interrupciones (llamada, alarma) | Móvil |
114
+ | Manejo de cambio de ruta (auriculares) | Móvil, consola |
115
+ | Respeto del switch de silencio | iOS |
116
+ | Comportamiento en background | Móvil |
117
+ | Mezcla con audio de terceros | Móvil |
118
+ | Audio no rompe al perder foco | Todas |
119
+ | Memoria dentro del budget de la plataforma | Todas |
120
+ | Se puede mutear todo desde opciones | Todas |
121
+ | Controles separados: música / SFX / voz / UI | Todas |
122
+ | Información crítica no exclusivamente por audio | Todas (accesibilidad) |
123
+ | Subtítulos para todo el diálogo | Todas (accesibilidad) |
124
+
125
+ El comportamiento en background y el switch de silencio en iOS son causas concretas de rechazo de store, no recomendaciones.
126
+
127
+ ---
128
+
129
+ ## Proceso
130
+
131
+ 1. **Determinar el alcance** y la plataforma más baja del target
132
+ 2. **Capturar** con el profiler del middleware en gameplay representativo, no en el editor
133
+ 3. **Medir performance** contra el presupuesto y comparar con los costos de referencia
134
+ 4. **Medir loudness** del programa completo, con true peak
135
+ 5. **Verificar assets** contra los standards, automatizado si el volumen lo justifica
136
+ 6. **Recorrer el checklist** de plataforma
137
+ 7. **Reportar** con severidad por hallazgo y, si el usuario lo pide, preguntar "¿Escribo el reporte a `<path>`?" antes de usar Write
138
+
139
+ ### Formato del reporte
140
+
141
+ Por hallazgo: qué se midió, valor medido, valor esperado, severidad, y dónde está el problema. Un hallazgo sin número medido no es un hallazgo, es una impresión.
142
+
143
+ ---
144
+
145
+ ## Verdict
146
+
147
+ Global, y por sección:
148
+
149
+ - **COMPLIANT** — performance dentro del presupuesto en la plataforma más baja, loudness dentro del target, assets conformes, checklist completo
150
+ - **CONCERNS** — hay desvíos que no bloquean: pico de voces tocando el límite, assets con naming inconsistente, loudness en el borde de la tolerancia
151
+ - **NON-COMPLIANT** — CPU o memoria fuera de presupuesto, loudness fuera del target, leak de game objects, o un ítem de checklist que es causa de rechazo de plataforma
152
+
153
+ Un NON-COMPLIANT en cualquier sección bloquea certificación.
154
+
155
+ ## Anti-patterns
156
+
157
+ > → Read references/anti-patterns.md
158
+
159
+ ## Next steps
160
+
161
+ - `/spatial-audio` si el costo de espacialización está fuera de presupuesto
162
+ - `/audio-mix` si el problema es loudness o balance entre categorías
163
+ - `/middleware-integration` si hay leaks, banks mal organizados o descartes de voces
164
+ - `/procedural-audio` si la memoria no cierra por cantidad de samples
@@ -0,0 +1,65 @@
1
+ # Audio Audit — Anti-patterns
2
+
3
+ ## Medir en el editor
4
+
5
+ El editor dispara eventos en orden, uno por vez, sin ruido de fondo. El jugador produce combinaciones que nadie planificó. Las mediciones del editor no predicen nada.
6
+
7
+ ## Medir en la plataforma más alta
8
+
9
+ El presupuesto cierra cómodo en PC y revienta en el handheld. La auditoría se hace contra el piso del target.
10
+
11
+ ## Medir loudness de un asset
12
+
13
+ Los targets de LUFS son del programa completo en gameplay representativo. Medir un `.wav` no dice nada sobre cumplimiento.
14
+
15
+ ## Sesión de medición demasiado corta
16
+
17
+ Treinta segundos de exploración tranquila da un LUFS que no representa el juego. La medición tiene que cubrir exploración, combate y diálogo.
18
+
19
+ ## Confiar en un target memorizado
20
+
21
+ Las recomendaciones de plataforma se revisan. Confirmar el vigente antes de certificación.
22
+
23
+ ## Medir peak de sample en vez de true peak
24
+
25
+ Un mix que llega a 0 dBFS en PCM puede generar picos por encima al codificarse en lossy. El −1 dBTP existe justamente por eso.
26
+
27
+ ## No buscar leaks
28
+
29
+ El contador de game objects registrados que crece durante dos horas y nunca baja es el hallazgo más frecuente, y solo se ve en sesiones largas. Una prueba de cinco minutos no lo encuentra.
30
+
31
+ ## Aceptar el pico de voces al límite
32
+
33
+ Si el pico toca el límite configurado, cualquier situación un poco peor empieza a descartar sonidos. Y si lo que se descarta es feedback de la acción del jugador, el juego se siente roto sin ningún error visible.
34
+
35
+ ## Ignorar qué se descarta
36
+
37
+ El número de descartes por sí solo no dice nada. Lo que importa es la prioridad de lo descartado: perder un ambiente lejano está bien, perder el disparo del jugador no.
38
+
39
+ ## Fuente 3D en estéreo
40
+
41
+ El hallazgo más silencioso: el middleware la colapsa o la trata distinto, y la localización espacial se degrada sin que aparezca ningún error. Verificar canales por categoría de uso.
42
+
43
+ ## Mezcla de sample rates
44
+
45
+ 44.1 y 48 kHz en el mismo proyecto obliga a resampleo en runtime, que cuesta CPU y puede introducir artefactos. Un solo sample rate por proyecto.
46
+
47
+ ## Silencio al inicio del asset
48
+
49
+ Retrasa el ataque y se percibe como lag de input, aunque el código responda instantáneo. Se detecta automáticamente y casi nunca se busca.
50
+
51
+ ## Hallazgo sin número
52
+
53
+ "El audio suena saturado" no es un hallazgo. Qué se midió, valor medido, valor esperado, dónde. Sin eso, nadie puede arreglarlo ni verificar que se arregló.
54
+
55
+ ## Auditar a mano miles de assets
56
+
57
+ La conformidad de sample rate, canales, naming y duración es mecánica: se automatiza. La inspección manual de 4.000 archivos garantiza que algo se pase por alto.
58
+
59
+ ## Fallar cuando falta una herramienta externa
60
+
61
+ Si el chequeo profundo necesita una herramienta que no está instalada, reportar `[SKIP]` y seguir. Abortar la auditoría entera por una dependencia opcional deja al usuario sin los chequeos que sí se podían correr.
62
+
63
+ ## Dejar el checklist de plataforma para el final
64
+
65
+ El comportamiento en background y el switch de silencio en iOS son causas concretas de rechazo. Descubrirlos en certificación cuesta una release.