Saltar al contenido principal

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​

VariableDefaultQué hace
DAIMON_DISABLEoffInterruptor de apagado. Cuando es verdadero, cada hook se vuelve un no-op — sin captura, sin briefing.
DAIMON_ENV_FILE~/.daimon/envRuta 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_DIRsin definirDirectorio 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_HOSTsin definirPista 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_MESSAGES10Conteo mínimo de mensajes para que una sesión valga la pena serializar. Las sesiones más cortas se omiten.
DAIMON_TIMEOUT420Presupuesto 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_AFTER1800Segundos 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​

VariableDefaultQué hace
DAIMON_CHECKPOINT_DIR~/.daimon/checkpointsRaíz del almacén de checkpoints por sesión.
DAIMON_CHECKPOINT_KEEP100Cuá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_HISTORY3Cuá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_IMPORTANCE9Umbral 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.

VariableDefaultQué hace
DAIMON_CARRYonInterruptor maestro del arrastre. Activo salvo que valga exactamente 0 (cualquier otro valor lo mantiene activo).
DAIMON_CARRY_FLOOR0.05Peso 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_MAX24Tope de ítems arrastrados por tipo (los ítems nativos nunca cuentan contra él ni se descartan). Mínimo 1.

Briefing​

VariableDefaultQué hace
DAIMON_BRIEF_MAX_TOKENS3000Presupuesto 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_BYTES11264El 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_DECISIONS10Tope 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_FALLBACKsolo encabezadoControla 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_DAYS7.0Umbral 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_PLAINoffCuando es verdadero (sin distinción de mayúsculas), fuerza salida de texto plano — desactiva las tablas/paneles enriquecidos en status, brief y --help.
NO_COLORsin definirPor 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.

VariableDefaultQué hace
DAIMON_WORLDCHECKoffCuando 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.

SuperficieRecolección de evidencia con DAIMON_WORLDCHECK=1
Claude Code, Codex, Gemini CLI, Kimi CodeSoportada mediante el hook existente de daimon brief de cada host.
WindsurfSoportada 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 HermesNo soportada: estas rutas de renderizado no ejecutan worldcheck. Usá la CLI para recolectar evidencia.
Recall por CLI y MCP, sugerencias proactivasConsumen la evidencia registrada mediante el índice compartido de recall.

Recall​

VariableDefaultQué hace
DAIMON_RECALL_DB~/.daimon/recall.dbUbicació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_seenEstado 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.

VariableDefaultQué hace
DAIMON_TEAMoffCuando 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_AUTHORuser.name de git, luego el usuario del SOIdentidad 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/teamRaíz del mirror de memoria de equipo compartida.
DAIMON_TEAM_PROJECTsin definirRuta 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_DAYS365Ventana 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_FORGEToffConsentimiento 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_DELIVERYoffCuando 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.

VariableDefaultQué hace
DAIMON_RECEIPTSoffCuando es verdadero, mintea un receipt firmado junto a cada checkpoint. Off por defecto — un subproceso nuevo por serialización es opt-in.
DAIMON_VITNI_CLIvitni-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/keysDó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.

VariableDefaultQué hace
DAIMON_CODEX_SERIALIZE_ON_STOPonSi 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_ENDonSi 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_INTERVAL300Segundos mínimos entre lanzamientos de serialización de Codex. 0 serializa en cada Stop.
DAIMON_WINDSURF_MIN_SERIALIZE_INTERVAL300Segundos 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_SECONDS600Periodo 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/windsurfDó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_DAYS7Ventana 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.

VariableDefaultQué hace
DAIMON_HEAL_ESCALATIONoffCuando 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á.

HostCaptura rechazada
Claude Code, Codex, Gemini CLI, Kimi CodeSoportado: se cuenta, se avisa en el briefing y daimon heal lo reintenta mientras el host conserve el transcript.
WindsurfSoportado, 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 HermesSoportado solo cuando el host pasa una ruta de transcript que existe. Sin ella se cuenta como irrecuperable y no se puede reintentar.
Pods de anamnesisSoportado, 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.

VariableDefaultQué hace
DAIMON_SCENE_TRACESoffCuando es verdadero, le pide al serializador que también produzca el campo scene de cada ítem.

Operación y diagnóstico​

VariableDefaultQué hace
DAIMON_LOG_DIR~/.daimon/logsDirectorio 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/projectsDó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_HARVESToffCuando es verdadero, borra candidatos de scar (conocimiento negativo) desde el transcript al fin de sesión.
DAIMON_LOG_STDOUToffCuando 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.

VariableDefaultQué hace
DAIMON_LLM_BACKENDautoTransporte: 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_URLhttp://localhost:4000URL del endpoint compatible con OpenAI (se recorta la barra final). Cae a LITELLM_BASE_URL.
DAIMON_LLM_API_KEYsin definirAPI key del endpoint. Obligatoria para el backend litellm. Cae a LITELLM_API_KEY.
DAIMON_LLM_MODELsin definirNombre de modelo a enviar. Obligatorio para el backend litellm. Cae a LITELLM_MODEL.
DAIMON_LLM_TEMPERATURE0.0Temperatura 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_FALLBACKonCuando 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_SECONDSDAIMON_TIMEOUTPresupuesto 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_SECONDSDAIMON_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_STREAMonTransmite 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_CACHEoffCuando 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_BRIEFINGoffCuando es verdadero, renderiza el briefing vía LLM en lugar de la plantilla determinista.
DAIMON_LLM_COMMANDsin definirInvocació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_OUTPUTsin definirCómo extraer el texto del asistente del stdout del comando: text (stdout crudo) o json:<key> (parsear JSON, leer <key>).
DAIMON_LLM_COMMAND_INPUTstdinCó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_FALLBACKsin definirEl ú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_OUTPUTsin definirEspecificació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_INPUTstdinEspecificación de entrada del CLI de rescate, misma gramática que DAIMON_LLM_COMMAND_INPUT.
Qué proceso recibe tu transcripción

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.

VariableDefaultQué hace
DAIMON_CHUNK_LINES1200Conteo de líneas del transcript renderizado sobre el cual la serialización cambia a modo chunked.
DAIMON_CHUNK_OVERLAP100Líneas de solapamiento entre chunks adyacentes, para que un ítem que cruza un borde sea visto entero por al menos un chunk.
DAIMON_CHUNK_CONCURRENCY4Llamadas LLM de serialización de chunks en paralelo. Mínimo 1 (secuencial).
DAIMON_MERGE_GROUP_SIZE3Má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_CACHEon#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_DAYS3Ventana 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.