Skip to main content

Audit Logging

Every tool execution is logged to an append-only JSONL audit trail for security review and debugging.

Log Format

Audit logs use JSON Lines format — one JSON object per line, append-only:

{
"timestamp": "2026-03-27T10:30:15.123Z",
"session_id": "abc-123-def",
"user_prompt": "Delete the old-data folder",
"classified_command": "rm -rf ./old-data",
"tool_used": "execute_cli",
"execution_result": "success",
"voice_message": "Folder deleted successfully",
"duration_ms": 1250
}

Entry Schema

FieldTypeDescription
timestampstringISO 8601 timestamp
session_idstringWebRTC session identifier
user_promptstringOriginal user command
classified_commandstringActual command as classified by evaluator
tool_usedstringTool name (e.g., execute_cli, execute_gui)
execution_resultstringsuccess, error, or rejected
voice_messagestringVoice feedback sent to user
duration_msintExecution time in milliseconds

Log Files

Location

~/.contop/logs/session-{YYYY-MM-DD}.jsonl

One file per calendar day with daily rotation.

Examples

~/.contop/logs/session-2026-03-27.jsonl
~/.contop/logs/session-2026-03-26.jsonl

Session Lifecycle Events

Special log entries mark session boundaries:

  • log_session_start() — Records session ID, device info, connection type
  • log_session_end() — Records summary stats (total commands, duration, error count)

Fire-and-Forget Strategy

Audit logging uses an async fire-and-forget pattern:

async def log(...):
await asyncio.to_thread(self._write_line, ...)
  • Logging never blocks tool execution
  • Exceptions in the logger are caught and logged to stderr, never raised
  • A missed log entry is acceptable; a blocked execution is not

Action History Ring Buffer

In addition to the JSONL audit trail, the agent maintains a 50-entry ring buffer of recent actions (accessible via get_action_history tool). This provides the agent with short-term memory of what it has done without needing to read log files.

LLM Call Logging

Per-session LLM call logs capture the full request/response cycle for debugging and cost tracking:

Subscription Mode (CLI Proxy)

The CLI proxy writes detailed logs to ~/.contop/logs/llm-sub-{sessionId}-{timestamp}.log:

  • Lazy creation — Log file is only created on the first LLM call, not on proxy startup (avoids empty files)
  • Logged per call: CLI binary spawned, arguments, model, prompt text, response text, tool calls, token usage, duration, and exit code

API Mode (Direct)

When using API keys directly, the execution agent logs calls via its own logger (_llm_logger), initialized per-intent. In subscription mode, API-mode logging is skipped since the CLI proxy handles it.

Log Location

~/.contop/logs/llm-sub-{8-char-session-id}-{timestamp}.log    # Subscription mode
~/.contop/logs/session-{YYYY-MM-DD}.jsonl # Audit trail (all modes)

Related: Security Overview · Dual-Tool Evaluator · REST API