Logging
When cliq server runs, it produces structured JSON Lines logs capturing everything from high-level events (“server started”, “pipeline completed”) down to fine-grained internal traces (“signal file read”, “phase poll tick”). You control the verbosity with two knobs — one for the server shell, one for the core pipeline engine — and can override individual components when debugging a specific subsystem.
Quick Start
Section titled “Quick Start”Logging is enabled automatically when cliq server start runs. With default settings, logs are written at info level:
cliq server start# Logs to /var/log/cliq/server.log (or ~/.cliqrc/logs/server.log if /var/log is not writable)To see everything:
{ "logging": { "server_level": "trace", "core_level": "trace" }}To see only errors and warnings:
{ "logging": { "server_level": "warn", "core_level": "warn" }}Log Levels
Section titled “Log Levels”Five levels, from most severe to most verbose:
| Level | Numeric | What it captures |
|---|---|---|
error | 0 | Failures that prevent an operation from completing — mesh registration errors, pipeline crashes, notification delivery failures |
warn | 1 | Degraded conditions — stale config detected, orphaned workspace cleanup, best-effort operations that failed silently |
info | 2 | Key lifecycle events — server start/stop, task received, pipeline dispatched/completed, mesh registered, notification sent |
debug | 3 | Internal decisions — A2A path delegation, workspace created/torn down, channels created, checks executed, prompts generated |
trace | 4 | Every breath — individual HTTP requests, WebSocket messages, phase poll ticks, signal file reads |
A configured level allows all messages at that level and above (more severe). Setting server_level: "debug" captures error, warn, info, and debug but not trace.
Two-Level Architecture
Section titled “Two-Level Architecture”Logs from the cliq server fall into two categories, each with its own level control:
Server components
Section titled “Server components”These handle HTTP, WebSocket, A2A protocol, mesh registration, and task execution — the “outer shell” of the server process.
| Component | What it covers |
|---|---|
server | HTTP request handling, WebSocket connections, static file serving, server start/stop |
a2a | A2A task dispatch, capability extraction, pipeline lifecycle, status polling |
mesh | Savant token exchange, mesh registration/deregistration |
logger | Logger initialization and shutdown (meta) |
Controlled by logging.server_level.
Core engine components
Section titled “Core engine components”These are the internal pipeline orchestration modules — the same code that runs inside cliq run. When invoked through the server (via A2A tasks), these modules produce log entries. When invoked through the CLI directly, they are silent (the logger is not initialized).
| Component | What it covers |
|---|---|
orchestrator | Phase activation, gate loops, escalation decisions |
pipeline | Tmux session management, pane launch/reuse |
signal | Signal file writes (done, verdict, status), signal clearing |
channel | Channel directory creation for inter-agent communication |
workflow | Workflow YAML parsing and loading |
gate | Deterministic check execution, verdict parsing |
notify | Notification dispatch to Slack/Jira |
prompt | Agent prompt generation |
registry | Instance registration/deregistration |
Controlled by logging.core_level.
Configuration
Section titled “Configuration”Add a logging section to your ~/.cliqrc/settings.json:
{ "logging": { "server_level": "info", "core_level": "info", "component_levels": {}, "dir": "", "max_file_size_mb": 50, "max_files": 5 }}Settings Reference
Section titled “Settings Reference”| Field | Type | Default | Description |
|---|---|---|---|
server_level | string | "info" | Log level for server components (server, a2a, mesh, logger). |
core_level | string | Same as server_level | Log level for core engine components (orchestrator, pipeline, signal, etc.). When omitted, inherits from server_level. |
component_levels | object | {} | Per-component level overrides. Keys are component names, values are log levels. Takes precedence over both server_level and core_level. |
dir | string | Auto | Directory for log files. Tries /var/log/cliq/ first, falls back to ~/.cliqrc/logs/. Set explicitly to control placement. |
max_file_size_mb | number | 50 | Maximum size of server.log before rotation (in MB). |
max_files | number | 5 | Number of rotated log files to retain. Oldest files are deleted when the limit is reached. |
Level resolution order
Section titled “Level resolution order”For each log entry, the effective level is determined by:
component_levels[component]— if an override exists for this component, use itcore_level— if the component is a core engine component, usecore_levelserver_level— fallback for all other (server) components
This means you can keep the server quiet (server_level: "warn") while watching the pipeline engine in detail (core_level: "debug"), or vice versa. And if you need to debug one specific subsystem, override just that component.
Per-Component Overrides
Section titled “Per-Component Overrides”The component_levels map lets you set a different log level for any individual component without affecting the rest.
Debug mesh registration without flooding other logs:
{ "logging": { "server_level": "info", "core_level": "info", "component_levels": { "mesh": "debug" } }}Trace signal file operations while keeping everything else at info:
{ "logging": { "server_level": "info", "core_level": "info", "component_levels": { "signal": "trace" } }}Full detail on gate evaluation, quiet everywhere else:
{ "logging": { "server_level": "warn", "core_level": "warn", "component_levels": { "gate": "trace" } }}Silence a noisy component:
{ "logging": { "server_level": "debug", "core_level": "debug", "component_levels": { "server": "warn" } }}Log Format
Section titled “Log Format”Logs are written as JSON Lines — one JSON object per line. This format is human-readable with jq, machine-parseable by log aggregators (ELK, Datadog, Loki), and trivially greppable.
Entry structure
Section titled “Entry structure”{ "ts": "2026-03-18T14:23:01.456Z", "level": "info", "component": "a2a", "msg": "Task received", "ctx": { "taskId": "abc-123", "capability": "feature_dev_js" }}| Field | Type | Always present | Description |
|---|---|---|---|
ts | string | Yes | ISO 8601 timestamp |
level | string | Yes | Log level (error, warn, info, debug, trace) |
component | string | Yes | Originating subsystem (see component tables above) |
msg | string | Yes | Human-readable message |
ctx | object | No | Structured context — only present when there is additional data |
Example log entries
Section titled “Example log entries”Server startup:
{"ts":"2026-03-18T14:23:00.100Z","level":"info","component":"logger","msg":"Server logger initialized","ctx":{"dir":"/var/log/cliq","server_level":"info","core_level":"info"}}{"ts":"2026-03-18T14:23:00.200Z","level":"info","component":"a2a","msg":"A2A endpoints mounted","ctx":{"agent_card_path":"/.well-known/agent-card.json","rpc_path":"/a2a/jsonrpc","base_url":"https://cliq.example.com"}}{"ts":"2026-03-18T14:23:00.300Z","level":"info","component":"server","msg":"HTTP server listening","ctx":{"port":4100}}{"ts":"2026-03-18T14:23:00.400Z","level":"info","component":"server","msg":"Server started","ctx":{"port":4100,"pid":12345}}{"ts":"2026-03-18T14:23:01.000Z","level":"info","component":"mesh","msg":"Registered with mesh","ctx":{"mesh":"savant-prod","type":"savant"}}A2A task lifecycle:
{"ts":"2026-03-18T14:25:00.000Z","level":"info","component":"a2a","msg":"Task received","ctx":{"taskId":"abc-123","capability":"feature_dev_js"}}{"ts":"2026-03-18T14:25:00.100Z","level":"info","component":"a2a","msg":"Task created","ctx":{"task_id":"def-456","team":"feature-dev-js","workspace":"/tmp/cliq-workspaces/def-456"}}{"ts":"2026-03-18T14:25:00.200Z","level":"debug","component":"a2a","msg":"Workspace created","ctx":{"task_id":"def-456","workspace":"/tmp/cliq-workspaces/def-456"}}{"ts":"2026-03-18T14:25:00.300Z","level":"info","component":"a2a","msg":"Pipeline dispatched","ctx":{"taskId":"abc-123","internal_id":"def-456","team":"feature-dev-js"}}{"ts":"2026-03-18T14:25:30.000Z","level":"trace","component":"a2a","msg":"Phase poll","ctx":{"task_id":"def-456","running_phase":"architect"}}{"ts":"2026-03-18T14:28:00.000Z","level":"info","component":"a2a","msg":"Pipeline finished","ctx":{"task_id":"def-456","state":"completed","pipeline_status":"COMPLETED"}}{"ts":"2026-03-18T14:28:00.100Z","level":"info","component":"a2a","msg":"Task finished","ctx":{"taskId":"abc-123","state":"completed","message":"Pipeline completed"}}{"ts":"2026-03-18T14:28:00.200Z","level":"debug","component":"a2a","msg":"Workspace teardown","ctx":{"task_id":"def-456","workspace":"/tmp/cliq-workspaces/def-456"}}Gate evaluation (at debug level):
{"ts":"2026-03-18T14:26:00.000Z","level":"debug","component":"gate","msg":"Running checks","ctx":{"count":3,"cwd":"/tmp/cliq-workspaces/def-456"}}{"ts":"2026-03-18T14:26:05.000Z","level":"debug","component":"gate","msg":"Checks completed","ctx":{"total":3,"passed":2,"failed":1}}{"ts":"2026-03-18T14:26:10.000Z","level":"debug","component":"gate","msg":"Verdict parsed","ctx":{"outcome":"ROUTE","target":"developer"}}Log File Location
Section titled “Log File Location”The logger resolves the log directory in this order:
logging.dir— if explicitly set in settings, use that directory/var/log/cliq/— if the directory exists and is writable~/.cliqrc/logs/— fallback (always writable by the current user)
The active log file is always named server.log within the resolved directory.
To check where logs are being written, look at the first entry after server start — the logger component logs the resolved directory:
head -1 /var/log/cliq/server.log | jq .# orhead -1 ~/.cliqrc/logs/server.log | jq .Log Rotation
Section titled “Log Rotation”When server.log exceeds max_file_size_mb, it is rotated:
server.log.{max_files}is deleted (oldest archive)- Each
server.log.Nis renamed toserver.log.{N+1} server.logis renamed toserver.log.1- A fresh
server.logis created on the next write
With the defaults (max_file_size_mb: 50, max_files: 5), you retain up to 300 MB of log history:
server.log # current (up to 50 MB)server.log.1 # previous rotationserver.log.2server.log.3server.log.4server.log.5 # oldest — deleted on next rotationQuerying Logs
Section titled “Querying Logs”JSON Lines is designed for tooling. Here are common patterns:
View recent errors
Section titled “View recent errors”grep '"level":"error"' /var/log/cliq/server.log | jq .Follow live (tail)
Section titled “Follow live (tail)”tail -f /var/log/cliq/server.log | jq .Filter by component
Section titled “Filter by component”jq 'select(.component == "a2a")' /var/log/cliq/server.logFilter by level
Section titled “Filter by level”jq 'select(.level == "error" or .level == "warn")' /var/log/cliq/server.logFilter by time range
Section titled “Filter by time range”jq 'select(.ts >= "2026-03-18T14:00:00" and .ts <= "2026-03-18T15:00:00")' /var/log/cliq/server.logFind a specific task
Section titled “Find a specific task”jq 'select(.ctx.taskId == "abc-123" or .ctx.task_id == "abc-123")' /var/log/cliq/server.logCount entries by component
Section titled “Count entries by component”jq -r '.component' /var/log/cliq/server.log | sort | uniq -c | sort -rnPretty-print the last 20 entries
Section titled “Pretty-print the last 20 entries”tail -20 /var/log/cliq/server.log | jq '{ts: .ts, level: .level, comp: .component, msg: .msg}'Recipes
Section titled “Recipes”Development: see everything
Section titled “Development: see everything”Maximum verbosity during local development:
{ "logging": { "server_level": "trace", "core_level": "trace", "max_file_size_mb": 10, "max_files": 2 }}Production: quiet server, detailed core
Section titled “Production: quiet server, detailed core”Keep HTTP noise down, but capture full pipeline orchestration detail:
{ "logging": { "server_level": "warn", "core_level": "info" }}Debugging A2A integration
Section titled “Debugging A2A integration”Focused debugging of the A2A + mesh layer:
{ "logging": { "server_level": "info", "core_level": "info", "component_levels": { "a2a": "trace", "mesh": "debug" } }}Debugging gate failures
Section titled “Debugging gate failures”When gates keep failing and you need to see check execution and verdict parsing:
{ "logging": { "server_level": "info", "core_level": "info", "component_levels": { "gate": "trace", "signal": "debug" } }}Custom log directory
Section titled “Custom log directory”Write logs to a shared volume (e.g., for centralized collection):
{ "logging": { "dir": "/mnt/logs/cliq", "server_level": "info" }}CLI vs Server Logging
Section titled “CLI vs Server Logging”| Context | Logger active? | Where logs go |
|---|---|---|
cliq server start | Yes | server.log (JSON Lines) |
cliq run (interactive) | No | orchestrator.log (plain text, in .cliq/) |
cliq run --headless | No | orchestrator.log (plain text, in .cliq/) |
The server logger (SLog) is initialized only during cliq server start. When cliq run invokes the same core modules (signal manager, channel manager, etc.) directly, those modules call SLog but the calls are no-ops because the logger was never initialized. This is by design — interactive runs already have the orchestrator log and tmux pane output.
File Layout
Section titled “File Layout”/var/log/cliq/ # or ~/.cliqrc/logs/├── server.log # current log file├── server.log.1 # most recent rotation├── server.log.2├── server.log.3├── server.log.4└── server.log.5 # oldest rotationTroubleshooting
Section titled “Troubleshooting”| Issue | Fix |
|---|---|
| No log file created | Check that the server was started with cliq server start. The logger is not active during cliq run. |
Logs in ~/.cliqrc/logs/ instead of /var/log/cliq/ | /var/log/cliq/ is not writable by the current user. Create the directory and set permissions: sudo mkdir -p /var/log/cliq && sudo chown $USER /var/log/cliq |
| Log file growing too large | Reduce max_file_size_mb or lower the log level. At trace level with active A2A traffic, logs grow quickly. |
| Missing context in log entries | Not all entries include a ctx field. Entries with no additional data beyond the message omit ctx entirely. |
Want logs from cliq run | Interactive pipelines write to .cliq/orchestrator.log (plain text). Server logging covers the server process only. |
| Component not logging | Check that the effective level for that component allows the log level you expect. Use component_levels to set the component to trace for debugging. |