Configuración
Daimon se configura por completo con variables de entorno. Cada variable se
resuelve en el mismo orden: gana el entorno del proceso, y todo lo que no
esté ahí cae al archivo de entorno en ~/.daimon/env. La ubicación del
archivo se puede cambiar con DAIMON_ENV_FILE.
El archivo de entorno existe porque los hooks corren con el entorno que el
proceso host haya heredado — un agente lanzado desde la GUI no tiene perfil
de shell, así que los exports del shell no son un canal confiable. Su formato
es líneas KEY=VALUE; se toleran un export inicial, comillas alrededor,
líneas en blanco y comentarios #. Mantenlo en chmod 600 — puede contener
API keys.
daimon configure gestiona las perillas del backend LLM (mira
Backend LLM) y las escribe en ~/.daimon/env. Todo lo demás
se configura editando ese archivo o exportando la variable.
Las variables booleanas aceptan 1, true, yes u on como verdaderos
(sin distinción de mayúsculas donde se indica). Unas pocas usan convenciones
distintas — interruptores de apagado que están activos salvo que valgan 0,
o flags por presencia — y se señalan en la columna "Qué hace".
Las perillas internas de ajuste de la serialización (umbrales de chunking, solapamiento, concurrencia, tamaño de grupo de merge) deliberadamente no se documentan aquí — son defaults de carga calibrados contra comportamiento medido, no configuración de usuario.
Núcleo
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_DISABLE | off | Interruptor de apagado. Cuando es verdadero, cada hook se vuelve un no-op — sin captura, sin briefing. |
DAIMON_ENV_FILE | ~/.daimon/env | Ruta del archivo de entorno que respalda a todas las demás variables. Se lee solo del entorno del proceso (nombra al archivo, así que no puede vivir dentro de él). |
DAIMON_PROJECT_DIR | sin definir | Directorio de trabajo de la sesión que se briefea o serializa, usado para enrutar checkpoints por proyecto. Los hooks pasan el cwd del host a través de ella; sin definir significa proyecto desconocido y daimon cae al puntero global. |
DAIMON_CAPTURE_HOST | sin definir | Pista puesta por el host indicando qué agente produjo una captura (claude-code, codex, windsurf, gemini, hermes, manual), enviada por los hooks de captura instalados (#594). No es algo que definas a mano — un hook la mete en el entorno que le pasa al CLI, para los casos en que una ruta de transcript sola no alcanza para resolverlo. |
DAIMON_MIN_MESSAGES | 10 | Conteo mínimo de mensajes para que una sesión valga la pena serializar. Las sesiones más cortas se omiten. |
DAIMON_TIMEOUT | 420 | Presupuesto total de serialización en segundos, compartido entre reintentos (los timeouts de socket por intento se limitan al presupuesto restante). Las llamadas reales de serialize/merge en backends gateway y CLI corren 74s–25min; mantén ≥420 o las llamadas lentas y los reintentos no caben. |
DAIMON_HUNG_AFTER | 1800 | Segundos tras los cuales un proceso de serialización sin línea de resultado se trata como colgado/matado en lugar de aún corriendo. El default de 30 min queda con margen sobre una corrida lenta (las serializaciones en producción toman 4–25 min). |
Almacén de checkpoints y GC
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_CHECKPOINT_DIR | ~/.daimon/checkpoints | Raíz del almacén de checkpoints por sesión. |
DAIMON_CHECKPOINT_KEEP | 100 | Cuántos archivos de checkpoint por sesión retener (los N más nuevos). Los más viejos se recolectan tras una escritura exitosa. 0 desactiva el GC por completo (conservar para siempre). |
DAIMON_CHECKPOINT_HISTORY | 3 | Cuántos punteros de checkpoint retener por directorio (latest.json más prev-1 … prev-(N-1)), para que una serialización fallida pueda caer a un puntero previo. Mínimo 1 (solo latest). |
DAIMON_GC_PIN_IMPORTANCE | 9 | Umbral de importancia de ítem que fija un archivo de checkpoint contra el GC: un archivo cuya importancia máxima de ítem alcanza este valor sobrevive fuera de la ventana de los N más nuevos. 0 desactiva el fijado (ventana de recencia pura); valores sobre 10 se recortan a 10. |
Actualizar a través de la 0.42.0
Antes de la 0.42.0 la biblioteca nombraba el bucket de un proyecto a partir de la ruta literal que recibía. Desde la 0.42.0 cada entry point resuelve la ruta primero: la vuelve absoluta, colapsa los symlinks y después la normaliza al toplevel de git. Por eso hay dos formas de ruta que ahora nombran un bucket distinto al de antes:
- una ruta con un symlink en cualquier parte — en macOS eso incluye todo lo
que se alcanza a través de
/tmp, y cualquier punto de montaje que sea un enlace; - una ruta debajo de un toplevel de git, cuando la escritura vino por la biblioteca y no por la línea de comandos.
La CLI ya resolvía las dos cosas antes de la 0.42.0, así que un bucket escrito
corriendo daimon en una terminal no está afectado. Un bucket escrito por un
proceso anfitrión que llamó a la biblioteca desde una ruta así queda con el
nombre viejo, y nada lo lee.
daimon status lo dice. Cada vez que existe un bucket escrito con la regla
vieja para la ruta donde estás parado, el bloque de salud trae una línea
legacy: que lo nombra. Movelo una sola vez:
daimon bucket migrate # este proyecto
daimon bucket migrate --project /ruta/al/proyecto
daimon bucket migrate --project /ruta/al/proyecto --dry-run
El movimiento renombra el directorio viejo cuando el nuevo todavía no existe, y
en caso contrario fusiona. Una fusión agrega cada línea de ledger que el bucket
nuevo no tenga ya, y suma los punteros del bucket viejo a la cadena del nuevo.
Los punteros que ya están en el bucket nuevo nunca se borran ni se desplazan:
son del proyecto vivo. Los punteros viejos entran en los espacios que deje
libres DAIMON_CHECKPOINT_HISTORY, del más nuevo al más viejo, salvo que una
copia vieja de una sesión a la que el bucket nuevo ya apunta reemplaza ese
único espacio cuando es la más nueva de las dos. Todo lo demás, un puntero
viejo sin espacio libre o un archivo que daimon no escribe, queda exactamente
donde está y se nombra en el reporte junto con qué hacer al respecto.
Correrlo dos veces es seguro: una segunda corrida sobre un estado sin cambios no
escribe nada nuevo y devuelve el código que corresponde al estado que encuentra.
--dry-run imprime el mismo plan y no escribe nada.
La salida 0 significa que el movimiento terminó y el bucket viejo ya no está.
La salida 1 significa que no, y stdout nombra cada cosa que quedó con su propio
remedio: subí DAIMON_CHECKPOINT_HISTORY al número que indica y volvé a correr
para los punteros sin espacio libre; arreglá o movés un archivo que no se pudo
leer; sacá del bucket viejo un archivo que daimon no escribe. Un movimiento
parcial no cuenta como migrado, así que las filas del bucket viejo todavía no se
leen como historia de este proyecto. Si terminás el trabajo por tu cuenta
limpiando el directorio viejo, la siguiente corrida lo registra y la migración
queda completa.
La salida 2 es un rechazo. Un --project con un componente .. se rechaza
porque la regla vieja colapsa el .. antes de seguir un symlink y la actual
sigue el symlink primero, así que las dos nombran directorios distintos; un
bucket escrito antes de 0.42.0 se escribió bajo el slug literal de la ruta ya
colapsada, así que pasá esa ruta. En un home con alcance de inquilino
(DAIMON_TENANT_SCOPED) un --project explícito se rechaza directamente y el
proyecto sale de DAIMON_PROJECT_DIR, o del directorio de trabajo: una
migración escribe un alias duradero entre dos buckets, y elegir cuáles dos es
elegir un alcance.
Cada movimiento completado agrega una línea a
~/.daimon/checkpoints/migrations.jsonl. Ese archivo es lo que permite que
daimon recall y la bandeja de pedidos sigan encontrando el historial bajo el
nombre viejo del bucket una vez que el directorio ya no está: los archivos de
checkpoint por sesión conservan el nombre con el que fueron sellados, porque sus
receipts atan sus bytes exactos. Cuando un bucket ya absorbió a otro, daimon status muestra una línea migrated: from <bucket viejo> on <fecha> en lugar de
la advertencia.
Arrastre (carry)
Arrastre determinista de ítems sin resolver entre sesiones.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_CARRY | on | Interruptor maestro del arrastre. Activo salvo que valga exactamente 0 (cualquier otro valor lo mantiene activo). |
DAIMON_CARRY_FLOOR | 0.05 | Peso efectivo mínimo para que un ítem arrastrado siga arrastrándose. Con el default, las decisiones expiran en ~5–6 semanas (graduado por importancia) y las preguntas abiertas escaladas viven ~3–4 meses. |
DAIMON_CARRY_MAX | 24 | Tope de ítems arrastrados por tipo (los ítems nativos nunca cuentan contra él ni se descartan). Mínimo 1. |
Briefing
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_BRIEF_MAX_TOKENS | 3000 | Presupuesto de tokens para el briefing inyectado, estimado a 4 bytes por token (sin dependencia de tokenizador). Se pliega en un único presupuesto de bytes, min(DAIMON_BRIEF_MAX_BYTES, DAIMON_BRIEF_MAX_TOKENS * 4), que comparten todos los bloques de daimon brief. 0 = sin límite. |
DAIMON_BRIEF_MAX_BYTES | 11264 | El presupuesto de bytes para la salida COMPLETA de daimon brief, en bytes UTF-8 (lo que mide el límite de recorte de un host): el bloque de traspaso (handoff), las reglas vigentes, los paneles de solicitudes y decisiones, el cuerpo cognitivo, el bloque de desvío de código, la sección de compañeros de equipo y la nota de ítems ocultos cuentan contra él. Cuando se agota, el briefing suelta ítems completos en un único orden fijo (primero los arrastrados vencidos, las secciones de fondo antes que las accionables, lo arrastrado antes que lo de esta sesión) y cada sección dice qué ocultó. El saludo, las reglas vigentes, el traspaso y las decisiones más nuevas nunca se sueltan; si solo eso ya excede el presupuesto, el briefing dice por cuánto. 0 = sin límite. |
DAIMON_MAX_BRIEFING_DECISIONS | 10 | Tope de decisiones mostradas en el briefing (solo vista de renderizado, el checkpoint las conserva todas). La nota de Decisiones cuenta lo que el tope recortó. Las min(3, tope) decisiones más nuevas de la última sesión siempre se muestran. 0 = sin límite. |
DAIMON_BRIEF_GLOBAL_FALLBACK | solo encabezado | Controla el fallback al puntero global entre proyectos cuando un proyecto no tiene checkpoint propio. El default muestra solo un encabezado; ponlo en full (o 1) para inyectar el cuerpo foráneo completo. |
DAIMON_STALE_DAYS | 7.0 | Umbral de edad (días) tras el cual el sello efectivo de última verificación de un ítem arrastrado (su last_verified, si no el último evento de resolutions.jsonl, si no first_seen) está lo bastante desactualizado para que brief lo advierta. 0 advierte en cada ítem arrastrado. |
DAIMON_PLAIN | off | Cuando es verdadero (sin distinción de mayúsculas), fuerza salida de texto plano — desactiva las tablas/paneles enriquecidos en status, brief y --help. |
NO_COLOR | sin definir | Por presencia, según la convención NO_COLOR: si la variable está definida con cualquier valor (incluso vacío), la salida enriquecida se desactiva. |
Worldcheck
Opt-in (#365): un chequeo puntual, al momento del briefing, de las
afirmaciones de estado de PR/issue arrastradas contra la realidad, vía
probes de solo-lectura con gh. Apagado por defecto — daimon brief corre
en la ruta de inyección crítica en latencia del hook SessionStart (un
presupuesto de subproceso de 8s dentro de un presupuesto de hook de 10s),
así que incluso probes de red acotados en presupuesto ahí deben activarse a
propósito. Con el flag apagado, la ruta de render nunca toca el módulo de
worldcheck — la salida queda byte-idéntica a una build sin él.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_WORLDCHECK | off | Cuando es verdadero, chequea las afirmaciones de estado de PR/issue arrastradas contra la realidad vía probes de solo-lectura con gh al momento del briefing. |
Con worldcheck habilitado, las contradicciones detectadas sobre la existencia de archivos y ramas o el estado de PR/issues también bajan la prioridad del ítem en las búsquedas y sugerencias de recall. El ítem sigue visible. Una confirmación posterior solo levanta la contradicción de esa misma afirmación; un recibo válido no levanta una contradicción por un archivo ausente. Los chequeos omitidos o no disponibles no invalidan ni levantan contradicciones. Los chequeos de versiones de dependencias siguen anotando solo el briefing. La CLI compartida registra la evidencia; el renderizador no escribe estos datos.
| Superficie | Recolección de evidencia con DAIMON_WORLDCHECK=1 |
|---|---|
| Claude Code, Codex, Gemini CLI, Kimi Code | Soportada mediante el hook existente de daimon brief de cada host. |
| Windsurf | Soportada cuando el agente ejecuta daimon brief --team; sin inyección automática al iniciar sesión. |
MCP daimon_brief, hook de briefing en proceso de Hermes | No soportada: estas rutas de renderizado no ejecutan worldcheck. Usá la CLI para recolectar evidencia. |
| Recall por CLI y MCP, sugerencias proactivas | Consumen la evidencia registrada mediante el índice compartido de recall. |
Recall
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_RECALL_DB | ~/.daimon/recall.db | Ubicación del índice derivado de recall (SQLite FTS). Nunca es fuente de verdad — es seguro borrarlo en cualquier momento; recall lo reconstruye escaneando los directorios de checkpoints y de equipo. |
DAIMON_RECALL_SEEN_DIR | ~/.daimon/recall_seen | Estado de enfriamiento de sugerencias por sesión para que un tema repetido nunca se re-inyecte. Desechable — borrarlo solo reinicia los enfriamientos. |
Memoria de equipo
Mirror de memoria compartida opt-in. Mira memoria de equipo para el flujo completo.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_TEAM | off | Cuando es verdadero, refleja cada checkpoint en el directorio de equipo compartido para que brief --team pueda mostrar a los compañeros. Regula escrituras solamente — las lecturas del directorio de equipo siempre están permitidas. Un remoto sincronizado exige además que el proyecto esté en su allowlist de alcance (mira team.md); los proyectos fuera de alcance se reflejan solo al directorio local. |
DAIMON_AUTHOR | user.name de git, luego el usuario del SO | Identidad de autor de equipo usada para separar tus checkpoints. Cae a git config user.name, luego al usuario del SO, luego a unknown. |
DAIMON_TEAM_DIR | ~/.daimon/team | Raíz del mirror de memoria de equipo compartida. |
DAIMON_TEAM_PROJECT | sin definir | Ruta lógica de proyecto explícita para las sesiones de esta máquina (relativa, p. ej. core/api-gateway). Prevalece sobre el mapeo de daimon-team.toml del sidecar y sobre el fallback derivado del origin al enrutar checkpoints bajo projects/. |
DAIMON_TEAM_RETENTION_DAYS | 365 | Ventana de edad al leer: los checkpoints de compañeros más viejos que esta cantidad de días se omiten al leer. 0 = conservar todos. Nunca borra físicamente de la rama compartida de solo-anexado. |
DAIMON_TEAM_APPLY_FORGET | off | Consentimiento permanente para que el tombstone de olvido publicado por un COMPAÑERO reescriba los checkpoints propios de esta máquina. NO alcanza por sí solo — el borrado además exige el daimon team sync --apply-forget escrito a mano, porque un daimon team sync pelado se lanza en segundo plano al iniciar la sesión. Por defecto apagado: un tombstone ajeno siempre suprime el valor al leer y en el índice, pero borrar estado local a partir del hash de otra persona es una decisión que se toma a conciencia — la rama compartida es de solo-anexado, así que no hay vuelta atrás. Sin ella, daimon team sync --apply-forget se niega con código de salida 2 antes de sincronizar nada. Con la variable activada, daimon team status y la línea de equipo de daimon status lo reportan como armado. |
DAIMON_LIVE_DELIVERY | off | Cuando es verdadero, un request sin decidir dirigido a este proyecto se entrega a una sesión que ya estaba corriendo cuando llegó, en el siguiente límite de turno de esa sesión, en vez de esperar a su próximo briefing de SessionStart. Solo superficie de render: el ledger sigue siendo store-and-forward, el aviso entregado es el mismo registro pull-only que habría mostrado el próximo briefing, y los verbos que deciden siguen siendo solo humanos. Una vez por sesión y por revisión; un request revise vuelve a entregar el pedido afinado. Solo dentro del mismo daimon home. Por defecto apagado — solo-briefing es la postura correcta para sesiones cortas, así que un consumidor siempre-activo lo enciende a conciencia. |
Receipts
Receipts de procedencia firmados, opt-in (#204). Al habilitarlos, cada
checkpoint se empareja con un receipt de vinculación local de
vitni: una declaración firmada con
Ed25519 que vincula los bytes exactos en disco del checkpoint
(outputs_hash) con su transcript de origen (inputs_hash), escrita en un
archivo lateral <session>.receipt. Esto hace detectable una edición
posterior al archivo del checkpoint. Los receipts son totalmente válidos
offline — nada sale de la máquina.
Cada paso es fail-open: un CLI ausente, un openssl ausente, un timeout o
una salida mala registran una línea en serialize.log y se continúa sin
receipt — una falla de receipts nunca bloquea ni hace fallar una
serialización o un briefing. Verifica un checkpoint bajo demanda con
daimon verify-receipt [session]; al momento del briefing, un checkpoint de
la era de receipts cuyo receipt falta o ya no coincide con sus bytes tiene
sus etiquetas ✓ verbatim degradadas con una nota visible.
La derivación de la llave pública prefiere el comando keygen del CLI de
vitni (vitni 0.5.0+) y cae a openssl en CLIs más viejos o ante un probe
fallido — así en macOS, donde el LibreSSL de Apple no tiene Ed25519 en
openssl pkey, los receipts funcionan una vez instalado vitni ≥ 0.5.0, sin
necesidad de un openssl con Ed25519.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_RECEIPTS | off | Cuando es verdadero, mintea un receipt firmado junto a cada checkpoint. Off por defecto — un subproceso nuevo por serialización es opt-in. |
DAIMON_VITNI_CLI | vitni-verify (en el PATH) | El CLI verificador de vitni usado para firmar/verificar. Una ruta o un nombre resuelto en el PATH. Contrato: <cli> <command> con un objeto JSON por stdin y una línea JSON por stdout. |
DAIMON_KEYS_DIR | ~/.daimon/keys | Dónde viven la semilla de firma Ed25519 (signing.seed, modo 0600, auto-creada en el primer minteo) y la llave pública cacheada (signing.pub.json). |
Hooks de host
Perillas de throttle de serialización para hosts sin un evento limpio de fin de sesión. Mira Hosts para la configuración por host.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_CODEX_SERIALIZE_ON_STOP | on | Si el hook Stop de Codex serializa en absoluto. Activo salvo que valga 0, false, no u off (sin distinción de mayúsculas). |
DAIMON_CODEX_SERIALIZE_ON_SESSION_END | on | Si el hook SessionEnd de Codex serializa en absoluto — el fin real de una sesión, disparado una sola vez en el cierre ordenado con el transcript completo, deliberadamente sin throttle. Activo salvo que valga 0, false, no u off (sin distinción de mayúsculas). No reemplaza a Stop, que sigue como seguro ante un SIGKILL o una terminal cerrada que nunca llega a SessionEnd. |
DAIMON_CODEX_MIN_SERIALIZE_INTERVAL | 300 | Segundos mínimos entre lanzamientos de serialización de Codex. 0 serializa en cada Stop. |
DAIMON_WINDSURF_MIN_SERIALIZE_INTERVAL | 300 | Segundos mínimos entre lanzamientos de serialización de Windsurf (Windsurf no tiene evento de fin de sesión, así que la captura corre con este throttle). 0 serializa cada turno. |
DAIMON_WINDSURF_FINALIZER_QUIET_SECONDS | 600 | Periodo de silencio tras la última actividad de Windsurf antes de que un finalizador con debounce serialice el estado final del transcript de la trayectoria — cubre sesiones cuyos últimos turnos caen dentro de la ventana del throttle. Acepta valores fraccionarios; 0 desactiva el finalizador. |
DAIMON_WINDSURF_DIR | ~/.daimon/windsurf | Dónde guarda el adaptador de Windsurf los transcripts que acumula. Lo leen tanto el hook que los escribe como las rutas de forget/heal que los borran — cámbialo en un solo sitio, o el que escribe y el que borra dejan de coincidir. |
DAIMON_WINDSURF_STATE_DAYS | 7 | Ventana de antigüedad para los transcripts de Windsurf que escribe daimon y los volcados unparsed, recogidos por daimon heal. Es un límite de privacidad: un valor olvidado no puede localizarse dentro de la prosa, así que esto acota cuánto tiempo permanece la conversación de origen entre ejecuciones de forget. Con mínimo 1 — a diferencia de los otros ajustes de Windsurf, 0 no lo desactiva. |
Escalamiento de heal
Opt-in (#360): el reintento por defecto de daimon heal vuelve a correr la
misma forma de extracción que ya había fallado. El escalamiento serializa de
nuevo desde varias perspectivas distintas en su lugar, fusionadas por el paso
de merge de siempre — lo que multiplica el costo de tokens del LLM
aproximadamente por la cantidad de perspectivas en tu propio backend, razón
por la cual sale apagado por defecto. Regula solo la ruta de heal: la
serialización por defecto de fin de sesión nunca escala, con o sin el flag.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_HEAL_ESCALATION | off | Cuando es verdadero, daimon heal serializa de nuevo desde varias perspectivas en vez de reintentar la misma forma de extracción. Solo en la ruta de heal. |
Captura mientras un ledger no se puede leer
Cuando el events.jsonl de un proyecto no se puede leer (un marcador de
conflicto, un byte malo, un error del sistema), daimon no escribe un checkpoint
para él: la compuerta de olvidos tendría que adivinar, y un valor olvidado
podría volver. La sesión se rechaza antes de llamar al modelo, lo que no cuesta
nada. El rechazo es un serialize fallido común. daimon status lo cuenta desde
todo el log y nombra el remedio, el próximo briefing del proyecto dice cuántas
sesiones esperan, y daimon heal las reintenta de a una por inicio de sesión
cuando el ledger vuelve a leerse, sin gastar el único reintento. Un rechazo solo
se pierde cuando su transcript ya no está.
| Host | Captura rechazada |
|---|---|
| Claude Code, Codex, Gemini CLI, Kimi Code | Soportado: se cuenta, se avisa en el briefing y daimon heal lo reintenta mientras el host conserve el transcript. |
| Windsurf | Soportado, con un límite: sigue aplicando la limpieza propia de daimon a los transcripts de Windsurf a los 7 días (DAIMON_WINDSURF_STATE_DAYS), así que una sesión rechazada por más tiempo se pierde y se cuenta como irrecuperable. |
| Captura en proceso de Hermes | Soportado solo cuando el host pasa una ruta de transcript que existe. Sin ella se cuenta como irrecuperable y no se puede reintentar. |
| Pods de anamnesis | Soportado, por el mismo CLI. |
Scene traces
Experimento opt-in (#317): el serializador pide un scene por ítem, una o
dos oraciones de contexto episódico, junto con el resto de la extracción.
Depende de que el harness de LongMemEval lo confirme como ganancia neta
antes de poder volverse default.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_SCENE_TRACES | off | Cuando es verdadero, le pide al serializador que también produzca el campo scene de cada ítem. |
Operación y diagnóstico
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_LOG_DIR | ~/.daimon/logs | Directorio de logs. serialize-crash.log respeta esta variable de los dos lados: los hooks que lanzan el proceso hijo de serialize la leen (del entorno y de este archivo) igual que el CLI, porque daimon forget borra ese archivo y quien escribe y quien borra tienen que coincidir en dónde está. serialize.log es la excepción: los hooks lo siguen escribiendo en ~/.daimon/logs siempre, y este override solo cambia dónde lo busca el CLI (y los tests). |
DAIMON_CLAUDE_PROJECTS_DIR | ~/.claude/projects | Dónde viven los transcripts del host (<slug>/<session>.jsonl). Solo-lectura — la auditoría de re-verificación de citas los lee para re-revisar citas almacenadas contra su fuente. |
DAIMON_SCAR_HARVEST | off | Cuando es verdadero, borra candidatos de scar (conocimiento negativo) desde el transcript al fin de sesión. |
DAIMON_LOG_STDOUT | off | Cuando es verdadero, las líneas de resultado de serialize también llegan a stdout, el stream que recolecta un runtime de contenedores. El hook de fin de sesión deja que el proceso hijo desprendido herede stdout en vez de descartarlo, y el CLI también refleja ahí sus líneas error:, así que éxito, omisión y error caen todos en una sola superficie. Pensado para hosts en contenedores, donde una línea escrita solo en serialize.log sobre un volumen es invisible para la plataforma. Apagado por defecto: en una terminal esas líneas aparecen en tu shell minutos después de que terminó la sesión. No toca stderr, que queda reservado para serialize-crash.log. |
Backend LLM
La serialización necesita un endpoint de LLM. daimon configure es la vía
prevista para definir estas variables. La URL, la key y el modelo caen cada
uno a una variable LITELLM_* si la forma DAIMON_* no está definida. El
backend litellm necesita ambas DAIMON_LLM_MODEL y
DAIMON_LLM_API_KEY; mientras falte alguna, daimon configure reporta
backend: litellm — missing: ... nombrando exactamente qué falta — esa línea
significa que la configuración está incompleta, no que el endpoint esté caído.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_LLM_BACKEND | auto | Transporte: auto (litellm si hay credenciales, si no un CLI de comando nombrado si alguno resuelve), litellm, command o claude-cli. claude-cli es la opción sin configuración: ejecuta un claude encontrado en el PATH con un preset incorporado y no necesita nada más. command requiere DAIMON_LLM_COMMAND. |
DAIMON_LLM_BASE_URL | http://localhost:4000 | URL del endpoint compatible con OpenAI (se recorta la barra final). Cae a LITELLM_BASE_URL. |
DAIMON_LLM_API_KEY | sin definir | API key del endpoint. Obligatoria para el backend litellm. Cae a LITELLM_API_KEY. |
DAIMON_LLM_MODEL | sin definir | Nombre de modelo a enviar. Obligatorio para el backend litellm. Cae a LITELLM_MODEL. |
DAIMON_LLM_TEMPERATURE | 0.0 | Temperatura de muestreo de cada llamada de chat. 0.0 para extracción determinista; algunos upstreams rechazan cualquier valor que no sea uno fijo. |
DAIMON_LLM_FALLBACK | on | Cuando el backend primario falla, cae automáticamente al comando de rescate (DAIMON_LLM_COMMAND_FALLBACK). Aplica tanto a un primario litellm como a uno command. Ponlo en 0 para desactivarlo. |
DAIMON_FALLBACK_MIN_SECONDS | DAIMON_TIMEOUT | Presupuesto mínimo garantizado al comando de rescate al entrar. El primario pudo haber agotado el deadline compartido reintentando la misma falla que el rescate existe para resolver, lo que lo mataría al llegar; un presupuesto restante sano nunca se recorta. |
DAIMON_RESAMPLE_MIN_SECONDS | DAIMON_TIMEOUT | #553: presupuesto mínimo garantizado al remuestreo de validación al entrar — la misma falla que #341 arregló para el fallback de comando, un paso más allá. El deadline compartido puede agotarlo el intento cuya salida acaba de ser rechazada, lo que dejaría al remuestreo sin nada con qué trabajar. Cae a timeout_seconds() por la misma razón que DAIMON_FALLBACK_MIN_SECONDS. |
DAIMON_LLM_STREAM | on | Transmite la respuesta de litellm para que el timeout del socket acote el intervalo entre frames y no la longitud total de la respuesta. Sin esto, una respuesta larga dispara el timeout y reintenta desde cero. Ponlo en 0 para desactivarlo. |
DAIMON_LLM_NO_CACHE | off | Cuando es verdadero, evita el cache de respuestas del gateway por request — necesario cuando una respuesta mala cacheada fija una falla o cuando las corridas deben ser estadísticamente independientes. |
DAIMON_LLM_BRIEFING | off | Cuando es verdadero, renderiza el briefing vía LLM en lugar de la plantilla determinista. |
DAIMON_LLM_COMMAND | sin definir | Invocación completa del CLI para el backend command (binario + modelo + flags). Obligatoria para command, y obligatoria para que un claude en el PATH sea usado por cualquier backend que no sea claude-cli. |
DAIMON_LLM_COMMAND_OUTPUT | sin definir | Cómo extraer el texto del asistente del stdout del comando: text (stdout crudo) o json:<key> (parsear JSON, leer <key>). |
DAIMON_LLM_COMMAND_INPUT | stdin | Cómo llega el prompt al backend de comando: stdin (por tubería), arg (anexado como último elemento de argv) o file:<flag> (escrito a un archivo temporal, luego se anexa <flag> <path>). Un valor no reconocido registra una advertencia y cae a stdin. |
DAIMON_LLM_COMMAND_FALLBACK | sin definir | El único CLI de rescate, usado cuando el backend primario falla. Sirve tanto para un primario litellm como para uno command, que antes no tenía ninguna dirección de rescate. Un solo fallback, nunca una cadena: si el primario y este fallan, la causa casi siempre es del entorno, y un tercer CLI gasta presupuesto para llegar al mismo error mientras hace que la instalación parezca más protegida de lo que está. Si no se define, un primario litellm sigue cayendo a DAIMON_LLM_COMMAND como antes. |
DAIMON_LLM_COMMAND_FALLBACK_OUTPUT | sin definir | Especificación de salida del CLI de rescate, misma gramática que DAIMON_LLM_COMMAND_OUTPUT. Se lleva por separado porque el rescate es otro binario. |
DAIMON_LLM_COMMAND_FALLBACK_INPUT | stdin | Especificación de entrada del CLI de rescate, misma gramática que DAIMON_LLM_COMMAND_INPUT. |
Un binario claude que simplemente esté en el PATH no se adopta automáticamente. Serializar envía la transcripción completa de la sesión al CLI configurado, así que ese CLI debe nombrarse: o DAIMON_LLM_COMMAND, o DAIMON_LLM_BACKEND=claude-cli para optar por el preset incorporado.
Antes bastaba con dejar DAIMON_LLM_COMMAND sin definir y tener un claude en cualquier parte del PATH, tanto para instalaciones en auto como para la ruta de rescate de litellm. Si dependías de eso, definí una de las dos variables de arriba. daimon configure nombra el binario resuelto y su ruta para que puedas ver exactamente cuál está en uso.
El preset claude-cli corre su hijo claude -p con --strict-mcp-config, así que no carga ningún servidor MCP. Sin esa bandera, el lanzador propio del hijo sale temprano bajo el entorno de aislamiento que define el serializador, y Claude Code lo registra como una falla de conexión, así que toda sesión nueva de la máquina saltea el servidor MCP de daimon durante los siguientes 15 minutos (#1077). Si apuntás un DAIMON_LLM_COMMAND a claude vos mismo, agregale --strict-mcp-config también: el serializador solo convierte texto en JSON y nunca necesita una herramienta MCP.
Chunking del serializador
Las sesiones largas se serializan en chunks solapados cuyos checkpoints parciales se fusionan jerárquicamente. Los defaults vienen de mediciones de campo; solo importan si tus sesiones son rutinariamente muy largas.
| Variable | Default | Qué hace |
|---|---|---|
DAIMON_CHUNK_LINES | 1200 | Conteo de líneas del transcript renderizado sobre el cual la serialización cambia a modo chunked. |
DAIMON_CHUNK_OVERLAP | 100 | Líneas de solapamiento entre chunks adyacentes, para que un ítem que cruza un borde sea visto entero por al menos un chunk. |
DAIMON_CHUNK_CONCURRENCY | 4 | Llamadas LLM de serialización de chunks en paralelo. Mínimo 1 (secuencial). |
DAIMON_MERGE_GROUP_SIZE | 3 | Máximo de checkpoints parciales fusionados por llamada de merge jerárquico. Mínimo 2. Bájalo a 2 si las llamadas de merge mueren en un gateway con techo de request del lado del servidor (los modelos de razonamiento generando merges de 3 vías pueden excederlo; subir DAIMON_TIMEOUT no ayuda — el kill es del lado del servidor). |
DAIMON_CHUNK_CACHE | on | #48: cache de contenido-direccionado de la salida de extracción por chunk, indexada por los bytes del propio chunk, para que un reintento de heal o retry vuelva a pagar una llamada solo cuando el chunk de origen cambió de verdad. Interruptor de apagado — activo salvo que valga 0. |
DAIMON_CHUNK_CACHE_DAYS | 3 | Ventana de rotación del cache de chunks, en días. La salida cacheada es previa a la redacción (lo exige el orden de verificación de citas de #125), así que la ventana es tanto un límite de privacidad como de disco — 3 días cubre la ventana de heal/retry manteniendo la exposición corta. |