{"id":50312497,"url":"https://github.com/5queezer/aver","last_synced_at":"2026-05-28T22:01:49.856Z","repository":{"id":356834701,"uuid":"1232670081","full_name":"5queezer/aver","owner":"5queezer","description":"Local-first, auditable memory layer for coding agents in Rust","archived":false,"fork":false,"pushed_at":"2026-05-17T16:43:00.000Z","size":5260,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-17T18:49:17.344Z","etag":null,"topics":["agent-memory","coding-agents","local-first","mcp","memory-layer","rust","sqlite","tree-sitter"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/5queezer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-08T06:41:18.000Z","updated_at":"2026-05-17T16:43:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/5queezer/aver","commit_stats":null,"previous_names":["5queezer/aver"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/5queezer/aver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5queezer%2Faver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5queezer%2Faver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5queezer%2Faver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5queezer%2Faver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/5queezer","download_url":"https://codeload.github.com/5queezer/aver/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/5queezer%2Faver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33627946,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","coding-agents","local-first","mcp","memory-layer","rust","sqlite","tree-sitter"],"created_at":"2026-05-28T22:01:48.994Z","updated_at":"2026-05-28T22:01:49.836Z","avatar_url":"https://github.com/5queezer.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Aver\n\nAver is a local-first memory layer for coding agents: an append-only episodic log, a durable claim graph with first-class hyperedges, vector recall primitives, deterministic code extraction, and an MCP/OAuth server surface in one Rust workspace.\n\nAver is experimental. The architecture is ADR-driven and the current implementation is useful, but not all ADRs are complete yet. See [Implementation status](#implementation-status) for what is built today.\n\n## Why\n\nMost agent memory systems either store loose text chunks or rely on opaque background reasoning. Aver takes a more conservative route inspired by *The Memory Layer*: every durable memory should be structured, provenance-tracked, privacy-checked, and replayable from an append-only log.\n\nThe goal is a trustworthy substrate for coding agents that can:\n\n- remember explicit project facts as triples such as `PaymentGateway depends_on StripeSDK`,\n- keep an audit trail of memory writes in `log.jsonl`,\n- derive searchable claims and vectors from that log,\n- reject secrets before they enter memory,\n- extract code relationships deterministically with Tree-sitter,\n- expose memory through a small CLI and MCP-compatible server.\n\n## Features\n\n- **Local-first storage** — SQLite plus `log.jsonl` under a configurable memory directory.\n- **Append-first writes** — durable claims and hyperedges are appended to JSONL before SQLite insertion.\n- **Structured claims** — memories are stored as `(subject, predicate, object)` claims with source references, confidence, status, and agent provenance.\n- **First-class hyperedges** — n-ary memories can be stored with predicate, provenance, confidence, source references, status, timestamps, and role/entity participants.\n- **Privacy gate** — token/path/entropy checks run before writes; rejected content is not persisted.\n- **Keyword, vector, and hybrid recall primitives** — text recall is available through the CLI; vector chunks and hybrid ranking over active claims are implemented in the core crate.\n- **Adaptive HybridRAG weights** — structural graph questions lean toward graph context; broad summary questions lean toward vectors; explicit alpha overrides are range-validated.\n- **Graph expansion, path queries, and communities** — local claim neighborhoods, confidence/provenance-aware shortest path queries over active claims and hyperedges, and deterministic weighted community detection are available in core.\n- **Contradiction records and confidence decay** — contradictions are explicit audit records; consolidation can decay contradicted active claims and report merged/superseded/decayed counts.\n- **Deterministic code extraction** — `aver-extractor` uses Tree-sitter Rust to extract functions, imports, calls, structs, enums, traits, impl methods, tests, and code facts.\n- **Candidate claim workflow** — episodic events can produce staged claims that are promoted or rejected explicitly.\n- **Observation continuity surfaces** — episodic events can produce privacy-checked, source-backed observations that are recallable by ID, summarized by compaction, and coverage-accounted across full session event ranges.\n- **Continuity reliability controls** — coverage accounting, deterministic `catch-up`, gap warnings in summaries, destructive prune operations blocked when gaps remain, prune markers preserved in logs, and audit-aware observation recall.\n- **MCP/OAuth server** — `aver-server` exposes memory tools over Streamable HTTP MCP behind a local OAuth-style token flow, including the ADR-0008 five-tool surface with validated recall/write/event/extraction-trigger parameters, observation projection tools, explicit unsupported-scope errors, persisted confidence overrides, and recall subgraphs with confidence floors.\n- **Evaluation harnesses** — fixture evaluation plus a BEAM100K runner using local Ollama for embeddings, answer generation, and judging.\n\n## Quick Start\n\n### Install from this checkout\n\nPrerequisites:\n\n- Rust toolchain compatible with the workspace (`rust-version = 1.95`)\n- `cargo`\n\n```bash\n./install.sh\n# equivalent when run from the Aver git checkout:\n./install.sh --from-source\n# or, if you use just:\njust install\n```\n\nWhen run from the Aver git repository, `install.sh` detects the checkout and installs from source. This installs the `aver` CLI to `~/.cargo/bin` by default. For local MCP/OAuth service deployments that execute `target/release/aver-server`, run `just release-server` to build and strip the server binary before restarting the service.\n\n### Store and recall a claim\n\n```bash\naver --memory-dir .aver status\naver --memory-dir .aver remember PaymentGateway depends_on StripeSDK --source session_47\naver --memory-dir .aver recall Stripe\n```\n\nExpected recall output:\n\n```text\nPaymentGateway depends_on StripeSDK\n```\n\nThe store directory will contain:\n\n```text\n.aver/\n├── db.sqlite   # indexed SQLite projection\n└── log.jsonl   # append-only audit log\n```\n\n## How It Works\n\nAver separates memory into three projections:\n\n```text\nUser / Agent\n  → CLI or MCP tool\n  → privacy filter\n  → append JSONL event/claim first\n  → insert/update SQLite projection\n  → recall by text, vector, or hybrid ranking\n```\n\nThe design maps to the ADRs:\n\n- **Episodic log** — chronological append-only record in `log.jsonl` and `events.jsonl`.\n- **Observation projection** — privacy-checked session-continuity observations over episodic events, with source-event provenance and mechanical compaction summaries.\n- **Observation coverage accounting** — `Store::observation_coverage()` computes covered/uncovered event IDs per session; uncovered IDs are exposed to callers and used to block unsafe pruning.\n- **Continuity blockers** — session summaries mark uncovered ranges explicitly, and pruning refuses to proceed until coverage gaps are resolved by catch-up projection.\n- **Prune markers + audit recall** — pruning emits append-only tombstones in `observations.jsonl`; pruned observations disappear from default views but remain recallable with audit metadata.\n- **Semantic graph** — durable claims/triples in SQLite.\n- **Ontology reasoner** — ADR-0010 entity and predicate hierarchies are seeded on open, materialized into closure tables, and used by graph expansion and path predicate filters so abstract filters such as `depends_on` also match descendant predicates like `calls`, `imports`, and accepted aliases such as `requires`; MCP/tool-facing diagnostics for unknown non-user predicates use alias-aware fuzzy suggestions plus the current predicate/alias vocabulary.\n- **Typed entities** — claim subjects/objects are projected into `entities` with prefix-based types such as `Function:*` and fallback `Thing` for unknown entities.\n- **Vector store** — `vector_chunks` with JSON-serialized embeddings and a `sqlite-vec`/`vec0` ANN table where the bundled extension is available.\n- **Extraction** — Rust Tree-sitter extractor turns source code into structured facts.\n- **Graph tools** — recall, expand, add-triple, contradict, and consolidate map the ADR-0008 surface onto the local claim store.\n- **Consolidation** — duplicate/conflict handling supersedes older claims, explicit contradictions can decay confidence, and report counts summarize merged, superseded, and decayed claims.\n\nFor a deeper implementation walkthrough, see [`doc/how-it-works.md`](doc/how-it-works.md). For design rationale, see the ADRs in [`doc/adr/`](doc/adr/).\n\n## Design References\n\nAver's implementation is intentionally conservative and source-grounded:\n\n- *The Memory Layer* frames durable memory as append-only triples consolidated from episodic fragments into a persistent graph, with HybridRAG combining vector search and graph traversal [ch.147–148].\n- Karta demonstrates the value of active memory operations such as multi-hop traversal, contradiction detection, consolidation, confidence, and temporal awareness; Aver keeps those ideas behind explicit, auditable claim tools instead of opaque note mutation.\n- MuninnDB shows practical retrieval controls such as mode/weight selection, entity graph traversal, relationship types, confidence-preserving entity state, and use-strength/decay; Aver adopts the local-first graph and adaptive retrieval pieces that fit its SQLite/Rust ADRs.\n\n## CLI Usage\n\n```bash\naver --help\naver --memory-dir .aver status\naver --memory-dir .aver remember \u003csubject\u003e \u003cpredicate\u003e \u003cobject\u003e --source \u003csource\u003e\naver --memory-dir .aver recall \u003cquery\u003e\naver --memory-dir .aver communities\n```\n\nCurrent CLI commands:\n\n| Command | Purpose |\n|---|---|\n| `status` | Open the store and report readiness. |\n| `remember` | Append a user-asserted structured claim. |\n| `recall` | Search active claims by keyword. |\n| `record-event` | Record an episodic event with session/kind/payload and optional source. |\n| `should-extract-memories` | Check extraction trigger conditions for a session. |\n| `propose` | Propose a candidate claim from an event. |\n| `list-candidates` | List candidate claims with optional session/status filters. |\n| `promote` | Promote a candidate claim into durable memory. |\n| `reject` | Reject a candidate claim with a reason. |\n| `record-observation` | Record a session observation from source events. |\n| `recall-observation` | Recall an observation with its supporting event payloads and audit status. |\n| `observation-coverage` | Report event coverage and uncovered ranges for a session. |\n| `catch-up` | Run a deterministic catch-up projection over uncovered events. |\n| `compaction-summary` | Assemble a continuity summary including coverage gap warnings. |\n| `expand` | Expand an entity neighborhood from the local claim graph. |\n| `communities` | Print deterministic weighted graph communities with score and bridge nodes. |\n| `add-triple` | Append a confidence-bearing structured triple. |\n| `contradict` | Record a contradiction for a claim id and optional replacement claim. |\n| `consolidate` | Consolidate active duplicates/conflicts and apply confidence decay. |\n| `vacuum` | Run `VACUUM` (and optional analysis). |\n| `replay` | Rebuild SQLite from the append-only logs. |\n\n## Server and MCP Usage\n\nRun the MCP/OAuth HTTP server:\n\n```bash\ncargo run -p aver-server\n```\n\nDefault configuration:\n\n| Environment variable | Default | Purpose |\n|---|---:|---|\n| `AVER_HOST` | `127.0.0.1` | Bind host. |\n| `AVER_PORT` | `3317` | Bind port. |\n| `AVER_BASE_URL` | `http://127.0.0.1:3317` | Public base URL used in OAuth metadata. |\n| `AVER_MEMORY_DIR` | `.aver` | Memory store directory. |\n| `AVER_AUTH_DB_PATH` | `\u003cAVER_MEMORY_DIR\u003e/auth.db` | SQLite auth database path. |\n| `AVER_CORS_ORIGINS` | *(allow any origin)* | Optional comma-separated allowed origins for protected MCP CORS responses. |\n| `AVER_TRUSTED_AUTH_HEADER` | *(unset)* | Optional reverse-proxy header name (for example `X-Forwarded-User`) that enables non-loopback OAuth authorization using Profile C trusted-header auth. |\n\n\nUseful endpoints:\n\n- `GET /.well-known/oauth-authorization-server`\n- `POST /oauth/register`\n- `GET /oauth/authorize` (browser consent screen; loopback by default, optional trusted-header for non-loopback)\n- `POST /oauth/authorize/decision` (consent-screen form submission)\n- `POST /oauth/token` for authorization-code + PKCE token exchange and refresh-token grants\n- `GET /api/health` with `Authorization: Bearer \u003ctoken\u003e`\n- `/mcp` with `Authorization: Bearer \u003ctoken\u003e`\n\n`/oauth/authorize` drives a browser consent flow (ADR-0020). After a client dynamic-registers via `POST /oauth/register`, it redirects the user to `/oauth/authorize` with the standard PKCE parameters. Aver renders a consent screen showing the client name, redirect URI, and all supported scopes as checkboxes, with the client's requested scopes pre-selected; on **Approve** it stores a per-client consent row, mints an authorization code bound to the checked scopes, and redirects back to the client's `redirect_uri` with `code` and `state`. The client then exchanges the code at `/oauth/token` for an `access_token` plus `refresh_token`; refresh grants issue a new access token while preserving the existing refresh token, and access tokens carry only the scopes recorded on the consent row.\n\nThe flow supports loopback (`127.0.0.1` / `::1`) callers by default (Profile A in ADR-0020). Non-loopback callers can also authenticate via Profile C when `AVER_TRUSTED_AUTH_HEADER` is set to a trusted upstream identity header (for example `X-Forwarded-User`); otherwise they are rejected with an HTML 403.\n\n### Connecting an MCP client\n\nFor Visual Studio Code, drop a workspace-level `.vscode/mcp.json` similar to:\n\n```json\n{\n  \"servers\": {\n    \"aver\": {\n      \"type\": \"http\",\n      \"url\": \"http://127.0.0.1:3317/mcp\"\n    }\n  }\n}\n```\n\nThen run **MCP: Add Server** from the command palette and pick `aver`. VS Code dynamic-registers with `POST /oauth/register`, opens the consent screen in your browser, and — after you click **Approve** — receives the authorization code and exchanges it for an access token automatically. Other MCP clients that support the OAuth 2.1 + PKCE discovery profile (`/.well-known/oauth-authorization-server`) follow the same path.\n\nMCP currently exposes 18 tools through a progressive discovery card so agents keep the active choice set small:\n\n- **Default active set:** `recall`, `remember_claim`, `record_event`, `record_observation`, `assemble_compaction_summary`\n- **Event-to-claim workflow:** progressively load `should_extract_memories`, `propose_candidate_claim`, `list_candidate_claims`, `promote_candidate_claim`, `reject_candidate_claim` only when converting raw events into reviewed durable claims\n- **Graph navigation:** progressively load `expand` after recall returns an entity or an anchor is already known; use `add_triple` instead of `remember_claim` only when explicit source/confidence control is required\n- **Observation audit:** progressively load `recall_observation`, `observation_coverage` for handoff, compaction, or provenance checks\n- **Maintenance/repair:** keep `contradict`, `retire_claim`, `consolidate`, `add_vector_chunk` hidden until there is an explicit repair or retrieval-tuning need\n\nAver's MCP guide is intentionally proactive but selective: agents should recall first, then record durable user-shared preferences, project facts, and long-lived working context even when the user does not say \"remember this\" explicitly. Identity details should be recorded only when they are necessary, user-shared, and not sensitive personal data. When durability is uncertain, agents should prefer `record_event` over `remember_claim`, and they must not store secrets, credentials, sensitive personal data, transient chat, or facts they cannot explain with provenance.\n\nCLI-only continuity and maintenance surfaces (`catch-up`, `compaction-summary`) are implemented in `aver-cli`; MCP exposes `record_observation`, `assemble_compaction_summary`, and the observation audit tools above, while claim-maintenance tasks stay available through the four advanced tools when agents explicitly need them.\n\nAdapter boundaries are explicit in `aver-server` via the `adapters` module (`Pi`, `ClaudeCode`, `CodexOpenAi`, `OpenCode`, `Mcp`, `JsonlCliHarness`) so host runtimes can be added without leaking host-specific logic into `aver-core`.\n\n## Evaluation\n\nRun deterministic workspace tests:\n\n```bash\ncargo test --workspace --locked\n# or\njust test\n```\n\nRun the local quality gate:\n\n```bash\njust check\n```\n\nRun fixture evaluation:\n\n```bash\ncargo run -p aver-eval -- \u003cfixture.json\u003e [fixture.json ...]\n```\n\nThe eval crate also exposes deterministic data structures for ADR-0012 query-suite regression threshold checks, hallucination-rate memory-on/off reports, graph-stat drift snapshots with privacy-rejection counters, and typed prompt contracts. Prompt contracts validate rendered prompt text before a model call using deterministic checks such as required text, forbidden text, required sections, unresolved-template detection, and character budgets. These checks validate prompt generation code; live judge/provider integrations and output-quality evals should remain separate and feed recorded case results into the eval structures.\n\nRun BEAM100K with local Ollama:\n\n```bash\ncargo run -p aver-eval --bin aver-beam100k -- \\\n  --dataset path/to/beam-100k.json \\\n  --ollama-base-url http://localhost:11434 \\\n  --embedding-model nomic-embed-text \\\n  --generation-model gemma4 \\\n  --top-k 12\n```\n\nThe BEAM runner expects Ollama to provide both the embedding model and generation/judge model. Retrieval tuning can override HybridRAG alpha in addition to `top_k`:\n\n```bash\ncargo run -p aver-eval --bin aver-beam100k -- \\\n  --dataset path/to/beam-100k.json \\\n  --top-k 16 \\\n  --retrieval-alpha 0.65\n```\n\nFor Bayesian-style retrieval search over prior live runs, write JSONL observations with `top_k`, `alpha`, and `metric`, then ask Aver for the next autoresearch configuration:\n\n```bash\ncargo run -p aver-eval --bin aver-tune-retrieval -- \\\n  --observations retrieval-observations.jsonl\n```\n\nThe tuner prints `BEAM_TOP_K`, `BEAM_RETRIEVAL_ALPHA`, and `AVER_AUTORESEARCH_TARGET=beam` values that can be used for the next autoresearch run. Keep a held-out validation split; do not tune directly against final benchmark labels.\n\n## Prose/document plugin boundary\n\nADR-0013 permits non-Rust prose/document extraction plugins only behind stdin/stdout JSON-RPC. `aver-extractor::JsonRpcPluginRunner` sends one JSON-RPC request to a configured child process, parses the response, validates extracted fact fields, and returns facts to Rust callers. Plugins are extraction-only: they do not write memory directly and cannot bypass core privacy/log-first validation. The current runner is a process boundary, not an OS sandbox; production deployments should run plugins from an allowlisted command with external filesystem/environment sandboxing when untrusted plugins are enabled.\n\n## Project Structure\n\n```text\nagent-memory-layer/\n├── crates/\n│   ├── aver-core/       # Store, claims, events, privacy filter, vectors, recall, consolidation\n│   ├── aver-cli/        # `aver` command-line interface\n│   ├── aver-extractor/  # Tree-sitter Rust and prose fact extraction\n│   ├── aver-server/     # MCP/OAuth HTTP server\n│   └── aver-eval/       # Fixture and BEAM100K evaluation runners\n├── doc/\n│   ├── adr/             # Architecture decision records\n│   └── how-it-works.md  # Current implementation walkthrough\n├── migrations/          # Embedded SQLite migrations\n├── install.sh           # Source/release installer\n└── justfile             # Development automation\n```\n\n## Development\n\nCommon commands:\n\n```bash\njust build       # cargo build --workspace --locked\njust test        # cargo test --workspace --locked\njust fmt         # cargo fmt --all\njust clippy      # cargo clippy --workspace --no-deps -- -D warnings\njust check       # format check + clippy + tests + autoresearch checks\njust release     # release build for aver-cli\njust dist        # local release tarball and SHA256SUMS under target/dist\n```\n\nWithout `just`, use the equivalent Cargo commands shown in the [`justfile`](justfile).\n\n## Implementation Status\n\nImplemented today:\n\n- local-first `Store` backed by SQLite and JSONL,\n- migrations for claims, hyperedges, vector chunks, ontology tables, episodic events, candidate claims, and observation projections,\n- append-first claim, hyperedge, and event writes,\n- privacy filtering before claim, event, and observation writes,\n- claim CRUD and keyword recall,\n- active-only hyperedge create/list/recall/traversal APIs,\n- vector chunk storage and embedding abstractions,\n- Ollama embedding client and deterministic mock embedding client,\n- cosine similarity, adaptive HybridRAG weights, and hybrid vector/text recall primitives,\n- graph expansion/traversal over active claim triples, confidence/provenance-aware path queries over active claims and hyperedges, and weighted community detection,\n- explicit contradiction records and confidence decay for contradicted active claims,\n- basic consolidation for duplicate/conflicting claims,\n- CLI `status`, `remember`, `recall`, `communities`, and observation continuity surfaces (`record-observation`, `recall-observation`, `observation-coverage`, `catch-up`, `compaction-summary`),\n- Tree-sitter Rust extraction,\n- structured prose fact parsing,\n- MCP/OAuth server with ADR-0008 recall/expand/add-triple/contradict/consolidate tools, staged candidate-claim workflow, and observation recall/compaction-summary tools,\n- ADR-0020 browser consent flow for `/oauth/authorize` (loopback Profile A) replacing the legacy `approval_token` gate,\n- fixture and BEAM100K evaluation runners.\n\nPartial or planned:\n\n- production vector-index operations beyond the current bundled `sqlite-vec`/`vec0` local ANN path and JSON fallback metadata,\n- adapter-boundary runtime integration crates/modules for Pi, Claude Code, Codex/OpenAI, OpenCode, MCP, and JSONL/CLI harnesses are defined by stable config/runtime types and adapter tests; runtime connectors remain partially implemented outside core types.\n- production shared-graph backend adapter beyond the current local weighted community detection,\n- broader production packaging, signed releases, and release automation beyond the current installer/`just dist` workflow.\n\n## Documentation\n\n- [`doc/how-it-works.md`](doc/how-it-works.md) — current runtime flow and ADR mapping.\n- [`doc/adr/`](doc/adr/) — architecture decisions.\n- [`autoresearch.md`](autoresearch.md) — active experimental protocol and guardrails.\n\n## License\n\nMIT, as declared in the workspace package metadata.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F5queezer%2Faver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F5queezer%2Faver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F5queezer%2Faver/lists"}