Destructive Daemon Lifecycle Guard in no-mistakes: Preventing Daemon Stop During Active Runs
The Destructive Daemon Lifecycle Guard located in internal/lifecycle/guard.go blocks daemon stop, restart, and update commands whenever pipeline runs are active, requiring an explicit --force flag to proceed.
The no-mistakes repository implements a protective mechanism to prevent accidental daemon termination during critical operations. This lifecycle guard that prevents daemon stop during active runs ensures data integrity by verifying no pending or running pipelines exist before allowing destructive lifecycle changes. The implementation resides in the internal lifecycle package and integrates with the CLI to enforce strict safety checks.
How the Lifecycle Guard Works
The guard operates as a gatekeeper for all destructive daemon operations. Before executing stop, restart, or update commands, the system queries the current execution state to determine if intervention is safe.
When invoked, the guard checks lifecycle.ActiveRuns and lifecycle.RunList to enumerate any pipelines in pending or running states. If active runs exist, the CLI aborts the operation and displays a formatted list of blocking runs including their IDs, states, and associated branches. Only the presence of the --force flag overrides this protection, allowing users to acknowledge the risk of terminating the daemon while work is in progress.
Source Code Architecture and Key Files
The implementation spans several internal packages that coordinate to maintain daemon integrity:
internal/lifecycle/guard.go– Contains the core guard logic that evaluates active run states and enforces the force-requirement policy.internal/lifecycle/runlist.go– Provides theActiveRunsandRunListhelpers used to query the current execution landscape.internal/daemon/lock.go– Manages the exclusive daemon lock; the guard relies on this to confirm a daemon instance is alive before applying lifecycle checks.internal/cli/daemon_lifecycle_test.go– Comprehensive test suite verifying that the guard correctly blocks operations during active runs and permits override via--force.docs/src/content/docs/concepts/daemon.md– User-facing documentation explaining the protective behavior and override mechanisms.
Active Run Detection and Enforcement
The detection mechanism leverages shared helpers to inspect the run registry. The guard specifically looks for runs in non-terminal states before granting permission to proceed.
Querying Active Runs
The guard utilizes the following pattern to detect blocking executions:
runs, err := lifecycle.ActiveRuns(ctx)
if err != nil {
// handle error
}
for _, r := range runs {
fmt.Printf("run %d (%s) – branch %s\n", r.ID, r.State, r.Branch)
}
Blocking Behavior Without Force
If the guard detects active runs, it prevents daemon termination and outputs diagnostic information:
$ no-mistakes daemon stop
Daemon stop blocked – active runs detected:
• run 42 (pending) – branch feature/foo
• run 57 (running) – branch fix/bar
Use --force to override.
Force Override Mechanism
Users can bypass the protection by appending --force, acknowledging the risk of potential data loss or undefined worktree states:
$ no-mistakes daemon stop --force
Daemon stopped successfully (force‑override).
The same protection applies to restart and update operations:
$ no-mistakes update
Update aborted – the daemon has active runs.
Use --force to proceed anyway.
Audit Logging and Forensic Tracking
Every lifecycle guard invocation—whether blocked or permitted—is recorded in <NM_HOME>/logs/cli.log. Each entry includes caller attribution such as PID, PPID, and the full command line, creating an essential audit trail for forensic analysis of daemon lifecycle decisions.
This logging ensures administrators can trace who attempted to stop the daemon, whether the operation succeeded, and if force override was employed. The conservative design deliberately avoids silent daemon kills that could leave pipeline worktrees in corrupted states.
Summary
- The Destructive Daemon Lifecycle Guard in
internal/lifecycle/guard.goprevents accidental daemon termination during active pipeline execution. - It blocks
daemon stop,daemon restart, andupdatecommands when runs are in pending or running states. - Override requires the explicit
--forceflag, ensuring users consciously accept the risk of interrupting active work. - The guard utilizes
lifecycle.ActiveRunsandlifecycle.RunListfrominternal/lifecycle/runlist.goto detect active executions. - All lifecycle decisions are logged to
<NM_HOME>/logs/cli.logwith full caller attribution for audit purposes.
Frequently Asked Questions
What triggers the lifecycle guard to block a daemon stop command?
The guard triggers whenever the no-mistakes daemon stop command detects active pipeline runs through the lifecycle.ActiveRuns helper. If any runs report states of pending or running, the guard aborts the operation and lists the blocking runs, requiring --force to proceed.
How does the lifecycle guard prevent data loss during daemon updates?
By requiring explicit confirmation via --force, the guard ensures users acknowledge that stopping or restarting the daemon while pipelines are active could leave worktrees in undefined states. This prevents silent termination that might interrupt file operations or corrupt pipeline state.
Where is the lifecycle guard logic implemented in the no-mistakes codebase?
The core logic resides in internal/lifecycle/guard.go, with supporting run detection implemented in internal/lifecycle/runlist.go. The guard integrates with the daemon lock management in internal/daemon/lock.go to verify daemon status before enforcing lifecycle restrictions.
Can the lifecycle guard be disabled or configured to ignore active runs?
No, the guard cannot be disabled through configuration. It is a hard-coded safety mechanism that always evaluates active runs before permitting destructive operations. The only mechanism to proceed with active runs is the --force flag, which acts as an explicit user override rather than a configuration change.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →