{"id":37231001,"url":"https://github.com/sochdb/sochdb-python-sdk","last_synced_at":"2026-01-26T08:02:12.949Z","repository":{"id":331999281,"uuid":"1127902334","full_name":"sochdb/sochdb-python-sdk","owner":"sochdb","description":"SochDB is a high-performance embedded, ACID-compliant database purpose-built for AI agents and memory - python sdk","archived":false,"fork":false,"pushed_at":"2026-01-21T01:14:49.000Z","size":4847,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-21T12:56:02.773Z","etag":null,"topics":["agent-memory","agentic-ai","agentic-framework","agentic-rag","agents-databases","database","database-management","embeedings","python-database","vector-database"],"latest_commit_sha":null,"homepage":"https://sochdb.dev","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sochdb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-04T20:16:08.000Z","updated_at":"2026-01-21T01:13:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/sochdb/sochdb-python-sdk","commit_stats":null,"previous_names":["toondb/toondb-python-sdk","sochdb/sochdb-python-sdk"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/sochdb/sochdb-python-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sochdb%2Fsochdb-python-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sochdb%2Fsochdb-python-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sochdb%2Fsochdb-python-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sochdb%2Fsochdb-python-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sochdb","download_url":"https://codeload.github.com/sochdb/sochdb-python-sdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sochdb%2Fsochdb-python-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28770049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T07:45:00.504Z","status":"ssl_error","status_checked_at":"2026-01-26T07:45:00.070Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-memory","agentic-ai","agentic-framework","agentic-rag","agents-databases","database","database-management","embeedings","python-database","vector-database"],"created_at":"2026-01-15T03:41:13.811Z","updated_at":"2026-01-26T08:02:12.933Z","avatar_url":"https://github.com/sochdb.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SochDB Python SDK\n\n\u003e **📢 Note:** This project has been renamed from **ToonDB** to **SochDB**. All references, packages, and APIs have been updated accordingly. If you're upgrading from ToonDB, please update your imports from `toondb` to `sochdb`.\n\n**Dual-mode architecture: Embedded (FFI) + Server (gRPC/IPC)**  \nChoose the deployment mode that fits your needs.\n\n---\n\n## Installation\n\n```bash\npip install sochdb\n```\n\nOr from source:\n```bash\ncd sochdb-python-sdk\npip install -e .\n```\n\n---\n\n## Architecture: Flexible Deployment\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                    DEPLOYMENT OPTIONS                        │\n├─────────────────────────────────────────────────────────────┤\n│                                                               │\n│  1. EMBEDDED MODE (FFI)          2. SERVER MODE (gRPC)      │\n│  ┌─────────────────────┐         ┌─────────────────────┐   │\n│  │   Python App        │         │   Python App        │   │\n│  │   ├─ Database.open()│         │   ├─ SochDBClient() │   │\n│  │   └─ Direct FFI     │         │   └─ gRPC calls     │   │\n│  │         │           │         │         │           │   │\n│  │         ▼           │         │         ▼           │   │\n│  │   libsochdb_storage │         │   sochdb-grpc       │   │\n│  │   (Rust native)     │         │   (Rust server)     │   │\n│  └─────────────────────┘         └─────────────────────┘   │\n│                                                               │\n│  ✅ No server needed               ✅ Multi-language          │\n│  ✅ Local files                    ✅ Centralized logic      │\n│  ✅ Simple deployment              ✅ Production scale       │\n└─────────────────────────────────────────────────────────────┘\n```\n\n### When to Use Each Mode\n\n**Embedded Mode (FFI):**\n- ✅ Local development and testing\n- ✅ Jupyter notebooks and data science\n- ✅ Single-process applications\n- ✅ Edge deployments without network\n- ✅ No server setup required\n\n**Embedded Concurrent Mode:**\n- ✅ Web applications (Flask, FastAPI, Django)\n- ✅ Multi-process workers (Gunicorn, uWSGI)\n- ✅ Hot reloading development servers\n- ✅ Multi-reader, single-writer architecture\n- ✅ Lock-free reads (~100ns latency)\n\n**Server Mode (gRPC):**\n- ✅ Production deployments\n- ✅ Multi-language teams (Python, Node.js, Go)\n- ✅ Distributed systems\n- ✅ Centralized business logic\n- ✅ Horizontal scaling\n\n---\n\n# SochDB Python SDK Documentation\n\nLLM-Optimized Embedded Database with Native Vector Search\n\n---\n\n## Table of Contents\n\n1. [Quick Start](#1-quick-start)\n2. [Installation](#2-installation)\n3. [Architecture Overview](#3-architecture-overview)\n4. [Core Key-Value Operations](#4-core-key-value-operations)\n5. [Transactions (ACID with SSI)](#5-transactions-acid-with-ssi)\n6. [Query Builder](#6-query-builder)\n7. [Prefix Scanning](#7-prefix-scanning)\n8. [SQL Operations](#8-sql-operations)\n9. [Table Management \u0026 Index Policies](#9-table-management--index-policies)\n10. [Namespaces \u0026 Multi-Tenancy](#10-namespaces--multi-tenancy)\n11. [Collections \u0026 Vector Search](#11-collections--vector-search)\n12. [Hybrid Search (Vector + BM25)](#12-hybrid-search-vector--bm25)\n13. [Graph Operations](#13-graph-operations)\n14. [Temporal Graph (Time-Travel)](#14-temporal-graph-time-travel)\n15. [Semantic Cache](#15-semantic-cache)\n16. [Context Query Builder (LLM Optimization)](#16-context-query-builder-llm-optimization)\n17. [Memory System](#17-memory-system)\n18. [Session Management](#18-session-management)\n19. [Atomic Multi-Index Writes](#19-atomic-multi-index-writes)\n20. [Recovery \u0026 WAL Management](#20-recovery--wal-management)\n21. [Checkpoints \u0026 Snapshots](#21-checkpoints--snapshots)\n22. [Compression \u0026 Storage](#22-compression--storage)\n23. [Statistics \u0026 Monitoring](#23-statistics--monitoring)\n24. [Distributed Tracing](#24-distributed-tracing)\n25. [Workflow \u0026 Run Tracking](#25-workflow--run-tracking)\n26. [Server Mode (gRPC Client)](#26-server-mode-grpc-client)\n27. [IPC Client (Unix Sockets)](#27-ipc-client-unix-sockets)\n28. [Standalone VectorIndex](#28-standalone-vectorindex)\n29. [Vector Utilities](#29-vector-utilities)\n30. [Data Formats (TOON/JSON/Columnar)](#30-data-formats-toonjsoncolumnar)\n31. [Policy Service](#31-policy-service)\n32. [MCP (Model Context Protocol)](#32-mcp-model-context-protocol)\n33. [Configuration Reference](#33-configuration-reference)\n34. [Error Handling](#34-error-handling)\n35. [Async Support](#35-async-support)\n36. [Building \u0026 Development](#36-building--development)\n37. [Complete Examples](#37-complete-examples)\n38. [Migration Guide](#38-migration-guide)\n\n---\n\n## 1. Quick Start\n\n### Concurrent Embedded Mode\ndb = Database.open_concurrent(\"./app_data\")\n\n# Reads are lock-free and can run in parallel (~100ns)\nvalue = db.get(b\"user:123\")\n\n# Writes are automatically coordinated (~60µs amortized)\ndb.put(b\"user:123\", b'{\"name\": \"Alice\"}')\n\n# Check if concurrent mode is active\nprint(f\"Concurrent mode: {db.is_concurrent}\")  # True\n```\n\n### Flask Example\n\n```python\nfrom flask import Flask\nfrom sochdb import Database\n\napp = Flask(__name__)\ndb = Database.open_concurrent(\"./flask_db\")\n\n@app.route(\"/user/\u003cuser_id\u003e\")\ndef get_user(user_id):\n    # Multiple concurrent requests can read simultaneously\n    data = db.get(f\"user:{user_id}\".encode())\n    return data or \"Not found\"\n\n@app.route(\"/user/\u003cuser_id\u003e\", methods=[\"POST\"])\ndef update_user(user_id):\n    # Writes are serialized automatically\n    db.put(f\"user:{user_id}\".encode(), request.data)\n    return \"OK\"\n```\n\n### Performance\n\n| Operation | Standard Mode | Concurrent Mode |\n|-----------|---------------|-----------------|\n| Read (single process) | ~100ns | ~100ns |\n| Read (multi-process) | **Blocked** ❌ | ~100ns ✅ |\n| Write | ~5ms (fsync) | ~60µs (amortized) |\n| Max concurrent readers | 1 | 1024 |\n\n### Gunicorn Deployment\n\n```bash\n# Install Gunicorn\npip install gunicorn\n\n# Run with 4 worker processes (all can access same DB concurrently)\ngunicorn -w 4 -b 0.0.0.0:8000 app:app\n\n# Workers automatically share the database in concurrent mode\n```\n\n### uWSGI Deployment\n\n```bash\n# Install uWSGI\npip install uwsgi\n\n# Run with 4 processes\nuwsgi --http :8000 --wsgi-file app.py --callable app --processes 4\n```\n\n### Systemd Service Example\n\n```ini\n# /etc/systemd/system/myapp.service\n[Unit]\nDescription=MyApp with SochDB\nAfter=network.target\n\n[Service]\nType=notify\nUser=appuser\nWorkingDirectory=/opt/myapp\nExecStart=/opt/myapp/venv/bin/gunicorn -w 4 -b 0.0.0.0:8000 app:app\nRestart=always\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\n# Enable and start service\nsudo systemctl enable myapp\nsudo systemctl start myapp\nsudo systemctl status myapp\n```\n\n### Docker Compose Example\n\n```yaml\nversion: '3.8'\nservices:\n  app:\n    build: .\n    environment:\n      - WORKERS=4\n    volumes:\n      - ./data:/app/data  # Shared database volume\n    ports:\n      - \"8000:8000\"\n    command: gunicorn -w 4 -b 0.0.0.0:8000 app:app\n```\n\n---\n\n## System Requirements\n\n### For Concurrent Mode\n\n- **SochDB Core**: Latest version\n- **Python**: 3.9+ (3.11+ recommended)\n- **Native Library**: `libsochdb_storage.{dylib,so}`\n- **FFI**: ctypes (built-in to Python)\n\n**Operating Systems:**\n- ✅ Linux (Ubuntu 20.04+, RHEL 8+)\n- ✅ macOS (10.15+, both Intel and Apple Silicon)\n- ⚠️  Windows (requires native builds)\n\n**File Descriptors:**\n- Default limit: 1024 (sufficient for most workloads)\n- For high concurrency with Gunicorn: `ulimit -n 4096`\n\n**Memory:**\n- Standard mode: ~50MB base + data\n- Concurrent mode: +4KB per concurrent reader slot (1024 slots = ~4MB overhead)\n- Gunicorn: Each worker has independent memory\n\n---\n\n## Troubleshooting\n\n### \"Database is locked\" Error (Standard Mode)\n\n```\nOperationalError: database is locked\n```\n\n**Solution**: Use concurrent mode for multi-process access:\n\n```python\n# ❌ Standard mode - Gunicorn workers will conflict\ndb = Database.open(\"./data.db\")\n\n# ✅ Concurrent mode - all workers can access\ndb = Database.open_concurrent(\"./data.db\")\n```\n\n### Library Not Found Error\n\n```\nOSError: libsochdb_storage.dylib not found\n```\n\n**macOS**:\n```bash\n# Build and install library\ncd /path/to/sochdb\ncargo build --release\nsudo cp target/release/libsochdb_storage.dylib /usr/local/lib/\n```\n\n**Linux**:\n```bash\ncd /path/to/sochdb\ncargo build --release\nsudo cp target/release/libsochdb_storage.so /usr/local/lib/\nsudo ldconfig\n```\n\n**Development Mode** (no install):\n```bash\nexport DYLD_LIBRARY_PATH=/path/to/sochdb/target/release  # macOS\nexport LD_LIBRARY_PATH=/path/to/sochdb/target/release    # Linux\n```\n\n### Gunicorn Worker Issues\n\n**Symptom**: Workers crash with \"database locked\"\n\n**Solution 1** - Ensure concurrent mode is used:\n```python\n# app.py\nimport os\nfrom sochdb import Database\n\n# Use environment variable to control mode\nUSE_CONCURRENT = os.getenv('USE_CONCURRENT_MODE', 'true').lower() == 'true'\n\nif USE_CONCURRENT:\n    db = Database.open_concurrent('./db')\nelse:\n    db = Database.open('./db')\n\nprint(f\"Concurrent mode: {db.is_concurrent}\")  # Should be True\n```\n\n```bash\n# Start with concurrent mode enabled\nUSE_CONCURRENT_MODE=true gunicorn -w 4 -b 0.0.0.0:8000 app:app\n```\n\n**Solution 2** - Check preload settings:\n```bash\n# Don't use --preload with concurrent mode\n# ❌ This will cause issues:\ngunicorn --preload -w 4 app:app\n\n# ✅ Let each worker open the database:\ngunicorn -w 4 app:app\n```\n\n### FastAPI with Uvicorn Workers\n\n**Symptom**: `RuntimeError: Concurrent mode requires multi-process access`\n\n**Solution**: Use Uvicorn workers correctly:\n```bash\n# ❌ Single worker (async) - doesn't need concurrent mode\nuvicorn app:app --workers 1\n\n# ✅ Multiple workers - needs concurrent mode\nuvicorn app:app --workers 4\n```\n\n```python\n# main.py\nfrom fastapi import FastAPI\nfrom sochdb import Database\nimport multiprocessing\n\napp = FastAPI()\n\n# Detect if running in multi-worker mode\nworkers = multiprocessing.cpu_count()\nif workers \u003e 1:\n    db = Database.open_concurrent(\"./db\")\nelse:\n    db = Database.open(\"./db\")\n```\n\n### Performance Issues\n\n**Symptom**: Concurrent reads slower than expected\n\n**Check 1** - Verify concurrent mode is active:\n```python\nimport logging\nlogging.basicConfig(level=logging.INFO)\n\ndb = Database.open_concurrent(\"./db\")\nif not db.is_concurrent:\n    logging.error(\"Database is not in concurrent mode!\")\n    raise RuntimeError(\"Expected concurrent mode\")\nlogging.info(f\"Concurrent mode active: {db.is_concurrent}\")\n```\n\n**Check 2** - Monitor worker processes:\n```bash\n# Watch Gunicorn workers\nwatch -n 1 'ps aux | grep gunicorn'\n\n# Monitor file descriptors\nlsof | grep libsochdb_storage\n```\n\n**Check 3** - Batch writes:\n```python\n# ❌ Slow - individual writes with fsync\nfor item in items:\n    db.put(key, value)\n\n# ✅ Fast - batch in transaction\ntx = db.begin_txn()\nfor item in items:\n    tx.put(key, value)\ntx.commit()  # Single fsync for entire batch\n```\n\n---\n\n# SochDB Python SDK Documentation\n\nLLM-Optimized Embedded Database with Native Vector Search\n\n---\n\n## Table of Contents\n\n1. [Quick Start](#1-quick-start)\n2. [Installation](#2-installation)\n3. [Architecture Overview](#3-architecture-overview)\n4. [Core Key-Value Operations](#4-core-key-value-operations)\n5. [Transactions (ACID with SSI)](#5-transactions-acid-with-ssi)\n6. [Query Builder](#6-query-builder)\n7. [Prefix Scanning](#7-prefix-scanning)\n8. [SQL Operations](#8-sql-operations)\n9. [Table Management \u0026 Index Policies](#9-table-management--index-policies)\n10. [Namespaces \u0026 Multi-Tenancy](#10-namespaces--multi-tenancy)\n11. [Collections \u0026 Vector Search](#11-collections--vector-search)\n12. [Hybrid Search (Vector + BM25)](#12-hybrid-search-vector--bm25)\n13. [Graph Operations](#13-graph-operations)\n14. [Temporal Graph (Time-Travel)](#14-temporal-graph-time-travel)\n15. [Semantic Cache](#15-semantic-cache)\n16. [Context Query Builder (LLM Optimization) and Session](#16-context-query-builder-llm-optimization)\n17. [Priority Queue \u0026 Task Management](#17-priority-queue--task-management)\n18. [Memory System (LLM-Native)](#18-memory-system-llm-native)\n19. [Atomic Multi-Index Writes](#19-atomic-multi-index-writes)\n20. [Recovery \u0026 WAL Management](#20-recovery--wal-management)\n21. [Checkpoints \u0026 Snapshots](#21-checkpoints--snapshots)\n22. [Compression \u0026 Storage](#22-compression--storage)\n23. [Statistics \u0026 Monitoring](#23-statistics--monitoring)\n24. [Distributed Tracing](#24-distributed-tracing)\n25. [Workflow \u0026 Run Tracking](#25-workflow--run-tracking)\n26. [Server Mode (gRPC Client)](#26-server-mode-grpc-client)\n27. [IPC Client (Unix Sockets)](#27-ipc-client-unix-sockets)\n28. [Standalone VectorIndex](#28-standalone-vectorindex)\n29. [Vector Utilities](#29-vector-utilities)\n30. [Data Formats (TOON/JSON/Columnar)](#30-data-formats-toonjsoncolumnar)\n31. [Policy Service](#31-policy-service)\n32. [MCP (Model Context Protocol)](#32-mcp-model-context-protocol)\n33. [Configuration Reference](#33-configuration-reference)\n34. [Error Handling](#34-error-handling)\n35. [Async Support](#35-async-support)\n36. [Building \u0026 Development](#36-building--development)\n37. [Complete Examples](#37-complete-examples)\n38. [Migration Guide](#38-migration-guide)\n\n---\n\n## 1. Quick Start\n\n```python\nfrom sochdb import Database\n\n# Open (or create) a database\ndb = Database.open(\"./my_database\")\n\n# Store and retrieve data\ndb.put(b\"hello\", b\"world\")\nvalue = db.get(b\"hello\")  # b\"world\"\n\n# Use transactions for atomic operations\nwith db.transaction() as txn:\n    txn.put(b\"key1\", b\"value1\")\n    txn.put(b\"key2\", b\"value2\")\n    # Auto-commits on success, auto-rollbacks on exception\n\n# Clean up\ndb.delete(b\"hello\")\ndb.close()\n```\n\n**30-Second Overview:**\n- **Key-Value**: Fast reads/writes with `get`/`put`/`delete`\n- **Transactions**: ACID with SSI isolation\n- **Vector Search**: HNSW-based semantic search\n- **Hybrid Search**: Combine vectors with BM25 keyword search\n- **Graph**: Build and traverse knowledge graphs\n- **LLM-Optimized**: TOON format uses 40-60% fewer tokens than JSON\n\n---\n\n## 2. Installation\n\n```bash\npip install sochdb\n```\n\n**Platform Support:**\n| Platform | Architecture | Status |\n|----------|--------------|--------|\n| Linux | x86_64, aarch64 | ✅ Full support |\n| macOS | x86_64, arm64 | ✅ Full support |\n| Windows | x86_64 | ✅ Full support |\n\n**Optional Dependencies:**\n```bash\n# For async support\npip install sochdb[async]\n\n# For server mode\npip install sochdb[grpc]\n\n# Everything\npip install sochdb[all]\n```\n\n---\n\n## 3. Architecture Overview\n\nSochDB supports two deployment modes:\n\n### Embedded Mode (Default)\n\nDirect Rust bindings via FFI. No server required.\n\n```python\nfrom sochdb import Database\n\nwith Database.open(\"./mydb\") as db:\n    db.put(b\"key\", b\"value\")\n    value = db.get(b\"key\")\n```\n\n**Best for:** Local development, notebooks, single-process applications.\n\n### Server Mode (gRPC)\n\nThin client connecting to `sochdb-grpc` server.\n\n```python\nfrom sochdb import SochDBClient\n\nclient = SochDBClient(\"localhost:50051\")\nclient.put(b\"key\", b\"value\", namespace=\"default\")\nvalue = client.get(b\"key\", namespace=\"default\")\n```\n\n**Best for:** Production, multi-process, distributed systems.\n\n### Feature Comparison\n\n| Feature | Embedded | Server |\n|---------|----------|--------|\n| Setup | `pip install` only | Server + client |\n| Performance | Fastest (in-process) | Network overhead |\n| Multi-process | ❌ | ✅ |\n| Horizontal scaling | ❌ | ✅ |\n| Vector search | ✅ | ✅ |\n| Graph operations | ✅ | ✅ |\n| Semantic cache | ✅ | ✅ |\n| Context service | Limited | ✅ Full |\n| MCP integration | ❌ | ✅ |\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│                    DEPLOYMENT OPTIONS                        │\n├─────────────────────────────────────────────────────────────┤\n│  EMBEDDED MODE (FFI)             SERVER MODE (gRPC)         │\n│  ┌─────────────────────┐         ┌─────────────────────┐   │\n│  │   Python App        │         │   Python App        │   │\n│  │   ├─ Database.open()│         │   ├─ SochDBClient() │   │\n│  │   └─ Direct FFI     │         │   └─ gRPC calls     │   │\n│  │         │           │         │         │           │   │\n│  │         ▼           │         │         ▼           │   │\n│  │   libsochdb_storage │         │   sochdb-grpc       │   │\n│  │   (Rust native)     │         │   (Rust server)     │   │\n│  └─────────────────────┘         └─────────────────────┘   │\n│                                                              │\n│  ✅ No server needed             ✅ Multi-language          │\n│  ✅ Local files                  ✅ Centralized logic       │\n│  ✅ Simple deployment            ✅ Production scale        │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## 4. Core Key-Value Operations\n\nAll keys and values are **bytes**.\n\n### Basic Operations\n\n```python\nfrom sochdb import Database\n\ndb = Database.open(\"./my_db\")\n\n# Store data\ndb.put(b\"user:1\", b\"Alice\")\ndb.put(b\"user:2\", b\"Bob\")\n\n# Retrieve data\nuser = db.get(b\"user:1\")  # Returns b\"Alice\" or None\n\n# Check existence\nexists = db.exists(b\"user:1\")  # True\n\n# Delete data\ndb.delete(b\"user:1\")\n\ndb.close()\n```\n\n### Path-Based Keys (Hierarchical)\n\nOrganize data hierarchically with path-based access:\n\n```python\n# Store with path (strings auto-converted to bytes internally)\ndb.put_path(\"users/alice/name\", b\"Alice Smith\")\ndb.put_path(\"users/alice/email\", b\"alice@example.com\")\ndb.put_path(\"users/bob/name\", b\"Bob Jones\")\n\n# Retrieve by path\nname = db.get_path(\"users/alice/name\")  # b\"Alice Smith\"\n\n# Delete by path\ndb.delete_path(\"users/alice/email\")\n\n# List at path (like listing directory)\nchildren = db.list_path(\"users/\")  # [\"alice\", \"bob\"]\n```\n\n### With TTL (Time-To-Live)\n\n```python\n# Store with expiration (seconds)\ndb.put(b\"session:abc123\", b\"user_data\", ttl_seconds=3600)  # Expires in 1 hour\n\n# TTL of 0 means no expiration\ndb.put(b\"permanent_key\", b\"value\", ttl_seconds=0)\n```\n\n### Batch Operations\n\n```python\n# Batch put (more efficient than individual puts)\ndb.put_batch([\n    (b\"key1\", b\"value1\"),\n    (b\"key2\", b\"value2\"),\n    (b\"key3\", b\"value3\"),\n])\n\n# Batch get\nvalues = db.get_batch([b\"key1\", b\"key2\", b\"key3\"])\n# Returns: [b\"value1\", b\"value2\", b\"value3\"] (None for missing keys)\n\n# Batch delete\ndb.delete_batch([b\"key1\", b\"key2\", b\"key3\"])\n```\n\n### Context Manager\n\n```python\nwith Database.open(\"./my_db\") as db:\n    db.put(b\"key\", b\"value\")\n    # Automatically closes when exiting\n```\n\n---\n\n## 5. Transactions (ACID with SSI)\n\nSochDB provides full ACID transactions with **Serializable Snapshot Isolation (SSI)**.\n\n### Context Manager Pattern (Recommended)\n\n```python\n# Auto-commits on success, auto-rollbacks on exception\nwith db.transaction() as txn:\n    txn.put(b\"accounts/alice\", b\"1000\")\n    txn.put(b\"accounts/bob\", b\"500\")\n    \n    # Read within transaction sees your writes\n    balance = txn.get(b\"accounts/alice\")  # b\"1000\"\n    \n    # If exception occurs, rolls back automatically\n```\n\n### Closure Pattern (Rust-Style)\n\n```python\n# Using with_transaction for automatic commit/rollback\ndef transfer_funds(txn):\n    alice = int(txn.get(b\"accounts/alice\") or b\"0\")\n    bob = int(txn.get(b\"accounts/bob\") or b\"0\")\n    \n    txn.put(b\"accounts/alice\", str(alice - 100).encode())\n    txn.put(b\"accounts/bob\", str(bob + 100).encode())\n    \n    return \"Transfer complete\"\n\nresult = db.with_transaction(transfer_funds)\n```\n\n### Manual Transaction Control\n\n```python\ntxn = db.begin_transaction()\ntry:\n    txn.put(b\"key1\", b\"value1\")\n    txn.put(b\"key2\", b\"value2\")\n    \n    commit_ts = txn.commit()  # Returns HLC timestamp\n    print(f\"Committed at: {commit_ts}\")\nexcept Exception as e:\n    txn.abort()\n    raise\n```\n\n### Transaction Properties\n\n```python\ntxn = db.transaction()\nprint(f\"Transaction ID: {txn.id}\")      # Unique identifier\nprint(f\"Start timestamp: {txn.start_ts}\")  # HLC start time\nprint(f\"Isolation: {txn.isolation}\")    # \"serializable\"\n```\n\n### SSI Conflict Handling\n\n```python\nfrom sochdb import TransactionConflictError\n\nMAX_RETRIES = 3\n\nfor attempt in range(MAX_RETRIES):\n    try:\n        with db.transaction() as txn:\n            # Read and modify\n            value = int(txn.get(b\"counter\") or b\"0\")\n            txn.put(b\"counter\", str(value + 1).encode())\n        break  # Success\n    except TransactionConflictError:\n        if attempt == MAX_RETRIES - 1:\n            raise\n        # Retry on conflict\n        continue\n```\n\n### All Transaction Operations\n\n```python\nwith db.transaction() as txn:\n    # Key-value\n    txn.put(key, value)\n    txn.get(key)\n    txn.delete(key)\n    txn.exists(key)\n    \n    # Path-based\n    txn.put_path(path, value)\n    txn.get_path(path)\n    \n    # Batch operations\n    txn.put_batch(pairs)\n    txn.get_batch(keys)\n    \n    # Scanning\n    for k, v in txn.scan_prefix(b\"prefix/\"):\n        print(k, v)\n    \n    # SQL (within transaction isolation)\n    result = txn.execute(\"SELECT * FROM users WHERE id = 1\")\n```\n\n### Isolation Levels\n\n```python\nfrom sochdb import IsolationLevel\n\n# Default: Serializable (strongest)\nwith db.transaction(isolation=IsolationLevel.SERIALIZABLE) as txn:\n    pass\n\n# Snapshot isolation (faster, allows some anomalies)\nwith db.transaction(isolation=IsolationLevel.SNAPSHOT) as txn:\n    pass\n\n# Read committed (fastest, least isolation)\nwith db.transaction(isolation=IsolationLevel.READ_COMMITTED) as txn:\n    pass\n```\n\n---\n\n## 6. Query Builder\n\nFluent API for building efficient queries with predicate pushdown.\n\n### Basic Query\n\n```python\n# Query with prefix and limit\nresults = db.query(\"users/\")\n    .limit(10)\n    .execute()\n\nfor key, value in results:\n    print(f\"{key.decode()}: {value.decode()}\")\n```\n\n### Filtered Query\n\n```python\nfrom sochdb import CompareOp\n\n# Query with filters\nresults = db.query(\"orders/\")\n    .where(\"status\", CompareOp.EQ, \"pending\")\n    .where(\"amount\", CompareOp.GT, 100)\n    .order_by(\"created_at\", descending=True)\n    .limit(50)\n    .offset(10)\n    .execute()\n```\n\n### Column Selection\n\n```python\n# Select specific fields only\nresults = db.query(\"users/\")\n    .select([\"name\", \"email\"])  # Only fetch these columns\n    .where(\"active\", CompareOp.EQ, True)\n    .execute()\n```\n\n### Aggregate Queries\n\n```python\n# Count\ncount = db.query(\"orders/\")\n    .where(\"status\", CompareOp.EQ, \"completed\")\n    .count()\n\n# Sum (for numeric columns)\ntotal = db.query(\"orders/\")\n    .sum(\"amount\")\n\n# Group by\nresults = db.query(\"orders/\")\n    .select([\"status\", \"COUNT(*)\", \"SUM(amount)\"])\n    .group_by(\"status\")\n    .execute()\n```\n\n### Query in Transaction\n\n```python\nwith db.transaction() as txn:\n    results = txn.query(\"users/\")\n        .where(\"role\", CompareOp.EQ, \"admin\")\n        .execute()\n```\n\n---\n\n## 7. Prefix Scanning\n\nIterate over keys with common prefixes efficiently.\n\n### Safe Prefix Scan (Recommended)\n\n```python\n# Requires minimum 2-byte prefix (prevents accidental full scans)\nfor key, value in db.scan_prefix(b\"users/\"):\n    print(f\"{key.decode()}: {value.decode()}\")\n\n# Raises ValueError if prefix \u003c 2 bytes\n```\n\n### Unchecked Prefix Scan\n\n```python\n# For internal operations needing empty/short prefixes\n# WARNING: Can cause expensive full-database scans\nfor key, value in db.scan_prefix_unchecked(b\"\"):\n    print(f\"All keys: {key}\")\n```\n\n### Batched Scanning (1000x Faster)\n\n```python\n# Fetches 1000 results per FFI call instead of 1\n# Performance: 10,000 results = 10 FFI calls vs 10,000 calls\n\nfor key, value in db.scan_batched(b\"prefix/\", batch_size=1000):\n    process(key, value)\n```\n\n### Reverse Scan\n\n```python\n# Scan in reverse order (newest first)\nfor key, value in db.scan_prefix(b\"logs/\", reverse=True):\n    print(key, value)\n```\n\n### Range Scan\n\n```python\n# Scan within a specific range\nfor key, value in db.scan_range(b\"users/a\", b\"users/m\"):\n    print(key, value)  # All users from \"a\" to \"m\"\n```\n\n### Streaming Large Results\n\n```python\n# For very large result sets, use streaming to avoid memory issues\nfor batch in db.scan_stream(b\"logs/\", batch_size=10000):\n    for key, value in batch:\n        process(key, value)\n    # Memory is freed after processing each batch\n```\n\n---\n\n## 8. SQL Operations\n\nExecute SQL queries for familiar relational patterns.\n\n### Creating Tables\n\n```python\ndb.execute_sql(\"\"\"\n    CREATE TABLE users (\n        id INTEGER PRIMARY KEY,\n        name TEXT NOT NULL,\n        email TEXT UNIQUE,\n        age INTEGER,\n        created_at TEXT DEFAULT CURRENT_TIMESTAMP\n    )\n\"\"\")\n\ndb.execute_sql(\"\"\"\n    CREATE TABLE posts (\n        id INTEGER PRIMARY KEY,\n        user_id INTEGER REFERENCES users(id),\n        title TEXT NOT NULL,\n        content TEXT,\n        likes INTEGER DEFAULT 0\n    )\n\"\"\")\n```\n\n### CRUD Operations\n\n```python\n# Insert\ndb.execute_sql(\"\"\"\n    INSERT INTO users (id, name, email, age) \n    VALUES (1, 'Alice', 'alice@example.com', 30)\n\"\"\")\n\n# Insert with parameters (prevents SQL injection)\ndb.execute_sql(\n    \"INSERT INTO users (id, name, email, age) VALUES (?, ?, ?, ?)\",\n    params=[2, \"Bob\", \"bob@example.com\", 25]\n)\n\n# Select\nresult = db.execute_sql(\"SELECT * FROM users WHERE age \u003e 25\")\nfor row in result.rows:\n    print(row)  # {'id': 1, 'name': 'Alice', ...}\n\n# Update\ndb.execute_sql(\"UPDATE users SET email = 'alice.new@example.com' WHERE id = 1\")\n\n# Delete\ndb.execute_sql(\"DELETE FROM users WHERE id = 2\")\n```\n\n### Upsert (Insert or Update)\n\n```python\n# Insert or update on conflict\ndb.execute_sql(\"\"\"\n    INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')\n    ON CONFLICT (id) DO UPDATE SET \n        name = excluded.name,\n        email = excluded.email\n\"\"\")\n```\n\n### Query Results\n\n```python\nfrom sochdb import SQLQueryResult\n\nresult = db.execute_sql(\"SELECT id, name FROM users\")\n\nprint(f\"Columns: {result.columns}\")      # ['id', 'name']\nprint(f\"Row count: {len(result.rows)}\")\nprint(f\"Execution time: {result.execution_time_ms}ms\")\n\nfor row in result.rows:\n    print(f\"ID: {row['id']}, Name: {row['name']}\")\n\n# Convert to different formats\ndf = result.to_dataframe()  # pandas DataFrame\njson_data = result.to_json()\n```\n\n### Index Management\n\n```python\n# Create index\ndb.execute_sql(\"CREATE INDEX idx_users_email ON users(email)\")\n\n# Create unique index\ndb.execute_sql(\"CREATE UNIQUE INDEX idx_users_email ON users(email)\")\n\n# Drop index\ndb.execute_sql(\"DROP INDEX IF EXISTS idx_users_email\")\n\n# List indexes\nindexes = db.list_indexes(\"users\")\n```\n\n### Prepared Statements\n\n```python\n# Prepare once, execute many times\nstmt = db.prepare(\"SELECT * FROM users WHERE age \u003e ? AND status = ?\")\n\n# Execute with different parameters\nyoung_active = stmt.execute([25, \"active\"])\nold_active = stmt.execute([50, \"active\"])\n\n# Close when done\nstmt.close()\n```\n\n### Dialect Support\n\nSochDB auto-detects SQL dialects:\n\n```python\n# PostgreSQL style\ndb.execute_sql(\"INSERT INTO users VALUES (1, 'Alice') ON CONFLICT DO NOTHING\")\n\n# MySQL style\ndb.execute_sql(\"INSERT IGNORE INTO users VALUES (1, 'Alice')\")\n\n# SQLite style  \ndb.execute_sql(\"INSERT OR IGNORE INTO users VALUES (1, 'Alice')\")\n```\n\n---\n\n## 9. Table Management \u0026 Index Policies\n\n### Table Information\n\n```python\n# Get table schema\nschema = db.get_table_schema(\"users\")\nprint(f\"Columns: {schema.columns}\")\nprint(f\"Primary key: {schema.primary_key}\")\nprint(f\"Indexes: {schema.indexes}\")\n\n# List all tables\ntables = db.list_tables()\n\n# Drop table\ndb.execute_sql(\"DROP TABLE IF EXISTS old_table\")\n```\n\n### Index Policies\n\nConfigure per-table indexing strategies for optimal performance:\n\n```python\n# Policy constants\nDatabase.INDEX_WRITE_OPTIMIZED  # 0 - O(1) insert, O(N) scan\nDatabase.INDEX_BALANCED         # 1 - O(1) amortized insert, O(log K) scan\nDatabase.INDEX_SCAN_OPTIMIZED   # 2 - O(log N) insert, O(log N + K) scan\nDatabase.INDEX_APPEND_ONLY      # 3 - O(1) insert, O(N) scan (time-series)\n\n# Set by constant\ndb.set_table_index_policy(\"logs\", Database.INDEX_APPEND_ONLY)\n\n# Set by string\ndb.set_table_index_policy(\"users\", \"scan_optimized\")\n\n# Get current policy\npolicy = db.get_table_index_policy(\"users\")\nprint(f\"Policy: {policy}\")  # \"scan_optimized\"\n```\n\n### Policy Selection Guide\n\n| Policy | Insert | Scan | Best For |\n|--------|--------|------|----------|\n| `write_optimized` | O(1) | O(N) | High-write ingestion |\n| `balanced` | O(1) amortized | O(log K) | General use (default) |\n| `scan_optimized` | O(log N) | O(log N + K) | Analytics, read-heavy |\n| `append_only` | O(1) | O(N) | Time-series, logs |\n\n---\n\n## 10. Namespaces \u0026 Multi-Tenancy\n\nOrganize data into logical namespaces for tenant isolation.\n\n### Creating Namespaces\n\n```python\nfrom sochdb import NamespaceConfig\n\n# Create namespace with metadata\nns = db.create_namespace(\n    name=\"tenant_123\",\n    display_name=\"Acme Corp\",\n    labels={\"tier\": \"premium\", \"region\": \"us-east\"}\n)\n\n# Simple creation\nns = db.create_namespace(\"tenant_456\")\n```\n\n### Getting Namespaces\n\n```python\n# Get existing namespace\nns = db.namespace(\"tenant_123\")\n\n# Get or create (idempotent)\nns = db.get_or_create_namespace(\"tenant_123\")\n\n# Check if exists\nexists = db.namespace_exists(\"tenant_123\")\n```\n\n### Context Manager for Scoped Operations\n\n```python\nwith db.use_namespace(\"tenant_123\") as ns:\n    # All operations automatically scoped to tenant_123\n    collection = ns.collection(\"documents\")\n    ns.put(\"config/key\", b\"value\")\n    \n    # No need to specify namespace in each call\n```\n\n### Namespace Operations\n\n```python\n# List all namespaces\nnamespaces = db.list_namespaces()\nprint(namespaces)  # ['tenant_123', 'tenant_456']\n\n# Get namespace info\ninfo = db.namespace_info(\"tenant_123\")\nprint(f\"Created: {info['created_at']}\")\nprint(f\"Labels: {info['labels']}\")\nprint(f\"Size: {info['size_bytes']}\")\n\n# Update labels\ndb.update_namespace(\"tenant_123\", labels={\"tier\": \"enterprise\"})\n\n# Delete namespace (WARNING: deletes all data in namespace)\ndb.delete_namespace(\"old_tenant\", force=True)\n```\n\n### Namespace-Scoped Key-Value\n\n```python\nns = db.namespace(\"tenant_123\")\n\n# Operations automatically prefixed with namespace\nns.put(\"users/alice\", b\"data\")      # Actually: tenant_123/users/alice\nns.get(\"users/alice\")\nns.delete(\"users/alice\")\n\n# Scan within namespace\nfor key, value in ns.scan(\"users/\"):\n    print(key, value)  # Keys shown without namespace prefix\n```\n\n### Cross-Namespace Operations\n\n```python\n# Copy data between namespaces\ndb.copy_between_namespaces(\n    source_ns=\"tenant_123\",\n    target_ns=\"tenant_456\",\n    prefix=\"shared/\"\n)\n```\n\n---\n\n## 11. Collections \u0026 Vector Search\n\nCollections store documents with embeddings for semantic search using HNSW.\n\n**Strategy note:** HNSW is the default, correctness‑first navigator (training‑free, robust under updates). A learned navigator (CHN) is only supported behind a feature gate with strict acceptance checks (recall@k, worst‑case fallback to HNSW, and drift detection). This keeps production behavior stable while allowing controlled experimentation.\n\n### Collection Configuration\n\n```python\nfrom sochdb import (\n    CollectionConfig,\n    DistanceMetric,\n    QuantizationType,\n)\n\nconfig = CollectionConfig(\n    name=\"documents\",\n    dimension=384,                          # Embedding dimension (must match your model)\n    metric=DistanceMetric.COSINE,           # COSINE, EUCLIDEAN, DOT_PRODUCT\n    m=16,                                   # HNSW M parameter (connections per node)\n    ef_construction=100,                    # HNSW construction quality\n    ef_search=50,                           # HNSW search quality (higher = slower but better)\n    quantization=QuantizationType.NONE,     # NONE, SCALAR (int8), PQ (product quantization)\n    enable_hybrid_search=False,             # Enable BM25 + vector\n    content_field=None,                     # Field for BM25 indexing\n)\n```\n\n### Creating Collections\n\n```python\nns = db.namespace(\"default\")\n\n# With config object\ncollection = ns.create_collection(config)\n\n# With parameters (simpler)\ncollection = ns.create_collection(\n    name=\"documents\",\n    dimension=384,\n    metric=DistanceMetric.COSINE\n)\n\n# Get existing collection\ncollection = ns.collection(\"documents\")\n```\n\n### API Methods Overview\n\n| Method | Purpose | Usage |\n|--------|---------|-------|\n| `add(ids, embeddings/vectors, metadatas)` | Bulk insert/update | Batch operations |\n| `upsert(ids, embeddings/vectors, metadatas)` | Insert or update | Batch upsert |\n| `query(query_embeddings, n_results, where)` | Search vectors | Standard query |\n| `insert(id, vector, metadata)` | Single insert | Single document |\n| `insert_batch(ids, vectors, metadatas)` | Bulk insert | Batch insert |\n| `search(SearchRequest)` | Advanced search | Full control |\n| `vector_search(vector, k, filter)` | Vector similarity | Convenience method |\n| `keyword_search(query, k, filter)` | BM25 search | Text search |\n| `hybrid_search(vector, text_query, k, alpha)` | Vector + BM25 | Combined search |\n\n### Adding Documents\n\n```python\n# Single insert\ncollection.insert(\n    id=\"doc1\",\n    vector=[0.1, 0.2, ...],  # 384-dim float array\n    metadata={\"title\": \"Introduction\", \"author\": \"Alice\", \"category\": \"tech\"}\n)\n\n# Batch add\ncollection.add(\n    ids=[\"doc1\", \"doc2\", \"doc3\"],\n    embeddings=[[...], [...], [...]],  # or vectors=[[...], ...]\n    metadatas=[\n        {\"title\": \"Doc 1\"},\n        {\"title\": \"Doc 2\"},\n        {\"title\": \"Doc 3\"}\n    ]\n)\n\n# Upsert (insert or update)\ncollection.upsert(\n    ids=[\"doc1\", \"doc2\"],\n    embeddings=[[...], [...]],  # or vectors=[[...], ...]\n    metadatas=[{\"title\": \"Updated Doc 1\"}, {\"title\": \"Updated Doc 2\"}]\n)\n\n# Batch insert (alternative API)\ncollection.insert_batch(\n    ids=[\"doc1\", \"doc2\", \"doc3\"],\n    vectors=[[...], [...], [...]],\n    metadatas=[\n        {\"title\": \"Doc 1\"},\n        {\"title\": \"Doc 2\"},\n        {\"title\": \"Doc 3\"}\n    ]\n)\n\n# Multi-vector insert (multiple vectors per document, e.g., chunks)\ncollection.insert_multi(\n    id=\"long_doc\",\n    vectors=[[...], [...], [...]],  # Multiple vectors for same doc\n    metadata={\"title\": \"Long Document\"}\n)\n```\n\n### Vector Search\n\n```python\nfrom sochdb import SearchRequest\n\n# Query API\nresults = collection.query(\n    query_embeddings=[[0.15, 0.25, ...]],  # or query_vectors\n    n_results=10,\n    where={\"author\": \"Alice\"}  # metadata filter\n)\n# Returns: {\"ids\": [[...]], \"distances\": [[...]], \"metadatas\": [[...]]}\n\n# Using SearchRequest (full control)\nrequest = SearchRequest(\n    vector=[0.15, 0.25, ...],       # Query vector\n    k=10,                           # Number of results\n    filter={\"author\": \"Alice\"},     # Metadata filter\n    min_score=0.7,                  # Minimum similarity score\n    include_vectors=False,          # Include vectors in results\n    include_metadata=True,          # Include metadata in results\n)\nresults = collection.search(request)\n\n# Convenience method (simpler)\nresults = collection.vector_search(\n    vector=[0.15, 0.25, ...],\n    k=10,\n    filter={\"author\": \"Alice\"}\n)\n\n# Process results (SearchResults object)\nfor result in results:\n    print(f\"ID: {result.id}\")\n    print(f\"Score: {result.score:.4f}\")  # Similarity score\n    print(f\"Metadata: {result.metadata}\")\n```\n\n### Metadata Filtering\n\n```python\n# Equality\nfilter={\"author\": \"Alice\"}\n\n# Comparison operators\nfilter={\"age\": {\"$gt\": 30}}              # Greater than\nfilter={\"age\": {\"$gte\": 30}}             # Greater than or equal\nfilter={\"age\": {\"$lt\": 30}}              # Less than\nfilter={\"age\": {\"$lte\": 30}}             # Less than or equal\nfilter={\"author\": {\"$ne\": \"Alice\"}}      # Not equal\n\n# Array operators\nfilter={\"category\": {\"$in\": [\"tech\", \"science\"]}}    # In array\nfilter={\"category\": {\"$nin\": [\"sports\"]}}            # Not in array\n\n# Logical operators\nfilter={\"$and\": [{\"author\": \"Alice\"}, {\"year\": 2024}]}\nfilter={\"$or\": [{\"category\": \"tech\"}, {\"category\": \"science\"}]}\nfilter={\"$not\": {\"author\": \"Bob\"}}\n\n# Nested filters\nfilter={\n    \"$and\": [\n        {\"$or\": [{\"category\": \"tech\"}, {\"category\": \"science\"}]},\n        {\"year\": {\"$gte\": 2020}}\n    ]\n}\n```\n\n### Collection Management\n\n```python\n# Get collection\ncollection = ns.get_collection(\"documents\")\n# or\ncollection = ns.collection(\"documents\")\n\n# List collections\ncollections = ns.list_collections()\n\n# Collection info\ninfo = collection.info()\nprint(f\"Name: {info['name']}\")\nprint(f\"Dimension: {info['dimension']}\")\nprint(f\"Count: {info['count']}\")\nprint(f\"Metric: {info['metric']}\")\nprint(f\"Index size: {info['index_size_bytes']}\")\n\n# Delete collection\nns.delete_collection(\"old_collection\")\n\n# Individual document operations\ndoc = collection.get(\"doc1\")\ncollection.delete(\"doc1\")\ncollection.update(\"doc1\", metadata={\"category\": \"updated\"})\ncount = collection.count()\n```\n\n### Quantization for Memory Efficiency\n\n```python\n# Scalar quantization (int8) - 4x memory reduction\nconfig = CollectionConfig(\n    name=\"documents\",\n    dimension=384,\n    quantization=QuantizationType.SCALAR\n)\n\n# Product quantization - 32x memory reduction\nconfig = CollectionConfig(\n    name=\"documents\",\n    dimension=768,\n    quantization=QuantizationType.PQ,\n    pq_num_subvectors=96,   # 768/96 = 8 dimensions per subvector\n    pq_num_centroids=256    # 8-bit codes\n)\n```\n\n---\n\n## 12. Hybrid Search (Vector + BM25)\n\nCombine vector similarity with keyword matching for best results.\n\n### Enable Hybrid Search\n\n```python\nconfig = CollectionConfig(\n    name=\"articles\",\n    dimension=384,\n    enable_hybrid_search=True,      # Enable BM25 indexing\n    content_field=\"text\"            # Field to index for BM25\n)\ncollection = ns.create_collection(config)\n\n# Insert with text content (supports add() or insert())\ncollection.add(\n    ids=[\"article1\"],\n    embeddings=[[...]],\n    metadatas=[{\n        \"title\": \"Machine Learning Tutorial\",\n        \"text\": \"This tutorial covers the basics of machine learning...\",\n        \"category\": \"tech\"\n    }]\n)\n\n# Or use insert for single document\ncollection.insert(\n    id=\"article2\",\n    vector=[...],\n    metadata={\n        \"title\": \"Deep Learning Basics\",\n        \"text\": \"Introduction to neural networks...\",\n        \"category\": \"tech\"\n    }\n)\n```\n\n### Keyword Search (BM25 Only)\n\n```python\nresults = collection.keyword_search(\n    query=\"machine learning tutorial\",\n    k=10,\n    filter={\"category\": \"tech\"}\n)\n```\n\n### Hybrid Search (Vector + BM25)\n\n```python\n# Combine vector and keyword search\nresults = collection.hybrid_search(\n    vector=[0.1, 0.2, ...],        # Query embedding\n    text_query=\"machine learning\",  # Keyword query\n    k=10,\n    alpha=0.7,  # 0.0 = pure keyword, 1.0 = pure vector, 0.5 = balanced\n    filter={\"category\": \"tech\"}\n)\n```\n\n### Full SearchRequest for Hybrid\n\n```python\nrequest = SearchRequest(\n    vector=[0.1, 0.2, ...],\n    text_query=\"machine learning\",\n    k=10,\n    alpha=0.7,                      # Blend factor\n    rrf_k=60.0,                     # RRF k parameter (Reciprocal Rank Fusion)\n    filter={\"category\": \"tech\"},\n    aggregate=\"max\",                # max | mean | first (for multi-vector docs)\n    as_of=\"2024-01-01T00:00:00Z\",   # Time-travel query\n    include_vectors=False,\n    include_metadata=True,\n    include_scores=True,\n)\nresults = collection.search(request)\n\n# Access detailed results\nprint(f\"Query time: {results.query_time_ms}ms\")\nprint(f\"Total matches: {results.total_count}\")\nprint(f\"Vector results: {results.vector_results}\")    # Results from vector search\nprint(f\"Keyword results: {results.keyword_results}\")  # Results from BM25\nprint(f\"Fused results: {results.fused_results}\")      # Combined results\n```\n\n---\n\n## 13. Graph Operations\n\nBuild and query knowledge graphs.\n\n### Adding Nodes\n\n```python\n# Add a node\ndb.add_node(\n    namespace=\"default\",\n    node_id=\"alice\",\n    node_type=\"person\",\n    properties={\"role\": \"engineer\", \"team\": \"ml\", \"level\": \"senior\"}\n)\n\ndb.add_node(\"default\", \"project_x\", \"project\", {\"status\": \"active\", \"priority\": \"high\"})\ndb.add_node(\"default\", \"bob\", \"person\", {\"role\": \"manager\", \"team\": \"ml\"})\n```\n\n### Adding Edges\n\n```python\n# Add directed edge\ndb.add_edge(\n    namespace=\"default\",\n    from_id=\"alice\",\n    edge_type=\"works_on\",\n    to_id=\"project_x\",\n    properties={\"role\": \"lead\", \"since\": \"2024-01\"}\n)\n\ndb.add_edge(\"default\", \"alice\", \"reports_to\", \"bob\")\ndb.add_edge(\"default\", \"bob\", \"manages\", \"project_x\")\n```\n\n### Graph Traversal\n\n```python\n# BFS traversal from a starting node\nnodes, edges = db.traverse(\n    namespace=\"default\",\n    start_node=\"alice\",\n    max_depth=3,\n    order=\"bfs\"  # \"bfs\" or \"dfs\"\n)\n\nfor node in nodes:\n    print(f\"Node: {node['id']} ({node['node_type']})\")\n    print(f\"  Properties: {node['properties']}\")\n    \nfor edge in edges:\n    print(f\"{edge['from_id']} --{edge['edge_type']}--\u003e {edge['to_id']}\")\n```\n\n### Filtered Traversal\n\n```python\n# Traverse with filters\nnodes, edges = db.traverse(\n    namespace=\"default\",\n    start_node=\"alice\",\n    max_depth=2,\n    edge_types=[\"works_on\", \"reports_to\"],  # Only follow these edge types\n    node_types=[\"person\", \"project\"],        # Only include these node types\n    node_filter={\"team\": \"ml\"}               # Filter nodes by properties\n)\n```\n\n### Graph Queries\n\n```python\n# Find shortest path\npath = db.find_path(\n    namespace=\"default\",\n    from_id=\"alice\",\n    to_id=\"project_y\",\n    max_depth=5\n)\n\n# Get neighbors\nneighbors = db.get_neighbors(\n    namespace=\"default\",\n    node_id=\"alice\",\n    direction=\"outgoing\"  # \"outgoing\", \"incoming\", \"both\"\n)\n\n# Get specific edge\nedge = db.get_edge(\"default\", \"alice\", \"works_on\", \"project_x\")\n\n# Delete node (and all connected edges)\ndb.delete_node(\"default\", \"old_node\")\n\n# Delete edge\ndb.delete_edge(\"default\", \"alice\", \"works_on\", \"project_old\")\n```\n\n---\n\n## 14. Temporal Graph (Time-Travel)\n\nTrack state changes over time with temporal edges.\n\n### Adding Temporal Edges\n\n```python\nimport time\n\nnow = int(time.time() * 1000)  # milliseconds since epoch\none_hour = 60 * 60 * 1000\n\n# Record: Door was open from 10:00 to 11:00\ndb.add_temporal_edge(\n    namespace=\"smart_home\",\n    from_id=\"door_front\",\n    edge_type=\"STATE\",\n    to_id=\"open\",\n    valid_from=now - one_hour,  # Start time (ms)\n    valid_until=now,             # End time (ms)\n    properties={\"sensor\": \"motion_1\", \"confidence\": 0.95}\n)\n\n# Record: Light is currently on (no end time yet)\ndb.add_temporal_edge(\n    namespace=\"smart_home\",\n    from_id=\"light_living\",\n    edge_type=\"STATE\",\n    to_id=\"on\",\n    valid_from=now,\n    valid_until=0,  # 0 = still valid (no end time)\n    properties={\"brightness\": \"80%\", \"color\": \"warm\"}\n)\n```\n\n### Time-Travel Queries\n\n```python\n# Query modes:\n# - \"CURRENT\": Edges valid right now\n# - \"POINT_IN_TIME\": Edges valid at specific timestamp\n# - \"RANGE\": All edges within a time range\n\n# What is the current state?\nedges = db.query_temporal_graph(\n    namespace=\"smart_home\",\n    node_id=\"door_front\",\n    mode=\"CURRENT\",\n    edge_type=\"STATE\"\n)\ncurrent_state = edges[0][\"to_id\"] if edges else \"unknown\"\n\n# Was the door open 1.5 hours ago?\nedges = db.query_temporal_graph(\n    namespace=\"smart_home\",\n    node_id=\"door_front\",\n    mode=\"POINT_IN_TIME\",\n    timestamp=now - int(1.5 * 60 * 60 * 1000)\n)\nwas_open = any(e[\"to_id\"] == \"open\" for e in edges)\n\n# All state changes in last hour\nedges = db.query_temporal_graph(\n    namespace=\"smart_home\",\n    node_id=\"door_front\",\n    mode=\"RANGE\",\n    start_time=now - one_hour,\n    end_time=now\n)\nfor edge in edges:\n    print(f\"State: {edge['to_id']} from {edge['valid_from']} to {edge['valid_until']}\")\n```\n\n### End a Temporal Edge\n\n```python\n# Close the current \"on\" state\ndb.end_temporal_edge(\n    namespace=\"smart_home\",\n    from_id=\"light_living\",\n    edge_type=\"STATE\",\n    to_id=\"on\",\n    end_time=int(time.time() * 1000)\n)\n```\n\n---\n\n## 15. Semantic Cache\n\nCache LLM responses with similarity-based retrieval for cost savings.\n\n### Storing Cached Responses\n\n```python\n# Store response with embedding\ndb.cache_put(\n    cache_name=\"llm_responses\",\n    key=\"What is Python?\",           # Original query (for display/debugging)\n    value=\"Python is a high-level programming language...\",\n    embedding=[0.1, 0.2, ...],       # Query embedding (384-dim)\n    ttl_seconds=3600,                # Expire in 1 hour (0 = no expiry)\n    metadata={\"model\": \"claude-3\", \"tokens\": 150}\n)\n```\n\n### Cache Lookup\n\n```python\n# Check cache before calling LLM\ncached = db.cache_get(\n    cache_name=\"llm_responses\",\n    query_embedding=[0.12, 0.18, ...],  # Embed the new query\n    threshold=0.85                       # Cosine similarity threshold\n)\n\nif cached:\n    print(f\"Cache HIT!\")\n    print(f\"Original query: {cached['key']}\")\n    print(f\"Response: {cached['value']}\")\n    print(f\"Similarity: {cached['score']:.4f}\")\nelse:\n    print(\"Cache MISS - calling LLM...\")\n    # Call LLM and cache the result\n```\n\n### Cache Management\n\n```python\n# Delete specific entry\ndb.cache_delete(\"llm_responses\", key=\"What is Python?\")\n\n# Clear entire cache\ndb.cache_clear(\"llm_responses\")\n\n# Get cache statistics\nstats = db.cache_stats(\"llm_responses\")\nprint(f\"Total entries: {stats['count']}\")\nprint(f\"Hit rate: {stats['hit_rate']:.2%}\")\nprint(f\"Memory usage: {stats['size_bytes']}\")\n```\n\n### Full Usage Pattern\n\n```python\ndef get_llm_response(query: str, embed_fn, llm_fn):\n    \"\"\"Get response from cache or LLM.\"\"\"\n    query_embedding = embed_fn(query)\n    \n    # Try cache first\n    cached = db.cache_get(\n        cache_name=\"llm_responses\",\n        query_embedding=query_embedding,\n        threshold=0.90\n    )\n    \n    if cached:\n        return cached['value']\n    \n    # Cache miss - call LLM\n    response = llm_fn(query)\n    \n    # Store in cache\n    db.cache_put(\n        cache_name=\"llm_responses\",\n        key=query,\n        value=response,\n        embedding=query_embedding,\n        ttl_seconds=86400  # 24 hours\n    )\n    \n    return response\n```\n\n---\n\n## 16. Context Query Builder (LLM Optimization)\n\nAssemble LLM context with token budgeting and priority-based truncation.\n\n### Basic Context Query\n\n```python\nfrom sochdb import ContextQueryBuilder, ContextFormat, TruncationStrategy\n\n# Build context for LLM\ncontext = ContextQueryBuilder() \\\n    .for_session(\"session_123\") \\\n    .with_budget(4096) \\\n    .format(ContextFormat.TOON) \\\n    .literal(\"SYSTEM\", priority=0, text=\"You are a helpful assistant.\") \\\n    .section(\"USER_PROFILE\", priority=1) \\\n        .get(\"user.profile.{name, preferences}\") \\\n        .done() \\\n    .section(\"HISTORY\", priority=2) \\\n        .last(10, \"messages\") \\\n        .where_eq(\"session_id\", \"session_123\") \\\n        .done() \\\n    .section(\"KNOWLEDGE\", priority=3) \\\n        .search(\"documents\", \"$query_embedding\", k=5) \\\n        .done() \\\n    .execute()\n\nprint(f\"Token count: {context.token_count}\")\nprint(f\"Context:\\n{context.text}\")\n```\n\n### Section Types\n\n| Type | Method | Description |\n|------|--------|-------------|\n| `literal` | `.literal(name, priority, text)` | Static text content |\n| `get` | `.get(path)` | Fetch specific data by path |\n| `last` | `.last(n, table)` | Most recent N records from table |\n| `search` | `.search(collection, embedding, k)` | Vector similarity search |\n| `sql` | `.sql(query)` | SQL query results |\n\n### Truncation Strategies\n\n```python\n# Drop from end (keep beginning) - default\n.truncation(TruncationStrategy.TAIL_DROP)\n\n# Drop from beginning (keep end)\n.truncation(TruncationStrategy.HEAD_DROP)\n\n# Proportionally truncate across sections\n.truncation(TruncationStrategy.PROPORTIONAL)\n\n# Fail if budget exceeded\n.truncation(TruncationStrategy.STRICT)\n```\n\n### Variables and Bindings\n\n```python\nfrom sochdb import ContextValue\n\ncontext = ContextQueryBuilder() \\\n    .for_session(\"session_123\") \\\n    .set_var(\"query_embedding\", ContextValue.Embedding([0.1, 0.2, ...])) \\\n    .set_var(\"user_id\", ContextValue.String(\"user_456\")) \\\n    .section(\"KNOWLEDGE\", priority=2) \\\n        .search(\"documents\", \"$query_embedding\", k=5) \\\n        .done() \\\n    .execute()\n```\n\n### Output Formats\n\n```python\n# TOON format (40-60% fewer tokens)\n.format(ContextFormat.TOON)\n\n# JSON format\n.format(ContextFormat.JSON)\n\n# Markdown format (human-readable)\n.format(ContextFormat.MARKDOWN)\n\n# Plain text\n.format(ContextFormat.TEXT)\n```\n\n\n## Session Management (Agent Context)\n\nStateful session management for agentic use cases with permissions, sandboxing, audit logging, and budget tracking.\n\n### Session Overview\n\n```\nAgent session abc123:\n  cwd: /agents/abc123\n  vars: $model = \"gpt-4\", $budget = 1000\n  permissions: fs:rw, db:rw, calc:*\n  audit: [read /data/users, write /agents/abc123/cache]\n```\n\n### Creating Sessions\n\n```python\nfrom sochdb import SessionManager, AgentContext\nfrom datetime import timedelta\n\n# Create session manager with idle timeout\nsession_mgr = SessionManager(idle_timeout=timedelta(hours=1))\n\n# Create a new session\nsession = session_mgr.create_session(\"session_abc123\")\n\n# Get existing session\nsession = session_mgr.get_session(\"session_abc123\")\n\n# Get or create (idempotent)\nsession = session_mgr.get_or_create(\"session_abc123\")\n\n# Remove session\nsession_mgr.remove_session(\"session_abc123\")\n\n# Cleanup expired sessions\nremoved_count = session_mgr.cleanup_expired()\n\n# Get active session count\ncount = session_mgr.session_count()\n```\n\n### Agent Context\n\n```python\nfrom sochdb import AgentContext, ContextValue\n\n# Create agent context\nctx = AgentContext(\"session_abc123\")\nprint(f\"Session ID: {ctx.session_id}\")\nprint(f\"Working dir: {ctx.working_dir}\")  # /agents/session_abc123\n\n# Create with custom working directory\nctx = AgentContext.with_working_dir(\"session_abc123\", \"/custom/path\")\n\n# Create with full permissions (trusted agents)\nctx = AgentContext.with_full_permissions(\"session_abc123\")\n```\n\n### Session Variables\n\n```python\n# Set variables\nctx.set_var(\"model\", ContextValue.String(\"gpt-4\"))\nctx.set_var(\"budget\", ContextValue.Number(1000.0))\nctx.set_var(\"debug\", ContextValue.Bool(True))\nctx.set_var(\"tags\", ContextValue.List([\n    ContextValue.String(\"ml\"),\n    ContextValue.String(\"production\")\n]))\n\n# Get variables\nmodel = ctx.get_var(\"model\")  # Returns ContextValue or None\nbudget = ctx.get_var(\"budget\")\n\n# Peek (read-only, no audit)\nvalue = ctx.peek_var(\"model\")\n\n# Variable substitution in strings\ntext = ctx.substitute_vars(\"Using $model with budget $budget\")\n# Result: \"Using gpt-4 with budget 1000\"\n```\n\n### Context Value Types\n\n```python\nfrom sochdb import ContextValue\n\n# String\nContextValue.String(\"hello\")\n\n# Number (float)\nContextValue.Number(42.5)\n\n# Boolean\nContextValue.Bool(True)\n\n# List\nContextValue.List([\n    ContextValue.String(\"a\"),\n    ContextValue.Number(1.0)\n])\n\n# Object (dict)\nContextValue.Object({\n    \"key\": ContextValue.String(\"value\"),\n    \"count\": ContextValue.Number(10.0)\n})\n\n# Null\nContextValue.Null()\n```\n\n### Permissions\n\n```python\nfrom sochdb import (\n    AgentPermissions,\n    FsPermissions,\n    DbPermissions,\n    NetworkPermissions\n)\n\n# Configure permissions\nctx.permissions = AgentPermissions(\n    filesystem=FsPermissions(\n        read=True,\n        write=True,\n        mkdir=True,\n        delete=False,\n        allowed_paths=[\"/agents/session_abc123\", \"/shared/data\"]\n    ),\n    database=DbPermissions(\n        read=True,\n        write=True,\n        create=False,\n        drop=False,\n        allowed_tables=[\"user_*\", \"cache_*\"]  # Pattern matching\n    ),\n    calculator=True,\n    network=NetworkPermissions(\n        http=True,\n        allowed_domains=[\"api.example.com\", \"*.internal.net\"]\n    )\n)\n\n# Check permissions before operations\ntry:\n    ctx.check_fs_permission(\"/agents/session_abc123/data.json\", AuditOperation.FS_READ)\n    # Permission granted\nexcept ContextError as e:\n    print(f\"Permission denied: {e}\")\n\ntry:\n    ctx.check_db_permission(\"user_profiles\", AuditOperation.DB_QUERY)\n    # Permission granted\nexcept ContextError as e:\n    print(f\"Permission denied: {e}\")\n```\n\n### Budget Tracking\n\n```python\nfrom sochdb import OperationBudget\n\n# Configure budget limits\nctx.budget = OperationBudget(\n    max_tokens=100000,        # Maximum tokens (input + output)\n    max_cost=5000,            # Maximum cost in millicents ($50.00)\n    max_operations=10000      # Maximum operation count\n)\n\n# Consume budget (called automatically by operations)\ntry:\n    ctx.consume_budget(tokens=500, cost=10)  # 500 tokens, $0.10\nexcept ContextError as e:\n    if \"Budget exceeded\" in str(e):\n        print(\"Budget limit reached!\")\n\n# Check budget status\nprint(f\"Tokens used: {ctx.budget.tokens_used}/{ctx.budget.max_tokens}\")\nprint(f\"Cost used: ${ctx.budget.cost_used / 100:.2f}/${ctx.budget.max_cost / 100:.2f}\")\nprint(f\"Operations: {ctx.budget.operations_used}/{ctx.budget.max_operations}\")\n```\n\n### Session Transactions\n\n```python\n# Begin transaction within session\nctx.begin_transaction(tx_id=12345)\n\n# Create savepoint\nctx.savepoint(\"before_update\")\n\n# Record pending writes (for rollback)\nctx.record_pending_write(\n    resource_type=ResourceType.FILE,\n    resource_key=\"/agents/session_abc123/data.json\",\n    original_value=b'{\"old\": \"data\"}'\n)\n\n# Commit transaction\nctx.commit_transaction()\n\n# Or rollback\npending_writes = ctx.rollback_transaction()\nfor write in pending_writes:\n    print(f\"Rolling back: {write.resource_key}\")\n    # Restore original_value\n```\n\n### Path Resolution\n\n```python\n# Paths are resolved relative to working directory\nctx = AgentContext.with_working_dir(\"session_abc123\", \"/home/agent\")\n\n# Relative paths\nresolved = ctx.resolve_path(\"data.json\")  # /home/agent/data.json\n\n# Absolute paths pass through\nresolved = ctx.resolve_path(\"/absolute/path\")  # /absolute/path\n```\n\n### Audit Trail\n\n```python\n# All operations are automatically logged\n# Audit entry includes: timestamp, operation, resource, result, metadata\n\n# Export audit log\naudit_log = ctx.export_audit()\nfor entry in audit_log:\n    print(f\"[{entry['timestamp']}] {entry['operation']}: {entry['resource']} -\u003e {entry['result']}\")\n\n# Example output:\n# [1705312345] var.set: model -\u003e success\n# [1705312346] fs.read: /data/config.json -\u003e success\n# [1705312347] db.query: users -\u003e success\n# [1705312348] fs.write: /forbidden/file -\u003e denied:path not in allowed paths\n```\n\n### Audit Operations\n\n```python\nfrom sochdb import AuditOperation\n\n# Filesystem operations\nAuditOperation.FS_READ\nAuditOperation.FS_WRITE\nAuditOperation.FS_MKDIR\nAuditOperation.FS_DELETE\nAuditOperation.FS_LIST\n\n# Database operations\nAuditOperation.DB_QUERY\nAuditOperation.DB_INSERT\nAuditOperation.DB_UPDATE\nAuditOperation.DB_DELETE\n\n# Other operations\nAuditOperation.CALCULATE\nAuditOperation.VAR_SET\nAuditOperation.VAR_GET\nAuditOperation.TX_BEGIN\nAuditOperation.TX_COMMIT\nAuditOperation.TX_ROLLBACK\n```\n\n### Tool Registry\n\n```python\nfrom sochdb import ToolDefinition, ToolCallRecord\nfrom datetime import datetime\n\n# Register tools available to the agent\nctx.register_tool(ToolDefinition(\n    name=\"search_documents\",\n    description=\"Search documents by semantic similarity\",\n    parameters_schema='{\"type\": \"object\", \"properties\": {\"query\": {\"type\": \"string\"}}}',\n    requires_confirmation=False\n))\n\nctx.register_tool(ToolDefinition(\n    name=\"delete_file\",\n    description=\"Delete a file from the filesystem\",\n    parameters_schema='{\"type\": \"object\", \"properties\": {\"path\": {\"type\": \"string\"}}}',\n    requires_confirmation=True  # Requires user confirmation\n))\n\n# Record tool calls\nctx.record_tool_call(ToolCallRecord(\n    call_id=\"call_001\",\n    tool_name=\"search_documents\",\n    arguments='{\"query\": \"machine learning\"}',\n    result='[{\"id\": \"doc1\", \"score\": 0.95}]',\n    error=None,\n    timestamp=datetime.now()\n))\n\n# Access tool call history\nfor call in ctx.tool_calls:\n    print(f\"{call.tool_name}: {call.result or call.error}\")\n```\n\n### Session Lifecycle\n\n```python\n# Check session age\nage = ctx.age()\nprint(f\"Session age: {age}\")\n\n# Check idle time\nidle = ctx.idle_time()\nprint(f\"Idle time: {idle}\")\n\n# Check if expired\nif ctx.is_expired(idle_timeout=timedelta(hours=1)):\n    print(\"Session has expired!\")\n```\n\n### Complete Session Example\n\n```python\nfrom sochdb import (\n    SessionManager, AgentContext, ContextValue,\n    AgentPermissions, FsPermissions, DbPermissions,\n    OperationBudget, ToolDefinition, AuditOperation\n)\nfrom datetime import timedelta\n\n# Initialize session manager\nsession_mgr = SessionManager(idle_timeout=timedelta(hours=2))\n\n# Create session for an agent\nsession_id = \"agent_session_12345\"\nctx = session_mgr.get_or_create(session_id)\n\n# Configure the agent\nctx.permissions = AgentPermissions(\n    filesystem=FsPermissions(\n        read=True,\n        write=True,\n        allowed_paths=[f\"/agents/{session_id}\", \"/shared\"]\n    ),\n    database=DbPermissions(\n        read=True,\n        write=True,\n        allowed_tables=[\"documents\", \"cache_*\"]\n    ),\n    calculator=True\n)\n\nctx.budget = OperationBudget(\n    max_tokens=50000,\n    max_cost=1000,  # $10.00\n    max_operations=1000\n)\n\n# Set initial variables\nctx.set_var(\"model\", ContextValue.String(\"claude-3-sonnet\"))\nctx.set_var(\"temperature\", ContextValue.Number(0.7))\n\n# Register available tools\nctx.register_tool(ToolDefinition(\n    name=\"vector_search\",\n    description=\"Search vectors by similarity\",\n    parameters_schema='{\"type\": \"object\", \"properties\": {\"query\": {\"type\": \"string\"}, \"k\": {\"type\": \"integer\"}}}',\n    requires_confirmation=False\n))\n\n# Perform operations with permission checks\ndef safe_read_file(ctx: AgentContext, path: str) -\u003e bytes:\n    resolved = ctx.resolve_path(path)\n    ctx.check_fs_permission(resolved, AuditOperation.FS_READ)\n    ctx.consume_budget(tokens=100, cost=1)\n    # ... actual file read ...\n    return b\"file contents\"\n\ndef safe_db_query(ctx: AgentContext, table: str, query: str):\n    ctx.check_db_permission(table, AuditOperation.DB_QUERY)\n    ctx.consume_budget(tokens=500, cost=5)\n    # ... actual query ...\n    return []\n\n# Use in transaction\nctx.begin_transaction(tx_id=1)\ntry:\n    # Operations here...\n    ctx.commit_transaction()\nexcept Exception as e:\n    ctx.rollback_transaction()\n    raise\n\n# Export audit trail for debugging/compliance\naudit = ctx.export_audit()\nprint(f\"Session performed {len(audit)} operations\")\n\n# Cleanup\nsession_mgr.cleanup_expired()\n```\n\n### Session Errors\n\n```python\nfrom sochdb import ContextError\n\ntry:\n    ctx.check_fs_permission(\"/forbidden\", AuditOperation.FS_READ)\nexcept ContextError as e:\n    if e.is_permission_denied():\n        print(f\"Permission denied: {e.message}\")\n    elif e.is_variable_not_found():\n        print(f\"Variable not found: {e.variable_name}\")\n    elif e.is_budget_exceeded():\n        print(f\"Budget exceeded: {e.budget_type}\")\n    elif e.is_transaction_error():\n        print(f\"Transaction error: {e.message}\")\n    elif e.is_invalid_path():\n        print(f\"Invalid path: {e.path}\")\n    elif e.is_session_expired():\n        print(\"Session has expired\")\n```\n---\n\n## 17. Priority Queue \u0026 Task Management\n\nSochDB provides a first-class priority queue implementation with atomic claim protocol for reliable distributed task processing. The queue supports both embedded (FFI) and server (gRPC) modes.\n\n### Features\n\n- **Priority-based ordering**: Tasks dequeued by priority, then ready time, then sequence\n- **Atomic claim protocol**: Linearizable claim semantics prevent double-delivery\n- **Visibility timeout**: Automatic retry for failed workers (at-least-once delivery)\n- **Delayed tasks**: Schedule tasks for future execution\n- **Batch operations**: Enqueue multiple tasks atomically\n- **Streaming Top-K**: O(N log K) selection for efficient ranking\n- **Dual-mode support**: Works with embedded Database or gRPC SochDBClient\n\n### Quick Start\n\n```python\nfrom sochdb import Database, PriorityQueue, create_queue\n\n# Create queue from database\ndb = Database.open(\"./queue_db\")\nqueue = PriorityQueue.from_database(db, \"my_queue\")\n\n# Or use convenience function (auto-detects backend)\nqueue = create_queue(db, \"my_queue\")\n\n# Enqueue tasks with priority\ntask_id1 = queue.enqueue(priority=10, payload=b\"high priority task\")\ntask_id2 = queue.enqueue(priority=1, payload=b\"low priority task\")\n\n# Dequeue tasks (highest priority first)\ntask = queue.dequeue(worker_id=\"worker-1\")\nif task:\n    print(f\"Processing: {task.payload}\")\n    # Process task...\n    queue.ack(task.task_id)  # Mark as completed\n```\n\n### Enqueue Operations\n\n```python\n# Simple enqueue with priority\ntask_id = queue.enqueue(\n    priority=10,\n    payload=b\"task data\",\n)\n\n# Delayed task (execute after 60 seconds)\ntask_id = queue.enqueue(\n    priority=5,\n    payload=b\"delayed task\",\n    delay_ms=60000,\n)\n\n# Batch enqueue (atomic)\ntask_ids = queue.enqueue_batch([\n    (10, b\"task 1\"),\n    (20, b\"task 2\"),\n    (15, b\"task 3\"),\n])\n```\n\n### Dequeue and Processing\n\n```python\n# Dequeue with automatic visibility timeout\ntask = queue.dequeue(worker_id=\"worker-1\")\n\nif task:\n    try:\n        # Process the task\n        result = process_task(task.payload)\n        \n        # Mark as successfully completed\n        queue.ack(task.task_id)\n        \n    except Exception as e:\n        # Return to queue for retry (optionally change priority)\n        queue.nack(\n            task_id=task.task_id,\n            new_priority=task.priority - 1  # Lower priority on retry\n        )\n```\n\n### Peek and Stats\n\n```python\n# Peek at next task without claiming\ntask = queue.peek()\nif task:\n    print(f\"Next task: {task.payload}, priority: {task.priority}\")\n\n# Get queue statistics\nstats = queue.stats()\nprint(f\"Pending: {stats['pending']}\")\nprint(f\"Claimed: {stats['claimed']}\")\nprint(f\"Total: {stats['total']}\")\n\n# List all tasks (for monitoring)\ntasks = queue.list_tasks(limit=100)\nfor task in tasks:\n    print(f\"Task {task.task_id}: priority={task.priority}, status={task.status}\")\n```\n\n### Configuration\n\n```python\nfrom sochdb import PriorityQueue, QueueConfig\n\n# Custom configuration\nconfig = QueueConfig(\n    queue_id=\"my_queue\",\n    visibility_timeout_ms=30000,  # 30 seconds\n    max_retries=3,\n    dead_letter_queue=\"dlq_queue\",\n)\n\nqueue = PriorityQueue.from_database(db, config=config)\n```\n\n### Worker Pattern\n\n```python\nimport time\n\ndef worker_loop(worker_id: str):\n    \"\"\"Simple worker loop.\"\"\"\n    while True:\n        task = queue.dequeue(worker_id=worker_id)\n        \n        if task:\n            try:\n                # Process task\n                result = process_task(task.payload)\n                queue.ack(task.task_id)\n                print(f\"✓ Completed task {task.task_id}\")\n                \n            except Exception as e:\n                print(f\"✗ Failed task {task.task_id}: {e}\")\n                queue.nack(task.task_id)\n        else:\n            # No tasks available, wait\n            time.sleep(1)\n\n# Start multiple workers\nfrom concurrent.futures import ThreadPoolExecutor\n\nwith ThreadPoolExecutor(max_workers=4) as executor:\n    for i in range(4):\n        executor.submit(worker_loop, f\"worker-{i}\")\n```\n\n### Streaming Top-K Selection\n\nThe queue includes a `StreamingTopK` utility for efficient ranking with O(N log K) complexity:\n\n```python\nfrom sochdb.queue import StreamingTopK\n\n# Create top-K selector (k=10, ascending order)\ntopk = StreamingTopK(k=10, ascending=True)\n\n# Process items one at a time\nfor score, item in candidates:\n    topk.push(item, key=lambda x: score)\n\n# Get sorted top-K results\nresults = topk.get_sorted()\n\n# With custom key function\ntopk = StreamingTopK(\n    k=5, \n    ascending=False,  # Descending (highest first)\n    key=lambda x: x['score']\n)\n\nfor item in items:\n    topk.push(item)\n\ntop_5 = topk.get_sorted()\n```\n\n### Server Mode (gRPC)\n\n```python\nfrom sochdb import SochDBClient, PriorityQueue\n\n# Connect to server\nclient = SochDBClient(\"localhost:50051\")\n\n# Create queue using gRPC backend\nqueue = PriorityQueue.from_client(client, \"distributed_queue\")\n\n# All operations work the same way\ntask_id = queue.enqueue(priority=10, payload=b\"server task\")\ntask = queue.dequeue(worker_id=\"worker-1\")\nif task:\n    queue.ack(task.task_id)\n```\n\n### Queue Backend Architecture\n\n```python\nfrom sochdb.queue import (\n    QueueBackend,\n    FFIQueueBackend,      # For embedded Database\n    GrpcQueueBackend,     # For SochDBClient\n    InMemoryQueueBackend, # For testing\n)\n\n# Use specific backend\nbackend = FFIQueueBackend(db)\nqueue = PriorityQueue.from_backend(backend, \"my_queue\")\n\n# Or use factory method (auto-detects)\nqueue = create_queue(db, \"my_queue\")  # Returns FFIQueueBackend\nqueue = create_queue(client, \"my_queue\")  # Returns GrpcQueueBackend\n```\n\n### Task Model\n\n```python\n# Task structure\nclass Task:\n    task_id: str           # Unique task identifier\n    priority: int          # Task priority (higher = more important)\n    ready_ts: int          # When task becomes ready (epoch millis)\n    sequence: int          # Sequence number for ordering\n    payload: bytes         # Task data\n    claim_token: Optional[ClaimToken]  # Proof of ownership\n    retry_count: int       # Number of retries\n    status: str           # 'pending', 'claimed', 'completed'\n\n# Claim token (for ack/nack operations)\nclass ClaimToken:\n    task_id: str\n    owner: str\n    instance: int\n    created_at: int\n    expires_at: int\n```\n\n### Best Practices\n\n**1. Choose appropriate visibility timeout:**\n```python\n# Short tasks (\u003c 10s)\nconfig = QueueConfig(visibility_timeout_ms=15000)  # 15s\n\n# Long tasks (minutes)\nconfig = QueueConfig(visibility_timeout_ms=300000)  # 5 minutes\n```\n\n**2. Handle idempotency:**\n```python\n# Tasks may be redelivered, design for idempotency\ndef process_task(payload):\n    task_id = extract_id(payload)\n    \n    # Check if already processed\n    if is_processed(task_id):\n        return  # Skip duplicate\n    \n    # Process and mark as done atomically\n    with db.transaction() as txn:\n        do_work(txn, payload)\n        mark_processed(txn, task_id)\n```\n\n**3. Use dead letter queue:**\n```python\nconfig = QueueConfig(\n    queue_id=\"main_queue\",\n    max_retries=3,\n    dead_letter_queue=\"dlq_main\",\n)\n\n# Monitor DLQ for failed tasks\ndlq = create_queue(db, \"dlq_main\")\nfailed_tasks = dlq.list_tasks()\n```\n\n**4. Batch operations for efficiency:**\n```python\n# Instead of individual enqueues\nfor item in items:\n    queue.enqueue(priority=1, payload=item)\n\n# Use batch enqueue\ntasks = [(1, item) for item in items]\nqueue.enqueue_batch(tasks)\n```\n\n### Performance\n\nBased on benchmarks with `InMemoryQueueBackend`:\n\n- **QueueKey encode/decode**: ~411K ops/s\n- **Enqueue**: ~31-83K ops/s (depends on queue size)\n- **Dequeue + Ack**: ~1K ops/s (includes claim protocol)\n- **StreamingTopK (n=10K, k=10)**: ~212 ops/s\n\n### Integration with Existing Features\n\n```python\n# Combine with transactions\nwith db.transaction() as txn:\n    # Update database\n    txn.put(b\"status:job1\", b\"queued\")\n    \n    # Enqueue task (outside transaction for reliability)\n    queue.enqueue(priority=10, payload=b\"job1\")\n\n# Combine with monitoring\nfrom sochdb import TraceStore\n\ntrace = TraceStore(db)\nspan = trace.start_span(\"process_queue_task\")\n\ntask = queue.dequeue(\"worker-1\")\nif task:\n    try:\n        process_task(task.payload)\n        queue.ack(task.task_id)\n        span.add_event(\"task_completed\")\n    finally:\n        span.finish()\n```\n\n---\n\n## 18. Memory System (LLM-Native)\n\nSochDB provides a complete memory system for AI agents with extraction, consolidation, retrieval, and namespace isolation. All components support both embedded (FFI) and server (gRPC) modes.\n\n### Features\n\n- **Extraction Pipeline**: Compile LLM outputs into typed, validated facts (Entity, Relation, Assertion)\n- **Event-Sourced Consolidation**: Append-only events with derived canonical facts (no destructive updates)\n- **Hybrid Retrieval**: RRF fusion with pre-filtering for multi-tenant safety\n- **Namespace Isolation**: Strong tenant isolation with explicit, auditable cross-namespace grants\n\n### Quick Start\n\n```python\nfrom sochdb import Database\nfrom sochdb.memory import (\n    Entity, Relation, Assertion,\n    ExtractionPipeline, Consolidator, HybridRetriever,\n    NamespaceManager, AllowedSet,\n)\n\n# Open database\ndb = Database.open(\"./memory_db\")\n\n# Create extraction pipeline\npipeline = ExtractionPipeline.from_database(db, namespace=\"user_123\")\n\n# Define an LLM extractor (your LLM integration)\ndef my_extractor(text):\n    # Call your LLM here and return structured output\n    return {\n        \"entities\": [\n            {\"name\": \"Alice\", \"entity_type\": \"person\"},\n            {\"name\": \"Acme Corp\", \"entity_type\": \"organization\"},\n        ],\n        \"relations\": [\n            {\"from_entity\": \"Alice\", \"relation_type\": \"works_at\", \"to_entity\": \"Acme Corp\"},\n        ],\n        \"assertions\": [\n            {\"subject\": \"Alice\", \"predicate\": \"role\", \"object\": \"Engineer\", \"confidence\": 0.95},\n        ],\n    }\n\n# Extract and commit\nresult = pipeline.extract_and_commit(\"Alice is an engineer at Acme Corp\", extractor=my_extractor)\nprint(f\"Extracted {len(result.entities)} entities, {len(result.relations)} relations\")\n```\n\n### Extraction Pipeline\n\nThe extraction pipeline compiles LLM outputs into typed, validated facts:\n\n```python\nfrom sochdb.memory import (\n    Entity, Relation, Assertion, ExtractionPipeline, ExtractionSchema\n)\n\n# Create with schema validation\nschema = ExtractionSchema(\n    entity_types=[\"person\", \"organization\", \"location\"],\n    relation_types=[\"works_at\", \"knows\", \"located_in\"],\n    min_confidence=0.5,\n)\n\npipeline = ExtractionPipeline.from_database(\n    db, \n    namespace=\"user_123\",\n    schema=schema,\n)\n\n# Extract entities and relations\nresult = pipeline.extract(\n    text=\"John works at Google in Mountain View\",\n    extractor=my_llm_extractor,\n)\n\n# Inspect before committing\nfor entity in result.entities:\n    print(f\"Entity: {entity.name} ({entity.entity_type})\")\n\nfor relation in result.relations:\n    print(f\"Relation: {relation.from_entity} --{relation.relation_type}--\u003e {relation.to_entity}\")\n\n# Commit atomically\npipeline.commit(result)\n```\n\n### Event-Sourced Consolidation\n\nConsolidation maintains append-only events and derives canonical facts without destructive updates:\n\n```python\nfrom sochdb.memory import Consolidator, RawAssertion, ConsolidationConfig\n\n# Create consolidator\nconfig = ConsolidationConfig(\n    similarity_threshold=0.85,\n    use_temporal_updates=True,\n)\nconsolidator = Consolidator.from_database(db, namespace=\"user_123\", config=config)\n\n# Add assertions (immutable events)\nassertion = RawAssertion(\n    id=\"\",  # Auto-generated\n    fact={\"subject\": \"Alice\", \"predicate\": \"lives_in\", \"object\": \"SF\"},\n    source=\"conversation_123\",\n    confidence=0.9,\n)\nconsolidator.add(assertion)\n\n# Handle contradictions (temporal interval update, not deletion)\nnew_assertion = RawAssertion(\n    id=\"\",\n    fact={\"subject\": \"Alice\", \"predicate\": \"lives_in\", \"object\": \"NYC\"},\n    source=\"conversation_456\",\n    confidence=0.95,\n)\nconsolidator.add_with_contradiction(\n    new_assertion=new_assertion,\n    contradicts=[\"old_assertion_id\"],\n)\n\n# Run consolidation (update canonical view)\nupdated_count = consolidator.consolidate()\n\n# Get canonical facts\nfacts = consolidator.get_canonical_facts()\nfor fact in facts:\n    print(f\"Fact: {fact.merged_fact}, confidence: {fact.confidence}\")\n\n# Explain provenance\nexplanation = consolidator.explain(fact_id=\"some_fact_id\")\nprint(f\"Evidence: {explanation['evidence_count']} supporting assertions\")\n```\n\n### Hybrid Retrieval with Pre-Filtering\n\nRetrieval uses RRF fusion with security-first pre-filtering:\n\n```python\nfrom sochdb.memory import HybridRetriever, AllowedSet, RetrievalConfig\n\n# Create retriever\nconfig = RetrievalConfig(\n    k=10,\n    alpha=0.5,  # Balance between vector (1.0) and keyword (0.0)\n    enable_rerank=False,\n)\nretriever = HybridRetriever.from_database(\n    db, \n    namespace=\"user_123\",\n    collection=\"documents\",\n    config=config,\n)\n\n# Retrieve with namespace isolation (security invariant)\nresponse = retriever.retrieve(\n    query_text=\"machine learning papers\",\n    query_vector=[0.1, 0.2, ...],  # Your embedding\n    allowed=AllowedSet.from_namespace(\"user_123\"),  # Pre-filter\n    k=10,\n)\n\nfor result in response.results:\n    print(f\"{result.id}: {result.score:.3f}\")\n\n# Explain ranking for debugging\nexplanation = retriever.explain(\n    query_text=\"machine learning\",\n    query_vector=[0.1, 0.2, ...],\n    doc_id=\"some_doc_id\",\n)\nprint(f\"Vector rank: {explanation.get('vector_rank')}\")\nprint(f\"Keyword rank: {explanation.get('keyword_rank')}\")\nprint(f\"Expected RRF score: {explanation.get('expected_rrf_score')}\")\n```\n\n### AllowedSet (Pre-Filtering)\n\n`AllowedSet` enforces the security invariant: `Results ⊆ allowed_set`\n\n```python\nfrom sochdb.memory import AllowedSet\n\n# Allow by explicit IDs\nallowed = AllowedSet.from_ids([\"doc1\", \"doc2\", \"doc3\"])\n\n# Allow by namespace prefix\nallowed = AllowedSet.from_namespace(\"user_123\")\n\n# Allow by custom filter function\nallowed = AllowedSet.from_filter(\n    lambda doc_id, metadata: metadata.get(\"tenant\") == \"acme\"\n)\n\n# Allow all (trusted context only)\nallowed = AllowedSet.allow_all()\n\n# Check membership\nprint(allowed.contains(\"user_123_doc1\"))  # True for namespace filter\n```\n\n### Namespace Isolation\n\nStrong multi-tenant isolation with explicit cross-namespace grants:\n\n```python\nfrom sochdb.memory import NamespaceManager, NamespacePolicy\n\n# Create namespace manager\nmanager = NamespaceManager.from_database(\n    db,\n    policy=NamespacePolicy.STRICT,  # No cross-namespace by default\n)\n\n# Create namespaces\nmanager.create(\"user_alice\", metadata={\"plan\": \"pro\"})\nmanager.create(\"user_bob\", metadata={\"plan\": \"free\"})\n\n# Get scoped interface (all operations isolated)\nalice_scope = manager.scope(\"user_alice\")\n\n# Operations are automatically scoped\nresponse = alice_scope.retrieve(query_text=\"my documents\")\n# Returns ONLY user_alice's documents (guaranteed)\n\n# Cross-namespace access (EXPLICIT policy required)\nmanager_explicit = NamespaceManager.from_database(\n    db,\n    policy=NamespacePolicy.EXPLICIT,\n)\n\ngrant = manager_explicit.create_grant(\n    from_namespace=\"user_alice\",\n    to_namespace=\"shared_docs\",\n    operations=[\"retrieve\"],\n    expires_in_seconds=3600,\n    reason=\"Collaboration project\",\n)\n\nalice_with_grant = alice_scope.with_grant(grant)\nresponse = alice_with_grant.retrieve_with_grants(query_text=\"shared documents\")\n```\n\n### gRPC/Server Mode\n\nAll memory components work with gRPC client:\n\n```python\nfrom sochdb import SochDBClient\nfrom sochdb.memory import (\n    ExtractionPipeline, Consolidator, HybridRetriever, NamespaceManager,\n)\n\n# Connect to server\nclient = SochDBClient(\"localhost:50051\")\n\n# Create components with gRPC backend\npipeline = ExtractionPipeline.from_client(client, namespace=\"user_123\")\nconsolidator = Consolidator.from_client(client, namespace=\"user_123\")\nretriever = HybridRetriever.from_client(client, namespace=\"user_123\")\nmanager = NamespaceManager.from_client(client)\n\n# Use exactly the same API as embedded mode\nresult = pipeline.extract_and_commit(text, extractor=my_extractor)\n```\n\n### In-Memory Backend (Testing)\n\nFor testing without persistence:\n\n```python\nfrom sochdb.memory import (\n    InMemoryBackend, InMemoryConsolidationBackend, \n    InMemoryRetrievalBackend, InMemoryNamespaceBackend,\n    ExtractionPipeline, Consolidator, HybridRetriever, NamespaceManager,\n)\n\n# Create in-memory backends\nbackend = InMemoryBackend()\npipeline = ExtractionPipeline.from_backend(backend, namespace=\"test\")\n\n# Perfect for unit tests\nresult = pipeline.extract(text, extractor=mock_extractor)\nassert len(result.entities) == 2\n```\n\n### Data Models\n\n#### Entity\n\n```python\nfrom sochdb.memory import Entity\n\nentity = Entity(\n    name=\"John Doe\",\n    entity_type=\"person\",\n    properties={\"role\": \"engineer\", \"department\": \"AI\"},\n    confidence=0.95,\n    provenance=\"document_123\",\n)\nprint(entity.id)  # Deterministic ID from name + type\n```\n\n#### Relation\n\n```python\nfrom sochdb.memory import Relation\n\nrelation = Relation(\n    from_entity=\"john_entity_id\",\n    relation_type=\"works_at\",\n    to_entity=\"company_entity_id\",\n    confidence=0.9,\n)\n```\n\n#### Assertion\n\n```python\nfrom sochdb.memory import Assertion\n\nassertion = Assertion(\n    subject=\"john_entity_id\",\n    predicate=\"believes\",\n    object=\"AI will transform healthcare\",\n    valid_from=1706000000000,  # Unix ms\n    valid_until=0,  # 0 = still valid\n    confidence=0.85,\n    embedding=[0.1, 0.2, ...],  # Optional\n)\nprint(assertion.is_current())  # True if valid now\n```\n\n---\n\n## 19. Atomic Multi-Index Writes\n\nEnsure consistency across KV storage, vectors, and graphs with atomic operations.\n\n### Problem Without Atomicity\n\n```\n# Without atomic writes, a crash can leave:\n# - Embedding exists but graph edges don't\n# - KV data exists but embedding is missing\n# - Partial graph relationships\n```\n\n### Atomic Memory Writer\n\n```python\nfrom sochdb import AtomicMemoryWriter, MemoryOp\n\nwriter = AtomicMemoryWriter(db)\n\n# Build atomic operation set\nresult = writer.write_atomic(\n    memory_id=\"memory_123\",\n    ops=[\n        # Store the blob/content\n        MemoryOp.PutBlob(\n            key=b\"memories/memory_123/content\",\n            value=b\"Meeting notes: discussed project timeline...\"\n        ),\n        \n        # Store the embedding\n        MemoryOp.PutEmbedding(\n            collection=\"memories\",\n            id=\"memory_123\",\n            embedding=[0.1, 0.2, ...],\n            metadata={\"type\": \"meeting\", \"date\": \"2024-01-15\"}\n        ),\n        \n        # Create graph nodes\n        MemoryOp.CreateNode(\n            namespace=\"default\",\n            node_id=\"memory_123\",\n            node_type=\"memory\",\n            properties={\"importance\": \"high\"}\n        ),\n        \n        # Create graph edges\n        MemoryOp.CreateEdge(\n            namespace=\"default\",\n            from_id=\"memory_123\",\n            edge_type=\"relates_to\",\n            to_id=\"project_x\",\n            properties={}\n        ),\n    ]\n)\n\nprint(f\"Intent ID: {result.intent_id}\")\nprint(f\"Operations applied: {result.ops_applied}\")\nprint(f\"Status: {result.status}\")  # \"committed\"\n```\n\n### How It Works\n\n```\n1. Write intent(id, ops...) to WAL    ← Crash-safe\n2. Apply ops one-by-one\n3. Write commit(id) to WAL            ← All-or-nothing\n4. Recovery replays incomplete intents\n```\n\n---\n\n## 20. Recovery \u0026 WAL Management\n\nSochDB uses Write-Ahead Logging (WAL) for durability with automatic recovery.\n\n### Recovery Manager\n\n```python\nfrom sochdb import RecoveryManager\n\nrecovery = db.recovery()\n\n# Check if recovery is needed\nif recovery.needs_recovery():\n    result = recovery.recover()\n    print(f\"Status: {result.status}\")\n    print(f\"Replayed entries: {result.replayed_entries}\")\n```\n\n### WAL Verification\n\n```python\n# Verify WAL integrity\nresult = recovery.verify_wal()\n\nprint(f\"Valid: {result.is_valid}\")\nprint(f\"Total entries: {result.total_entries}\")\nprint(f\"Valid entries: {result.valid_entries}\")\nprint(f\"Corrupted: {result.corrupted_entries}\")\nprint(f\"Last valid LSN: {result.last_valid_lsn}\")\n\nif result.checksum_errors:\n    for error in result.checksum_errors:\n        print(f\"Checksum error at LSN {error.lsn}: expected {error.expected}, got {error.actual}\")\n```\n\n### Force Checkpoint\n\n```python\n# Force a checkpoint (flush memtable to disk)\nresult = recovery.checkpoint()\n\nprint(f\"Checkpoint LSN: {result.checkpoint_lsn}\")\nprint(f\"Duration: {result.duration_ms}ms\")\n```\n\n### WAL Statistics\n\n```python\nstats = recovery.wal_stats()\n\nprint(f\"Total size: {stats.total_size_bytes} bytes\")\nprint(f\"Active size: {stats.active_size_bytes} bytes\")\nprint(f\"Archived size: {stats.archived_size_bytes} bytes\")\nprint(f\"Entry count: {stats.entry_count}\")\nprint(f\"Oldest LSN: {stats.oldest_entry_lsn}\")\nprint(f\"Newest LSN: {stats.newest_entry_lsn}\")\n```\n\n### WAL Truncation\n\n```python\n# Truncate WAL after checkpoint (reclaim disk space)\nresult = recovery.truncate_wal(up_to_lsn=12345)\n\nprint(f\"Truncated to LSN: {result.up_to_lsn}\")\nprint(f\"Bytes freed: {result.bytes_freed}\")\n```\n\n### Open with Auto-Recovery\n\n```python\nfrom sochdb import open_with_recovery\n\n# Automatically recovers if needed\ndb = open_with_recovery(\"./my_database\")\n```\n\n---\n\n## 21. Checkpoints \u0026 Snapshots\n\n### Application Checkpoints\n\nSave and restore application state for workflow interruption/resumption.\n\n```python\nfrom sochdb import CheckpointService\n\ncheckpoint_svc = db.checkpoint_service()\n\n# Create a checkpoint\ncheckpoint_id = checkpoint_svc.create(\n    name=\"workflow_step_3\",\n    state=serialized_state,  # bytes\n    metadata={\"step\": \"3\", \"user\": \"alice\", \"workflow\": \"data_pipeline\"}\n)\n\n# Restore checkpoint\nstate = checkpoint_svc.restore(checkpoint_id)\n\n# List checkpoints\ncheckpoints = checkpoint_svc.list()\nfor cp in checkpoints:\n    print(f\"{cp.name}: {cp.created_at}, {cp.state_size} bytes\")\n\n# Delete checkpoint\ncheckpoint_svc.delete(checkpoint_id)\n```\n\n### Workflow Checkpointing\n\n```python\n# Create a workflow run\nrun_id = checkpoint_svc.create_run(\n    workflow=\"data_pipeline\",\n    params={\"input_file\": \"data.csv\", \"batch_size\": 1000}\n)\n\n# Save checkpoint at each node/step\ncheckpoint_svc.save_node_checkpoint(\n    run_id=run_id,\n    node_id=\"transform_step\",\n    state=step_state,\n    metadata={\"rows_processed\": 5000}\n)\n\n# Load latest checkpoint for a node\ncheckpoint = checkpoint_svc.load_node_checkpoint(run_id, \"transform_step\")\n\n# List all checkpoints for a run\nnode_checkpoints = checkpoint_svc.list_run_checkpoints(run_id)\n```\n\n### Snapshot Reader (Point-in-Time)\n\n```python\n# Create a consistent snapshot for reading\nsnapshot = db.snapshot()\n\n# Read from snapshot (doesn't see newer writes)\nvalue = snapshot.get(b\"key\")\n\n# All reads within snapshot see consistent state\nwith db.snapshot() as snap:\n    v1 = snap.get(b\"key1\")\n    v2 = snap.get(b\"key2\")  # Same consistent view\n\n# Meanwhile, writes continue in main DB\ndb.put(b\"key1\", b\"new_value\")  # Snapshot doesn't see this\n```\n\n---\n\n## 22. Compression \u0026 Storage\n\n### Compression Settings\n\n```python\nfrom sochdb import CompressionType\n\ndb = Database.open(\"./my_db\", config={\n    # Compression for SST files\n    \"compression\": CompressionType.LZ4,      # LZ4 (fast), ZSTD (better ratio), NONE\n    \"compression_level\": 3,                   # ZSTD: 1-22, LZ4: ignored\n    \n    # Compression for WAL\n    \"wal_compression\": CompressionType.NONE,  # Usually NONE for WAL (already sequential)\n})\n```\n\n### Compression Comparison\n\n| Type | Ratio | Compress Speed | Decompress Speed | Use Case |\n|------|-------|----------------|------------------|----------|\n| `NONE` | 1x | N/A | N/A | Already compressed data |\n| `LZ4` | ~2.5x | ~780 MB/s | ~4500 MB/s | General use (default) |\n| `ZSTD` | ~3.5x | ~520 MB/s | ~1800 MB/s | Cold storage, large datasets |\n\n### Storage Statistics\n\n```python\nstats = db.storage_stats()\n\nprint(f\"Data size: {stats.data_size_bytes}\")\nprint(f\"Index size: {stats.index_size_bytes}\")\nprint(f\"WAL size: {stats.wal_size_bytes}\")\nprint(f\"Compression ratio: {stats.compression_ratio:.2f}x\")\nprint(f\"SST files: {stats.sst_file_count}\")\nprint(f\"Levels: {stats.level_stats}\")\n```\n\n### Compaction Control\n\n```python\n# Manual compaction (reclaim space, optimize reads)\ndb.compact()\n\n# Compact specific level\ndb.compact_level(level=0)\n\n# Get compaction stats\nstats = db.compaction_stats()\nprint(f\"Pending compactions: {stats.pending_compactions}\")\nprint(f\"Running compactions: {stats.running_compactions}\")\n```\n\n---\n\n## 23. Statistics \u0026 Monitoring\n\n### Database Statistics\n\n```python\nstats = db.stats()\n\n# Transaction stats\nprint(f\"Active transactions: {stats.active_transactions}\")\nprint(f\"Committed transactions: {stats.committed_transactions}\")\nprint(f\"Aborted transactions: {stats.aborted_transactions}\")\nprint(f\"Conflict rate: {stats.conflict_rate:.2%}\")\n\n# Operation stats\nprint(f\"Total reads: {stats.total_reads}\")\nprint(f\"Total writes: {stats.total_writes}\")\nprint(f\"Cache hit rate: {stats.cache_hit_rate:.2%}\")\n\n# Storage stats\nprint(f\"Key count: {stats.key_count}\")\nprint(f\"Total data size: {stats.total_data_bytes}\")\n```\n\n### Token Statistics (LLM Optimization)\n\n```python\nstats = db.token_stats()\n\nprint(f\"TOON tokens emitted: {stats.toon_tokens_emitted}\")\nprint(f\"Equivalent JSON tokens: {stats.json_tokens_equivalent}\")\nprint(f\"Token savings: {stats.token_savings_percent:.1f}%\")\n```\n\n### Performance Metrics\n\n```python\nmetrics = db.performance_metrics()\n\n# Latency percentiles\nprint(f\"Read P50: {metrics.read_latency_p50_us}µs\")\nprint(f\"Read P99: {metrics.read_latency_p99_us}µs\")\nprint(f\"Write P50: {metrics.write_latency_p50_us}µs\")\nprint(f\"Write P99: {metrics.write_latency_p99_us}µs\")\n\n# Throughput\nprint(f\"Reads/sec: {metrics.reads_per_second}\")\nprint(f\"Writes/sec: {metrics.writes_per_second}\")\n```\n\n---\n\n## 24. Distributed Tracing\n\nTrack operations for debugging and performance analysis.\n\n### Starting Traces\n\n```python\nfrom sochdb import TraceStore\n\ntraces = TraceStore(db)\n\n# Start a trace run\nrun = traces.start_run(\n    name=\"user_request\",\n    resource={\"service\": \"api\", \"version\": \"1.0.0\"}\n)\ntrace_id = run.trace_id\n```\n\n### Creating Spans\n\n```python\nfrom sochdb import SpanKind, SpanStatusCode\n\n# Start root span\nroot_span = traces.start_span(\n    trace_id=trace_id,\n    name=\"handle_request\",\n    parent_span_id=None,\n    kind=SpanKind.SERVER\n)\n\n# Start child span\ndb_span = traces.start_span(\n    trace_id=trace_id,\n    name=\"database_query\",\n    parent_span_id=root_span.span_id,\n    kind=SpanKind.CLIENT\n)\n\n# Add attributes\ntraces.set_span_attributes(trace_id, db_span.span_id, {\n    \"db.system\": \"sochdb\",\n    \"db.operation\": \"SELECT\",\n    \"db.table\": \"users\"\n})\n\n# End spans\ntraces.end_span(trace_id, db_span.span_id, SpanStatusCode.OK)\ntraces.end_span(trace_id, root_span.span_id, SpanStatusCode.OK)\n\n# End the trace run\ntraces.end_run(trace_id, TraceStatus.COMPLETED)\n```\n\n### Domain Events\n\n```python\n# Log retrieval (for RAG debugging)\ntraces.log_retrieval(\n    trace_id=trace_id,\n    query=\"user query\",\n    results=[{\"id\": \"doc1\", \"score\": 0.95}],\n    latency_ms=15\n)\n\n# Log LLM call\ntraces.log_llm_call(\n    trace_id=trace_id,\n    model=\"claude-3-sonnet\",\n    input_tokens=500,\n    output_tokens=200,\n    latency_ms=1200\n)\n```\n\n---\n\n## 25. Workflow \u0026 Run Tracking\n\nTrack long-running workflows with events and state.\n\n### Creating Workflow Runs\n\n```python\nfrom sochdb import WorkflowService, RunStatus\n\nworkflow_svc = db.workflow_service()\n\n# Create a new run\nrun = workflow_svc.create_run(\n    run_id=\"run_123\",\n    workflow=\"data_pipeline\",\n    params={\"input\": \"data.csv\", \"output\": \"results.json\"}\n)\n\nprint(f\"Run ID: {run.run_id}\")\nprint(f\"Status: {run.status}\")\nprint(f\"Created: {run.created_at}\")\n```\n\n### Appending Events\n\n```python\nfrom sochdb import WorkflowEvent, EventType\n\n# Append events as workflow progresses\nworkflow_svc.append_event(WorkflowEvent(\n    run_id=\"run_123\",\n    event_type=EventType.NODE_STARTED,\n    node_id=\"extract\",\n    data={\"input_file\": \"data.csv\"}\n))\n\nworkflow_svc.append_event(WorkflowEvent(\n    run_id=\"run_123\",\n    event_type=EventType.NODE_COMPLETED,\n    node_id=\"extract\",\n    data={\"rows_extracted\": 10000}\n))\n```\n\n### Querying Events\n\n```python\n# Get all events for a run\nevents = workflow_svc.get_events(\"run_123\")\n\n# Get events since a sequence number\nnew_events = workflow_svc.get_events(\"run_123\", since_seq=10, limit=100)\n\n# Stream events (for real-time monitoring)\nfor event in workflow_svc.stream_events(\"run_123\"):\n    print(f\"[{event.seq}] {event.event_type}: {event.node_id}\")\n```\n\n### Update Run Status\n\n```python\n# Update status\nworkflow_svc.update_run_status(\"run_123\", RunStatus.COMPLETED)\n\n# Or mark as failed\nworkflow_svc.update_run_status(\"run_123\", RunStatus.FAILED)\n```\n\n---\n\n## 26. Server Mode (gRPC Client)\n\nFull-featured client for distributed deployments.\n\n### Connection\n\n```python\nfrom sochdb import SochDBClient\n\n# Basic connection\nclient = SochDBClient(\"localhost:50051\")\n\n# With TLS\nclient = SochDBClient(\"localhost:50051\", secure=True, ca_cert=\"ca.pem\")\n\n# With authentication\nclient = SochDBClient(\"localhost:50051\", api_key=\"your_api_key\")\n\n# Context manager\nwith SochDBClient(\"localhost:50051\") as client:\n    client.put(b\"key\", b\"value\")\n```\n\n### Key-Value Operations\n\n```python\n# Put with TTL\nclient.put(b\"key\", b\"value\", namespace=\"default\", ttl_seconds=3600)\n\n# Get\nvalue = client.get(b\"key\", namespace=\"default\")\n\n# Delete\nclient.delete(b\"key\", namespace=\"default\")\n\n# Batch operations\nclient.put_batch([\n    (b\"key1\", b\"value1\"),\n    (b\"key2\", b\"value2\"),\n], namespace=\"default\")\n```\n\n### Vector Operations (Server Mode)\n\n```python\n# Create index\nclient.create_index(\n    name=\"embeddings\",\n    dimension=384,\n    metric=\"cosine\",\n    m=16,\n    ef_construction=200\n)\n\n# Insert vectors\nclient.insert_vectors(\n    index_name=\"embeddings\",\n    ids=[1, 2, 3],\n    vectors=[[...], [...], [...]]\n)\n\n# Search\nresults = client.search(\n    index_name=\"embeddings\",\n    query=[0.1, 0.2, ...],\n    k=10,\n    ef_search=50\n)\n\nfor result in results:\n    print(f\"ID: {result.id}, Distance: {result.distance}\")\n```\n\n### Collection Operations (Server Mode)\n\n```python\n# Create collection\nclient.create_collection(\n    name=\"documents\",\n    dimension=384,\n    namespace=\"default\",\n    metric=\"cosine\"\n)\n\n# Add documents\nclient.add_documents(\n    collection_name=\"documents\",\n    documents=[\n        {\"id\": \"1\", \"content\": \"Hello\", \"embedding\": [...], \"metadata\": {...}},\n        {\"id\": \"2\", \"content\": \"World\", \"embedding\": [...], \"metadata\": {...}}\n    ],\n    namespace=\"default\"\n)\n\n# Search\nresults = client.search_collection(\n    collection_name=\"documents\",\n    query_vector=[...],\n    k=10,\n    namespace=\"default\",\n    filter={\"author\": \"Alice\"}\n)\n```\n\n### Context Service (Server Mode)\n\n```python\n# Query context for LLM\ncontext = client.query_context(\n    session_id=\"session_123\",\n    sections=[\n        {\"name\": \"system\", \"priority\": 0, \"type\": \"literal\", \n         \"content\": \"You are a helpful assistant.\"},\n        {\"name\": \"history\", \"priority\": 1, \"type\": \"recent\", \n         \"table\": \"messages\", \"top_k\": 10},\n        {\"name\": \"knowledge\", \"priority\": 2, \"type\": \"search\", \n         \"collection\": \"documents\", \"embedding\": [...], \"top_k\": 5}\n    ],\n    token_limit=4096,\n    format=\"toon\"\n)\n\nprint(context.text)\nprint(f\"Tokens used: {context.token_count}\")\n```\n\n---\n\n## 27. IPC Client (Unix Sockets)\n\nLocal server communication via Unix sockets (lower latency than gRPC).\n\n```python\nfrom sochdb import IpcClient\n\n# Connect\nclient = IpcClient.connect(\"/tmp/sochdb.sock\", timeout=30.0)\n\n# Basic operations\nclient.put(b\"key\", b\"value\")\nvalue = client.get(b\"key\")\nclient.delete(b\"key\")\n\n# Path operations\nclient.put_path([\"users\", \"alice\"], b\"data\")\nvalue = client.get_path([\"users\", \"alice\"])\n\n# Query\nresult = client.query(\"users/\", limit=100)\n\n# Scan\nresults = client.scan(\"prefix/\")\n\n# Transactions\ntxn_id = client.begin_transaction()\n# ... operations ...\ncommit_ts = client.commit(txn_id)\n# or client.abort(txn_id)\n\n# Admin\nclient.ping()\nclient.checkpoint()\nstats = client.stats()\n\nclient.close()\n```\n\n---\n\n## 28. Standalone VectorIndex\n\nDirect HNSW index operations without collections.\n\n```python\nfrom sochdb import VectorIndex, VectorIndexConfig, DistanceMetric\nimport numpy as np\n\n# Create index\nconfig = VectorIndexConfig(\n    dimension=384,\n    metric=DistanceMetric.COSINE,\n    m=16,\n    ef_construction=200,\n    ef_search=50,\n    max_elements=100000\n)\nindex = VectorIndex(config)\n\n# Insert single vector\nindex.insert(id=1, vector=np.array([0.1, 0.2, ...], dtype=np.float32))\n\n# Batch insert\nids = np.array([1, 2, 3], dtype=np.uint64)\nvectors = np.array([[...], [...], [...]], dtype=np.float32)\ncount = index.insert_batch(ids, vectors)\n\n# Fast batch insert (returns failures)\ninserted, failed = index.insert_batch_fast(ids, vectors)\n\n# Search\nquery = np.array([0.1, 0.2, ...], dtype=np.float32)\nresults = index.search(query, k=10, ef_search=100)\n\nfor id, distance in results:\n    print(f\"ID: {id}, Distance: {distance}\")\n\n# Properties\nprint(f\"Size: {len(index)}\")\nprint(f\"Dimension: {index.dimension}\")\n\n# Save/load\nindex.save(\"./index.bin\")\nindex = VectorIndex.load(\"./index.bin\")\n```\n\n---\n\n## 29. Vector Utilities\n\nStandalone vector operations for preprocessing and analysis.\n\n```python\nfrom sochdb import vector\n\n# Distance calculations\na = [1.0, 0.0, 0.0]\nb = [0.707, 0.707, 0.0]\n\ncosine_dist = vector.cosine_distance(a, b)\neuclidean_dist = vector.euclidean_distance(a, b)\ndot_product = vector.dot_product(a, b)\n\nprint(f\"Cosine distance: {cosine_dist:.4f}\")\nprint(f\"Euclidean distance: {euclidean_dist:.4f}\")\nprint(f\"Dot product: {dot_product:.4f}\")\n\n# Normalize a vector\nv = [3.0, 4.0]\nnormalized = vector.normalize(v)\nprint(f\"Normalized: {normalized}\")  # [0.6, 0.8]\n\n# Batch normalize\nvectors = [[3.0, 4.0], [1.0, 0.0]]\nnormalized_batch = vector.normalize_batch(vectors)\n\n# Compute centroid\nvectors = [[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]\ncentroid = vector.centroid(vectors)\n\n# Cosine similarity (1 - distance)\nsimilarity = vector.cosine_similarity(a, b)\n```\n\n---\n\n## 30. Data Formats (TOON/JSON/Columnar)\n\n### Wire Formats\n\n```python\nfrom sochdb import WireFormat\n\n# Available formats\nWireFormat.TOON      # Token-efficient (40-66% fewer tokens)\nWireFormat.JSON      # Standard JSON\nWireFormat.COLUMNAR  # Raw columnar for analytics\n\n# Parse from string\nfmt = WireFormat.from_string(\"toon\")\n\n# Convert between formats\ndata = {\"users\": [{\"id\": 1, \"name\": \"Alice\"}]}\ntoon_data = WireFormat.to_toon(data)\njson_data = WireFormat.to_json(data)\n```\n\n### TOON Format Benefits\n\nTOON uses **40-60% fewer tokens** than JSON:\n\n```\n# JSON (15 tokens)\n{\"users\": [{\"id\": 1, \"name\": \"Alice\"}]}\n\n# TOON (9 tokens)\nusers:\n  - id: 1\n    name: Alice\n```\n\n### Context Formats\n\n```python\nfrom sochdb import ContextFormat\n\nContextFormat.TOON      # Token-efficient\nContextFormat.JSON      # Structured data\nContextFormat.MARKDOWN  # Human-readable\n\n# Format capabilities\nfrom sochdb import FormatCapabilities\n\n# Convert between formats\nctx_fmt = FormatCapabilities.wire_to_context(WireFormat.TOON)\nwire_fmt = FormatCapabilities.context_to_wire(ContextFormat.JSON)\n\n# Check round-trip support\nif FormatCapabilities.supports_round_trip(WireFormat.TOON):\n    print(\"Safe for decode(encode(x)) = x\")\n```\n\n---\n\n## 31. Policy Service\n\nRegister and evaluate access control policies.\n\n```python\nfrom sochdb import PolicyService\n\npolicy_svc = db.policy_service()\n\n# Register a policy\npolicy_svc.register(\n    policy_id=\"read_own_data\",\n    name=\"Users can read their own data\",\n    trigger=\"READ\",\n    action=\"ALLOW\",\n    condition=\"resource.owner == user.id\"\n)\n\n# Register another policy\npolicy_svc.register(\n    policy_id=\"admin_all\",\n    name=\"Admins can do everything\",\n    trigger=\"*\",\n    action=\"ALLOW\",\n    condition=\"user.role == 'admin'\"\n)\n\n# Evaluate policy\nresult = policy_svc.evaluate(\n    action=\"READ\",\n    resource=\"documents/123\",\n    context={\"user.id\": \"alice\", \"user.role\": \"user\", \"resource.owner\": \"alice\"}\n)\n\nif result.allowed:\n    print(\"Access granted\")\nelse:\n    print(f\"Access denied: {result.reason}\")\n    print(f\"Denying policy: {result.policy_id}\")\n\n# List policies\npolicies = policy_svc.list()\nfor p in policies:\n    print(f\"{p.policy_id}: {p.name}\")\n\n# Delete policy\npolicy_svc.delete(\"old_policy\")\n```\n\n---\n\n## 32. MCP (Model Context Protocol)\n\nIntegrate SochDB as an MCP tool provider.\n\n### Built-in MCP Tools\n\n| Tool | Description |\n|------|-------------|\n| `sochdb_query` | Execute ToonQL/SQL queries |\n| `sochdb_context_query` | Fetch AI-optimized context |\n| `sochdb_put` | Store key-value data |\n| `sochdb_get` | Retrieve data by key |\n| `sochdb_search` | Vector similarity search |\n\n### Using MCP Tools (Server Mode)\n\n```python\n# List available tools\ntools = client.list_mcp_tools()\nfor tool in tools:\n    print(f\"{tool.name}: {tool.description}\")\n\n# Get tool schema\nschema = client.get_mcp_tool_schema(\"sochdb_search\")\nprint(schema)\n\n# Execute tool\nresult = client.execute_mcp_tool(\n    name=\"sochdb_query\",\n    arguments={\"query\": \"SELECT * FROM users\", \"format\": \"toon\"}\n)\nprint(result)\n```\n\n### Register Custom Tool\n\n```python\n# Register a custom tool\nclient.register_mcp_tool(\n    name=\"search_documents\",\n    description=\"Search documents by semantic similarity\",\n    input_schema={\n        \"type\": \"object\",\n        \"properties\": {\n            \"query\": {\"type\": \"string\", \"description\": \"Search query\"},\n            \"k\": {\"type\": \"integer\", \"description\": \"Number of results\", \"default\": 10}\n        },\n        \"required\": [\"query\"]\n    }\n)\n```\n\n---\n\n## 33. Configuration Reference\n\n### Database Configuration\n\n```python\nfrom sochdb import Database, CompressionType, SyncMode\n\ndb = Database.open(\"./my_db\", config={\n    # Durability\n    \"wal_enabled\": True,                      # Write-ahead logging\n    \"sync_mode\": SyncMode.NORMAL,             # FULL, NORMAL, OFF\n    \n    # Performance\n    \"memtable_size_bytes\": 64 * 1024 * 1024,  # 64MB (flush threshold)\n    \"block_cache_size_bytes\": 256 * 1024 * 1024,  # 256MB\n    \"group_commit\": True,                      # Batch commits\n    \n    # Compression\n    \"compression\": CompressionType.LZ4,\n    \n    # Index policy\n    \"index_policy\": \"balanced\",\n    \n    # Background workers\n    \"compaction_threads\": 2,\n    \"flush_threads\": 1,\n})\n```\n\n### Sync Modes\n\n| Mode | Speed | Safety | Use Case |\n|------|-------|--------|----------|\n| `OFF` | ~10x faster | Risk of data loss | Development, caches |\n| `NORMAL` | Balanced | Fsync at checkpoints | Default |\n| `FULL` | Slowest | Fsync every commit | Financial data |\n\n### CollectionConfig Reference\n\n| Field | Type | Default | Description |\n|-------|------|---------|-------------|\n| `name` | str | required | Collection name |\n| `dimension` | int | required | Vector dimension |\n| `metric` | DistanceMetric | COSINE | COSINE, EUCLIDEAN, DOT_PRODUCT |\n| `m` | int | 16 | HNSW M parameter |\n| `ef_construction` | int | 100 | HNSW build quality |\n| `ef_search` | int | 50 | HNSW search quality |\n| `quantization` | QuantizationType | NONE | NONE, SCALAR, PQ |\n| `enable_hybrid_search` | bool | False | Enable BM25 |\n| `content_field` | str | None | Field for BM25 indexing |\n\n### Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| `SOCHDB_LIB_PATH` | Custom path to native library |\n| `SOCHDB_DISABLE_ANALYTICS` | Disable anonymous usage tracking |\n| `SOCHDB_LOG_LEVEL` | Log level (DEBUG, INFO, WARN, ERROR) |\n\n---\n\n## 34. Error Handling\n\n### Error Types\n\n```python\nfrom sochdb import (\n    # Base\n    SochDBError,\n    \n    # Connection\n    ConnectionError,\n    ConnectionTimeoutError,\n    \n    # Transaction\n    TransactionError,\n    TransactionConflictError,  # SSI conflict - retry\n    TransactionTimeoutError,\n    \n    # Storage\n    DatabaseError,\n    CorruptionError,\n    DiskFullError,\n    \n    # Namespace\n    NamespaceNotFoundError,\n    NamespaceExistsError,\n    NamespaceAccessError,\n    \n    # Collection\n    CollectionNotFoundError,\n    CollectionExistsError,\n    CollectionConfigError,\n    \n    # Validation\n    ValidationError,\n    DimensionMismatchError,\n    InvalidMetadataError,\n    \n    # Query\n    QueryError,\n    QuerySyntaxError,\n    QueryTimeoutError,\n)\n```\n\n### Error Handling Pattern\n\n```python\nfrom sochdb import (\n    SochDBError,\n    Transact","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsochdb%2Fsochdb-python-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsochdb%2Fsochdb-python-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsochdb%2Fsochdb-python-sdk/lists"}