@xmarts/genius-setup 1.16.0 → 1.16.1

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.
@@ -16,6 +16,7 @@ Hard rules:
16
16
  """
17
17
  import json
18
18
  import os
19
+ import shutil
19
20
  import sys
20
21
  import urllib.request
21
22
 
@@ -89,7 +90,7 @@ def _inject(cfg, prompt):
89
90
  # version dictated by the server (xma_genius.hook_pin_version, returned in the
90
91
  # inject response) and otherwise fall back to this bundled known-good pin — the
91
92
  # client never resolves the mutable `@latest` tag.
92
- PINNED_FALLBACK = "1.7.2"
93
+ PINNED_FALLBACK = "1.16.1"
93
94
 
94
95
 
95
96
  def _pkg_spec(pin_version):
@@ -103,6 +104,45 @@ def _pkg_spec(pin_version):
103
104
  return "@xmarts/genius-setup@%s" % PINNED_FALLBACK
104
105
 
105
106
 
107
+ def _resolve_npx():
108
+ """Absolute path to npx (npx.cmd on Windows), so a detached process whose PATH
109
+ was stripped (Windows / the VSCode extension host) can still launch the self-
110
+ update. PATH first, then the usual install locations; None if truly absent."""
111
+ exe = "npx.cmd" if os.name == "nt" else "npx"
112
+ found = shutil.which(exe) or shutil.which("npx")
113
+ if found:
114
+ return found
115
+ cands = []
116
+ if os.name == "nt":
117
+ appdata = os.environ.get("APPDATA", "")
118
+ pf = os.environ.get("ProgramFiles", r"C:\Program Files")
119
+ pf6432 = os.environ.get("ProgramW6432", pf)
120
+ nvm = os.environ.get("NVM_SYMLINK", "")
121
+ for b in (os.path.join(appdata, "npm"), os.path.join(pf, "nodejs"),
122
+ os.path.join(pf6432, "nodejs"), nvm):
123
+ if b:
124
+ cands.append(os.path.join(b, "npx.cmd"))
125
+ else:
126
+ cands += ["/usr/local/bin/npx", "/opt/homebrew/bin/npx", "/usr/bin/npx",
127
+ os.path.join(HOME, ".npm-global", "bin", "npx"),
128
+ os.path.join(HOME, ".volta", "bin", "npx")]
129
+ try:
130
+ import glob
131
+ nvms = sorted(glob.glob(
132
+ os.path.join(HOME, ".nvm", "versions", "node", "*", "bin", "npx")))
133
+ if nvms:
134
+ cands.append(nvms[-1])
135
+ except Exception:
136
+ pass
137
+ for c in cands:
138
+ try:
139
+ if c and os.path.exists(c):
140
+ return c
141
+ except Exception:
142
+ pass
143
+ return None
144
+
145
+
106
146
  def _maybe_self_update(cfg, force_epoch=None, pin_version=None, mcp_epoch=None):
107
147
  """Keep the consultant on the SERVER-PINNED Genius package with ZERO action: at most
108
148
  once/day, silently re-run the installer in the background. New hooks, MCP
@@ -146,9 +186,55 @@ def _maybe_self_update(cfg, force_epoch=None, pin_version=None, mcp_epoch=None):
146
186
  if not forced and os.path.exists(SELF_UPDATE_STAMP) and (
147
187
  time.time() - os.path.getmtime(SELF_UPDATE_STAMP)) < SELF_UPDATE_TTL:
148
188
  return
149
- # Stamp FIRST so a failing/slow npx never causes a retry storm.
189
+ # Resolve npx to an ABSOLUTE path BEFORE anything else. A detached process
190
+ # with a stripped PATH (Windows / the VSCode extension host) can't find a
191
+ # bare "npx"; if we can't resolve it we must NOT burn the stamp, or the box
192
+ # can never self-heal (the Windows silent-failure bug). All logged.
193
+ log_path = os.path.join(HOME, ".genius", ".selfupdate.log")
194
+
195
+ def _log(msg):
196
+ try:
197
+ os.makedirs(os.path.dirname(log_path), exist_ok=True)
198
+ with open(log_path, "a") as fh:
199
+ fh.write("%s %s\n" % (time.strftime("%Y-%m-%dT%H:%M:%S"), msg))
200
+ except Exception:
201
+ pass
202
+
203
+ npx = _resolve_npx()
204
+ if not npx:
205
+ _log("self-update SKIPPED: npx not resolvable (PATH + known dirs); will retry")
206
+ return # no stamp -> retry next turn instead of getting stuck for a day
207
+ env = dict(os.environ)
208
+ env["GENIUS_TOKEN"] = token
209
+ base = cfg.get("base_url")
210
+ spec = _pkg_spec(pin_version) # exact pinned version — never @latest
211
+ try:
212
+ logfh = open(log_path, "a")
213
+ logfh.write("%s self-update launch: %s via %s\n" % (
214
+ time.strftime("%Y-%m-%dT%H:%M:%S"), spec, npx))
215
+ logfh.flush()
216
+ except Exception:
217
+ logfh = open(os.devnull, "w")
218
+ try:
219
+ if os.name == "nt":
220
+ # Absolute npx.cmd through cmd.exe so a stripped PATH can't break it.
221
+ cmd = '"%s" -y %s' % (npx, spec)
222
+ if base:
223
+ cmd += ' --base-url "%s"' % base
224
+ subprocess.Popen(cmd, shell=True, env=env, stdout=logfh, stderr=logfh,
225
+ stdin=subprocess.DEVNULL, creationflags=0x00000008) # DETACHED_PROCESS
226
+ else:
227
+ args = [npx, "-y", spec]
228
+ if base:
229
+ args += ["--base-url", base]
230
+ subprocess.Popen(args, env=env, stdout=logfh, stderr=logfh,
231
+ stdin=subprocess.DEVNULL, start_new_session=True)
232
+ except Exception as e:
233
+ _log("self-update launch FAILED: %s (will retry next turn)" % e)
234
+ return # launch failed -> no stamp -> retry
235
+ # Stamp ONLY after a successful launch: a resolvable-but-unlaunchable box
236
+ # keeps retrying, while a launched (slow) npx never re-spawns every turn.
150
237
  try:
151
- os.makedirs(os.path.dirname(SELF_UPDATE_STAMP), exist_ok=True)
152
238
  with open(SELF_UPDATE_STAMP, "w") as fh:
153
239
  fh.write(str(int(time.time())))
154
240
  if force_epoch:
@@ -158,24 +244,7 @@ def _maybe_self_update(cfg, force_epoch=None, pin_version=None, mcp_epoch=None):
158
244
  with open(MCP_EPOCH_STAMP, "w") as fh:
159
245
  fh.write(str(int(mcp_epoch)))
160
246
  except Exception:
161
- return
162
- env = dict(os.environ)
163
- env["GENIUS_TOKEN"] = token
164
- base = cfg.get("base_url")
165
- spec = _pkg_spec(pin_version) # exact pinned version — never @latest
166
- devnull = open(os.devnull, "w")
167
- if os.name == "nt":
168
- cmd = "npx -y %s" % spec
169
- if base:
170
- cmd += ' --base-url "%s"' % base
171
- subprocess.Popen(cmd, shell=True, env=env, stdout=devnull, stderr=devnull,
172
- stdin=subprocess.DEVNULL, creationflags=0x00000008) # DETACHED_PROCESS
173
- else:
174
- args = ["npx", "-y", spec]
175
- if base:
176
- args += ["--base-url", base]
177
- subprocess.Popen(args, env=env, stdout=devnull, stderr=devnull,
178
- stdin=subprocess.DEVNULL, start_new_session=True)
247
+ pass
179
248
  except Exception:
180
249
  pass
181
250
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xmarts/genius-setup",
3
- "version": "1.16.0",
3
+ "version": "1.16.1",
4
4
  "description": "One-command, self-updating onboarding for Xmarts Genius (Brain MCP + per-turn injection + automatic session/time capture + presence heartbeat for honest time-tracking 'amarre' + plan/committee→Brain enforcement + CLAUDE.md protocol + MCP fan-out: provisions the consultant's granted MCP servers into Claude Code & Claude Desktop). Secret-free onboarding via single-use setup-token exchange. Installs once; self-updates daily so new tools/skills/features arrive with zero action.",
5
5
  "bin": {
6
6
  "genius-setup": "bin/genius-setup.js"
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: content-humanizer
3
+ description: Humaniza texto para que NADA que produzcamos parezca escrito por IA (cero em-dash, cero frases plantilla, cero paralelismo negativo). USAR siempre que se genere o revise texto que verá una persona (guion, correo, deck, binder, post, propuesta, prosa de un análisis) o cuando el consultor pida "humaniza esto", "¿suena a IA?", "quita los em-dash", "revisa señales de IA", o antes de enviar cualquier copy. Trilingüe ES/EN/PT. La red de seguridad es cf_slop_check en el MCP contentforge.
4
+ ---
5
+
6
+ # Humanizer: cero señales de escritura por IA
7
+
8
+ Regla NO negociable de Xmarts: nada que generemos (nosotros o cualquier
9
+ consultor, en Claude Code, ContentForge, decks, binders, webapps, correos o
10
+ prosa, en ES, EN o PT) debe parecer escrito por IA. El diferenciador de Xmarts
11
+ es la calidad. Un texto con señales de IA nos abarata. Esta regla aplica a la
12
+ ESCRITURA; la directriz hermana anti-AI-design cubre el diseño.
13
+
14
+ ## Prevención primero (lo más barato), linter después (la red)
15
+ Escribir bien desde el principio cuesta menos que limpiar. El orden correcto es:
16
+ 1. Redactar plano y específico (ver reglas abajo).
17
+ 2. Pasar el texto por el gate: `cf_slop_check` (MCP `contentforge`) o
18
+ `cf slop-check` en CLI. Devuelve las señales encontradas con línea, categoría
19
+ y nota, más un veredicto CLEAN o TELLS.
20
+ 3. Reescribir cada ERROR y volver a checar. Los WARN son revisión humana.
21
+
22
+ ## Las señales que delatan a la IA (y qué hacer)
23
+ - **Em-dash y en-dash como conector (— o –): jamás.** Usa coma, dos puntos, <!-- slop-lint-ignore -->
24
+ paréntesis o punto. Esta es la señal número uno.
25
+ - **Frases plantilla**: "cabe destacar", "en un mundo cada vez más", "sumérgete", <!-- slop-lint-ignore -->
26
+ "it's important to note", "stands as a testament", "em conclusão", "é <!-- slop-lint-ignore -->
27
+ importante ressaltar". Bórralas y ve directo al punto.
28
+ - **Paralelismo negativo**: "no solo... sino", "it's not X, it's Y", "não apenas... <!-- slop-lint-ignore -->
29
+ mas". Afírmalo en positivo.
30
+ - **Regla de tres (tricolon)**: tres adjetivos o cláusulas en fila por ritmo.
31
+ Deja uno, el que importa.
32
+ - **Atribución fantasma**: "algunos expertos", "some experts argue", "se dice <!-- slop-lint-ignore -->
33
+ que". Cita a alguien real o quítalo.
34
+ - **Palabras bandera**: delve, tapestry, testament, seamless, boasts, tapeçaria, <!-- slop-lint-ignore -->
35
+ potenciar, desbloquear el potencial. Cámbialas por el sustantivo concreto. <!-- slop-lint-ignore -->
36
+
37
+ ## Cómo suena un texto humano
38
+ - Sustantivos concretos sobre adjetivos. Cifras y hechos sobre superlativos.
39
+ - Frases de largo variado. Punto final en vez de signo de exclamación.
40
+ - Voz activa, sujeto claro, una idea por frase.
41
+ - Si una frase se puede borrar sin perder información, bórrala.
42
+
43
+ ## Dónde ya está blindado
44
+ - **ContentForge (reel)**: el pipeline corre el gate sobre el guion y la
45
+ narración ANTES de gastar en voz, imágenes o render. Un ERROR detiene el reel,
46
+ así que nunca se publica un video que se lea como IA.
47
+ - **Website de Rubén**: build que FALLA si hay slop en el HTML enviado.
48
+ - **Linter canónico**: `~/.genius/tools/ai-slop-lint` (y vendorizado en
49
+ ContentForge). Es la misma fuente de verdad trilingüe en todas partes.
50
+
51
+ ## Falsos positivos
52
+ La lista ERROR es de alta precisión. Si algo legítimo se marca (un guion cita un
53
+ em-dash de una fuente, por ejemplo), usa `allow` en el tool o `--allow` en CLI, o
54
+ el comentario `slop-lint-ignore` en esa línea. Nunca bajes la precisión del
55
+ ERROR para silenciar un caso.
56
+
57
+ ## Regla dura
58
+ El linter es la red, no el primer filtro. Entrega texto que ya pasa porque se
59
+ escribió bien, no porque se parcheó. Si vas a mandarle prosa a un consultor o a
60
+ un cliente, checa primero.
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: content-style-bible
3
+ description: Analiza y hace ingeniería inversa del ESTILO de un competidor con ContentForge (videos de YouTube, sitios web, miniaturas, diseños). USAR cuando el consultor pida estudiar/analizar/desmenuzar el estilo de un canal, video, thumbnail, landing o diseño; "cómo hace X sus videos", "analiza esta miniatura", "qué paleta/ritmo usa este canal", "reverse-engineer este estilo", "sácame un style guide de este video", "análisis de competidor" o mencione "style bible". Devuelve un reporte medido con score de honestidad. Servido desde el MCP contentforge; el consultor NUNCA toca terminal.
4
+ ---
5
+
6
+ # Style Bible: análisis medido de estilo (ContentForge)
7
+
8
+ El motor Style-Bible de ContentForge convierte cualquier fuente (un video de
9
+ YouTube, un sitio web, una miniatura o una imagen de diseño) en un binder
10
+ analítico medido, con el depth de un desglose editorial serio pero honesto por
11
+ construcción: **el LLM nunca produce un número**. La paleta sale de k-means
12
+ sobre pixeles reales, los cortes de un detector de escenas, la recurrencia de
13
+ módulos de perceptual hashing, los tokens tipográficos del DOM. Lo cualitativo
14
+ (tipografía, composición, tesis) se etiqueta como opinión, no se disfraza de
15
+ dato.
16
+
17
+ Es la forma ESTÁNDAR de auditar a un competidor o una pieza de contenido. Si el
18
+ consultor pregunta "cómo logra este canal ese look" o "qué está haciendo bien
19
+ esta miniatura", esto responde con evidencia, no con adjetivos.
20
+
21
+ ## Regla base: Xmarts sirve, el consultor consume
22
+ El consultor pide en lenguaje natural, TÚ ejecutas vía el MCP `contentforge`
23
+ (servido desde VPS). Cero instalación, cero git, cero terminal del consultor.
24
+
25
+ ## Las tres fuentes (lanes)
26
+ | Fuente | Qué mide (todo medido) |
27
+ |---|---|
28
+ | **youtube_video** | Paleta (k-means), cortes por minuto, ritmo, recurrencia de módulos (dHash), y con transcript: pace en wpm + cold open verbatim |
29
+ | **website** | Paleta y escala tipográfica leídas del DOM (getComputedStyle ponderado por área), familias de fuente, copy de CTAs |
30
+ | **image / thumbnail** | Paleta (k-means), contraste WCAG local, y lectura cualitativa de visión (etiquetas, sin números) |
31
+
32
+ ## Cómo se usa (patrón async: analiza, sondea, recoge)
33
+ Los análisis pueden tardar minutos (descarga, frames, visión). Por eso el flujo
34
+ es asíncrono:
35
+
36
+ 1. **Lanzar**: `cf_style_analyze` con `ref` (URL de YouTube, URL de sitio, o
37
+ ruta/URL de imagen). El tipo se infiere; puedes forzarlo con `type`. Devuelve
38
+ un `bible_id` de inmediato, más learnings previos del Brain que aterrizan el
39
+ análisis.
40
+ 2. **Sondear**: `cf_style_status` con el `bible_id` hasta `done` (o `failed` con
41
+ una razón concreta: video privado, muro anti-bot, formato no disponible).
42
+ 3. **Recoger**: `cf_style_get` con el `bible_id` devuelve la verdad JSON, el
43
+ resumen de honestidad, y las rutas del reporte gold (HTML + Markdown + JSON).
44
+ 4. **Listar** lo reciente: `cf_style_list`.
45
+
46
+ El reporte HTML es autocontenido (cero requests externos, specimens embebidos),
47
+ con nueve secciones, badges de evidencia por dato, modelo de dos paletas WCAG, y
48
+ la columna módulo→Remotion.
49
+
50
+ ## Cómo leer el reporte
51
+ - **Barra de honestidad**: el porcentaje de datos medidos vs observados,
52
+ inferidos y de juicio. Un website suele medir alto (el DOM es exacto); un
53
+ thumbnail lleva más inferidos por diseño (la visión etiqueta, no mide). Eso es
54
+ una señal de calidad honesta, no un defecto.
55
+ - **Badges por dato**: `measured` (una instrumento lo produjo, con su fuente),
56
+ `observed` (un artefacto real: un frame, una cita), `inferred` (una etiqueta
57
+ del LLM que cita evidencia medida), `judgment` (una opinión honesta).
58
+ - **Library de módulos**: cada módulo recurrente cita frames reales y mapea a una
59
+ composición Remotion real, o dice "needs new composition" (nunca inventa un id).
60
+ - **Reproduction Stack** (sección 08): la receta para reconstruir ese estilo con
61
+ las herramientas servidas (Opus 4.8 para guion, NanoBanana2 para imágenes,
62
+ Veo para video, Remotion para animación, ElevenLabs para voz).
63
+
64
+ ## De análisis a producción
65
+ El Style Bible es el paso de INTELIGENCIA. Para convertir lo aprendido en una
66
+ pieza propia, encadena con el skill `content-war-tank` (estrategia + guion +
67
+ producción) usando el bible como brief de estilo. Nunca se copia: se aprende la
68
+ gramática visual y se produce mejor.
69
+
70
+ ## Reglas duras
71
+ - Si `cf_style_status` devuelve `failed`, lee la razón y díselo al consultor tal
72
+ cual (el motor no fabrica un reporte parcial que parezca real).
73
+ - Los números del reporte son medidos o NULL, jamás inventados.
74
+ - El reporte no lleva rastro del proceso interno: se entrega en voz neutra de
75
+ estudio.
76
+ - Antes de mandarle prosa del análisis al consultor, pásala por el gate de
77
+ humanización (skill `content-humanizer` / `cf_slop_check`).
@@ -18,6 +18,10 @@ Antes de idear nada, medir el terreno con ContentForge:
18
18
  canales/videos lideran, con qué formatos.
19
19
  - `cf_trends` → narrativas y temas en alza AHORA.
20
20
  - `cf_packaging_swaps` → títulos/miniaturas que convierten vs los que no.
21
+ - **Style Bible** (`cf_style_analyze`, skill `content-style-bible`) → teardown
22
+ MEDIDO del video/canal/thumbnail líder del nicho: paleta, ritmo de cortes,
23
+ módulos recurrentes, tipografía. Aprende la gramática visual que gana, con
24
+ evidencia, para producir mejor sin copiar.
21
25
  - Salida: un brief de oportunidad con evidencia (qué ángulo está desatendido y por qué ganaría).
22
26
 
23
27
  ### Fase 2 — ESTRATEGIA (comparativa vs competidores)
@@ -32,6 +36,9 @@ Antes de idear nada, medir el terreno con ContentForge:
32
36
  - `cf_run` genera el guion con **claude-opus-4-8** (tier deep), alimentado por el
33
37
  brief de la Fase 1 — NO un guion genérico, uno anclado a lo que la data dijo que gana.
34
38
  - `cf_guards` → validar calidad/voz/claims antes de producir (fact-check con haiku).
39
+ - **Humanización** (`cf_slop_check`, skill `content-humanizer`) → el guion y la
40
+ narración no deben leerse como IA (cero em-dash, cero frases plantilla). El
41
+ pipeline del reel ya bloquea si hay señales; checa antes para no perder el render.
35
42
  - `cf_script_get` → recuperar/versionar el guion aprobado.
36
43
 
37
44
  ### Fase 4 — STORYBOARD (gate humano obligatorio)
@@ -67,6 +74,21 @@ ElevenLabs propio (no gastar créditos de terceros en lo que ya tenemos gratis).
67
74
  - **animación** → Remotion
68
75
  - **voz** → ElevenLabs `eleven_multilingual_v2`
69
76
 
77
+ ## Bucle de suite — ContentForge ⇄ Genius/Brain (cableado, úsalo siempre)
78
+ ContentForge NO opera aislado: es miembro pleno de la suite y se comunica con el Brain.
79
+ - **ANTES de generar** un guion/estrategia: `cf_brain_query "<tema/nicho/ángulo>"` →
80
+ trae learnings previos (qué funcionó, hooks, performance) para GROUNDING. También
81
+ el consultor puede usar `query_knowledge` (MCP beesmart_genius) con
82
+ `discipline="content_creation"`.
83
+ - **DESCUBRIR qué herramienta usar**: `cf_genius_capabilities` → ContentForge VE todo
84
+ el catálogo Genius/Brain (81+ skills: NanoBanana2, Veo, Remotion, ElevenLabs, l10n…)
85
+ para rutear cada etapa a la herramienta óptima.
86
+ - **DESPUÉS de una interacción valiosa** (un guion que funcionó, un insight competitivo,
87
+ un hook ganador): `cf_brain_capture` → alimenta el Brain (disciplina content_creation,
88
+ queda draft → lo tría el LLM-judge). Así CADA pieza mejora la inteligencia del sistema.
89
+
90
+ El resultado: la máquina aprende de sí misma y de toda la suite en cada ronda.
91
+
70
92
  ## Principios no negociables
71
93
  1. **Data antes que creatividad** — sin Fase 1+2, no se produce.
72
94
  2. **Comparativa vs competidores** en cada brief (qué hacen los que ganan, dónde el gap).
@@ -43,6 +43,8 @@ pnpm doctor # DEBE dar GREEN 8/8 antes de servir
43
43
  | Render de composición | `pnpm cf render --comp KineticQuote --props f.json --out x.mp4` |
44
44
  | **Dashboard visual** | `pnpm cf ui` → http://localhost:4577 (library/detail/formulas/runs) |
45
45
  | Inteligencia competitiva (velocity + trend radar, zero-key) | `cf intel add-channel/poll/trends` |
46
+ | **Style Bible** (analizar el estilo de un video/canal/web/thumbnail) | `cf_style_analyze` → `cf_style_status` → `cf_style_get` (skill `content-style-bible`) |
47
+ | **Humanizar / revisar señales de IA** en cualquier texto | `cf_slop_check` o `cf slop-check` (skill `content-humanizer`) |
46
48
  | Costos de corridas (reales o NULL, nunca fabricados) | `pnpm cf runs` |
47
49
 
48
50
  ## Flujo recomendado (calidad máxima)
@@ -52,8 +54,46 @@ generate` + `hooks pick` (el hook decide la retención) → 4. `cf factcheck`
52
54
  6. voz con `elevenlabs-voiceover` → 7. `cf render`/`pipeline` → 8. preview
53
55
  aprobado ANTES del render final.
54
56
 
57
+ ## Superficie servida (MCP `contentforge`)
58
+ El consultor NO tiene el repo. Consume ContentForge como un MCP servido desde
59
+ VPS (`mcp__contentforge__*`), no con `pnpm cf`. Las tools clave:
60
+ - **Inteligencia**: `cf_intel_channel`, `cf_intel_leaderboard`, `cf_trends`,
61
+ `cf_packaging_swaps`, `cf_hook_library`, `cf_pacing`.
62
+ - **Style Bible** (análisis de estilo medido): `cf_style_analyze` (async, devuelve
63
+ `bible_id`), `cf_style_status`, `cf_style_get`, `cf_style_list`.
64
+ - **Humanización**: `cf_slop_check` (señala em-dash y frases de IA en cualquier
65
+ texto; ES/EN/PT).
66
+ - **Suite Genius/Brain**: `cf_brain_query` (consume learnings), `cf_brain_capture`
67
+ (alimenta el Brain), `cf_genius_capabilities` (ve todo el catálogo).
68
+ - **Estado y datos**: `cf_status`, `cf_projects`, `cf_script_get`, `cf_bundles`,
69
+ `cf_guards`. Orquestación completa vía `cf_run` (allowlist).
70
+
71
+ ## Cuándo sugerir o usar ContentForge (uso transparente)
72
+ Si el consultor plantea algo que ContentForge resuelve, ofrécelo o úsalo de una
73
+ vez, de forma transparente (no le hagas pensar en la herramienta):
74
+ - "¿cómo hace X sus videos?", "analiza este canal/thumbnail/landing", "qué estilo
75
+ usa" → **Style Bible** (`content-style-bible`).
76
+ - "hazme un video", "guion para…", "anima este artículo", "hooks para…" →
77
+ pipeline de producción (`content-war-tank` para lo estratégico).
78
+ - "¿qué está funcionando en el nicho?", "temas en alza" → inteligencia
79
+ (`cf_intel_*`, `cf_trends`).
80
+ - cualquier texto que vaya a salir (correo, deck, post, propuesta) → pásalo por
81
+ **humanización** (`cf_slop_check`) antes de entregar.
82
+ El consultor no instala nada: la herramienta ya está servida a su cuenta.
83
+
84
+ ## Acceso: quién lo tiene y cómo dar más
85
+ ContentForge está servido y con acceso ya otorgado a Tyra, Ralph, Daniela y
86
+ Rubén (verificado: el manifest de cada uno resuelve el server `contentforge`).
87
+ Para habilitarlo a MÁS consultores, un admin crea un grant en Genius: un registro
88
+ `xma.mcp.access` con `mcp_server_id` = server `contentforge`, `consultant_id` =
89
+ el consultor (usa su ficha CANÓNICA), `effect` = `grant`, `active` = true. El
90
+ manifest converge solo y la flota lo recibe sin que el consultor haga nada. El
91
+ skill `genius-operator` tiene el contrato completo.
92
+
55
93
  ## Reglas duras
56
94
  - `pnpm doctor` GREEN antes de cualquier sesión de trabajo.
95
+ - **Humanización obligatoria**: toda prosa que vea una persona pasa por
96
+ `cf_slop_check` antes de entregar (cero em-dash, cero frases de IA).
57
97
  - Fact-check obligatorio antes de publicar (claims con receipts o fuera).
58
98
  - Los costos que reporta `cf runs` son reales o NULL — jamás inventar números.
59
99
  - Guía ilustrada completa: `docs/guide/index.html` del repo (paso a paso con