Skip to content

release: develop → main (des-branding claude-brain→cortex + perf #313 de hooks + 35 commits) - #314

Merged
unjordi merged 35 commits into
mainfrom
develop
Aug 22, 2026
Merged

release: develop → main (des-branding claude-brain→cortex + perf #313 de hooks + 35 commits)#314
unjordi merged 35 commits into
mainfrom
develop

Conversation

@unjordi

@unjordi unjordi commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Release deliberado develop→main (OK súper-explícito de unjordi: "haz el release a main").

Trae VIVO a main lo que estaba en develop:

SIN squash (release conserva historia). develop NO se borra.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

unjordi and others added 30 commits August 7, 2026 12:28
…cosistema-claude.md (#41)

Rescata docs/referencia-cli-claude-code.md, que vivía UNTRACKED en el
arbol principal y se perderia con un git clean (516 lineas: referencia
del ecosistema Claude CLI / OAuth / curl al juez).

Agrega un nugget answer-first en .claude/memory/ecosistema-claude.md que
remite al doc y captura el hecho clave: la Messages API de
api.anthropic.com acepta el token OAuth de suscripcion con el header
anthropic-beta: oauth-2025-04-20.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…e/Bash) (#53)

Problema (#53): el squash-merge rompe `git branch -d` y `fetch --prune` no toca
ramas locales → las ramitas squasheadas se acumulan. La lógica de barrido ya
existía (`limpiar-ramas.sh` + lib `ramas-zombie.sh`, detección por equivalencia
de parche / PR mergeado, conserva vivas+protegidas), pero su ÚNICO trigger era
SessionStart con throttle de 24h: tras mergear seguías viendo la rama muerta
hasta la siguiente sesión.

Solución: se CABLEA el barrido al INSTANTE del merge, sin reescribir el algoritmo.
`barrer-ramas.sh` gana un 2º trigger PostToolUse/Bash que, tras un
`glab mr merge|accept` / `gh pr merge` (detectado por `acg_es_merge_mr`), lanza
`limpiar-ramas.sh` en segundo plano — que es justo cuando nace el zombie.

- Vías INDEPENDIENTES: (B) merge no toca el throttle de (A) SessionStart → A
  sigue de backstop; ambas comparten barredor y noción de "zombie".
- Debounce corto (BARRER_RAMAS_MERGE_DEBOUNCE, def 30s) para no relanzar N
  barridos en una ráfaga de merges (cada pasada ya limpia todos los zombies).
- Fail-open: sin jq / Bash no-merge / sin remoto / sin limpiar-ramas → silencio.
- Se EXTIENDE el hook existente (no un hook nuevo): sin entrada nueva en el
  MANIFEST → sin cascada al drift-widget; ev_de en install-brain devuelve el par
  doble "SessionStart| PostToolUse|Bash" (multi-evento, como exportar-sesion-master).
- Tests: +5 asserts (b5e vía B: merge→lanza+stamp, no-merge→silencio, debounce;
  e7: doble evento cableado). Batería 527 PASS; los 7 FAIL son pre-existentes y
  ajenos (2 skills huérfanas sin tile de widget, commit 4549f39).
- Doc=realidad: fila del README de `barrer-ramas.sh` actualizada al doble trigger.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…huérfanos (#45)

* docs(flowcharts): re-sincroniza leyenda-árbol de 01-05 desde README + arregla drift de 02

doc=realidad sobre la serie canónica tracked (01-05):
- Re-inyecta la leyenda-árbol (gen-leyenda-arbol.sh) en los 5 .dot: estaba
  stale vs el árbol actual del README (p.ej. recordar-cosechar describía la
  versión vieja del nudge; faltaba el espejo TaskList→estado-proyecto.md).
- 02: título usaba el circulado ① (viola CONVENCIONES §5, "rotula por nº de
  archivo") → "02 ·". Y el nodo aviso-contexto describía la métrica vieja
  ("proxy: líneas del transcript") — el código real (aviso-contexto.sh:18-25,
  69-76) mide TOKENS REALES del último `usage`; corregido a la realidad.
- Re-render de los 5 .svg (graphviz 15.0.0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(flowcharts): re-canoniza los 9 huérfanos → serie 06-14 (.dot + leyenda + doc=realidad)

Rescate de los flowcharts que estaban SOLO como .svg gitignored, sin .dot fuente ni
leyenda-árbol (deuda de mantenimiento, no basura). NO SE BORRA NADA: cada tema real
recupera su fuente versionada.

- Crea .dot fuente para 9 charts, con la leyenda-árbol inyectada (gen-leyenda-arbol.sh
  desde el árbol del README) y re-render .svg con graphviz 15.0.0.
- Re-numeración única (resuelve las colisiones dos-03/04/05 y el circulado −1). Mapeo
  viejo→nuevo documentado en CONVENCIONES.md §9:
    03-integrar②→06 · 04-comando-git③→07 · 05-push-nudges④→08 · 06-declarar-listo⑤→09
    · 07-cerrar-slice⑥→10 · 08-delegar⑦→11 · 09-orquestar⑧→12 · 10-normas📜→13 · 11-referencia🔩→14.
- doc=realidad (cotejado contra el CÓDIGO de brain/hooks/): 09 (dod-verificar) y 06
  (confirmar-merge-develop) ahora describen el JUEZ-LLM (Haiku/juez-comun.sh), no el
  pilón de regex viejo (STATUS_RE/10-mensajes). secret-scan con los patrones reales.
  14 refleja las libs compartidas actuales del MANIFEST (juez-comun la usan dod+confirmar).
- .gitignore: des-ignora los 06-14 (.dot y .svg) para que queden git-tracked (canónicos).
- CONVENCIONES.md: §5/§6 apuntan a los nuevos nº (03 = vista; 06/07/08 = sus zooms);
  §9 nueva con el inventario 01-14 + el mapeo + la decisión de diseño VISTA-vs-ZOOM
  que queda para unjordi (poda deliberada, no la fuerza este rescate).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…los 5 catálogos (#57)

El commit #275 agregó `ingenieria-inversa-gui-db-navegador` y `markdown-a-pdf`
a `brain/skills/` pero no a los catálogos que los parity-checks vigilan → 7 FAIL
(drift real). Se propagan las 2 skills, con la descripción tomada del frontmatter
de cada SKILL.md (doc = realidad), a:

- README.md — árbol 💡 Skills
- .claude/memory/MEMORY.md — árbol 💡 Skills + lista detallada
- windows/PopupForm.cs (tile) + BrainInspector.cs (clasificación de estado)
- macos/PopoverView.swift (tile + switch de estado)
- src/plasmoid/.../main.qml (tile + switch de estado)

test-brain.sh: 522/7 FAIL → 526 PASS / 0 FAIL. Verificador de árbol en paridad
(21 skills en README ↔ MEMORY ↔ brain/skills/).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…E la idea)

El checkpoint capturaba el QUÉ de cada plan/decisión pero no el linaje: al comprimir
se pierde de dónde salió la idea, y el default es re-leerse una hipótesis PROPIA como
si fuera del usuario ('unjordi cree X') → lava la idea de Claude en la voz de unjordi
(primo hermano de fabricar autorización). Fix: cada ítem del PLAN COMPLETO y cada
decisión de RESUELTO HOY llevan un marcador de PROCEDENCIA — [user: '<cita>'] /
[INFER-mío] / [juntos <fecha>] — para que el linaje viaje CON la idea a través del
compact. Regla dura: nunca convertir [INFER-mío] en [user] al re-resumir; ante duda,
[INFER-mío] (conservador).

Origen: unjordi señaló (2026-08-07) que Claude le atribuye sus propias ideas de forma
recurrente, e hipotetizó (correctamente) que es cómo Claude redacta sus memorias.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…#42)

CAUSA RAÍZ de #42 (el gate de consentimiento de costo nunca dispara): el tool de
subagentes se renombró Task→Agent, pero el CABLEADO y los checks seguían en 'Task':
- install-brain ev_de(): matcher PreToolUse|Task / PostToolUse|Task → hooks JAMÁS
  invocados con el tool nuevo 'Agent' → gate/limite/registrar/reporte muertos.
- 4 checks in-script comparaban tool_name == 'Task' literal.

Fix (precisión, restaura un candado de supervisión roto — NO afloja nada):
- ev_de(): matcher 'Task|Agent' (regex) para los 4 hooks de delegación.
- register_hook(): AUTO-SANA el matcher al re-instalar (antes solo dedupeaba por
  existencia y NUNCA actualizaba el matcher → una instalación existente con el matcher
  viejo 'Task' NO se curaba al re-correr install-brain vía widget). Ahora converge.
- delegacion-comun/gate/reporte/limite-gasto: aceptan Task|Agent.
- Tests (#42): 'Agent' dispara el gate + delegacion-reporte; e7 espera Task|Agent.
  Batería 534/0.
- doc=realidad: headers de los hooks actualizados a (Task|Agent).

Nota: para curar la instalación GLOBAL de ESTA máquina, el widget debe re-correr
install-brain (self-heal del matcher) — validación en vivo queda ligada a esa corrida.

Closes #42.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…recto (#23, C2)

C2 — persist_env_active(): captura el VALOR ACTIVO de las env del brain
(CLAUDE_SESSIONS_DRIVE, CLAUDE_SESSIONS_DEBOUNCE_MIN) y lo asienta en
settings.json .env — a diferencia de set_env_default (planta un fijo si falta),
esto persiste lo que YA está exportado al correr el bootstrap. Antídoto a
CLAUDE_SESSIONS_DRIVE seteada ad-hoc por sesión en vez de por el instalador.
SET/UPDATE si activa+no-vacía; si no está activa, NO inventa la clave.

#23 — hint de alias en entorno-esta-maquina.md: decía 'salta el alias con
/bin/<cmd>', pero en macOS grep vive en /usr/bin (no /bin) y rg/eza/etc. no
están en /bin en ningún lado → el hint MENTÍA y hacía caer en el bache. Ahora:
'command <cmd>' o '\<cmd>' (agnósticos de ubicación). Se auto-cura en el bloque
detectado al re-correr install-brain (widget).

Tests: 2 casos C2 (persiste activa · no inventa inactiva). Batería 533/0.

Closes #23.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
… B1/web-escape (#6/#7/#12/#13)

- #6 install-brain: documenta la regla de env-seeding + set revisado de env vars capturadas-si-activas.
- #7 sincronizar-cerebro --disable: de-cablea + borra hook(s) nombrado(s); dry-run default, idempotente.
- #12 guard no-bypass-deploy (tier both, ADVISORY): avisa al correr instalador/deploy a mano en vez de la herramienta oficial.
- #12a norma B1 'actualiza por la herramienta real' generalizada + su mecanismo.
- #13 norma anti-web-escape del juez.
Tests g1-g4; suite 563/0.
…tos antes del LLM (#2)

- #1 destino in-hook: parsea --base/--target-branch del comando en vez de depender solo de 'gh pr view' en vivo (root cause: PATH de launchd GUI sin gh/glab).
- #2 dod-verificar: reordena checks estructurales/baratos ANTES de invocar al LLM.
Suite 566/0.
… con el catálogo)

El comentario fijaba 13 (8 hooks + 4 normas + 1 skill) como número mágico → se desincroniza con el catálogo (justo el drift que el widget existe para evitar; #12 agregó un hook y '13' ya mentía). Ahora describe el total como derivado de BrainMissing(), sin número fijo. Solo comentario; sin cambio de lógica.
…das (#3) + bitacora.md tracked con merge=union (#8)

- #3 cerrar-slice: quita --auto-merge del recetario para el MR de mini-develop->develop/main (integracion coordinada = OK explicito, sin auto-merge); el auto-merge sigue OK para ramitas->tu-mini.
- #8 bitacora.md pasa a tracked + .gitattributes merge=union (varias sesiones appendean sin chocar).
…unificado por estatus (#18)

- #14: las decisiones pendientes se CITAN inline (opciones + recomendacion), nunca 'espera tu OK' vacio.
- #18: /to-do produce la vista agrupada por estatus, orden VIVO->CERRADO->lapidas, con tags 📘/📝/➖. Deriva del backlog durable al vuelo.
- Un item que solo espera el 'go' de unjordi es ATACABLE (🟢), no un limbo aparte.
…al final')

La línea del árbol del README describía el flujo viejo ('⚰️ Lápidas AL FINAL' inline); ahora refleja la convención real: los descartados se mudan al cementerio.md con un ID content-hash 🪦#<id>. doc=realidad.
unjordi: 'estos dos son LO MISMO'. El MCP/grafo (#48) es la FASE 4 de la estrategia de memoria, no un proyecto aparte. Se funden en Fase 4: las 5 guardas de diseño, el miedo fundado textual, la precondicion dura (cerebros sanos -> auditor #44 gate) y el estado. Fases 0-3 = camino; grafo = escalon final.
- El OK por el widget AskUserQuestion vive en .toolUseResult.answers (+annotations.notes), no en type:text -> las 2 ventanas (merge _recent_intercalado + dod usertext) lo filtraban -> el juez nunca lo veia.
- Fix: surfacea .answers+notes como linea USUARIO en ambas ventanas, SOLO si existe .answers (especifico de AskUserQuestion -> no ensancha inyeccion, frontera #3 intacta). Fail-safe intacto (merge fail-CLOSED, dod fail-OPEN), aditivo.
- Tests deterministas: widget-OK surfaceado + cita OK; el MISMO texto como stdout de Bash NO se surfacea -> filtro conservador. 538/0.
…ale por cambio de rama/cwd

- ADVISORY (nunca bloquea): additionalContext cuando el contexto de tarea rota (rama git o proyecto/cwd) en la misma sesion -> el HUD puede mostrar pendientes de la tarea anterior.
- Precision por capas: trigger objetivo (solo rama/cwd, jamas lee el HUD) · stamp per-session_id · first-sight silencioso · debounce · gate de backlog durable · fail-open.
- Tier global. Escape CLAUDE_SKIP_HUD_STALE=1. 3 refinamientos abiertos (tier both · recall dir-sin-backlog · HUD<->hilo). 578/0.
…hooks/libs)

- Nuevo brain/skills/MANIFEST (tiers global/both, paralelo del de hooks). install-brain despliega global; sincronizar-cerebro despliega por-repo las 'both' (arbol completo, diff-aware, prune por LEDGER que jamas toca skills propias del repo).
- aviso-drift/drift-cerebro-comun detectan drift de skills igual que hooks: per-repo (via resumen del sync) + GLOBAL (~/.claude/skills vs fuente) WARN-ONLY (nunca sobreescribe: la direccion puede ser 'edit en vivo sin portar').
- Seed CONSERVADOR: TODAS las skills en 'global' -> CERO cambio de comportamiento hoy; el plumbing 'both' queda listo. Decision abierta (tu OK): marcar 'both' a cerrar-slice/checkpoint/rehidratar-hilo. Antidoto al drift real (~/.claude/skills/to-do se desincronizo de la fuente). Aditivo, sin tocar fail-safes. 598/0.
…EAN @import (#60)

- brain/lib/detectar-shells.sh (nueva, install-time, sourceable): enumera zsh/bash/fish INSTALADOS, vuelca aliases via su rc, filtra por SOMBRA de binario real (type -P, no lista fija), escape 'command <cmd>' (nunca /bin/<cmd>). Bloque <!-- shells:posix -->.
- install-brain.ps1: detector PowerShell NATIVO (pwsh+5.1), ASCII-puro, bloque <!-- shells:powershell --> coexiste con el posix.
- install-brain.sh genera ~/.claude/aliases-activos.md (LEAN ~8 lineas, escape answer-first) y cabla @import idempotente (marcador brain:import-aliases, fuera del bloque gestionado, guarda anti-truncado BEGIN-sin-END). uninstall lo revierte. Artefacto GENERADO per-maquina, no viaja por git.
- 615/0, shellcheck limpio, .ps1 parse OK. Spec de unjordi al pie (cross-shell, PS Windows, detectar instalados, LEAN, @import en CLAUDE.md).
…ida (#297)

* feat(hud-stale): tier global→both (viaja por-repo a repos compartidos)

hud-stale ahora viaja por-repo como CORREO a los repos COMPARTIDOS (misma
lógica que los demás `both`, p.ej. secret-scan), además de instalarse global.

- MANIFEST: hud-stale global→both (movido al grupo `both`).
- hud-stale.sh: AÑADE la cláusula de dedupe doble-cableado (patrón EXACTO de
  los hooks `both` hermanos) — en máquina CON brain global la copia por-repo
  CEDE a la global; en un clon SIN bootstrap la del repo sí corre. Actualiza el
  encabezado (tier BOTH). Sin tocar la lógica (fail-open, advisory, stamp
  per-sesión).
- sincronizar-cerebro.sh: ev_de aprende hud-stale (multi-evento SessionStart +
  PostToolUse/Bash) y el loop de cablear ahora itera VARIOS pares "Event|Matcher"
  (como install-brain) — hud-stale es el primer hook multi-evento que va por-repo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(skills): tier both para las 4 skills de repo compartido

Marca `both` (viajan por-repo a repos COMPARTIDOS como CORREO, además de global)
las 4 skills que un colega en un repo compartido usa: cerrar-slice, checkpoint,
rehidratar-hilo (compañeras de los guards `both`: receta del MR + continuidad del
hilo) y to-do (carga el backlog durable del repo = estado del EQUIPO en un
compartido). El resto sigue `global` (seed conservador). Las skills NO llevan
cláusula de dedupe (markdown que lee el modelo, no script que se ejecute → sin
doble disparo). Actualiza el bloque DECISIÓN DE TIER (era «pendiente de unjordi»).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(checkpoint): garantía DURA de barrido hilo→estado-proyecto SIN pérdida

Endurece el contrato del skill: ANTES de sobrescribir hilo-mental-actual.md
(volátil), el checkpoint DEBE barrer el hilo y asegurar que TODO pendiente/
decisión DURABLE ya esté en estado-proyecto.md (o el backlog durable del repo) →
la sobrescritura queda SIN PÉRDIDA (el hilo se puede tirar sin perder nada).

- Endurece el paso 2 (antes «solo si avanzó», SUAVE) a GARANTÍA DURA de barrido.
- Callout answer-first al frente de «Qué hace»; ajusta la description (LIGERO).
- Encuadra la dirección de la flecha: hilo (volátil) → SUBE a estado-proyecto
  (durable), NUNCA al revés; conecta con /to-do (HUD scratch vs backlog fuente
  de verdad) y la norma «ninguna decisión se queda solo en el chat».
- test-brain: checkpoint|to-do al allowlist de refs bidireccionales benignas
  (la conexión con /to-do la exige el contrato endurecido).

Sin hook nuevo ni cambio de tier de checkpoint: es endurecimiento de redacción.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…l-hook.sh (#298)

Residuo del ítem #7. El --uninstall de-cableaba a mano el hook GLOBAL
exportar-sesion-master (3 eventos + borrado del .sh); NO era 1:1 con el
--disable por-repo de sincronizar-cerebro.sh, así que no se consolidó ahí.

Sin consumidor vivo (ningún script/CI/test/README lo invocaba). El retiro
del hook va ahora por su vía consolidada, documentada en la cabecera:
- GLOBAL (exportar-sesion-master y demás tier global/both) -> uninstall-brain.sh,
  que deriva la lista del MISMO MANIFEST (fuente única, sin drift).
- POR-REPO -> sincronizar-cerebro.sh <repo> --disable <hook> --apply.

install-hook.sh queda como atajo delgado de instalación (redirige a install-brain).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ll (#299)

Consolida en la sección "Formato de salida" las 5 reglas afinadas en vivo con
la vista BACKLOG-UNIFICADO que el skill aún no reflejaba:

- SIN subsección 🅿️ Parqueado (era clutter): parqueado se marca inline (estatus
  parked + nota datada) o no se lista, nunca como grupo propio.
- SIN referencias externas ni punteros a otro repo/cerebro: el backlog de UN
  cerebro lleva SOLO sus propios ítems vivos.
- SIN editorializar ítems parqueados/ajenos (no "candidato a cerrar", no cruces
  inventados): déjalos como están.
- Orden explícito: VIVO arriba (verde→amarillo) → CERRADO al final → lápidas al final del todo.
- "Espera tu go" = ATACABLE, no una lista/categoría aparte.

test-brain: 566 PASS · 0 FAIL.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…serial (#59) (#300)

Hook PostToolUse ADVISORY (tier global) que recuerda considerar fan-out/
delegación cuando Claude lleva N mutaciones consecutivas (edits/commits) SIN
delegar a ningún agente en la sesión. Mecanismo de la norma orquestar-fanout
("delega lo paralelizable"), hermano-EMPUJE del gate de costo delegacion-gate
(el freno).

Señal: contador per-session_id de mutaciones (Edit/Write/MultiEdit/NotebookEdit
+ git commit vía Bash). Un Agent/Task RESETEA el contador (si delegaste, no
regaña). Al llegar a N (RECORDAR_ORQUESTAR_N, def 10) → un aviso advisory;
debounce de N en N. NUNCA bloquea (additionalContext pasivo), fail-open sin
jq/session_id, escape CLAUDE_SKIP_RECORDAR_ORQUESTAR=1. El texto deja claro que
el trabajo intrínsecamente secuencial se ignora (precisión = 1ª clase).

Cableado: MANIFEST (global/hook) + ev_de() de install-brain (PostToolUse sin
matcher, casa toda tool). Doc en la misma tanda: README raíz + brain/README +
mapa-cerebro + los 3 catálogos del widget (win/mac/qml, known-global + tile).
Tests: b3i (11 casos: umbral, reset, debounce, neutral, git commit vs log,
aislamiento per-sesión, fail-open, escape) + e6b/e7 (mapeo de evento). Suite
580 PASS · 0 FAIL. shellcheck limpio.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…rebones (#301)

Par de 'definición-de-tipo-de-dato' de la firma-árbol canónica: el CLAUDE
barebones (la firma del entry-point) ya existía untracked → se versiona; el
MEMORY barebones es su gemelo (el DETALLE 1:1 de la firma + índice por prefijo
dom-/dev-/ux-/qa-/núcleo, answer-first, invariante 1:1 índice↔archivos, sin
inventar pipeline). Instancia canónica de referencia = cps.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
… canónica (#304)

* feat(firma): detector determinista de la firma-árbol canónica (#71)

`brain/verificar-firma-canonica.sh` FLAGGEA (no auto-muta) el drift de un
cerebro INSTANCIADO respecto a la firma canónica:
- CLAUDE.md sin las secciones de la firma-árbol (🎯/🧠/📁/🖋️/🛡️ + @import)
- memorias sin prefijo dom-/dev-/ux-/qa- ni núcleo
- invariante MEMORY↔archivos roto (huérfanas + enlaces/wikilinks rotos)
- nombres de hook retirados en la prosa (p.ej. precompact-volcar-estado)

FAIL (estructural)=exit1; WARN (drift)=reporte, `--strict` lo eleva a exit1
(modo GATE para #44). Se salta el meta-repo claude-brain (su árbol vive en
README, no en un CLAUDE.md-firma → verificar-arbol-sync.sh).

Batería `g5` en test-brain.sh: cerebro bueno/malo/no-indexado/local/strict/
meta-repo. Verificado contra fluxcore y cps (pasan) y plantilladotnet (drift
cazado). Suite verde.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(skill): canonizar-cerebro — playbook humano-en-el-loop (#71)

Destila el prototipo manual corrido sobre fluxcore (2026-08-07) en un
procedimiento repetible: lleva un cerebro instanciado drifteado a la
firma-árbol canónica sin auto-mutar a ciegas.

Pasos: inventario + detector → clasificar cada memoria a su prefijo →
reprefijar con git mv (historia intacta) → dedup con RESCATE de datos
únicos → reescribir CLAUDE.md a firma-árbol y MEMORY.md a índice-por-prefijo
→ arreglar punteros vivos → verificar 1:1 con verificar-firma-canonica.sh.

Con LA CERCA (no-destructivo, narrativa fechada intacta, lo destructivo se
PARQUEA, fidelidad, doc=realidad) y el criterio de LISTO (QA/OK de unjordi).
Es el paso ESTRUCTURAL de consolidar-cerebro; ata el detector al GATE #44.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(arbol): indexa canonizar-cerebro en los 5 catálogos del árbol

doc=realidad para el skill nuevo: README árbol + MEMORY.md árbol/detalle +
los 3 widgets (macOS PopoverView.swift, Linux main.qml, Windows PopupForm.cs)
con su tile 📐 + estado opt-in (PopoverView case, main.qml array,
BrainInspector switch). verificar-arbol-sync.sh en paridad (22↔22↔22).

Los tiles de los widgets quedan PENDIENTES de QA visual (no compilados).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(memoria): backlog #71 + bitácora del detector/skill de firma canónica

Pendientes: (a) atar verificar-firma-canonica.sh al GATE del auditor (#44) —
decisión de forma parqueada para unjordi; (b) QA visual de los 3 tiles nuevos.
Bitácora: línea del slice.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…e-brain (nace con tests) (#302)

* feat(skill): reubicar-master — mudar un brain-master COMPLETO a claude-brain (nace con tests)

Coloca el skill `reubicar-master` (canónico 09-skill-B, auditado en 10-dictamen):
re-ancla una sesión master CERRADA a un repo destino (transcript + cwd + slug
global + masters.json target por-id + alias + symlink `memory`), migrando el
cerebro del master clasificado en 3 tiers por su canal correcto, de forma ATÓMICA
y QUIRÚRGICA. Cuatro candados duros: no-lobotomía (G-PARITY por CONTENIDO),
no-self-move-en-vivo (G-LIVENESS por mtime), no-tail (move+target-fix+alias en un
bloque) y no-fuga (G-GITIGNORE + T3 se queda en plantilladotnet).

Fixes del dictamen foldeados en el SKILL: referencia
`exportar-sesion-master.sh:139` → `:144` (copia instalada) y nota "correr los
bloques en una sola shell / re-declarar Variables base".

Nace con su bloque de tests en brain/test-brain.sh (sección `(rm)`, casos g1–g12,
23 asserts): mezcla asserts de MOTOR reales (session-move/export.js, writeAlias,
colisión) con greps estructurales sobre el SKILL.md; $HOME falso y armado partido
para no auto-disparar merge-squash-guard/secret-scan. Aplicado el fix HIGH g1 del
dictamen (grep negativo anclado a `fuser.*(prueba|cerrada|liveness)`), y dos fixes
de PRECISIÓN adicionales del MISMO anti-patrón, hallados al correr el bloque contra
el skill/motor reales y NO listados en el dictamen: g7 (el negativo `18 vs 4`
self-falla igual que g1, anclado ahora a "conteo de skills") y g9 (el motor aborta
con 2 mensajes de colisión elegidos por readdirSync sin ordenar; grep ampliado a
ambos + ok:false). 23/23 PASS, `bash -n` limpio.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(cerebro): registra el skill reubicar-master en los catálogos (paridad)

Agrega reubicar-master a la familia 💡 Skills en README.md y
.claude/memory/MEMORY.md para que el parity-check del árbol
(verificar-arbol-sync.sh, caso (f) de test-brain.sh) quede VERDE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(widgets): tile de reubicar-master en los 3 brainTiers (fase 2 paridad widget)

Agrega el tile del skill reubicar-master (hermano de claude-proyecto-autocontenido)
a los 3 widgets del cerebro: main.qml (Linux/QML), PopoverView.swift (macOS) y
PopupForm.cs (Windows). Con esto el check drift-widget[qml/mac/win] pasa verde:
toda skill de brain/skills tiene su tile de display.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(widgets): clasifica reubicar-master en StatusOf en las 3 plataformas (cero deuda: punto de estado correcto)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(widgets): parity-check de StatusOf en los 3 widgets (cero deuda de clasificación)

Antes solo había parity-check de TILES (drift-widget, e3): su cover() matchea el
nombre en CUALQUIER parte del archivo, así que una skill con tile pero fuera de la
clasificación de ESTADO (StatusOf/status/brainStatus) pintaba su punto MAL en silencio.

Nuevo caso e3b (drift-status), hermano de e3: para cada skill dir de brain/skills
verifica su membresía en la REGIÓN de clasificación de estado de cada widget —
unión de known-global + known-repo + el bloque del switch de skills, acotada por
anclas robustas del código (no por nº de línea) y probada con el token entrecomillado
exacto (no matchea el tile ni subcadenas). Falla si una skill tiene tile pero no está
en StatusOf; pasa cuando todas están.

Al correrlo, cero skills faltantes en los 3 widgets: reubicar-master era la última
brecha, ya cerrada en 457bbf4, y rehidratar-hilo se clasifica bien como hook (`both`
en el MANIFEST → known-global). El check nace VERDE e institucionaliza la invariante.
test-brain completo: 641 PASS · 0 FAIL. drift-widget sigue verde. qmllint main.qml exit 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(test): nbd_ctx limpia env de CI para ejercitar la vía de AVISO de no-bypass-deploy

El hook no-bypass-deploy calla en CI (CI/GITHUB_ACTIONS/GITLAB_CI/BUILD_ID)
a propósito (ahí el pipeline ES la herramienta), pero el grupo g1 ejercita la
vía de AVISO de una máquina de dev sin limpiar esas env vars. Al correr la suite
DENTRO de GitHub Actions eso daba 5 falsos FAIL. Se limpian las vars con `env -u`
solo en nbd_ctx; el test de "silencio en CI" ya fija CI=1 por su cuenta y no se
toca. Falla preexistente en develop, no la introdujo el merge del PR #302.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: t <t@t>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…r-both (#80) (#307)

El test g1 invocaba la copia del REPO de no-bypass-deploy.sh; su cláusula de
dedupe (tier both) hace exit 0 si existe la copia GLOBAL en $HOME/.claude/hooks/.
Al instalar el brain global (#69) esa copia empezó a existir → la del repo cedía →
5 FAIL (no avisaba). El test no aislaba $HOME (a diferencia de g2/g3/g5). Fix:
$HOME temporal vacío para las invocaciones del hook → hermético, independiente de
si la máquina tiene el brain global instalado. 641 PASS · 0 FAIL.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…mecanismo anti-§9 (#308)

Cierra las 4 aristas del sync de sesiones que el skill reubicar-master delegó a su §9 — indispensables para que el move real de los masters no rompa nada:
- #2 [ALTO·destructivo] seed --force gana freshness gate (no regresa una sesión viva); escape --force-stale.
- #3 [ALTO] exportar-sesion-master actualiza el target (y name en rename) de un master movido; antes solo añadía.
- #1 [MEDIO] findSession tie-break determinista (mtime desc, slug asc) + collisions.
- #4 [BAJO] session-move poda ~/.claude/session-move-backups (KEEP=10).
Y el mecanismo anti-§9 en cerrar-slice (+ corolario en orquestar-fanout, test s5): lo delegado al texto de un artefacto va al backlog con severidad antes de cerrar.
Suite 673 PASS / 0 FAIL. OK explícito de unjordi.
El aviso lideraba con '% del punto de auto-compact' (p. ej. 95% del techo), número que un Claude confabulaba como '% de la ventana' (~66% en /context) → pánico y /compact con ventana de sobra. Y el re-arm del debounce no tenía margen → re-emitía en cada tool result por aleteo de tokens.

- Cada aviso LIDERA con el mismo número que /context (% de la ventana) + anti-confabulación explícito; DESPUÉS cita el % del punto de auto-compact.
- Histéresis en el re-arm (margen CEILING*2/100) → no más spam por cruces de banda.

Arreglo de MENSAJE y debounce; NO toca la medición (ya correcta) ni el env. Verificado forense 2026-08-08: era el fix VARADO sin mergear del síntoma real que se sentía 'roto esta semana'. OK explícito de unjordi: 'integra a develop el #303 plzm con su rebase si es necesario'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-trabajar-con-<user> (#310)

El conocimiento de TRATO/preferencia personal del usuario (cómo le gusta que le
comuniquen, decidan, trabajen) debe vivir en UN solo lugar: la memoria GLOBAL
per-máquina ~/.claude/projects/-Users-<user>/memory/como-trabajar-con-<user>.md.
Hoy los Claude re-crean feedback-*.md sueltos por-repo → drift y duplicación.

Añade la REGLA como PASO explícito en las skills que procesan/cosechan/consolidan
memoria (un hook no puede juzgar semánticamente "trato" → sin guard bloqueante):

- cosechar-sesion: nueva sección de RUTEO — TRATO personal → archivo GLOBAL (no al
  inbox per-repo), answer-first, desinflado, con procedencia cita-vs-[INFER], y
  REFERENCIANDO (no copiando) las normas universales del brain. Distingue TRATO
  (→ global) de conocimiento de PROYECTO (→ repo) y de TRATO sobre-otro-dev (→ inbox).
- unificar-cerebro: nuevo destino de graduación (Paso 3b) — TRATO → archivo GLOBAL
  per-máquina, NO a develop (per-persona, no viaja por git).
- desinflar-memorias: al toparse con un feedback-* de TRATO per-repo, MIGRA su
  lección al archivo GLOBAL, elimina la mención migrada y borra el archivo si queda
  vacío (+ su línea en MEMORY.md).
- recordar-cosechar (hook): el nudge de cosecha recuerda que el TRATO va al archivo
  GLOBAL, no al inbox ni a un feedback-*.md per-repo.
- test-brain.sh: 4 tests nuevos que verifican la regla en las 3 skills + el hook.

Molde canónico referenciado: como-trabajar-con-unjordi.md (5 secciones).
Esta pieza es el GATE para retirar las memorias feedback-* de trato sin que se recreen.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…309)

Documenta CRISP el criterio para decidir el tier de un hook/skill nuevo por
el PATRÓN REPO-COMPARTIDO, para que deje de re-preguntarse "¿global o both?":
- both = correo que viaja por-repo a clones COMPARTIDOS sin brain global
- global = solo la máquina del dueño (default conservador)
- repo = solo por-repo, se carga si la sesión INICIA en el repo

Toca:
- brain/hooks/MANIFEST  : bloque "CÓMO DECIDIR EL TIER" en el header
- brain/skills/MANIFEST : bloque análogo (skill both no requiere dedupe)
- brain/norms/global-claude-md.md : sección en prosa "Tiers: cómo decidir"
  bajo la norma "Cerebro por-repo = CORREO" (misma raíz)
- brain/test-brain.sh   : test (e2-tiers) que verifica que ambos headers
  documentan los 3 tiers + la regla repo-compartido

No recategoriza ningún tier existente (solo documenta la regla).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
unjordi and others added 5 commits August 8, 2026 15:28
…ts anti-regresión (#311)

Construye sobre #303 (reconciliación con /context + histéresis). Dos entregas:

1. Bug latente hallado y arreglado: la auto-justificación de la PROCEDENCIA del
   techo decía "override DELIBERADO" con solo mirar si CLAUDE_AUTOCOMPACT_PCT_OVERRIDE
   estaba NO-vacía. Un override INVÁLIDO (typo `70%`, out-of-range `150`, espacios)
   caía a PCT=92 pero el mensaje lo vendía como "=92 (override DELIBERADO de Jordi,
   NO un bug — créele)" → la feature de confianza MINTIENDO sobre un valor que el
   usuario nunca fijó. Fix: flag PCT_SRC distingue el override VÁLIDO del default; la
   PROCEDENCIA solo cita "DELIBERADO" cuando el override fue válido, si no dice (default).

2. Tests anti-regresión de #303 que DISCRIMINAN (fallan contra pre-#303, pasan contra
   el actual; verificado forense contra `git show 5224aaa^`):
   - Bug1 (denominador/confabulación): repro del reporte de campo 673K/1M@70% (banda 3)
     y el escenario ~66% de ventana (banda 2) — el aviso LIDERA con el % de la VENTANA
     (verificable con /context) + anti-confabulación, no solo el % del auto-compact.
   - Bug2 (histéresis anti-spam): aleteo de tokens en el borde de banda (655K↔680K con
     techo 700K, margen 14K) NO re-emite; solo un compact real (<651K) re-arma.
   - Procedencia honesta: override inválido→(default), válido→DELIBERADO.

Robustez verificada (sin cambio): fail-safe ante stdin no-JSON/vacío y líneas de
transcript malformadas (fromjson? las salta); PCT nunca queda unbound bajo set -u.

690 PASS · 0 FAIL.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…del ecosistema de auditores (#306)

* feat(auditor-semantico): porta el MOTOR GENÉRICO de Capa 1 al template (brain/scripts/)

Hoist del auditor semántico desde fluxcore al cerebro-template. El MOTOR es
agnóstico de stack (ejecutar.sh + lib-formato.sh); los checks/*.sh son EJEMPLOS
de la plantilla .NET que cada repo afina a su stack. Genericizado:

- ejecutar.sh: la detección de PREFIX (*.domain) ya NO aborta si falta — avisa y
  corre igual (un repo no-.NET puede tener sus propios checks). Antes: `:?` fatal.
- invariantes-semanticos.yml: EJEMPLO/esqueleto con solo invariantes `general`
  (arquitectura); se quitó la entrada `proyecto-especifico` de dominio fluxcore
  (checklist117). Cada repo agrega su dominio como `proyecto-especifico`.
- README.md: reencuadrado motor-genérico vs checks-de-ejemplo + cómo cada repo
  afina su catálogo + snippet de CI de ejemplo (antes calcado de un repo concreto).
- checks 01-04 (permisos endpoints, ruta-id auditoría, Dapper/DateOnly, grid
  homologado) y lib-formato.sh: copiados verbatim (ya eran arquitectura-genéricos
  de la plantilla .NET, sin dominio de negocio fluxcore).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* feat(auditor-semantico): registra la skill de Capa 2 en el template (tier global)

Skill de la Capa 2 (semántica, criterio LLM) portada a brain/skills/ y declarada
en brain/skills/MANIFEST como `global` (seed CONSERVADOR): se instala en
~/.claude/skills de cada máquina por el bootstrap; disponible en cualquier repo.
Depende del payload repo-root scripts/auditor-semantico/ (Capa 1) para el paso 1.

NOTA (para la revisión con unjordi): el tier `global` es la elección conservadora.
Alternativa `both` = viajaría por-repo en repos COMPARTIDOS como correo, pero
aterrizaría en repos NO-.NET donde scripts/auditor-semantico/ no existe. Decisión
de tier abierta.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(auditor-semantico): tile en los 3 widgets + árbol de skills (README + MEMORY)

Cierra el drift que test-brain (e3) y verificar-arbol-sync.sh exigen al agregar una
skill: tile 🧬 auditor-semantico en el catálogo curado de los 3 widgets (Windows/C#
PopupForm.cs, macOS/Swift PopoverView.swift + su clasificación, plasmoid/QML main.qml
tile + clasificación) y en la familia 💡 Skills del árbol de README.md y
.claude/memory/MEMORY.md (paridad README ↔ MEMORY ↔ brain/skills/).

test-brain.sh: 636 PASS · 5 FAIL (los 5 FAIL son g1/no-bypass-deploy, PRE-EXISTENTES
en develop, ajenos a este cambio).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(auditores): mapa del ecosistema de auditores del cerebro (para la revisión)

Mapea las piezas de auditoría y cómo componen: auditor-semantico (código de
producto, ORTOGONAL), la DUPLA coherencia+suficiencia (cerebro/docs, van JUNTAS),
auditar-proceso-algoritmo (motor-metodología), verificar-firma-canonica.sh (#71,
detector determinista) + su hermano verificar-arbol-sync.sh (meta-repo), y los
meta-orquestadores consolidar/canonizar + unificar-cerebro.

Hallazgo clave para la revisión: el GATE #44 está DEFINIDO en la doc
(verificar-firma-canonica.sh + canonizar-cerebro lo prometen como sub-check de
auditar-coherencia en modo gate) pero NO CABLEADO — auditar-coherencia/SKILL.md no
lo menciona y ningún hook/CI lo invoca. Documenta 6 preguntas abiertas del cableado.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs(ecosistema-auditores): familia de enforcement viva (dod-verificar) + precisión = requisito del gate #44

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…a QA" (#305)

Cosecha genérica de la nota de proyecto cps `qa-entorno-antes-de-pedir.md`:
es una disciplina UNIVERSAL de la invitación a QA, no algo de cps. Su HOME
correcto es un PASO del ritual de cierre (una norma sin mecanismo es solo un
buen deseo; cerrar-slice ES el mecanismo que se invoca al cerrar), no una
norma global mecanism-less.

Añade a §3 (Confirma con el usuario) el bullet: al invitar a QA, el entorno
desplegado debe contener TODO lo que le pides revisar — reconcilia las ramas
divergentes + redespliega ANTES; si no puedes, avísalo por adelantado, nunca
a media QA; la reconciliación es del orquestador.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* chore(rename): claude-brain → cortex (des-branding por marca)

Identidad de persona (*-master) preservada; se decide al reconciliar con el gemelo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(rename): mv archivos/dirs claude-brain → cortex + fix NOTICE

Renombra los 8 archivos/dirs kebab-case cuyo nombre era claude-brain
(service/timer/plist/fetch/skill widget/memoria/icono svg) para que
coincidan con las referencias ya barridas. NOTICE: nombre de asset real.
Pendiente aparte: título-case "Claude Brain" y CamelCase ClaudeBrain.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* chore(rename): ClaudeBrain / "Claude Brain" → Cortex (branding del widget)

CamelCase de C#/Swift (namespace, csproj, Package.swift), CI workflows,
Info.plist/bundle id, scripts de build, y título-case en prosa/NOTICE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: t <t@t>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…/comando) (#313)

* perf(hooks): pre-filtro barato en no-bypass-deploy y proteger-arbol + baseline

Modelo de capas al nivel del hook: un filtro determinista en-proceso (case)
que early-exit en el camino comun ANTES de gastar sed/tr/grep. Conservador
(nunca salta un caso real); hooks ADVISORY. Camino comun ~9->3ms y ~5->3ms.
Peaje total ~28->16ms. test-brain 696 PASS.

Doc: docs/perf-baseline-hooks-2026-08.md documenta la medicion y la conclusion
honesta: los hooks del cortex NO son el cuello (juez ya es direct-API+Haiku+capas);
el downtime real vive en el loop/contexto del modelo -> territorio axon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* perf(hooks): pre-filtro barato en 4 guards calientes + advisory + memoize

4 guards de seguridad (OK EXPLICITO de unjordi): git-branch-guard, secret-scan,
merge-squash-guard, confirmar-merge-develop. Patron superset (case sobre cmd
crudo, ANTES de source-lib/juez): ~30->~7 subprocesos/comando, cobertura EXACTA.
Mismo patron (mandato general): rama-vieja, entorno-maquina-guard,
recordar-dashboard (advisory) + detectar-secretos (memoiza funciones puras).
test-brain 696 PASS. El backstop auto-mode marco la auto-mod -> unjordi dio OK
y corrio este commit el mismo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: t <t@t>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@unjordi
unjordi merged commit 3add9df into main Aug 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant