{"id":31642379,"url":"https://github.com/arqonai/pixelog","last_synced_at":"2026-04-27T23:01:49.563Z","repository":{"id":318764965,"uuid":"1074007092","full_name":"ArqonAi/Pixelog","owner":"ArqonAi","description":"Video based archival system encoding documents as QR frames in MP4 files. Features Git like version control, sub 100ms semantic search, LLM chat (OpenRouter), AES-256-GCM encryption, and streaming for multi GB files with constant 10MB memory.","archived":false,"fork":false,"pushed_at":"2025-11-24T17:09:27.000Z","size":103961,"stargazers_count":3,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-20T22:38:53.770Z","etag":null,"topics":["ai","encryption","ffmpeg","file-conversion","go","llm","memory","mp4","pixe","qr-code","video-encoding"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ArqonAi.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-11T01:32:36.000Z","updated_at":"2025-11-24T17:09:32.000Z","dependencies_parsed_at":"2025-10-15T10:42:26.913Z","dependency_job_id":null,"html_url":"https://github.com/ArqonAi/Pixelog","commit_stats":null,"previous_names":["arqonai/pixelog"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ArqonAi/Pixelog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArqonAi%2FPixelog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArqonAi%2FPixelog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArqonAi%2FPixelog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArqonAi%2FPixelog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ArqonAi","download_url":"https://codeload.github.com/ArqonAi/Pixelog/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ArqonAi%2FPixelog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32358509,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-27T20:07:02.737Z","status":"ssl_error","status_checked_at":"2026-04-27T20:07:00.910Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["ai","encryption","ffmpeg","file-conversion","go","llm","memory","mp4","pixe","qr-code","video-encoding"],"created_at":"2025-10-07T03:58:49.441Z","updated_at":"2026-04-27T23:01:49.556Z","avatar_url":"https://github.com/ArqonAi.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"arqon-nextr-10.svg\" alt=\"Arqon AI Banner\" width=\"100%\"\u003e\n\u003c/p\u003e\n\n# Pixelog\n\n[![Tests](https://github.com/ArqonAi/Pixelog/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/ArqonAi/Pixelog/actions/workflows/test.yml)\n[![Release](https://github.com/ArqonAi/Pixelog/actions/workflows/release.yml/badge.svg)](https://github.com/ArqonAi/Pixelog/actions/workflows/release.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/ArqonAi/Pixelog)](https://goreportcard.com/report/github.com/ArqonAi/Pixelog)\n[![Go Reference](https://pkg.go.dev/badge/github.com/ArqonAi/Pixelog.svg)](https://pkg.go.dev/github.com/ArqonAi/Pixelog)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)\n[![Go Version](https://img.shields.io/badge/Go-1.25+-blue.svg)](https://golang.org/)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)\n[![CLI](https://img.shields.io/badge/CLI-19%20commands-orange.svg)](cmd/pixe)\n[![Security](https://img.shields.io/badge/Security-AES--256--GCM-green.svg)](https://en.wikipedia.org/wiki/Galois/Counter_Mode)\n[![Format](https://img.shields.io/badge/Format-MP4%20Video-red.svg)](https://en.wikipedia.org/wiki/MP4_file_format)\n[![Retrieval](https://img.shields.io/badge/Retrieval-Sub--100ms-green.svg)](benchmarks/BENCHMARKS.md)\n[![Durability](https://img.shields.io/badge/Durability-IPFS%20%2B%20Arweave-blueviolet.svg)](pkg/publish/E2E.md)\n\n**A content-addressed archival format that stores documents as QR-encoded\nframes inside an MP4 container, with a self-similar fractal memory\nhierarchy, salience-preserved compaction, IPFS+Arweave durability, and\na benchmark-validated retrieval stack on top.**\n\n---\n\n## Overview\n\nPixelog encodes a document into a `.pixe` file — an MP4 whose video track\ncarries QR-encoded data chunks instead of imagery. The container is\nstandard MP4, so any media stack (browsers, mobile players, OS\nthumbnailers, FFmpeg, archival storage) handles transport, seeking, and\nstreaming without bespoke tooling. Higher layers add content-addressed\nidentity, delta-encoded versioning, AES-256-GCM authenticated\nencryption, a self-similar fractal memory hierarchy with salience-\npreserved compaction, and a hybrid retriever that hits state-of-the-art\nrecall on four public benchmarks.\n\n**Design rationale.** Pixelog is built around five observations:\n\n1. **Transport layers should be commodity.** MP4 has the widest\n   playback surface of any container in existence. Building on top of\n   it eliminates a whole class of distribution problems (mobile\n   playback, CDN edge caching, browser preview, cold storage).\n2. **Storage should be content-addressed and self-verifying.** Every\n   frame carries SHA-256 metadata; every capsule has a stable hash;\n   integrity verification is a local, deterministic operation.\n3. **Retrieval should not require an LLM in the hot path.** The hybrid\n   retriever (semantic + BM25 + temporal + preference + entity +\n   recency) is fully algorithmic and runs in ~0.6 ms per query with no\n   network calls. LLMs are an opt-in stage for answer synthesis only.\n4. **Memory should be self-similar across scales.** Per-session capsules\n   and era capsules share the same `(L0, L1, L2)` schema; the same\n   retrieval interface works whether you're matching today's events or\n   a decade-old summary. Active context cost is `O(log T)` regardless\n   of agent age.\n5. **Durability is a separate concern from storage format.** A capsule\n   identified by `pixe://capsule/\u003chash\u003e` resolves uniformly across\n   local SSD, IPFS, and Arweave permaweb — the agent never knows or\n   cares which tier holds a given memory.\n\n**At-a-glance properties:**\n\n| Property                  | Value |\n| ------------------------- | ----- |\n| Container                 | MP4 (H.264) — universally playable |\n| Payload density           | 2.9 KB / frame at 1080p (≈ 87 KB/s) |\n| Damage tolerance          | Reed-Solomon, ≈30 % per frame; QR ECC level H |\n| Encryption (optional)     | AES-256-GCM, PBKDF2-SHA-256 (600k iters), 32-byte salt, 12-byte nonce |\n| Memory footprint          | Constant ≈10 MB during conversion, independent of file size |\n| Retrieval (flat)          | HNSW vector index + hybrid lexical/temporal scoring |\n| Retrieval (fractal)       | Surface (`O(1)`) + depth-bounded URI graph traversal (`O(depth)`) |\n| Active context per agent  | `O(log T)` — ~3 k tokens for 10-year-old agent, ~3.5 k for 100-year-old |\n| Durability targets        | Local SSD, IPFS (Kubo HTTP API), Arweave permaweb (self-signing) |\n| Network dependency        | None for archival, integrity, retrieval; durability + LLM stages opt-in |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\ngo install github.com/ArqonAi/Pixelog/cmd/pixe@latest\n```\n\nOr build from source:\n\n```bash\ngit clone https://github.com/ArqonAi/Pixelog.git\ncd Pixelog\ngo build -o pixe ./cmd/pixe\n```\n\n### Basic Workflow\n\n```bash\n# Convert document to .pixe format\npixe convert document.txt -o doc.pixe\n\n# Build semantic search index (offline hash embedder, no key needed)\npixe index doc.pixe --embedder hash\n\n# Or use any hosted provider you have a key for:\n#   export OPENAI_API_KEY=...      # OpenAI\n#   export ANTHROPIC_API_KEY=...   # Anthropic\n#   export GEMINI_API_KEY=...      # Gemini\n#   export OPENROUTER_API_KEY=...  # OpenRouter aggregator\n# pixe index doc.pixe\n\n# Search by meaning\npixe search doc.pixe \"machine learning concepts\" --top 5\n\n# Chat with your document\npixe chat doc.pixe\n```\n\n---\n\n## Core Features\n\n### File Operations\n- Convert any file type to .pixe format\n- Extract original files from .pixe archives\n- Display file metadata and structure\n- Integrity checking via SHA-256 hashing\n- AES-256-GCM encryption with password\n\n### Semantic Search\n- Build vector embeddings for sub-100ms search\n- Meaning-based queries (not just keyword matching)\n- Interactive LLM Q\u0026A with automatic context retrieval\n- Ranked results by cosine similarity\n\n### Version Control\n- Create version snapshots with messages\n- List all versions with timestamps\n- Compare versions (frame-level changes)\n- Time-travel search across historical versions\n- Delta encoding (64% average space savings)\n\n### Performance\n- Sub-100ms search with HNSW indexing\n- Constant 10MB memory footprint (any file size)\n- Streaming support for multi-GB files\n- Parallel frame encoding/decoding\n\n### Security\n- AES-256-GCM authenticated encryption\n- PBKDF2 key derivation (600,000 iterations)\n- Reed-Solomon error correction (30% damage tolerance)\n- SHA-256 frame hashing for tamper detection\n- Air-gapped operation (no internet required)\n\n---\n\n## Tiered Memory \u0026 Agent Capsules\n\nPixelog ships a typed, three-tier memory subsystem (`internal/memory`) designed for long-horizon LLM agents. Each capsule is content-addressed under the `pixe://` URI scheme.\n\n### URI scheme\n\n```\npixe://capsule/\u003csha256\u003e                       # content-addressed capsule\npixe://memory/\u003cnamespace\u003e/\u003ccategory\u003e/\u003cid\u003e     # typed memory entry\npixe://agent/\u003ctokenID\u003e/v\u003cversion\u003e             # ERC-8004 agent identity\npixe://agent/\u003ctokenID\u003e/v\u003cversion\u003e/capsule/\u003csha256\u003e\npixe://arweave/\u003ctxID\u003e                         # mirrored Arweave permaweb pointer\n```\n\nBuild / parse round-trips via `memory.BuildCapsuleURI`, `memory.BuildMemoryURI`, `memory.ParseURI`.\n\n### Six typed memory categories\n\n| Category       | Weight | Purpose                                       |\n| -------------- | ------ | --------------------------------------------- |\n| `preference`   | 1.2    | User preferences, likes/dislikes              |\n| `instruction`  | 1.5    | Persistent rules (`always`, `never`)          |\n| `fact`         | 1.0    | World facts, definitions                      |\n| `event`        | 0.9    | Temporal references (meetings, deadlines)    |\n| `relationship` | 1.1    | Social graph (`works at`, `manager is`)       |\n| `skill`        | 1.0    | Procedures, how-to flows                      |\n\nThe `CategoryStore` partitions a vector index per category, weights search scores by category importance, and exposes `Search`, `SearchCategory`, `Stats`.\n\n### Three context tiers\n\n```go\ntype ContextTier string\nconst (\n    TierL0 ContextTier = \"l0\" // ≤32 tokens   — abstract\n    TierL1 ContextTier = \"l1\" // ≤128 tokens  — overview\n    TierL2 ContextTier = \"l2\" // unbounded    — full content\n)\n```\n\nGenerated automatically via `memory.GenerateTiers` (LLM summariser preferred, deterministic heuristic fallback when offline).\n\n### Three-phase archival pipeline\n\n```\n                ┌──────────────┐   ┌──────────────┐   ┌──────────────┐\n   messages ──\u003e │  Compress    │──\u003e│   Archive    │──\u003e│   Publish    │\n                │  (condense + │   │  (.pixe blob │   │  (durable    │\n                │   classify)  │   │   + sha256)  │   │   storage +  │\n                │              │   │              │   │   anchor)    │\n                └──────────────┘   └──────────────┘   └──────────────┘\n                       │                  │                   │\n                       ▼                  ▼                   ▼\n                  TypedMemory[]      pixe://capsule/...    ipfs://\u003cCID\u003e\n                  TieredEntry[]                            ar://\u003ctxID\u003e\n                                                           ERC-8004 anchor\n```\n\nThe Publish phase has two independent legs:\n\n- **Blob durability** — the capsule MP4 is uploaded in parallel to every\n  `publish.Publisher` configured under `BlobPublishers` (IPFS, Arweave, …).\n  Per-publisher failures are recorded in `ArchivalResult.PublishErrors`\n  but do not abort the pipeline; archival succeeds as long as the local\n  capsule is written. Locators (`Qm…`, `bafy…`, Arweave tx-id) are\n  returned in `ArchivalResult.Publications`.\n- **On-chain anchor** — the 32-byte content hash is optionally written\n  to an EVM contract (e.g. ERC-8004 agent registry) via the host-supplied\n  `OnChainPublisher`. The hash itself is independent of where the blob\n  lives, so anchors and blob CIDs/tx-ids compose naturally.\n\nBuilt-in publishers (real, no SDK dependencies):\n\n| Network  | Package                                | Endpoint                          |\n| -------- | -------------------------------------- | --------------------------------- |\n| IPFS     | `pkg/publish/ipfs`                     | Kubo `/api/v0/add` (CIDv1, raw-leaves, sha2-256) |\n| Arweave  | `pkg/publish/arweave`                  | format-2 tx with merkle data-root, RSA-PSS-SHA256 self-signing |\n\n```go\nipfsPub, _ := ipfs.New(ipfs.Config{APIURL: \"http://127.0.0.1:5001\"})\nwallet, _ := arweave.LoadWalletFromFile(\"wallet.json\")\narPub, _  := arweave.New(arweave.Config{NodeURL: \"https://arweave.net\", Wallet: wallet})\n\npipeline := memory.NewArchivalPipeline(\u0026memory.ArchivalConfig{\n    Namespace:         \"agent-42\",\n    Summarizer:        llmSummarizer,\n    ContentSummarizer: contentSummarizer,\n    Converter:         pixeWriter,                        // .pixe writer\n    BlobPublishers:    []publish.Publisher{ipfsPub, arPub}, // durability layer\n    Publisher:         erc8004Publisher,                  // optional on-chain anchor\n    Categories:        memory.NewCategoryStore(embedder, nil),\n})\nresult, _ := pipeline.RunFull(ctx, namespace, messages, capsulePath, agentTokenID)\n// result.Publications: [{network:\"ipfs\", locator:\"bafy…\"}, {network:\"arweave\", locator:\"…\"}]\n```\n\nCLI shortcut for already-built capsules:\n\n```bash\nexport IPFS_API_URL=http://127.0.0.1:5001\nexport ARWEAVE_NODE_URL=https://arweave.net\nexport ARWEAVE_WALLET_PATH=./wallet.json\n\npixe publish doc.pixe --target ipfs,arweave\n# [{\"network\":\"ipfs\",\"result\":{\"locator\":\"bafy…\",…}},\n#  {\"network\":\"arweave\",\"result\":{\"locator\":\"…\",…}}]\n```\n\nThe condenser supports four strategies: `noop`, `sliding_window`, `llm_summary`, `hybrid` (default).\n\n### Fractal memory (self-similar tier hierarchy)\n\nThe flat `(L0, L1, L2)` per session capsule is the leaf of a recursive\nstructure: at every level above the session, an **EraCapsule** carries\nthe same triplet but with its `L2` populated by child-capsule URIs\ninstead of raw events. Same retrieval interface at every scale, content-\naddressed all the way down — Sierpinski-style.\n\n```\nera-of-eras (year)        ── (L0, L1, L2 = era URIs)\n  ├── era (quarter)       ── (L0, L1, L2 = era URIs)\n  │     ├── era (week)    ── (L0, L1, L2 = era URIs)\n  │     │     ├── era (day)\n  │     │     │     ├── session capsule  ── (L0, L1, L2 = raw events)\n  │     │     │     └── ...\n  │     │     └── ...\n  │     └── ...\n  └── ...\n```\n\n**Compaction triggers** (both fire the same primitive):\n\n- **Circadian** (`internal/memory/trigger_circadian.go`) — calendar-aligned\n  scheduler: ISO-week / month / quarter / year / decade boundaries fire\n  rollups once each window closes. Models sleep-cycle consolidation.\n- **Salience pressure** (`trigger_pressure.go`) — token-budget watcher\n  that fires opportunistic compaction when the active context exceeds\n  the configured cap. Models stress-driven consolidation. Falls back to\n  the same `Compact()` primitive.\n\n**Salience-preserved collapse** (`compaction.go`) implements the\n\"removed middle\" — at each rollup, children are scored on\n`α·access_freq + β·recency + γ·emotional_weight + δ·tier_weight`. Top-K\nstay surfaced (full L1 inlined); the rest are buried (L1 stripped from\nthe parent, full content still reachable via the URI graph). This is\nthe formal mechanism behind \"subconscious / repressed memory\" — content\nis present but not loaded by surface retrieval.\n\n**Storage tiers** (`resolver.go`):\n\n| Tier | Where | Holds |\n| --- | --- | --- |\n| Hot | local capsule store (`CapsuleStore`) | current session + recent eras |\n| Warm | IPFS (`ResolverBackend`) | weeks → months |\n| Cold | Arweave permaweb | years → decades |\n\nThe `pixe://capsule/\u003chash\u003e` URI resolves uniformly across all three —\nthe agent never knows which tier holds a memory until it tries to fetch\nit. Active context cost is `O(log T)` regardless of agent age; total\nstorage scales naturally to PB at fleet scale.\n\n**Two retrieval modes** (`retrieval_deep.go`):\n\n- **Surface** — match against currently-active eras' L0/L1. Bounded\n  cost per query, independent of total memory size.\n- **Deep** (`DeepRetrieve`) — depth-bounded URI graph traversal that\n  models \"free association\": always descends into era-level children\n  within the depth budget, so buried memories surface when the agent\n  deliberately reflects. `SurfaceOnly: true` flips to conscious-recall\n  semantics that skips buried entries.\n\n```go\nsvc := memory.NewFractalService(memory.DefaultFractalConfig(\"agent-42\", store, compactor))\nsvc.Start(ctx)\ndefer svc.Stop()\n\n// After each archival pass:\nsvc.AddSession(ctx, sessionRef)   // queues + notifies the scheduler\nsvc.AddTokens(estimatedTokens)    // updates pressure monitor\n\n// Anywhere:\nhits, _ := memory.DeepRetrieve(ctx, resolver, []*memory.EraCapsule{currentEra},\n    memory.DeepRetrieveOptions{Query: \"what did we decide about X\", MaxDepth: 3})\n```\n\n---\n\n## Benchmarking\n\nPixelog includes a unified harness for evaluating memory quality against external benchmarks. Run via `cmd/pixe-bench`:\n\n```bash\ngo build -o pixe-bench ./cmd/pixe-bench\n```\n\n### Supported suites\n\n| Suite      | Source                                   | Modes                | Categories                                                                                                                  |\n| ---------- | ---------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------- |\n| `locomo`   | [snap-research/locomo][locomo] (ACL '24) | `session`, `hybrid`  | `single_hop`, `multi_hop`, `temporal`, `open_domain`, `adversarial`                                                         |\n| `convomem` | [Salesforce/ConvoMem][convomem]          | `session`            | `user_evidence`, `assistant_facts_evidence`, `changing_evidence`, `abstention_evidence`, `preference_evidence`, `implicit_connection_evidence` |\n| `membench` | [import-myself/Membench][membench] (ACL '25 Findings) | `full` | `participation_reflective`, `participation_factual`, `observation_reflective`, `observation_factual`              |\n\n[locomo]: https://github.com/snap-research/locomo\n[convomem]: https://huggingface.co/datasets/Salesforce/ConvoMem\n[membench]: https://github.com/import-myself/Membench\n\n### Quickstart\n\n```bash\n# 1. Fetch a dataset (LoCoMo example)\ncurl -L https://raw.githubusercontent.com/snap-research/locomo/main/data/locomo10.json -o locomo10.json\n\n# 2. Run offline (deterministic hash embedder, retrieval-only, F1 judge)\n./pixe-bench --suite locomo --mode session --dataset locomo10.json \\\n             --embedder hash --answerer=false --judge exact \\\n             --out locomo-report.json\n\n# 3. Run with full LLM stack — pick any supported provider.\nexport OPENAI_API_KEY=sk-...     # or ANTHROPIC_API_KEY / GEMINI_API_KEY / OPENROUTER_API_KEY / ...\n./pixe-bench --suite locomo --mode hybrid --dataset locomo10.json \\\n             --judge llm --answerer --provider openai --llm-model gpt-4o-mini \\\n             --out locomo-report.json\n```\n\n### Modes\n\n- **`session`** — replays each conversation session-by-session, calling `Consolidate` between sessions. Models the live agent flow.\n- **`hybrid`** — LoCoMo's RAG-on-summaries baseline; session ingestion plus a final consolidation pass.\n- **`full`** — dumps the entire transcript in one batch, then consolidates. Useful for MemBench's pre-built information flows.\n\n### Metrics\n\nEvery report includes `judge_mean` (LLM rubric 0–5 normalised), `f1_mean` (token F1), `exact_match_rate`, `abstain_accuracy` (for adversarial / abstention probes), and per-category breakdowns. Results are emitted as JSON for downstream comparison.\n\n### CI-friendly offline runs\n\nThe bundled `HashEmbedder` (deterministic SHA-256 → 384-d bag-of-words) plus `ExactMatchJudge` (exact match → token F1 fallback) lets benchmark runs execute without any network calls — useful for regression gates in CI.\n\n### Session reflection\n\n`--reflect` triggers a **per-session structured summary pass** during `Consolidate` (PERSON / EVENT / FACT / PREFERENCE / PLAN / RELATIONSHIP / FEELING tagged lines, with relative-date resolution). When combined with `--full-context`, the answerer receives the dense session summaries instead of the raw transcript — denser, faster, and lets the model reason over linked entities. `--reflect-provider` / `--reflect-model` let you run reflection on a different model than the answerer.\n\n## Benchmarks\n\nAll numbers below are reproducible from this repository with the\ncommands in [`benchmarks/BENCHMARKS.md`](benchmarks/BENCHMARKS.md).\nPer-question result files are written to whatever path you pass via\n`--out`.\n\nThe headline metric is **retrieval recall (R@k)** — the fraction of\ngold evidence sessions / turns that the retriever surfaces in the\ntop-k candidates.\n\n\u003e **No LLM is invoked for any of the headline numbers below.** Recall@k\n\u003e is a ranking task (does the gold session land in the top-k?), which\n\u003e is a pure search problem and needs no text generation. Producing a\n\u003e final natural-language answer from the retrieved context still needs\n\u003e an LLM and is reported separately under end-to-end QA.\n\n| Benchmark | Metric | **Pixelog** | Notes |\n| --- | --- | --- | --- |\n| LongMemEval S (500 QA) | Hit@5  | **97.20%** | 115k-token haystacks, hash embedder, no LLM |\n| LongMemEval S (500 QA) | Hit@10 | **98.20%** | same config |\n| LongMemEval Oracle (500 QA) | Hit@5 | **100.00%** | oracle haystack |\n| LoCoMo (1,986 QA) | Hit@10 | **96.62%** | 10 conversations, hash embedder, no LLM |\n| LoCoMo (1,986 QA) | Hit@5  | **92.08%** | same config |\n| ConvoMem (top-bucket × 6 cats, 265 cases) | Hit@5 | **100.00%** | hardest bucket per category, hash embedder |\n| MemBench ACL 2025 (6,779 QA) | Hit@5 | **98.45%** | all FirstAgent + ThirdAgent splits, hash embedder |\n\n**Every Pixelog row uses the deterministic hash embedder — no API key,\nno cloud, no LLM at any stage.** The retriever lives in\n[`internal/bench/hybrid_retriever.go`](internal/bench/hybrid_retriever.go)\nand combines semantic cosine, BM25, temporal proximity,\npreference-pattern boosts, capitalised-entity overlap, and a small\nrecency tiebreaker.\n\nDefault weights (tuned once on LongMemEval, held fixed across every\nother benchmark — *no per-suite tuning, no LLM rerank, no retrieval\nfinesse beyond what is committed*):\n\n```text\nsemantic=1.0  bm25=0.6  temporal=0.5  preference=0.3  keyword=0.4  recency=0.05\n```\n\nWe deliberately **do not headline a \"100%\" number on any benchmark\nwhere a sub-1% slice can be closed by inspecting the misses** — that\nis teaching to the test, and\n[`benchmarks/BENCHMARKS.md`](benchmarks/BENCHMARKS.md) flags it.\n\nWe also deliberately **do not include a side-by-side comparison\nagainst other memory systems**. Those projects publish different\nmetrics on different splits, and placing retrieval recall next to\nend-to-end QA accuracy is not an honest comparison. See each\nproject's own research page for their published numbers.\n\nEnd-to-end QA accuracy under the LLM answerer (`--full-context --cot\n--reflect`) is documented separately as *Latest QA results* below.\n\n### Reproducing every result\n\n```bash\ngit clone https://github.com/ArqonAi/Pixelog.git pixelog\ncd pixelog\ngo build -o pixe-bench ./cmd/pixe-bench\n# see benchmarks/BENCHMARKS.md for dataset download commands\n./pixe-bench --suite longmemeval --recall-k 5 --embedder hash \\\n    --dataset /tmp/pixe-bench/datasets/longmemeval_s.json\n```\n\n### Latest QA results (LoCoMo, 30 QA pilot, conversation 0)\n\nQA-accuracy mode — judge: `openai/gpt-4o`, answerer: `anthropic/claude-sonnet-4.6` via OpenRouter. Embedder: `nomic-embed-text` (Ollama).\n\n| Run                         | judge_mean | single_hop | multi_hop | temporal | latency  |\n| --------------------------- | ---------- | ---------- | --------- | -------- | -------- |\n| `--full-context --cot`      | **62.70%** | 82.00%     | 46.30%    | 80.00%   | 6.6 s/qa |\n| `--full-context --reflect --cot` | 60.00% | 78.00%     | 45.00%    | 75.00%   | 5.7 s/qa |\n\nThis is end-to-end QA accuracy (judged), not retrieval recall — different metric.\n\n---\n\n## CLI Commands\n\n### Basic Operations\n\n```bash\npixe convert \u003cinput\u003e -o \u003coutput.pixe\u003e    # Convert to .pixe\npixe extract \u003cfile.pixe\u003e -o \u003coutput\u003e      # Extract from .pixe\npixe info \u003cfile.pixe\u003e                     # Show file info\npixe verify \u003cfile.pixe\u003e                   # Verify integrity\npixe publish \u003cfile.pixe\u003e --target ipfs,arweave   # Upload to durability layers\n```\n\n### Semantic Search (any supported provider, or fully offline)\n\n```bash\n# Offline: deterministic hash embedder, no key needed.\npixe index \u003cfile.pixe\u003e --embedder hash\n\n# Hosted: pick any supported provider via its env var.\nexport OPENAI_API_KEY=sk-...           # or ANTHROPIC_API_KEY / GEMINI_API_KEY / OPENROUTER_API_KEY / ...\npixe index \u003cfile.pixe\u003e                           # Build index\npixe search \u003cfile.pixe\u003e \"query\" --top 5          # Search\npixe chat \u003cfile.pixe\u003e                            # Interactive chat\npixe chat \u003cfile.pixe\u003e --model openai/gpt-5       # Specific model\npixe chat \u003cfile.pixe\u003e --list                     # Show models\n```\n\n### Version Control\n\n```bash\npixe version \u003cfile.pixe\u003e -m \"message\"            # Create version\npixe versions \u003cfile.pixe\u003e                        # List versions\npixe diff \u003cfile.pixe\u003e \u003cv1\u003e \u003cv2\u003e                 # Compare versions\npixe query \u003cfile.pixe\u003e \u003cversion\u003e \"query\"         # Time-travel query\n```\n\n### Encryption / Decryption\n\n```bash\n# Encrypt at convert time\npixe convert file.txt -o file.pixe --encrypt --password 'long-strong-passphrase'\n\n# Decrypt at extract time\npixe extract file.pixe -o ./out --password 'long-strong-passphrase'\n```\n\n`--encrypt` and `--password` are flags on `pixe convert` and `pixe\nextract` only. Every other command (`info`, `verify`, `publish`,\n`hybrid-search` over the raw frames) operates on the encrypted bytes\nverbatim and never sees the plaintext. See the\n[Encryption \u0026 Decryption](#encryption--decryption) section for the\nfull operational model.\n\n### Durable publishing\n\n```bash\nexport IPFS_API_URL=http://127.0.0.1:5001\nexport ARWEAVE_NODE_URL=https://arweave.net\nexport ARWEAVE_WALLET_PATH=./wallet.json\n\npixe publish doc.pixe --target ipfs,arweave\n# returns one Result per network, each with locator + gateway URL\n```\n\n### Fractal memory\n\n```bash\n# Fold every day-level era into a week-level era (or week→month, month→quarter, ...).\npixe compact --data-dir ./.pixe-data --namespace agent-1 --level week\n\n# Free-association DeepRetrieve over the era graph; walks year→month→...→session.\npixe recall \"trip to Lisbon\" --data-dir ./.pixe-data --namespace agent-1 \\\n    --depth 3 --top 5\n\n# Conscious-recall mode: skip buried children.\npixe recall \"trip to Lisbon\" --surface-only --json\n```\n\n`compact` drives the same code path as the running `FractalService`'s\ncircadian scheduler but as a one-shot, so offline batch jobs and\ncatch-up after long downtime work without a daemon.\n`recall` is the read side: `DeepRetrieve` walks the URI graph from the\nhighest-level capsules in the store down through every level, returning\nranked hits with their depth, matched tier, and buried flag.\n\n---\n\n## Use Cases\n\n### Knowledge Base Management\n\n```bash\n# Create and index\npixe convert docs/ -o knowledge.pixe\npixe index knowledge.pixe\n\n# Semantic search\npixe search knowledge.pixe \"authentication best practices\"\n\n# Track changes\npixe version knowledge.pixe -m \"Added security section\"\npixe diff knowledge.pixe 1 2\n```\n\n### Compliance \u0026 Audit Trails\n\n```bash\n# Encrypted archive\npixe convert compliance-docs/ -o audit.pixe --encrypt --password xxx\n\n# Track all changes\npixe versions audit.pixe\n\n# Time-travel query\npixe query audit.pixe 1 \"Q1 data retention policy\"\n\n# Verify integrity\npixe verify audit.pixe --password xxx\n```\n\n### Research Paper Collections\n\n```bash\n# Index papers\npixe convert papers/ -o research.pixe\npixe index research.pixe\n\n# Semantic citation search\npixe search research.pixe \"transformer attention mechanisms\"\n\n# Chat with research\npixe chat research.pixe\n```\n\n### Secure Document Archival\n\n```bash\n# Encrypted, offline-first storage\npixe convert sensitive-docs/ -o vault.pixe --encrypt --password xxx\npixe verify vault.pixe --password xxx\npixe extract vault.pixe -o restored/ --password xxx\n```\n\n### Large-Scale Code Archival\n\n```bash\n# Streaming for multi-GB codebases\npixe convert monorepo.tar.gz -o codebase.pixe\n# Auto-streaming: 2.5 GB with 10MB RAM\n\n# Version control\npixe version codebase.pixe -m \"Release v2.0\"\n\n# Semantic code search\npixe search codebase.pixe \"authentication middleware\"\n```\n\n---\n\n## How It Works\n\n### Per-capsule pipeline\n\n```\nDocument → Chunks (2.9KB) → Encryption → QR Codes → MP4 Frames → .pixe File\n```\n\nEach `.pixe` file is an MP4 video:\n- Frame 0: Metadata (file info, encryption params, version history)\n- Frame 1+: QR-encoded data chunks\n- Audio track: Silent (required for MP4 spec)\n\n### Multi-capsule fractal\n\nSession capsules are the leaves of a self-similar tree. Era capsules\nat each level above (Day / Week / Month / Quarter / Year / Decade)\ncarry the same `(L0, L1, L2)` schema, with `L2` populated by child\ncapsule URIs instead of raw events. Compaction is triggered by either\ncircadian boundaries (calendar-aligned) or salience pressure (token-\nbudget watcher); both feed a single `Compact()` primitive that applies\nsalience-preserved collapse — top-K children stay surfaced (full L1\ninlined), the rest are buried (L1 stripped, content still URI-reachable).\n\n### Durability\n\nThe `CapsuleResolver` fans hash lookups across local store → IPFS\ngateway → Arweave node, transparently warming the local cache on\nremote hits. Publishing is the symmetric path: `BlobPublishers`\n(`pkg/publish/{ipfs,arweave}`) upload the capsule bytes to every\nconfigured durability network in parallel during the Archive phase.\n\n### Directory Structure\n\n```\npixelog/\n├── cmd/\n│   ├── pixe/                  # CLI (convert, extract, search, publish, ...)\n│   └── pixe-bench/            # benchmark harness (LoCoMo, ConvoMem, LongMemEval, MemBench)\n├── internal/\n│   ├── converter/             # document → .pixe\n│   ├── crypto/                # AES-256-GCM\n│   ├── qr/                    # QR encode/decode\n│   ├── video/                 # MP4 muxing / frame extraction\n│   ├── index/                 # HNSW + delta versioning\n│   ├── search/                # vector + lexical hybrid retriever\n│   ├── llm/                   # provider-agnostic LLM client\n│   └── memory/                # archival pipeline + fractal memory\n│       ├── archival.go        # 3-phase compress → archive → publish\n│       ├── condenser.go       # event-stream condensation\n│       ├── categories.go      # typed-memory category enum\n│       ├── category_store.go  # per-category vector subspace\n│       ├── retention.go       # Ebbinghaus retention scoring\n│       ├── access_tracker.go  # access frequency / recency\n│       ├── tiered.go          # (L0, L1, L2) tier triplet + GenerateTiers\n│       ├── era.go             # EraCapsule, EraLevel, ChildRef (fractal node)\n│       ├── capsule_store.go   # content-addressed local store\n│       ├── salience.go        # capsule-level salience scoring\n│       ├── compaction.go      # Compact() primitive + removed-middle\n│       ├── fractal_service.go # orchestrator (queues + triggers + storage)\n│       ├── trigger_circadian.go  # calendar-aligned scheduler\n│       ├── trigger_pressure.go   # token-budget watcher\n│       ├── resolver.go        # local → IPFS → Arweave fallback chain\n│       ├── retrieval_deep.go  # depth-bounded URI graph traversal\n│       └── uri.go             # pixe:// URI scheme parser\n├── pkg/\n│   ├── config/                # configuration types\n│   └── publish/               # durable-publish substrate\n│       ├── publish.go         # Publisher interface + Result\n│       ├── ipfs/              # Kubo HTTP API uploader\n│       └── arweave/           # self-signing format-2 tx + chunk upload\n└── benchmarks/                # benchmark report archive\n```\n\n---\n\n## Performance\n\n| Operation | Time | Notes |\n|-----------|------|-------|\n| Index Build | 136ms | One-time per file |\n| Semantic Search | \u003c100ms | With 1000+ frames |\n| Frame Extraction | 20ms | Direct FFmpeg seek |\n| LLM Chat Response | \u003c200ms | Excl. LLM latency |\n| Version Creation | 85ms | Delta calculation |\n| Integrity Check | 50ms/frame | Parallel decoding |\n\n### Per-file storage efficiency\n\n- Delta encoding: 64 % space savings\n- GZIP compression: 75 % reduction\n- Combined: ~80 % smaller than raw storage\n\n### Memory efficiency during conversion\n\n| File Size | Traditional | Pixelog streaming |\n|-----------|-------------|-------------------|\n| 10 MB | 10 MB RAM | 10 MB RAM |\n| 100 MB | 100 MB RAM | 10 MB RAM |\n| 1 GB | 1 GB RAM | 10 MB RAM |\n| 10 GB | 10 GB RAM | 10 MB RAM |\n\nStreaming auto-enables for files \u003e100 MB.\n\n### Lifetime storage scalability (fractal memory)\n\nAssumes a sustained 10 sessions/day with default circadian compaction\n(`SurfaceRatio = 0.30`).\n\nPer fold, salience-preserved collapse keeps the top 30 % of children\nfully surfaced (`L1` inlined) and buries the rest (`L0` only). Token\nmath: `0.3N · 550 + 0.7N · 50 + 550` → ~2.75× compression *per level*\nin surface-loadable bytes; compounded across the seven levels (Session\n→ Day → Week → Month → Quarter → Year → Decade) that's **~410×\nsurface-context compression**.\n\n| Lifetime | Leaf capsules | Era capsules | Total disk | Active context |\n| --- | --- | --- | --- | --- |\n| 1 year | 182 MB | ~5 MB | **~187 MB** | ~3 k tokens |\n| 10 years | 1.82 GB | ~50 MB | **~1.87 GB** | ~3 k tokens |\n| 100 years | 18.2 GB | ~500 MB | **~18.7 GB** | ~3.5 k tokens |\n| 1 000 years (theoretical) | 182 GB | ~5 GB | ~187 GB | ~4 k tokens |\n\nFleet projections:\n\n| Fleet × lifetime | Total | Practical tier |\n| --- | --- | --- |\n| 1 k agents × 10 yr | 1.87 TB | local + IPFS |\n| 100 k agents × 10 yr | 187 TB | IPFS + Arweave |\n| 1 M agents × 10 yr | **1.87 PB** | Arweave dominant |\n| 100 k agents × 100 yr | **1.87 PB** | Arweave dominant |\n\n**Headline.** Active memory cost grows logarithmically with agent age;\ntotal disk is bounded only by the underlying durability substrate.\nPB-scale fleet memory is realistic on the IPFS+Arweave stack.\n\n### Theoretical bounds\n\n| Bound | Value | Practical meaning |\n| --- | --- | --- |\n| Hash address space | 2²⁵⁶ ≈ 10⁷⁷ | Effectively infinite — no collision concern |\n| Per-capsule resolvable bytes | 2⁶⁴ − 1 | 16 EB before format-level overflow |\n| Active context per query | ~7 × L1 ≈ 3.5 k tokens | Bounded regardless of agent age |\n| Disk substrate | Arweave endowment | Permaweb economics |\n| Retrieval depth | configurable (`MaxDepth`) | `O(branching·depth)` worst case |\n\n---\n\n## Security Model\n\nPixelog's security posture is intentionally narrow: it protects payload\nconfidentiality and integrity at rest. It is *not* a key-management\nsystem, an access-control system, or a secure-enclave runtime. Compose\nit with those layers when needed.\n\n### Cryptographic primitives\n\n| Primitive       | Choice                          | Rationale |\n| --------------- | ------------------------------- | --------- |\n| Symmetric AEAD  | AES-256-GCM                     | NIST-standard, hardware-accelerated, authenticated |\n| KDF             | PBKDF2-HMAC-SHA-256, 600 000 iters | OWASP-current, deterministic, no GPU shortcut for small budgets |\n| Salt            | 32 bytes / file, CSPRNG         | Per-file domain separation |\n| Nonce           | 12 bytes / operation, CSPRNG    | GCM-correct length, no reuse |\n| Integrity tag   | 16 bytes (GCM)                  | Detects single-bit tamper |\n| Frame integrity | SHA-256 on chunk pre-encryption | Independent of GCM tag |\n\nNo bespoke crypto. All primitives come from `crypto/aes`, `crypto/cipher`,\n`crypto/sha256`, `golang.org/x/crypto/pbkdf2`.\n\n### Resilience to physical / channel damage\n\n- Reed-Solomon at the chunk layer tolerates ≈ 30 % loss per frame.\n- QR error-correction level H gives a second redundancy layer at the\n  pixel level.\n- The two combined mean a `.pixe` file remains decodable through severe\n  re-encoding, scaling, color-space conversion, and partial frame loss.\n\n### What this does *not* address\n\n- Side-channel attacks against the host running decryption.\n- Adversaries with the password (encryption is symmetric).\n- Forward-secrecy across versions (use external key rotation if\n  required).\n- Confidentiality of the *fact that a file exists* (the MP4 container\n  is plaintext metadata).\n\n### File Structure\n\n```\n.pixe File (MP4 Container)\n├── Video Track (H.264)\n│   ├── Frame 0: Metadata\n│   ├── Frame 1+: [32B salt][12B nonce][encrypted data][16B auth tag]\n└── Audio Track (silent)\n```\n\n---\n\n## Encryption \u0026 Decryption\n\nEncryption is a per-file, AES-256-GCM operation applied at convert\ntime and reversed at extract time. The cryptographic primitives, the\nKDF parameters, and the on-disk layout are documented in\n[Security Model](#security-model); this section is the operational\nguide.\n\n### CLI\n\n```bash\n# Encrypt at convert time.\npixe convert plaintext.pdf -o secret.pixe \\\n    --encrypt --password 'long-strong-passphrase'\n\n# Decrypt at extract time.\npixe extract secret.pixe -o ./out \\\n    --password 'long-strong-passphrase'\n```\n\n`--encrypt` and `--password` are flags on `pixe convert` only;\n`--password` is also accepted by `pixe extract`. Every other command\n(`info`, `verify`, `publish`) operates on the encrypted bytes\nverbatim and never sees the plaintext.\n\n### What is encrypted, what stays plaintext\n\nOnly the **payload chunks** inside each video frame are encrypted.\nThe MP4 container, per-frame headers, and the metadata frame remain\nplaintext so any commodity media stack (browsers, FFmpeg, mobile OS\nthumbnailers, S3, IPFS gateways) can transport, seek, and stream a\n`.pixe` file without ever holding the password.\n\nPer encrypted payload chunk the on-disk layout is:\n\n```\n[ 32-byte salt ][ 12-byte nonce ][ ciphertext… ][ 16-byte GCM tag ]\n```\n\n- **Salt**: CSPRNG-fresh per file. Domain-separates the KDF output so\n  two encryptions of the same plaintext under the same password\n  produce different ciphertext.\n- **Nonce**: CSPRNG-fresh per chunk. GCM-correct length, never reused.\n- **GCM tag**: 16 bytes of authentication. A single-bit tamper\n  anywhere in salt / nonce / ciphertext fails the open with\n  `cipher: message authentication failed`.\n- **Key**: AES-256, derived via PBKDF2-HMAC-SHA-256 with 600 000\n  iterations from the user password and the per-file salt.\n\n### Integrity verification works without the password\n\n`pixe verify` checks SHA-256 frame hashes recorded in the metadata\nframe; those hashes cover the ciphertext, not the plaintext. So you\ncan publish an encrypted `.pixe` to IPFS / Arweave and any third\nparty can confirm the bytes haven't been tampered with **without\never holding the decryption key**. Confidentiality and integrity are\northogonal in the design.\n\n### Durability layers stay encrypted\n\nAn encrypted `.pixe` uploaded via `pixe publish --target ipfs,arweave`\ngoes onto those networks encrypted. The Kubo daemon, the Arweave\nminers, and any gateway that fetches the CID / tx-id all see only the\nciphertext. There is no in-flight or at-rest decryption on the\ndurability path.\n\n### What encryption does not cover\n\n- **Existence and shape.** The MP4 container, file size, frame count,\n  and metadata frame are plaintext. An adversary on the wire learns\n  that a `.pixe` file exists and roughly how big it is.\n- **Indexing and search.** `pixe index`, `pixe search`, and\n  `pixe chat` need the plaintext today. The current workflow is to\n  extract to a temporary unencrypted `.pixe`, index, then discard.\n  In-memory decrypt-then-index without touching disk is on the\n  roadmap.\n- **Password recovery.** There is no master key, no recovery file,\n  no vendor backdoor. Lose the password and the file is\n  unrecoverable. PBKDF2 at 600 000 iterations slows brute force by a\n  large constant factor but does not save weak passwords — use a\n  passphrase manager and at least 80 bits of entropy.\n- **Forward secrecy across versions.** A captured ciphertext stays\n  decryptable with the password forever. If you need rotation,\n  re-encrypt with a new password and re-publish; old CIDs / tx-ids\n  remain decryptable until they are unpinned / archived.\n\n### Library API\n\nThe converter package exposes the same primitives so embedded users\ncan drive the lifecycle programmatically:\n\n```go\nimport \"github.com/ArqonAi/Pixelog/internal/converter\"\n\nconv, _ := converter.New(\"./output\")\n\n// Encrypt at write.\nconv.ConvertFile(\"doc.txt\", \u0026converter.ConvertOptions{\n    OutputPath:    \"doc.pixe\",\n    EncryptionKey: \"long-strong-passphrase\",\n})\n\n// Decrypt at read.\nconv.Extract(\"doc.pixe\", \"./out\", \"long-strong-passphrase\")\n```\n\n`EncryptionKey == \"\"` skips the KDF and writes plaintext frames; the\nrest of the pipeline (chunking, QR encoding, MP4 muxing, SHA-256\nframe hashes) is identical between encrypted and plaintext modes.\n\n---\n\n## LLM Integration\n\nPixelog speaks any of the major chat / embedding APIs through a single\n`MultiClient` (`internal/llm/providers.go`). Pick the provider via\n`--provider` (or `LLM_PROVIDER`), supply that provider's key in its\nstandard environment variable, and every command that takes `--model`\njust works. There is no preferred vendor and no lockin — each provider\nis spoken in its own native API.\n\n### Supported providers\n\n| Provider | Env var | API |\n| --- | --- | --- |\n| `openai` | `OPENAI_API_KEY` | OpenAI Chat Completions (native) |\n| `anthropic` | `ANTHROPIC_API_KEY` | Anthropic Messages (native) |\n| `gemini` | `GEMINI_API_KEY` | Google Gemini (native) |\n| `ollama` | _(none, local)_ | Ollama (native) |\n| `xai` | `XAI_API_KEY` | Chat Completions wire format |\n| `groq` | `GROQ_API_KEY` | Chat Completions wire format |\n| `deepseek` | `DEEPSEEK_API_KEY` | Chat Completions wire format |\n| `moonshot` | `MOONSHOT_API_KEY` | Chat Completions wire format |\n| `nvidia` | `NVIDIA_API_KEY` | Chat Completions wire format |\n| `zai` | `ZAI_API_KEY` | Chat Completions wire format |\n| `openrouter` | `OPENROUTER_API_KEY` | Chat Completions wire format (200+ model aggregator) |\n| `local` | _(none, local)_ | Chat Completions wire format on localhost |\n\nThe \"Chat Completions wire format\" is a de-facto industry-standard\nrequest / response schema that every vendor in the lower block of the\ntable has independently adopted; it is a JSON shape, not an OpenAI\nproduct dependency. Any future vendor that ships the same shape works\nin Pixelog with one entry in `providerSpecs()` — endpoint, env var,\ndefault model.\n\nEmbedding providers mirror the same set (`internal/search/embeddings.go`):\nOpenAI, Gemini, xAI, OpenRouter, and Ollama. The deterministic\n`HashEmbedder` is built in and needs no key — it is what every benchmark\nrow in [`benchmarks/BENCHMARKS.md`](benchmarks/BENCHMARKS.md) uses.\n\n### Usage\n\n```bash\n# Local-only path: deterministic hash embedder + on-host Ollama for chat.\npixe chat doc.pixe --provider ollama --model llama3.1:8b\n\n# OpenAI path.\nexport OPENAI_API_KEY=sk-...\npixe chat doc.pixe --provider openai --model gpt-4o-mini\n\n# Anthropic path.\nexport ANTHROPIC_API_KEY=sk-ant-...\npixe chat doc.pixe --provider anthropic --model claude-sonnet-4-5\n\n# OpenRouter aggregator (any of its 200+ models via one key).\nexport OPENROUTER_API_KEY=sk-or-v1-...\npixe chat doc.pixe --provider openrouter --model openai/gpt-5\n```\n\nAdding a new provider is one entry in `providerSpecs()` — endpoint,\nauth header, env var, default model, and which API shape it speaks.\n\n---\n\n## FAQ\n\n### Why video-based storage?\n\n1. **Universal compatibility**: MP4 plays everywhere\n2. **Built-in streaming**: Progressive loading\n3. **Frame-level access**: Direct seek without loading full file\n4. **Visual inspection**: See data as scannable QR codes\n5. **Novel use cases**: Video-based data transmission\n\n### Do I need an API key?\n\n**Optional**. Core operations work offline:\n- Convert, extract, verify, version control: no API needed\n- Semantic search with the bundled `HashEmbedder`: no API needed\n- Local LLM chat via `--provider ollama`: no API needed\n\n**An API key is only required when you choose a hosted provider** for\nLLM chat or for higher-quality embeddings. Pick whichever of the\nsupported providers above you already have a key for; there is no\nlock-in to any single vendor.\n\n### How secure is it?\n\nPayload confidentiality and integrity are protected by AES-256-GCM\nwith PBKDF2-SHA-256 key derivation (600 000 iterations) and per-file\nrandom salts and nonces. Integrity is verified independently via\nSHA-256 frame hashes. The implementation uses standard-library and\n`x/crypto` primitives only — no bespoke cryptography.\n\nThis is appropriate for at-rest protection of sensitive material under\ncommon compliance regimes (HIPAA, SOC 2, ISO 27001) when paired with a\nproper key-management story. It does **not** provide forward secrecy\nacross versions, key rotation, or access control — those are out of\nscope and should be layered above Pixelog.\n\n### How does memory scale over an agent's lifetime?\n\nThe fractal memory hierarchy keeps active context cost at\n`O(log T)` regardless of how long the agent has been alive: a\n100-year-old agent loads roughly the same number of summary tokens\n(~3.5 k) as a 1-year-old agent. Total disk grows linearly in raw\nsessions, but ~70 % of each level's children are *buried* on every\nrollup — their content is still URI-reachable via deep retrieval but\ndoesn't cost active-context tokens. See the storage-scalability table\nin Performance for concrete numbers.\n\n### What about durability — what happens when my disk dies?\n\nThe `pkg/publish` package ships real, no-SDK uploaders for IPFS\n(Kubo `/api/v0/add`, CIDv1 raw-leaves) and Arweave (self-signed format-2\ntxs with merkle data-root, RSA-PSS-SHA256 over the deep-hash payload).\nThe archival pipeline fans the capsule out to every configured\npublisher in parallel; the `CapsuleResolver` reads back through the\nsame networks transparently. Live runbook in `pkg/publish/E2E.md`.\n\n### Can I use it offline?\n\n**Yes, most features**:\n- Offline: convert, extract, encrypt/decrypt, verify, version control,\n  hash-embedded semantic search, local LLM chat via Ollama\n- Online (only when you opt in to a hosted provider): higher-quality\n  embeddings, frontier-model chat\n\n### How large can files be?\n\n**No practical limit** due to streaming:\n- Small files (\u003c100MB): Loaded into memory\n- Large files (\u003e100MB): Auto-streaming mode\n- Memory: Constant 10MB footprint\n- Tested: Up to 10GB files\n\n### What file types?\n\n**All types**: Documents, code, archives, media, databases, binaries.\nPixelog is format-agnostic.\n\n### How fast is search?\n\n**Sub-100ms**:\n- Index build: 136ms (one-time)\n- Search query: \u003c100ms (1000+ frames)\n- Total: Query → Results in \u003c100ms\n\n---\n\n## API \u0026 Library Usage\n\n```go\npackage main\n\nimport (\n    \"github.com/ArqonAi/Pixelog/internal/converter\"\n    \"github.com/ArqonAi/Pixelog/internal/index\"\n    \"github.com/ArqonAi/Pixelog/internal/llm\"\n)\n\nfunc main() {\n    // Convert\n    conv, _ := converter.New(\"./output\")\n    conv.ConvertFile(\"doc.txt\", \u0026converter.ConvertOptions{\n        OutputPath:    \"doc.pixe\",\n        EncryptionKey: \"password\",\n    })\n\n    // Index\n    // Provider can be \"openai\", \"anthropic\", \"gemini\", \"xai\",\n    // \"openrouter\", \"ollama\", \"hash\" (offline), etc.\n    embedder := index.NewSimpleEmbedder(\"openai\", apiKey, \"auto\")\n    indexer, _ := index.NewIndexer(\"./indexes\", embedder)\n    idx, _ := indexer.BuildIndex(\"doc\", \"doc.pixe\")\n\n    // Search\n    results, _ := indexer.Search(idx, \"query\", 5)\n\n    // Version control\n    deltaManager, _ := index.NewDeltaManager(\"./deltas\", indexer)\n    deltaManager.CreateVersion(\"doc\", \"doc.pixe\", \"Initial\", \"user\")\n\n    // LLM chat\n    client := llm.NewClient(\"deepseek/deepseek-r1\", apiKey)\n    response, _ := client.Chat(\"Explain main concepts\")\n}\n```\n\n---\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md)\n\n```bash\ngit checkout -b feature/amazing-feature\n./test_e2e.sh\ngit commit -m \"feat: Add amazing feature\"\ngit push origin feature/amazing-feature\n```\n\n---\n\n## License\n\nApache License 2.0 - see [LICENSE](LICENSE)\n\n---\n\n## Support\n\n- [Documentation](docs/)\n- [Issue Tracker](https://github.com/ArqonAi/Pixelog/issues)\n- [Discussions](https://github.com/ArqonAi/Pixelog/discussions)\n\n---\n\n**Made by [ArqonAi](https://github.com/ArqonAi)**\n\n*Turn documents into videos. Search at the speed of thought. Track changes like Git. Chat with AI.*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farqonai%2Fpixelog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farqonai%2Fpixelog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farqonai%2Fpixelog/lists"}