# Daemon Runtime > Nota interna del proyecto no-mistakes. Se usa al cambiar el arranque del daemon, la propiedad singleton, el apagado, el logging, las suscripciones a eventos o los comandos de ciclo de vida. Fuente: https://skillsagentes.com/skills/kunchenguid/no-mistakes/daemon-runtime Markdown: https://skillsagentes.com/skills/kunchenguid/no-mistakes/daemon-runtime.md Repositorio: https://github.com/kunchenguid/no-mistakes Autor: kunchenguid Licencia: MIT Actualizado: hace 3 días Coste de contexto: 29 tok instalada, 2k tok al activarse, 2k tok con todos los archivos del bundle Bundle: 1 archivo, 8 KB Permisos que pide: ninguno declarado ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add kunchenguid/no-mistakes --skill daemon-runtime --agent claude-code # Cursor npx -y skills add kunchenguid/no-mistakes --skill daemon-runtime --agent cursor # Codex npx -y skills add kunchenguid/no-mistakes --skill daemon-runtime --agent codex # Gemini CLI npx -y skills add kunchenguid/no-mistakes --skill daemon-runtime --agent gemini # Windsurf npx -y skills add kunchenguid/no-mistakes --skill daemon-runtime --agent windsurf # Cline npx -y skills add kunchenguid/no-mistakes --skill daemon-runtime --agent cline ``` ## Qué hace - Nota interna sobre el lock singleton del daemon (`internal/daemon/lock.go`): un lock de archivo OS exclusivo sobre `daemon.lock` se adquiere como primera acción de `RunWithOptions`, antes de la recuperación y del bind del socket. - El lanzamiento del proceso no es readiness: el PID se publica tras el lock y antes de la recuperación exclusiva, y el arranque solo tiene éxito con una respuesta real de salud por IPC. - Un stop con éxito significa que el proceso del daemon ya no está, no solo que la salud IPC desapareció, porque solo la salida del proceso libera el lock singleton. - La limpieza de worktrees al arrancar es consciente de la BD: nunca borra un worktree cuyo run está `pending` o `running`. - `internal/logstore` acota todos los bytes y la retención de los logs del daemon; el driving de runs AXI es subscribe-first y no se debe reintroducir polling de `get_run` a intervalo fijo. ## Cuándo usarla - Se cambia el arranque del daemon, la propiedad singleton, el apagado, el logging, las suscripciones a eventos o los comandos de ciclo de vida. ## Qué la activa - "Voy a tocar el arranque del daemon de no-mistakes" - "Cambia cómo se maneja el apagado del daemon" - "Revisa las suscripciones a eventos acotadas por pérdida" ## Archivos - SKILL.md — 8 KB ## SKILL.md Reproducido tal cual desde kunchenguid/no-mistakes bajo MIT. Esta sección es el documento original y está en inglés. **Daemon Singleton Lock (`internal/daemon/lock.go`)** - Only one live daemon may own an `NM_HOME`: an exclusive OS file lock on `/daemon.lock` is acquired as the very first action in `RunWithOptions`, strictly before stale-run recovery and socket bind, and held for the process lifetime. The kernel releases it on any process death, so a held lock always means a live holder and no staleness heuristic is needed. Without it, a second daemon stole the socket and ran global crash recovery against the live daemon's runs and worktrees. - Process launch is not readiness: the PID record is published after the singleton lock and before exclusive recovery, while startup succeeds only after a real IPC health response. The 45s production budget covers cold environment setup and recovery; early exits fail promptly, timeout cleanup reaps detached children before fallback or rollback, and managed plus detached failures retain both causes. Regressions: `TestStartDetachedDaemonDetectsChildExitPromptly`, `TestStartDetachedDaemonTimeoutKillsAndReapsChild`, `TestStartPreservesManagedAndDetachedFallbackErrors`, `TestColdDetachedStartupProductionGateCardinality`. - A successful stop means the daemon process is gone, not merely that IPC health has disappeared, because only process exit releases the singleton lock. Capture the daemon instance before requesting shutdown, and close the shutdown client before waiting because the daemon drains in-flight handlers during exit. See `waitForDaemonStop` and `stopDetachedDaemon`; regressions: e2e `TestDaemonStopLeavesNoDaemonProcessOwningTheRoot`, `TestDaemonRestartReplacesTheDaemonWithExactlyOneOwner`. - Independent layers: `internal/ipc` `listen()` dials the socket before unlinking it and refuses to steal a live one; client probes bound the dial with `daemon_connect_timeout` and fail fast on a dead or wedged socket instead of starting a replacement daemon (`EnsureDaemon` surfaces the error with a `daemon start` recovery hint; the health RPC itself is bounded separately by `ipc.DefaultDialTimeout`). - Daemon execution is explicit-only (`no-mistakes daemon run --root`); never let inherited environment reinterpret probes like `--version` or `status` as daemon workers. - Startup worktree cleanup is DB-aware: never remove a worktree whose run row is `pending` or `running`; `startRun` inserts the run row before creating the worktree, so a no-row directory is safe to remove immediately. That no-row rule holds only inside `/worktrees`, which is discovered by walking because no-mistakes owns it; a configured worktree root is the operator's directory, so cleanup and eject there act on exactly the recorded run worktrees and never enumerate anything else. - The user-facing model lives in `docs/src/content/docs/concepts/daemon.md`; the lock rationale lives in the `internal/daemon/lock.go` and `daemon.go` comments. Regressions: `TestAcquireSingletonLock_*`, `TestRunWithResources_SecondDaemonForSameRootFailsWithoutStealingSocket`, `TestRunWithOptions_RequiresSingletonLockBeforeRecovery`, `TestRecoverOnStartup_DoesNotDeleteActiveRunWorktree`, `TestServe_SecondListenerForLiveSocketDoesNotStealIt`, `TestDialConnectTimeoutFailsFastAndNamesSocket`, `TestIsRunningFailsFastWhenSocketAcceptsButDoesNotRespond`, `TestIsRunningSurfacesExistingDeadSocket`, `TestDaemonRunRootFromArgs_EnvDoesNotForceDaemonModeForProbes`, `TestValidateDaemonPIDFallback_RefusesToKillOwnProcess`. **Bounded Daemon Logging and Event-Driven AXI Runs** - `internal/logstore` owns all daemon-process byte and retention bounds. Lifecycle output uses `logs/daemon.log`, managed Rovo Dev/OpenCode stdout and stderr use `logs/managed-server.log`, and service bootstrap/direct crash output uses `logs/daemon-bootstrap.log`. Rotation snapshots backups and truncates the current inode in place so held service and child descriptors keep writing to the bounded current file. Regressions: `internal/logstore/rotate_test.go`, `TestDetachedDaemonUsesBoundedDedicatedLogSinks`, `TestManagedServerOutputIsSeparatedFromLifecycleFailureSummary`. - Successful read-only IPC methods are DEBUG; mutations and stream starts are INFO; every request failure is WARN. AXI run driving is subscribe-first and `internal/cli/run_reconciler.go` is the sole owner of event reconciliation, reconnect, duplicate-event coalescing, and the slow lost-event heartbeat. Do not reintroduce fixed-interval `get_run` polling. Regressions: `TestSuccessfulReadRequestsDoNotLogAtInfo`, `TestRequestLoggingKeepsMutationsAndFailuresVisible`, `TestDriveRun_HealthyWaitStaysWithinRequestBudget`, `TestRunReconciler_*`. **Bounded Loss-Aware Event Subscriptions** - `internal/ipc/events.go` (`ClassOf`) is the single event taxonomy: activity is droppable, state is not, control is broker-generated, and an unrecognized type fails safe to state. Brokers and consumers must read loss tolerance from it rather than re-listing event names. - `internal/daemon/eventmailbox.go` is the single overflow owner: a per-subscriber ring bounded by 64 events and 1 MiB, non-blocking publish (the executor is never stalled), activity as the only evictable class, and everything else folded into one sticky coalescing `stream_gap` that drains ahead of queued payload. A reserved slot is not enough - it fails at the second simultaneous transition - and producer-side channel receives race the reader, which is why the queue is a ring under a mutex. - Every state event and every `get_run` snapshot carries a monotonic `StateRev`; `runSnapshot` samples it **before** the DB read, which is sound only because every producer writes state and then emits. Consumers apply a delta only when its revision is newer, so a delta queued before a snapshot cannot regress state after it. Every subscription opens gapped, so attach and reconnect always reconcile first. - The fix-review working-tree diff is the only gate context that is never persisted, so it is served on demand by `ipc.MethodGetStepDiff` (`RunManager.StepDiff`, bounded at 512 KiB) instead of riding the stream: it was the only unbounded payload, and one frame past the 1 MiB transport line limit ends the subscription and hides every later event. - Regressions: `internal/daemon/eventmailbox_test.go` (A1-A13 plus the byte/count ceilings), `TestRunSnapshot_*`, `TestStepDiff_*`, `TestExecutor_StateEventsAreEmittedAfterTheirDatabaseWrite`, `TestClassOfUnknownEventFailsSafeToState`, `TestRunReconciler_StreamGapForcesOneAuthoritativeRead`, `TestSubscribeOversizedFrameEndsTheStreamAndHidesLaterEvents`, `internal/tui/overflow_contract_test.go`. **Destructive Daemon Lifecycle Guard (`internal/lifecycle/guard.go`)** - `daemon stop`, `daemon restart`, and `update` refuse by default while pending/running runs exist (the daemon is machine-wide, so stopping it can fail every active pipeline), list the runs via the shared `lifecycle.ActiveRuns`/`lifecycle.RunList` helpers, and require an explicit `--force`. `update -y` answers only the different-executable prompt and deliberately does not bypass this guard. - Every invocation of the three commands is logged with caller attribution (PID, PPID, parent command line) via `logLifecycleInvocation` to `/logs/cli.log`; this is the incident forensic trail, do not remove or weaken it. - Regressions: `TestDaemonStopRefusesWithActiveRunsAndListsThem`, `TestDaemonStopForceOverridesActiveRunGuard`, `TestDaemonRestartRefusesWithActiveRuns`, `TestLifecycleCommandsWriteCallerAttributionToCLILog` (`internal/cli/daemon_lifecycle_test.go`), `TestUpdaterRunRefusesWithActiveRunsAndListsThem`, `TestUpdaterActiveRunGuardAllowsForce` (`internal/update`). ## Dónde encaja - Categoría: [DevOps e infraestructura](https://skillsagentes.com/categorias/devops-infraestructura.md) — Despliegues, contenedores, IaC y flujos de gestión de incidentes. - Creador: [kunchenguid](https://skillsagentes.com/creators/kunchenguid.md) — 16 skills en el directorio - [Todas las skills](https://skillsagentes.com/skills.md) - [Ranking de instalaciones](https://skillsagentes.com/ranking.md) ## Otras skills del mismo repositorio - [No Mistakes](https://skillsagentes.com/skills/kunchenguid/no-mistakes/no-mistakes.md): Valida tus cambios de código por el pipeline de no-mistakes (review de código automatizado, tests, lint, docs, push, PR y CI) antes de que lleguen al destino de push configurado. Se activa con `/no-mistakes`. - [Testing Conventions](https://skillsagentes.com/skills/kunchenguid/no-mistakes/testing-conventions.md): Nota interna del proyecto no-mistakes. Se usa al añadir o cambiar tests, el harness e2e, el aislamiento de procesos de test o el sharding de tests en CI. - [Ci Monitor](https://skillsagentes.com/skills/kunchenguid/no-mistakes/ci-monitor.md): Nota interna del proyecto no-mistakes. Se usa al cambiar la readiness de CI, la recogida de checks del forge, los reruns, los timeouts de CI o la monitorización del ciclo de vida del PR. - [Pr Publication Safety](https://skillsagentes.com/skills/kunchenguid/no-mistakes/pr-publication-safety.md): Nota interna de seguridad del proyecto no-mistakes. Se usa al cambiar el render del cuerpo del PR, la redacción de rutas de home, la publicación de rutas de artefacto o los marcadores de attestation de pipeline. - [Pipeline Review And Agents](https://skillsagentes.com/skills/kunchenguid/no-mistakes/pipeline-review-and-agents.md): Nota interna del proyecto no-mistakes. Se usa al cambiar las sesiones de review, las decisiones sobre findings, los timeouts de agente, el comportamiento del Test local o la conformidad con la intención. ## Skills relacionadas - [Gstack Upgrade](https://skillsagentes.com/skills/garrytan/gstack/gstack-upgrade.md): Actualiza gstack a la última versión. - [Canary](https://skillsagentes.com/skills/garrytan/gstack/canary.md): Monitoreo canary post-deploy: vigila la app en producción tras el despliegue. (gstack) - [X402](https://skillsagentes.com/skills/browser-use/browser-use/x402.md): Configura pagos de Browser Use Cloud con x402: paga por solicitud desde una wallet cripto (USDC en Base mainnet), sin registro ni API key. - [Vercel Deploy](https://skillsagentes.com/skills/bytedance/deer-flow/vercel-deploy.md): Despliega aplicaciones y sitios web en Vercel. Úsala cuando pidan 'despliega mi app', 'llévalo a producción', 'crea un despliegue de vista previa' o 'ponlo en vivo'. No requiere autenticación. - [Dependabot Triager](https://skillsagentes.com/skills/cli/cli/dependabot-triager.md): Evalúa un PR abierto de Dependabot y publica una recomendación (Merge / Review / Do not merge) con nivel de confianza, basada en los cambios reales upstream. Solo asesora, nunca fusiona ni aprueba. --- Skills Agentes · [Índice de páginas en markdown](https://skillsagentes.com/sitemap.md) · [Inicio](https://skillsagentes.com/index.md)