세션 저장소

The Python-side session store is built around the StoredSession dataclass, which captures the minimal state needed to fully restore a conversation. Each stored session contains four fields:

class StoredSession: session_id: str messages: tuple # immutable snapshot of message history input_tokens: int output_tokens: int

Sessions are serialized to JSON and saved to .port_sessions/{session_id}.json. The messages field is stored as a tuple (not a list) to enforce immutability of the persisted snapshot — the live session continues to mutate its own message list, but the saved state is frozen at the point of persistence.

Rust 세션 모델

The Rust layer defines its own session type with stronger type guarantees. A Rust Session contains a version field (u32) for schema migration and a messages field (Vec<ConversationMessage>) that holds the full conversation history. Two methods handle persistence: save_to_path serializes to JSON and writes to disk, while load_from_path deserializes and validates the schema version.

메시지 역할과 콘텐츠 블록

Every message in a claw code session is tagged with a MessageRole enum that identifies the speaker:

Message content is represented as an array of ContentBlock variants. The Rust implementation defines three variants:

enum ContentBlock { Text { text: String }, ToolUse { id: String, name: String, input: Value }, ToolResult { tool_use_id: String, tool_name: String, output: String, is_error: bool, }, }

Text blocks carry plain text content. ToolUse blocks represent the agent's decision to invoke a tool, with a unique id for correlation, the tool name, and the JSON input payload. ToolResult blocks carry the tool's response back to the model, linked to the originating tool use via tool_use_id, and include an is_error flag that tells the model whether the tool succeeded or failed.

압축 시스템

The claw code compaction system prevents context window overflow in long-running sessions. It is governed by a CompactionConfig with two key parameters:

struct CompactionConfig { preserve_recent_messages: usize, // default: 4 max_estimated_tokens: usize, // default: 10000 }

The should_compact function checks two conditions: whether the message count exceeds a threshold, and whether the estimated token count exceeds max_estimated_tokens. Token estimation uses a heuristic of approximately 4 characters per token — simple but effective for deciding when compaction is needed.

When compaction triggers, compact_session preserves the most recent 4 messages (configurable via preserve_recent_messages) and replaces everything older with a single system message summary. The format_compact_summary function generates this summary by:

  1. Stripping <analysis> tags from the conversation history
  2. Collecting key file references (filtering for extensions: rs, ts, tsx, js, json, md)
  3. Inferring pending_work and current_work from the conversation context
  4. Truncating the summary at 160 characters to keep it compact

토큰 추정

The ~4 characters per token heuristic is intentionally conservative. It over-estimates for code (which is denser) and under-estimates for prose, but the compaction trigger is a soft threshold — a few hundred tokens of inaccuracy does not affect correctness.

TranscriptStore

The TranscriptStore is an in-memory buffer that accumulates conversation entries before flushing them to persistent storage. It provides four operations:

The replay method returns a tuple (not a list) to prevent accidental mutation of the replayed history. The compact method with keep_last=10 provides a separate compaction boundary from the main engine's compact_after_turns setting, ensuring the transcript store does not grow unbounded even if the engine's compaction is configured aggressively.

히스토리 로깅

Alongside the raw transcript, the claw code session system maintains a structured history log via HistoryEvent and HistoryLog. Each HistoryEvent has two fields: title (a short summary like "Edited main.rs") and detail (longer context about what changed and why). The HistoryLog class provides add (to append events) and as_markdown (to render the log as a readable markdown document for inclusion in prompts or reports).

컨텍스트 탐색

Before the first turn of a session, the claw code harness discovers workspace context through the PortContext dataclass. This context informs the system prompt and helps the agent understand the project it is working in:

class PortContext: source_root: Path tests_root: Path assets_root: Path archive_root: Path python_file_count: int test_file_count: int asset_file_count: int archive_available: bool

The context scanner counts Python files, test files, and asset files to give the agent a quick sense of project scale and structure. The archive_available flag indicates whether archived session data exists for potential reference.

시스템 프롬프트 조립

The system prompt is the foundation of every claw code session. It is assembled by discovering and merging instruction files from the project hierarchy. The discovery process walks the ancestor directory chain looking for three specific files:

Two hard limits prevent instruction files from overwhelming the context window:

A content hash deduplication step ensures that identical instruction content discovered at multiple levels of the directory hierarchy is only included once. This prevents redundancy when, for example, a monorepo has the same CLAUDE.md symlinked in multiple subdirectories.

지시 우선순위

Instruction files discovered closer to the working directory take priority over those found in parent directories. The content hash dedup ensures this does not result in duplicate instructions, while the character limits prevent deeply nested monorepos from exceeding the context budget.