ADR-133: KIMI Automated Session Export Architecture
Status
Accepted (2026-01-28)
Implementation Note: KASE design is now implemented via ADR-134 (Unified Multi-LLM Watcher). The kimi_extractor.py handles extraction, and the unified codi-watcher v2.0 handles file watching and triggers.
Context
KIMI CLI (Moonshot AI) writes session data to wire.jsonl which grows continuously during a session. Unlike Claude Code which has compaction, KIMI's wire.jsonl is append-only and grows without bound.
Current State Analysis
| Metric | Value |
|---|---|
| Growth Rate | ~0.88 MB/hour |
| 8-hour session | ~7 MB |
| 24-hour session | ~21 MB |
| Week-long session | ~150 MB |
| Current file | 1.8 MB (2 hours) |
Problems
- Unbounded Growth:
wire.jsonlgrows continuously without compaction - Data Loss Risk: No automated export means sessions can be lost if:
- KIMI crashes
- System reboots
- User forgets to export
- Context compaction (if implemented) removes history
- Manual Export Burden: Users must remember to run export commands
- No Real-time Visibility: No live monitoring of context usage or export status
Decision
Implement KIMI Automated Session Export (KASE) - a file-watcher-based automated export system with configurable triggers.
Architecture
Components
┌─────────────────────────────────────────────────────────────────┐
│ KASE Architecture │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ KIMI CLI │──────│ wire.jsonl │──────│ KASE Watcher │ │
│ │ (running) │ │ (growing) │ │ (inotify/fs) │ │
│ └──────────────┘ └──────────────┘ └──────┬───────┘ │
│ │ │
│ ┌──────────────────────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Trigger Engine │ │
│ │ - Size-based │ │
│ │ - Time-based │ │
│ │ - Turn-based │ │
│ │ - Context-based │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Export Pipeline │ │
│ │ - KimiExtractor │ │
│ │ - CUSF Format │ │
│ │ - Rotate/Archive│ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Pending Directory │ │
│ │ ~/.coditect-data/kimi-sessions-pending/ │ │
│ │ - Auto-exported sessions │ │
│ │ - Timestamped, ready for processing │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Trigger Strategies
| Trigger | Condition | Use Case |
|---|---|---|
| Size-based | wire.jsonl > 5MB | Prevent excessive file growth |
| Time-based | Every 15 minutes | Regular backup during long sessions |
| Turn-based | Every N user turns | Export after significant work |
| Context-based | Context usage > 79% | Export before compaction (starts at 80%) |
| Event-based | TurnEnd + idle > 30s | Export when user pauses |
File Management Strategies
Strategy A: Continuous Rotation (Recommended)
wire.jsonl.000 (0-5MB)
wire.jsonl.001 (5-10MB) → Export → Archive
wire.jsonl.002 (10-15MB) → Export → Archive
Strategy B: Incremental Export
Export only NEW entries since last export
- Track last exported line number
- Append to existing CUSF file
- Single file per session, continuously appended
Strategy C: Hourly Segments
2026-01-28T10-00-00Z-session-kimi-<uuid>--hour-00.jsonl
2026-01-28T11-00-00Z-session-kimi-<uuid>--hour-01.jsonl
2026-01-28T12-00-00Z-session-kimi-<uuid>--hour-02.jsonl
Recommended Configuration
{
"kase": {
"enabled": true,
"triggers": {
"size_mb": 5,
"time_minutes": 15,
"turns": 10,
"context_threshold": 0.79
},
"strategy": "incremental",
"output_dir": "~/.coditect-data/kimi-sessions-auto/",
"retention": {
"pending_max_age_hours": 24,
"archive_after_export": true
}
}
}
Implementation
Phase 1: File Watcher (MVP)
Create kimi-session-watcher.py:
#!/usr/bin/env python3
"""KIMI Automated Session Export (KASE) Watcher"""
import json
import time
from pathlib import Path
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class WireJsonlHandler(FileSystemEventHandler):
def __init__(self, session_path: Path):
self.session_path = session_path
self.wire_file = session_path / "wire.jsonl"
self.last_size = 0
self.last_export_line = 0
def on_modified(self, event):
if event.src_path == str(self.wire_file):
self.check_export_trigger()
def check_export_trigger(self):
current_size = self.wire_file.stat().st_size
size_mb = current_size / 1024 / 1024
# Trigger: Size threshold
if size_mb - (self.last_size / 1024 / 1024) > 5:
self.export_incremental()
self.last_size = current_size
def watch_session(session_path: Path):
handler = WireJsonlHandler(session_path)
observer = Observer()
observer.schedule(handler, str(session_path), recursive=False)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
if __name__ == "__main__":
import sys
watch_session(Path(sys.argv[1]))
Phase 2: Service Integration
Add to existing CODITECT watcher infrastructure:
# systemd service
[Service]
ExecStart=/usr/bin/python3 %h/.coditect/scripts/kimi-session-watcher.py %h/.kimi/sessions/
Phase 3: Context Monitoring
Add real-time context status display:
# Show in terminal or status bar
Context: 55.9% | Tokens: 146K in / 534 out | Last export: 2m ago
File Lifecycle
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ KIMI CLI │────▶│ wire.jsonl │────▶│ Auto-Export │────▶│ Pending │
│ (running) │ │ (growing) │ │ (KASE) │ │ Directory │
└─────────────┘ └─────────────┘ └─────────────┘ └──────┬──────┘
│
▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Archive │◀────│ Import │◀────│ Process │◀────│ sessions.db│
│ (long) │ │ (async) │ │ (batch) │ │ (SQLite) │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
Risks and Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| Watcher crashes | Data loss | Auto-restart, heartbeat check |
| Disk full | Export fails | Pre-export disk check, rotation |
| Concurrent access | Corruption | File locking, atomic moves |
| Long sessions | Huge files | Size-based rotation |
| Export during write | Incomplete data | Read consistency, retry logic |
Alternatives Considered
- Manual export only - Rejected: Too error-prone
- Cron-based periodic export - Rejected: Not real-time, misses short sessions
- KIMI hook/post-command - Rejected: No hook mechanism in KIMI CLI
- Wrap kimi command - Rejected: Invasive, breaks normal usage
Decision Outcome
Implement KASE with:
- File watcher (inotify/fs events)
- Incremental export strategy
- Size + time triggers
- Integration with existing CODITECT watcher infrastructure
Related
- ADR-122: Unified LLM Component Architecture
- ADR-123: Codex Session Export Management
- ADR-126: Gemini Session Export Management
- KIMI.1-KIMI.12: KIMI Integration Tasks
References
- KIMI CLI: https://github.com/moonshot-ai/kimi-cli
- Python watchdog: https://python-watchdog.readthedocs.io/
- CUSF Format:
schemas/cusf-v1.0.0.json