Prompt — Extracción de valor de exports personales → second-brain

Artefacto reutilizable. Consolida las dos versiones que circulaban (genérica + knowledge-factory), las aterriza en el pipeline real de second-brain-twitter y en el contrato vigente de ~/nef/second-brain.

Decisiones incorporadas (no re-litigar dentro del prompt):

  • Twitter: el export trae tweets.js, like.js y following.js. Los likes están truncados (~140) y sin autor ni fecha → son señal privada, nunca citables ni atribuibles. following.js viene sin screen names (solo user_id).
  • Pipeline local manda: ZIP de Twitter → scripts/; solo lo destilado va al LLM.
  • Clustering de likes: KMeans (k=64) > HDBSCAN en este corpus; HDBSCAN necesita UMAP previo (negativo documentado). No se reabre aquí.
  • Anonimización: solo MI contenido; los tweets de terceros son públicos.
  • second-brain es local-only: el nudge de “¿quién lo ve?” no aplica.
  • Decisiones y prompts viven en ~/nef/decisions/, no en el repo.

Cómo correrlo

Runner (en esta máquina): ~/nef/second-brain-twitter/scripts/extract_exports.py. Usa la API /api/chat con num_ctx explícito y think:false: el server de Ollama.app ignora OLLAMA_CONTEXT_LENGTH (corre -c 4096) y qwen3.5 devuelve content vacío si no se le apaga el thinking.

Sanitización determinista (obligatoria): scripts/sanitize.py scrubea reports/extraccion-*.md (emails, IPs, teléfonos, tokens) por si el LLM citó algún valor real. La anonimización del prompt no basta: siempre limpiar después.

cd ~/nef/second-brain-twitter
# OJO: no uses PROMPT (reservada en zsh); usa PROMPT_FILE
PROMPT_FILE=~/nef/decisions/[CREDENCIAL].md
 
# una pasada por fuente (no mezclar Twitter + Claude + ChatGPT: diluye señal)
python3 -u scripts/extract_exports.py "$PROMPT_FILE" exports/twitter/data
python3    scripts/extract_exports.py "$PROMPT_FILE" exports/claude/design_chats
python3    scripts/claude_export_split.py exports/claude/conversations.json /tmp/claude-conv
python3 -u scripts/extract_exports.py "$PROMPT_FILE" /tmp/claude-conv
python3    scripts/chatgpt_export_split.py exports/chatgpt /tmp/chatgpt-conv
python3 -u scripts/extract_exports.py "$PROMPT_FILE" /tmp/chatgpt-conv
 
# limpieza determinista de los resultados
python3 scripts/sanitize.py reports/extraccion-*.md
# → reports/extraccion-<fuente>[-NNN].md, ya sin valores crudos

Consolidación posterior (manual o con un paso corto de LLM que solo una 3.2/3.3/3.4/3.6, sin re-extraer).

Revisión obligatoria antes de pegar a content/nodes/:

  1. Anonimización: todo [NOMBRE-*]/[ID-*] debe tener contexto claro; si no, revisar el export.
  2. Edges: cada to: debe existir en content/nodes/; el npm run build de ~/nef/second-brain falla con un edge colgante. Validar en _enrich/ primero.
  3. Nodos nuevos: son 382 slots; mejor _enrich/<slug>.md + .meta.json que content/nodes/ directo.

PROMPT — Extracción de valor de exports personales → nodos second-brain

Rol

Actúa como extractor de conocimiento personal. Te pego contenido crudo de mis exports (Twitter/X, Claude, ChatGPT). Tu trabajo: (1) anonimizar, (2) extraer lo valioso, (3) entregar bloques markdown escribibles para un knowledge-factory local (~/nef/second-brain: markdown con frontmatter YAML + cuerpo de doctrina). No es un resumen: es material listo para content/nodes/, study/ y decisiones.

Reglas duras (violarlas invalida el output)

  1. No inventes títulos, slugs, kind, status, edges, autores ni URLs. Cada frase del cuerpo debe ser algo que verificaste en el contenido pegado.
  2. Integridad referencial: un edges[].to a un slug inexistente rompe el build. Si te doy la lista de slugs existentes, enlaza solo a esos; si no, deja edges: [] y anota la conexión deseada en open_questions.
  3. No rellenes Mecanismo/Límite/Ejercicio con paja enciclopédica. Sin material → omitir o una línea honesta.
  4. Idioma: conserva el idioma de cada item (los exports son multilingües). No traduzcas un nodo en español a inglés ni al revés.
  5. Slugs candidatos: kebab-case limpio, solo [a-z0-9-], sin espacios ni acentos; nunca inventar palabras que no estén en mi contenido.
  6. Chunk corrupto o no parseable → dilo y sáltalo, no adivines.

FASE 0 — Anonimización (SIEMPRE antes de extraer)

Aplica solo a MI contenido (mis mensajes, prompts, inputs, perfil). Nunca a contenido de terceros o público (tweets ajenos, papers, recursos).

  1. Nombres propios (míos, familiares, colegas): [NOMBRE-1], [NOMBRE-2]… por export.
  2. Identificadores directos: [ID-EMAIL], [ID-TEL], [ID-DNI], [ID-DIR], [ID-LINK] (conserva el tipo, no el valor).
  3. Ubicaciones personales: [UBICACION-1]…
  4. Cuentas, IDs internos, tokens, claves, passwords: [CREDENCIAL] — bórralos, no los anonimices.
  5. Proyectos/empresas propias con nombre revelador: [PROYECTO-1], [EMPRESA-1] (conserva la relación, no el nombre).
  6. Fechas de eventos personales (cumpleaños, citas, viajes): [FECHA-PERSONAL].
  7. Conversaciones sensibles (salud, finanzas, relaciones, decisiones íntimas): resume la idea sin detalle identificable → [RESUMEN-SENSIBLE].
  8. Nunca escribas el valor real en NINGUNA parte del output — ni en el resumen de anonimización, ni entre paréntesis, ni como ejemplo, ni “para trazabilidad”. Detectas un email/IP/teléfono/token → lo sustituyes por su placeholder y, si necesitas reportarlo, solo el conteo. El valor crudo no aparece nunca en el resultado.

Regla de oro: si identifica a mí o a alguien cercano → anonimiza. Si es conocimiento útil → conserva con nombres anonimizados. Duda → trátalo como sensible. El valor crudo jamás se reproduce: el output solo contiene placeholders y conteos.

FASE 0.5 — Ruta de ingesta (elige según lo que venga)

  • ZIP de Twitter: NO proceses like.js crudo con el LLM. El pipeline local manda: python3 scripts/ingest.py <ruta/data> → data/twitter.db, luego scripts/report.py, scripts/likes.py (KMeans) y scripts/distill.py. Al LLM le pasas solo lo destilado (reports/logica-*.md, reports/likes-mapa.md, reports/likes-temas-kmeans.md) + tus tweets propios. Ignora media/, DMs y following.js (sin screen names).
  • Export de Claude (ZIP con HTML/JSON): pega el texto de las conversaciones (no el HTML entero), con fecha si aparece.
  • ChatGPT: el export trae conversations-*.json (árbol mapping, no turnos lineales) + chat.html y .dat (adjuntos). Trocea con scripts/chatgpt_export_split.py (reconstruye el hilo activo desde current_node) y pasa esa carpeta al runner. Ignora chat.html, .dat y library_files.json.

Si el volumen es grande, procesa por bloque (export o período) y consolida al final.

FASE 1 — Contextualización

Antes de extraer, responde en 2-3 líneas: de qué plataformas viene y en qué formato aproximado, qué período cubre, y qué tipo de interacciones predominan.

FASE 2 — Extracción por buckets

Cada item lleva: qué es, de qué export vino + fecha, y por qué vale.

A. Nodos candidatos (concept / algorithm / paper / tool / model / dataset / experiment)

Solo si hay material real para un nodo. Mención pasajera → va a C, no a nodo. Para cada uno, emite el bloque completo del Contrato del nodo (más abajo). Si dos nodos están fuertemente relacionados, marca uno como primario y los derivados con rel: generalizes o applies.

B. Frases y marcos de pensamiento (citables)

Frases, metáforas o frames que surgieron, con el contexto que las provocó, anonimizadas. Si me sirvieron como regla de trabajo, márcalas como candidatas a nodo trivial (L0, status: unseen).

C. Proyectos e ideas en progreso

Idea, estado, próximo paso explícito, por qué vale o por qué se abandonó. Las ideas que maduren van a content/projects/ o al journal privado (npm run journal -- "<texto>" --idea), nunca directo a content/nodes/.

D. Acciones pendientes (para study/ + npm run review)

Cada acción asumida y no completada: - <acción concreta> (fuente: <export, fecha>). Si es estudio de un nodo: npm run node:log -- <slug> <minutos> -n "motivo". Marca cuáles son acciones reales vs. conversación difusa.

E. Open questions de alto nivel

Dudas recurrentes sin respuesta. Si cruzan con open_questions de un nodo existente, consérvalas ahí (conservar la incertidumbre > borrar la duda).

F. Decisiones y cambios de perspectiva

Decisión tomada, por qué, y si se mantiene. Cambios de opinión registrados. Autoconocimiento que todavía vale (anonimizado). Estas van a ~/nef/decisions/ como archivo fechado, no al repo.

G. Conocimiento externo útil de terceros

Recursos, referencias o insights de otras personas (atribución clara, no anonimizar si es público). Si un paper/tool citado merece nodo y no existe, márcalo como candidato aparte con kind: paper|tool.

FASE 3 — Output estructurado (escribible, en este orden)

3.1 Resumen de anonimización — tipos de datos sensibles encontrados y conteo por tipo. Solo tipos y conteos; nunca el valor, ni completo ni parcial, ni el placeholder repetido de forma que permita reconstruirlo.

3.2 Nodos candidatos — bloques completos (Contrato del nodo).

3.3 Ideas en progreso (para content/projects/ o journal privado).

3.4 Acciones pendientes (para study/ o npm run review), con el comando node:log cuando aplique.

3.5 Open questions recolectadas (contexto: export, fecha, nodo relacionado).

3.6 Decisiones y perspectivas (destino: ~/nef/decisions/<fecha>-<slug>.md).

3.7 Fuentes externas dignas de archivo (papers, tools, tweets de terceros).

3.8 Top 10 de lo más valioso — ranking con una línea de por qué; marca si es candidato a nodo, acción o cita.

3.9 Próximos pasos de conocimiento — qué a nodo ya (depende de profundidad y recurrencia), qué a acción de estudio hoy, qué a largo plazo, qué descartar.

Contrato del nodo (doctrina vigente 2026-09-19)

Bloque listo para content/nodes/<slug>.md:

---
title: <Title>
kind: <concept|paper|tool|model|algorithm|person|dataset|experiment>
status: <unseen|learning|applying|mastered>
level: <0–5>
edges:
  - to: <slug-existente>
    rel: <requires|implements|generalizes|applies|cites|contradicts>
    note: "<opcional>"
tags: [<contexto>]
open_questions:
  - <pregunta>
sources:
  - name: <fuente externa o "Export personal: Twitter/Claude/ChatGPT">
    url: '<url o vacío>'
---
 
<una línea de curator: qué es y por qué importa>
 
Mecanismo. <el cómo concreto: fórmula, pasos, algoritmo o razonamiento, suficiente
para reconstruir la idea sin buscador>
 
Límite. <dónde falla, con qué se confunde, qué no cubre>
 
Ejercicio. <si existe: nombre del notebook/script/repo; agrégalo como entrada
extra en sources apuntando al archivo exacto — no como campo nuevo>

Reglas del cuerpo: status: learning si el export muestra progreso, unseen si es nuevo; level por profundidad y reuso real, no por entusiasmo; hours = exposición real estimada. requires es la única relación que define ruta de aprendizaje. Si no hay conexión clara: edges: [].

Restricciones

  • No inventes datos ausentes del contenido.
  • No resumas tanto que se pierda lo valioso; prioriza profundidad > recencia (lo que aparece más veces y con más detalle > lo que aparece una vez).
  • Los likes de Twitter son señal truncada sin autor/fecha: úsalos para inferir temas, nunca como cita atribuible.
  • Todo el output debe ser escribible directamente, no una descripción de lo que habría que escribir.

CONTENIDO A PROCESAR:

<PEGAR AQUÍ LOS EXPORTS>