Version: v1.0.0 Last Updated: 2026-06-25 Effective Date: 2026-06-25
Context Chronicle is a local-first, zero-cloud-dependency memory and audit system for AI coding assistants. This document describes what data is collected, how it is stored, how long it is retained, and the rights you have over your data.
Context Chronicle records the following categories of data on the local machine to provide verifiable memory, constraint enforcement, and tool firewall capabilities:
| Category | Description | Source |
|---|---|---|
| Event log | User messages, assistant messages, tool calls, tool results, system events, and subagent messages. Each event carries a SHA-256 integrity hash that chains it to the previous event for tamper detection. | Lifecycle hooks intercepting AI client activity |
| Memory packets | Structured constraints, facts, hypotheses, and decisions extracted from the conversation. Each packet traces back to source events via evidence_chain. |
Detected from user messages and assistant responses |
| Decision timeline | Technical decisions and their rationale, including rejected alternatives to prevent solution regression. | Detected from conversation patterns |
| Compaction state | Rolling compaction summaries and reinjection snapshots used to manage context budget. | Generated by the compaction engine |
| Knowledge graph entities | Entities (agents, files, decisions, constraints) and relations between them, with SHA-256 deduplication. | Extracted from events |
| Audit reports | Stop Gate audit records produced when the audit trigger fires (firewall block rate, decision count, etc.). | Generated by the audit subsystem |
| File logs | JSON Lines structured logs for lifecycle hooks and internal operations, with 7-day retention and 50 MB cap. | Written by FileLogWriter |
- No biometric data, no personal identity information (PII) beyond what appears in coding conversations.
- No browsing history, no system telemetry, no hardware fingerprints.
- No geolocation data.
All data is stored locally on the machine where Context Chronicle runs:
| Platform | Path |
|---|---|
| Linux / macOS | ~/.opencode/context-chronicle/ |
| Windows | %USERPROFILE%\.opencode\context-chronicle\ |
~/.opencode/context-chronicle/
+-- config.json Configuration (no secrets; env vars referenced as ${VAR})
+-- db.sqlite Main SQLite database (event_log, memory_packets, decisions, kg_*)
+-- install-state.json Plugin install state
+-- logs/
+-- cc-YYYY-MM-DD.log JSON Lines log files (7-day retention, 50 MB cap)
- Engine: SQLite (via
better-sqlite3) - Vector index:
sqlite-vecextension (vec0virtual table +vec_distance_cosine) - Full-text search: SQLite FTS5 (with CJK trigram dual-table fallback)
- Encryption at rest: Not provided by Context Chronicle. Rely on OS-level disk encryption (BitLocker, FileVault, LUKS) if required.
Context Chronicle has zero cloud dependency for its core functionality.
- No telemetry, no analytics, no crash reports are sent to any server.
- No event log, memory packet, or decision data leaves the local machine.
- The application works fully offline once installed.
If you explicitly configure an embedding provider (via context-chronicle embedding use <id>), the system will send text snippets to that provider to be converted into vector embeddings. This is an opt-in feature for semantic search.
What gets sent to the embedding provider:
- Text content of memory packets and events being indexed
- Text of search queries
What does NOT get sent:
- The full event log
- Audit reports
- Decision timeline data
- File logs
- Configuration
Available local-only embedding options (no data leaves the machine):
ollama-*presets (locally hosted Ollama)- Cloud embedding providers transmit text to their APIs; no local model data is stored
To disable all external embedding traffic, run:
context-chronicle embedding use none| Data type | Default retention | Configurable? |
|---|---|---|
| Event log | Until manual deletion | No (managed by user) |
| Memory packets | Until manual deletion (or expires_at if set) |
Yes - expires_at field per packet |
| Decisions | Until manual deletion | No |
| File logs | 7 days, 50 MB cap | Yes - CC_LOG_RETENTION env var |
| Session cleanup | Sessions older than 180 days are auto-cleaned | Yes - cleanExpiredSessions(maxAgeDays) |
Constraints lose trustworthiness over time via a context-distance decay model (default half-life: 80 turns). This does not delete data - it only affects retrieval ranking. Decayed constraints remain in the database and can be reviewed via the STALE_CONSTRAINT audit.
You have full control over your data because it never leaves your machine.
# Export all user data as JSON to stdout
context-chronicle export
# Export to a specific file
context-chronicle export --output=./my-data.jsonThe export contains:
event_log- all recorded eventsmemory_packets- all constraints, facts, hypotheses, decisionsdecisions- full decision timeline with rationale and rejected optionsconstraints- subset of memory_packets wherepacket_type='constraint'
# Remove plugin registration but preserve database
context-chronicle uninstall
# Remove plugin registration AND delete all data (config + database + logs)
context-chronicle uninstall --purge --forceTo stop collecting new data without deleting existing data:
- Disable the plugin:
context-chronicle uninstall - Or set
contextChronicle.enabled: falsein~/.opencode/context-chronicle/config.json
The export command produces a standard JSON file that can be ingested by any other tool. The schema is documented in docs/ARCHITECTURE.md (Data Model section).
You can modify memory packet content directly:
# Via MCP tool
memoryManage({ action: 'update', id: <packet_id>, content: 'corrected content' })Event log entries are immutable by design - they carry SHA-256 integrity hashes and form a tamper-evident chain. Corrections must be made by adding new events that reference the original.
The sanitize() utility redacts known secret patterns before any data is written to the database:
- OpenAI API keys (
sk-...) - Stripe keys (
sk_live_...) - GitHub tokens (
ghp_...) - Password assignments (
password = "...")
Events have a visibility field (user | internal | secret) that controls searchability:
user- searchable by all queries (default)internal- excluded from user-facing searchsecret- excluded from all search, requires explicit access
The firewall enforces constraints at tool-call time, blocking execution of disallowed commands (e.g., npm install when pnpm is mandated). The force parameter is permanently disabled for MCP clients.
validateDbPath() performs multi-step validation before opening any SQLite database: path exists, is a file, has non-zero size, contains the SQLite magic header. This prevents malicious file substitution.
For a complete description of what Context Chronicle is and is not responsible for, see docs/ARCHITECTURE.md section System Boundaries.
| Responsible | Not Responsible |
|---|---|
| Event recording, constraint management, tool firewall | Network request interception, HTTP proxy |
| Local SQLite storage and FTS5 full-text search | Real-time filesystem monitoring, git hooks |
| Vector indexing (requires external embedding provider) | Cloud sync, multi-machine collaboration |
| Model switch detection and context bridging | IDE plugins, editor extensions |
| Plugin conflict detection (known plugins) | General process management, resource limits |
| Automatic key/sensitive data redaction | Encrypted storage, access control |
This document is versioned alongside the codebase. Any change to data collection scope, storage location, or retention policy will be:
- Reflected in an updated
PRIVACY.md - Noted in
CHANGELOG.md - Reflected in the first-run consent notice shown by
context-chronicle init
- Issues: GitHub Issues
- Security vulnerabilities: See
SECURITY.mdfor responsible disclosure process - Source code: GitHub repository
This privacy policy is part of the Context Chronicle project, licensed under Apache-2.0.