Understanding the AgentsView Daemon Runtime Record: Purpose and Implementation

The daemon runtime record is a JSON metadata file that stores the AgentsView daemon’s PID, network endpoint, service identity, and process timestamps, enabling CLI commands to discover, authenticate, and safely manage the running HTTP server.

AgentsView runs as a persistent HTTP daemon that serves SQLite-backed session data. To coordinate between the background server process and command-line tooling, the repository implements a daemon runtime record—a file-based registry written to the data directory (by default $XDG_DATA_HOME/agentsview). This record acts as the single source of truth for process discovery, mode negotiation, and safe lifecycle management across all AgentsView components.

What the Daemon Runtime Record Contains

The runtime record is a JSON file containing structured metadata about the active daemon process. According to the source code in cmd/agentsview/daemon_runtime.go, each record tracks:

  • PID: The process ID of the running daemon
  • Network endpoint: The host and port where the HTTP server listens
  • Service name: Identifies this as an agentsview service (distinguishing it from other potential daemons)
  • Version: The software version running
  • Metadata map: Extended attributes including host, port, read-only flags, optional Caddy child PID, and process-creation timestamps

When the server starts via daemon.Listen() in internal/server/server.go (lines 798–809), it automatically writes this record using the WithRuntimeStore option. The record persists until graceful shutdown, when RemoveDaemonRuntime (lines 95–100) cleans it up.

How the CLI Discovers Running Daemons

Most AgentsView CLI commands rely on the FindDaemonRuntime function (lines 18–44 in cmd/agentsview/daemon_runtime.go) to locate an active daemon before executing operations. This discovery process follows a specific verification chain:

  1. Scan: List all records in the runtime store directory
  2. Filter: Select only records matching the agentsview service name
  3. Verify: Check that the recorded PID is still alive using daemon.ProcessAlive()
  4. Probe: Send a ping request to the recorded endpoint to confirm responsiveness
  5. Select: Prefer the first writable daemon found; fall back to a read-only pg-serve instance if no writable daemon responds

This ensures that CLI commands always communicate with a valid, active process rather than stale data from a crashed daemon.

Write-Only vs Read-Only Mode Detection

The runtime record distinguishes between writable SQLite archives and read-only pg-serve instances through the runtimeReadOnly metadata key. When WriteDaemonRuntime creates the record (lines 50–63), it sets:

  • ReadOnly: false for standard AgentsView daemons serving writable SQLite databases
  • ReadOnly: true for pg-serve read-only instances

During discovery, daemonRuntimeFromRecord (lines 98–122) parses this flag to determine transport selection. A writable daemon supports direct HTTP operations, while a read-only daemon triggers transport-layer protections that prevent write attempts. This mode negotiation ensures data consistency by blocking mutations against snapshot or replica instances.

Preventing PID Reuse Attacks

One critical safety feature involves process-identity verification to prevent terminating the wrong process when stopping a daemon. The runtime record stores a runtimeCreateTime timestamp (lines 64–70 in WriteDaemonRuntime) representing when the daemon process started.

When executing serve stop, the stopTargetConfirmed function (lines 109–117 in cmd/agentsview/serve_lifecycle.go) compares the recorded creation time against the current process’s actual creation time. If the PID has been reused by a different process (indicating the original daemon crashed and a new unrelated process claimed the PID), the timestamps will mismatch, and the stop operation aborts. This prevents accidentally killing arbitrary system processes.

Server Lifecycle Integration

The runtime record integrates directly with the server lifecycle through the daemon package. When ListenAndServe initializes in internal/server/server.go, it passes daemon.WithRuntimeStore() to register the runtime record automatically:

// internal/server/server.go – ListenAndServe
ln, err := daemon.Listen(
    listenCtx,
    daemon.Endpoint{
        Network: daemon.NetworkTCP,
        Address: addr,
    },
    daemon.WithRuntimeStore(daemon.RuntimeStore{Dir: s.dataDir}), // ← writes the record
)

This registration happens atomically with socket binding, ensuring the record only exists while the server is actually listening. The RemoveDaemonRuntime function handles cleanup during graceful shutdown, preventing orphaned records that could mislead future discovery attempts.

Legacy Migration Support

Older versions of AgentsView stored daemon state in JSON files named server.<port>.json. The current implementation maintains backward compatibility through migrateLegacyDaemonRuntimes (lines 82–115 in cmd/agentsview/daemon_runtime.go). On startup, this function scans for legacy state files and converts them into the modern runtime record format, preserving existing user configurations without manual intervention.

Summary

  • Discovery: The FindDaemonRuntime function uses the record to locate active daemons by verifying PID liveness and ping responsiveness.
  • Safety: Process-creation timestamps in runtimeCreateTime prevent PID reuse attacks during daemon shutdown.
  • Mode Selection: The runtimeReadOnly flag distinguishes between writable SQLite daemons and read-only pg-serve instances.
  • Lifecycle: Automatic registration via daemon.Listen() and cleanup via RemoveDaemonRuntime maintain record accuracy.
  • Compatibility: Legacy server.<port>.json files are automatically migrated to the current runtime record format.

Frequently Asked Questions

Where is the daemon runtime record stored?

By default, AgentsView writes the runtime record to $XDG_DATA_HOME/agentsview (typically ~/.local/share/agentsview on Linux systems). The specific filename is managed by the daemon.RuntimeStore abstraction, which handles JSON serialization and directory scanning.

How does AgentsView prevent stopping the wrong process?

The stopTargetConfirmed function in cmd/agentsview/serve_lifecycle.go verifies process identity by comparing the runtimeCreateTime stored in the record against the actual creation time of the process with the recorded PID. If the timestamps differ, the system assumes PID reuse has occurred and aborts the stop operation to prevent terminating an unrelated process.

What is the difference between writable and read-only daemon records?

Writable records (ReadOnly: false) represent standard AgentsView daemons serving mutable SQLite databases, allowing full CRUD operations. Read-only records (runtimeReadOnly: true) indicate pg-serve instances or snapshot daemons where write operations are prohibited. The CLI uses this distinction to select appropriate transport mechanisms and prevent accidental write attempts against read-only archives.

How does the server register its runtime record on startup?

During initialization, internal/server/server.go invokes daemon.Listen() with the WithRuntimeStore() option, passing the data directory path. This triggers automatic JSON record creation containing the daemon’s PID, endpoint, and metadata. The record remains locked to the process lifecycle and is automatically removed by RemoveDaemonRuntime during graceful shutdown.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →