Daemon — Signet Docs

Docs / Reference

Daemon

Background service for file watching and HTTP API.

Signet Daemon

The Signet daemon is a background service that provides the HTTP API, serves the Dashboard, watches config files for changes, manages harness synchronization, and exposes an MCP server for native tool access. It also runs the memory pipeline and a suite of subsystem workers for ingestion, retention, maintenance, Analytics, and Diagnostics.

The daemon runs on http://localhost:3850 by default.

Starting and Stopping

Via CLI

signet daemon start    # Start the daemon
signet daemon stop     # Stop the daemon
signet daemon restart  # Restart the daemon
signet status          # Check status

Top-level aliases signet start, signet stop, and signet restart still exist, but signet daemon ... is the preferred command surface.

Via System Service

The daemon can be installed as a system service for auto-start on boot.

macOS (launchd):

cd packages/daemon
bun run install:service

launchctl load ~/Library/LaunchAgents/ai.signet.daemon.plist
launchctl unload ~/Library/LaunchAgents/ai.signet.daemon.plist

Linux (systemd):

cd packages/daemon
bun run install:service

systemctl --user start signet.service
systemctl --user stop signet.service
systemctl --user status signet.service
systemctl --user enable signet.service   # enable on boot

Configuration

Environment Variables

VariableDefaultDescription
SIGNET_PORT3850HTTP server port
SIGNET_HOST127.0.0.1Daemon host for local calls and default bind address
SIGNET_BINDSIGNET_HOSTExplicit bind address override (for example 0.0.0.0)
SIGNET_PATH$SIGNET_WORKSPACEBase agents directory
SIGNET_LOG_FILEOptional explicit log file path
SIGNET_LOG_DIR$SIGNET_WORKSPACE/.daemon/logsOptional log directory override
SIGNET_SQLITE_PATHmacOS explicit SQLite dylib override used before Bun opens the database

Files

When log path overrides are set:

  • SIGNET_LOG_FILE takes highest precedence and points to the exact file.
  • Else SIGNET_LOG_DIR overrides the default log directory.
  • Else the default $SIGNET_WORKSPACE/.daemon/logs/ paths below apply.
FileDescription
$SIGNET_WORKSPACE/.daemon/pidProcess ID file
$SIGNET_WORKSPACE/.daemon/logs/Log directory
$SIGNET_WORKSPACE/.daemon/logs/daemon-YYYY-MM-DD.logDaily log file
$SIGNET_WORKSPACE/.daemon/logs/daemon.out.logstdout capture
$SIGNET_WORKSPACE/.daemon/logs/daemon.err.logstderr capture

Subsystems

The daemon starts several concurrent workers when it initializes. Each worker runs its own loop and stops cleanly when the daemon shuts down.

Pipeline Workers

The pipeline lives at packages/daemon/src/pipeline/ and is managed by startPipeline() / stopPipeline(). Four workers run in parallel:

Extraction worker (worker.ts) polls the memory_jobs queue for pending extraction jobs. Each job runs the conversation through Ollama (default model: qwen3:4b), then passes the result to the decision stage which decides whether to write, update, or skip. The provider and decision stages run outside write locks to keep contention low.

Document worker (document-worker.ts) polls memory_jobs for document_ingest jobs. It fetches remote URLs if needed, chunks the content hierarchically, embeds each chunk, and links chunks to their source document via document_memories. The same transaction discipline applies: no provider calls inside write locks.

Retention worker (retention-worker.ts) runs on a periodic timer and purges memories that have decayed below their retention threshold. It can also be triggered manually by the maintenance worker.

Maintenance worker (maintenance-worker.ts) runs diagnostics on a configurable interval and, depending on maintenanceMode, either logs recommendations (observe) or executes repair actions (execute). It tracks consecutive ineffective repairs and halts a given repair action after three failed attempts to avoid thrashing. Requires autonomousEnabled: true and autonomousFrozen: false in pipeline config to activate the timed loop; otherwise it is passive and can be triggered via the API.

Pipeline config modes:

Mode flagEffect
shadowModeExtract memories but do not write them
mutationsFrozenRead-only; no writes at all
graphEnabledEnable knowledge graph traversal on recall
autonomousEnabledAllow the maintenance worker to run repairs
autonomousFrozenPause autonomous repairs without disabling
maintenanceMode"observe" (log only) or "execute" (act)

Session Tracker

The session tracker (session-tracker.ts) enforces a mutex on the runtime path per session. Connectors send an x-signet-runtime-path header with each hook request — either "plugin" or "legacy". Once a session is claimed by one path, any request arriving from the other path receives a 409 Conflict. Stale sessions expire after 4 hours and are cleaned up every 15 minutes.

Auth Middleware

The daemon supports three deployment modes: local (default, no authentication required), team (all requests require a bearer token), and hybrid (localhost requests bypass auth, remote requests require a token). Token roles are admin, operator, agent, and readonly, each with a different permission set. Rate limiting is applied per token. See docs/AUTH.md for full details on configuration, token creation, and permission scopes.

Analytics

The analytics collector (analytics.ts) accumulates ephemeral in-memory counters for the lifetime of the daemon process. Nothing is persisted to disk — the structured logs and memory_history table provide durable backing. The collector tracks:

  • Usage counters — per-endpoint call counts, error counts, and total latency; per-actor request/remember/recall/mutation counts; per-provider call counts and latency; per-connector sync counts.
  • Error ring buffer — a fixed-size circular buffer of recent errors keyed by stage (extraction, decision, embedding, mutation, connector).
  • Latency histograms — bucketed latency distributions per stage, useful for spotting tail latency without external tooling.

All counters reset on daemon restart. See docs/ANALYTICS.md for the API endpoints and data shapes.

Timeline

The timeline builder (timeline.ts) reconstructs a chronological incident trace for a given entity ID — a memory ID, request ID, or session ID. It joins across memory_history, memory_jobs, the in-process log buffer, and the error ring buffer to produce an ordered list of events. This is primarily a debugging tool for tracing what happened to a specific memory across extraction, decision, embedding, and mutation phases. See docs/ANALYTICS.md for details on the timeline endpoint.

Diagnostics

The diagnostics module (diagnostics.ts) evaluates six health domains and returns a composite score:

DomainWhat it measures
queueJob queue depth, dead job rate, stale leases
storageTotal memories, tombstone ratio, database size
indexFTS row count vs active memories, embedding coverage
providerOllama availability rate, recent timeouts and failures
mutationRecent recover and delete event rates
connectorActive connector count, sync errors, error age

Each domain produces a score (0–1) and a status of healthy, degraded, or unhealthy. The composite score is a weighted average across all six. The maintenance worker uses this report to decide which repair actions to invoke. See docs/DIAGNOSTICS.md for the full report schema and repair action catalog.

HTTP API

The daemon exposes endpoints across these domains: memory, skills, secrets, hooks, harnesses, auth, documents, connectors, diagnostics, pipeline, repair, analytics, telemetry, timeline, git sync, update, tasks, and logs. The table below lists the major groups. See docs/API.md for the full reference including request/response schemas.

GroupBase pathDescription
Health/healthLiveness check, daemon status
Auth/api/auth/*Token issuance, validation, rate limit status
Config/api/configRead and write identity files
Identity/api/identityParsed identity fields
Memories/api/memories, /memory/*List, search, similarity, remember, recall
Embeddings/api/embeddingsExport embedding vectors
Documents/api/documents/*Document ingest and chunk retrieval
Connectors/api/connectors/*Connector registry, status, cursor updates
Skills/api/skillsList installed skills
Harnesses/api/harnessesList harnesses, regenerate configs
Secrets/api/secretsList, get, set, delete secrets
Hooks/api/hooks/*Session start/stop, synthesis hooks
Git/api/git/*Commit history, sync status
Update/api/updateVersion check
Diagnostics/api/diagnosticsLive health report across all domains
Repair/api/repair/*Manually trigger repair actions
Analytics/api/analyticsUsage counters, error buffer, histograms
Timeline/api/timeline/:idIncident reconstruction by entity ID
Logs/api/logsRecent in-process log entries
MCP/mcpModel Context Protocol server (Streamable HTTP)

Health Check

GET /health
{
  "status": "healthy",
  "uptime": 3600,
  "pid": 12345,
  "version": "0.1.0",
  "port": 3850,
  "agentsDir": "/home/user/.agents"
}

Daemon Status

GET /api/status
{
  "status": "running",
  "version": "0.1.0",
  "pid": 12345,
  "uptime": 3600,
  "startedAt": "2025-02-17T16:00:00.000Z",
  "port": 3850,
  "host": "localhost",
  "agentsDir": "/home/user/.agents",
  "memoryDb": true
}

File Watcher

The daemon watches these paths with chokidar:

  • $SIGNET_WORKSPACE/agent.yaml
  • $SIGNET_WORKSPACE/AGENTS.md
  • $SIGNET_WORKSPACE/SOUL.md
  • $SIGNET_WORKSPACE/MEMORY.md
  • $SIGNET_WORKSPACE/IDENTITY.md
  • $SIGNET_WORKSPACE/USER.md
  • $SIGNET_WORKSPACE/memory/ (entire directory)
  • ~/.claude/projects/*/memory/MEMORY.md (Claude Code project memories)

Auto-Ingestion

When memory markdown files are created or modified, the daemon automatically ingests them using hierarchical chunking to preserve section structure. Each chunk includes its section header for context. A SHA-256 hash prevents re-processing unchanged files. Ingestion runs on startup and on file change.

File patternWhoTags
$SIGNET_WORKSPACE/memory/*.md (not MEMORY.md)openclaw-memoryopenclaw, memory-log, date
~/.claude/projects/*/memory/MEMORY.mdclaude-codeclaude-code, claude-project-memory, project ID

Auto Git Commit

When a watched file changes, the daemon waits 5 seconds (debounce), checks whether $SIGNET_WORKSPACE/ is a git repository, stages all changes with git add -A, and commits with a message in the form YYYY-MM-DDTHH-MM-SS_auto_<filename>.

Harness Sync

When AGENTS.md changes, the daemon waits 2 seconds, then regenerates harness configuration files. It writes to:

  • ~/.claude/CLAUDE.md (if ~/.claude/ exists)
  • ~/.config/opencode/AGENTS.md (if ~/.config/opencode/ exists)

Each generated file includes a header noting the source path and timestamp.

Security

Network Binding

The daemon binds to localhost by default and is not reachable from other machines. Set SIGNET_HOST to expose it on a broader interface, but pair that with auth mode team or hybrid.

Auth Modes

In local mode (the default), no credentials are required. This is fine for single-user local use. For any networked or shared deployment, switch to team or hybrid mode. See docs/AUTH.md for setup instructions.

File Permissions

The daemon reads and writes only files accessible to the running user. It does not escalate privileges.

Logging

Logs are written to the console and to a daily file at $SIGNET_WORKSPACE/.daemon/logs/daemon-YYYY-MM-DD.log by default. When SIGNET_LOG_FILE is set, logs are written to that exact file. When SIGNET_LOG_DIR is set (and SIGNET_LOG_FILE is unset), daily logs are written under $SIGNET_LOG_DIR/.

[2025-02-17T18:00:00.000Z] [INFO] Message here
[2025-02-17T18:00:01.000Z] [WARN] Warning message
[2025-02-17T18:00:02.000Z] [ERROR] Error message

Log levels: INFO for normal operations, WARN for non-fatal issues, ERROR for errors that do not crash the daemon.

Troubleshooting

Daemon won’t start

Check whether port 3850 is already in use:

lsof -i :3850

Remove a stale PID file if present:

rm $SIGNET_WORKSPACE/.daemon/pid
signet daemon start

Read the error log:

cat "${SIGNET_LOG_FILE:-$HOME/.agents/.daemon/logs/daemon.err.log}"

Daemon keeps crashing

Check for syntax errors in config:

cat $SIGNET_WORKSPACE/agent.yaml

Verify database integrity:

sqlite3 $SIGNET_WORKSPACE/memory/memories.db "PRAGMA integrity_check;"

Dashboard not loading

Confirm the daemon is running and the dashboard was built:

signet status
curl http://localhost:3850/health
ls packages/cli/dashboard/build/

File changes not syncing

Check the watcher logs, confirm the git repository exists, and verify file permissions:

ls $SIGNET_WORKSPACE/.git

Pipeline jobs stuck

Check diagnostics for queue health and dead job rates:

curl http://localhost:3850/api/diagnostics

If the dead job rate is high, trigger a repair manually:

curl -X POST http://localhost:3850/api/repair/requeue-dead-jobs