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.jsyfollowing.js. Los likes están truncados (~140) y sin autor ni fecha → son señal privada, nunca citables ni atribuibles.following.jsviene sin screen names (solouser_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-braines 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 crudosConsolidació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/:
- Anonimización: todo
[NOMBRE-*]/[ID-*]debe tener contexto claro; si no, revisar el export. - Edges: cada
to:debe existir encontent/nodes/; elnpm run buildde~/nef/second-brainfalla con un edge colgante. Validar en_enrich/primero. - Nodos nuevos: son 382 slots; mejor
_enrich/<slug>.md+.meta.jsonquecontent/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)
- No inventes títulos, slugs,
kind,status,edges, autores ni URLs. Cada frase del cuerpo debe ser algo que verificaste en el contenido pegado. - Integridad referencial: un
edges[].toa un slug inexistente rompe el build. Si te doy la lista de slugs existentes, enlaza solo a esos; si no, dejaedges: []y anota la conexión deseada enopen_questions. - No rellenes Mecanismo/Límite/Ejercicio con paja enciclopédica. Sin material → omitir o una línea honesta.
- 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.
- Slugs candidatos: kebab-case limpio, solo
[a-z0-9-], sin espacios ni acentos; nunca inventar palabras que no estén en mi contenido. - 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).
- Nombres propios (míos, familiares, colegas):
[NOMBRE-1],[NOMBRE-2]… por export. - Identificadores directos:
[ID-EMAIL],[ID-TEL],[ID-DNI],[ID-DIR],[ID-LINK](conserva el tipo, no el valor). - Ubicaciones personales:
[UBICACION-1]… - Cuentas, IDs internos, tokens, claves, passwords:
[CREDENCIAL]— bórralos, no los anonimices. - Proyectos/empresas propias con nombre revelador:
[PROYECTO-1],[EMPRESA-1](conserva la relación, no el nombre). - Fechas de eventos personales (cumpleaños, citas, viajes):
[FECHA-PERSONAL]. - Conversaciones sensibles (salud, finanzas, relaciones, decisiones íntimas):
resume la idea sin detalle identificable →
[RESUMEN-SENSIBLE]. - 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.jscrudo con el LLM. El pipeline local manda:python3 scripts/ingest.py <ruta/data>→data/twitter.db, luegoscripts/report.py,scripts/likes.py(KMeans) yscripts/distill.py. Al LLM le pasas solo lo destilado (reports/logica-*.md,reports/likes-mapa.md,reports/likes-temas-kmeans.md) + tus tweets propios. Ignoramedia/, DMs yfollowing.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(árbolmapping, no turnos lineales) +chat.htmly.dat(adjuntos). Trocea conscripts/chatgpt_export_split.py(reconstruye el hilo activo desdecurrent_node) y pasa esa carpeta al runner. Ignorachat.html,.datylibrary_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>