Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Session Logging

Overview

Each intendant invocation creates a structured session log directory at ~/.intendant/logs/<uuid>/. The log provides full observability for debugging and post-session analysis. No global state files are used — each session is fully isolated.

Directory Structure

~/.intendant/logs/<uuid>/
├── session_meta.json               # Session metadata (id, created_at, project_root, task, status, last_turn)
├── session.jsonl                    # Structured event log (one JSON per line)
├── conversation.jsonl               # Serialized conversation for session resume
├── summary.json                     # Post-session summary (task, outcome, turns)
├── human_question                   # askHuman IPC: question file (session-scoped)
├── human_response                   # askHuman IPC: response file (session-scoped)
├── 1_stdout.log                     # Runtime stdout for nonce 1
├── 1_stderr.log                     # Runtime stderr for nonce 1
└── turns/
    ├── turn_001_messages.json       # Full messages array sent to API
    ├── turn_001_model.txt           # Full model response
    ├── turn_001_reasoning.txt       # Full reasoning content (if available)
    ├── turn_001_agent_in.json       # Commands sent to runtime (pretty-printed)
    ├── turn_001_stdout.txt          # Agent stdout for this turn
    └── turn_001_stderr.txt          # Agent stderr (only if non-empty)

Session Metadata

session_meta.json contains:

{
  "session_id": "a1b2c3d4-...",
  "created_at": "2025-01-15T10:30:00Z",
  "project_root": "/home/user/myproject",
  "task": "Fix the authentication bug",
  "role": null,
  "status": "running",
  "last_turn": 5
}

This file is used by --continue (find most recent session for the project) and --resume <id> (find session by ID or prefix).

Event Types in session.jsonl

EventDescription
session_startSession initialization
turn_startTurn boundary with budget % and remaining tokens
messages_inputFull API input logged (file reference to messages.json)
model_responseModel output with token counts (200-char preview, full in file)
reasoningReasoning summary and full content (if available from API)
json_extractedExtracted command JSON with function names
agent_inputCommands sent to runtime
agent_outputRuntime stdout/stderr
approvalApproval decisions (category, preview, decision)
context_managementAuto-compaction or manual context directive
session_endSummary with outcome and turn count

Querying Logs

# Overview of a session
cat ~/.intendant/logs/<session>/session.jsonl | jq -r '.event'

# See what the model received on turn 5
cat ~/.intendant/logs/<session>/turns/turn_005_messages.json | jq .

# See model reasoning on turn 3
cat ~/.intendant/logs/<session>/turns/turn_003_reasoning.txt

# Find all commands executed
grep '"event":"agent_input"' ~/.intendant/logs/<session>/session.jsonl | jq -r '.message'

# List all sessions
ls -lt ~/.intendant/logs/

# Find sessions for a specific project
grep -l '"project_root":"/home/user/myproject"' ~/.intendant/logs/*/session_meta.json

Session Resume

Conversation history is saved to conversation.jsonl after each turn, enabling session resume:

# Resume most recent session for this project
./target/release/intendant --continue "fix that bug"

# Resume specific session by ID or prefix
./target/release/intendant --resume abc123 "continue"

When resuming, the conversation is loaded from conversation.jsonl and the agent continues from where it left off. Session metadata is updated with the new task.

Test Coverage

The test suite covers both binaries with inline #[cfg(test)] modules:

  • Agent binary: models serialization, error types, process state operations, nonce replacement, path inspection, blocking command execution, file editing, browsing, port waiting, human interaction, PTY sessions, memory storage/recall with tags and filters.
  • Caller binary: JSON extraction, done signal handling, conversation management with message layer protection, tool call tracking, and auto-compaction, context directives (drop/summarize), error types, project detection, config parsing with approval rules and MCP server config and sandbox config, provider selection with token usage tracking, Responses API support, rate-limit retry with exponential backoff, API key masking, SSE streaming and event parsing, shared message builders, structured output and reasoning controls, role mapping, native tool definitions (11+ tools including MCP client tools, provider conversion formats), tool call batch assembly and result routing (including MCP tool routing), Gemini provider request/response format, sub-agent spawning and result parsing, git worktree lifecycle, user mode orchestration, knowledge pub/sub system, prompt resolution cascade (project root, global config, compiled-in defaults, tools-mode variant) with INTENDANT.md loading, TUI rendering (status bar, log panel, action panel, approval panel, help overlay, layout calculations, orchestrator progress, streaming buffer), autonomy level resolution and command classification, event bus dispatch, theme color thresholds, control socket serialization, session log file creation, model summary formatting, Xvfb display configuration per provider, dynamic display allocation, MCP client tool name parsing and routing, Landlock sandbox config construction, JSON structured output mode, web gateway (WebSocket lifecycle, tool request/response, broadcast, state bootstrap, live connect/disconnect), and presence event filtering.

Integration tests in tests/e2e/ spawn a real binary and exercise the full stack (see Architecture):

  • Tier 1 (JSON mode): Full-stack exec, approval approve/deny via stdin, multi-round follow-up. No display required.
  • Tier 2 (Control socket): Status/usage queries, autonomy change, approve via Unix control socket. Requires Xvfb.
  • Tier 3 (Web/Voice): WebSocket state_snapshot, tool_request/response, ANSI term frames, /debug endpoint. Voice tests require Firefox, PulseAudio, and espeak-ng.