Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Eidetic Engine (ee)
Durable, local-first, explainable memory for coding agents.
Install
f=""
||
if [; then ; else ; fi
Always verifies the release binary's SHA-256 checksum, verifies its Sigstore
bundle when one is published and cosign is available, drops ee into
~/.local/bin, repairs PATH, installs shell completions, runs a self-test,
and prints guidance for detected agent harnesses; settings remain untouched. Pass
--require-provenance for fail-closed signature and SLSA provenance
verification. Pass --help (e.g. bash install.sh --help) for offline
tarballs, proxy options, --no-gum, and --force reinstall.
TL;DR
Why This Exists
Coding agents forget.
A fresh session re-discovers project conventions, re-reads the same files, and walks into traps another agent already hit. Bad assumptions become "facts" because the harness has no durable place to look for decisions, failures, rules, and evidence from prior runs.
The agent harness owns the loop. ee handles the memory layer.
What ee Does
ee is a Rust CLI that gives agents a durable, searchable memory layer. It
stores facts, decisions, procedural rules, anti-patterns, session evidence, and
outcomes; indexes them with lexical and semantic search; connects them with
graph features; and emits compact context packs with provenance.
The command returns a Markdown pack of matching durable memories, such as
project release rules, verification commands, branch traps, and high-severity
warnings. Each item carries an evidence pointer and a score breakdown. Imported
cass excerpts become searchable after the import report's indexing action
and can enter a pack directly as typed evidence_span items when they pass
live admission; curation is the optional step that promotes an excerpt into a
durable learned memory (see CASS Integration).
What You Get
| Capability | What you get |
|---|---|
| Hybrid retrieval | BM25 + neural-local vector search via Frankensearch's TwoTierSearcher; default builds use the pinned potion-multilingual-128M Model2Vec embedder, with deterministic hash fallback only when the local model path is unavailable |
| Cancellation-safe index intake | Single-memory and coalesced jobs build a complete validated generation in staging, publish it through a masked rollback-guarded in-process tail, and preserve exact cooperative-cancellation reasons with no partial active index; filesystem/DB hard-crash reconciliation is a separate protocol |
| Explainable scores | Every returned memory shows component scores, freshness, confidence, and which sources support it |
| Typed memory fields | Registry-backed sidecars for failures, decisions, commands, rules, conventions, risks, and anti-patterns; search filters use stable field names instead of prose parsing |
| Procedural rules with decay | Confidence ages out, harmful feedback demotes faster than helpful feedback promotes |
| Anti-patterns first-class | Explicit advisory queries surface matching risk, anti-pattern, and failure memories with provenance |
| Memory hygiene | ee curate doctor ranks content debt, ee learn gaps turns missed demand into capture templates, and steward snapshots show whether hygiene is improving |
| Graph-aware | PageRank, HITS, PPR, Gomory-Hu proximity, dominance, causal paths, structural health, Pack DNA, and skyline views |
| CASS session import | Mines your existing cass corpus (Claude Code, Codex, Cursor, Gemini, ChatGPT) for evidence |
| Context profiles | compact, balanced, grounding, orientation, thorough, and submodular quota/objective mixes |
| Local-first | No cloud service or paid LLM API is required. Embeddings run locally through Frankensearch, with one-time pinned model download and offline hash fallback |
| Stable JSON contract | Every machine-facing command emits versioned JSON with schema field for parsing and validation |
| Deterministic | Same DB + indexes + config + query → identical pack hash |
| Cancellation-aware core | Runtime-facing async APIs use Asupersync &Cx and Outcome |
| CLI first, daemon optional | Every essential workflow runs as a one-shot. No background process required |
| Auditable curation | Promotions, consolidations, and tombstones produce audit entries; no silent rewrites |
| Crowded-agent posture | Swarm brief, workspace hygiene, verification broker, QoS lanes, and flight recorder help agents coordinate without taking over the loop |
Agent Operating Loop
For agent use, the core rhythm is small and repetitive:
| Situation | First ee command |
|---|---|
| Resuming work — "where was I?" | ee resume --workspace . --json |
| Starting from a cold agent session | ee resume --workspace . --json (read data.report, then follow nextCommands) |
| You want the standing workspace charter | ee primer --workspace . --format markdown |
| AGENTS.md might be lying about the rules | ee diag agentsmd-drift --workspace . --json |
| Starting substantive work | ee pack "<task>" --workspace . --read-only --max-tokens 4000 --format markdown |
| About to edit known files or a diff | ee recall --path <path> --workspace . --budget-tokens 400 --format markdown |
| Joining a crowded checkout | ee swarm brief --workspace . --json |
| Capturing raw session observations | ee journal append "<text>" --workspace . --source manual --json |
| Ending a session with reviewable candidates | ee journal distill --workspace . --dry-run --json |
| Learning a durable rule | ee remember "<text>" --workspace . --level procedural --kind rule --json |
| Recording a retired memory that becomes relevant when a condition clears | ee remember "<text>" --workspace . --revive-when path_exists:path/to/marker --json |
| Listing revival conditions that pass now | ee tripwire check --revivals --workspace . --json (read-only; no trust or tombstone mutation) |
| Importing several curated facts | ee remember --batch --stdin --workspace . --json |
| Corroborating an existing lesson | ee remember "<text>" --workspace . --reinforce --json |
| A memory helped or misled you | ee outcome <id> --signal helpful|harmful --reason "<one sentence>" |
| A specific pack item helped | ee outcome --pack <pack-id> --item <n> --signal helpful --reason "<one sentence>" |
| You need feedback provenance | ee outcome trace <memory-id> --workspace . --json |
| Need a direct cited answer | ee ask "<question>" --workspace . --json |
| A high-ranked memory looks suspicious | ee why <id> --workspace . --json |
| A context pack looks odd | ee pack "<task>" --workspace . --explain --json |
| Want risk history before a destructive command | ee preflight check --cmd "<exact command>" --workspace . --json (advisory only) |
| You need a safe handoff | ee handoff create --workspace . --out <capsule.json> --json |
| You need a support artifact | ee support bundle --out <dir> --workspace . --json |
Quick Example
A typical session:
# 1. Initialize a workspace
)
)
# 2. Capture a durable rule you just learned
)
# 3. Pull session evidence from your cass history and inspect the v2 payload
|
{
}
# 4. Apply the reported indexing action (default workspace form shown)
# 5. Search the indexed CASS excerpts directly
# 6. Pack durable memories and live-admitted CASS excerpts for the task
# 7. Inspect that manually remembered rule
# 8. Record that the rule helped
The manual rule and imported CASS evidence are separate records in this
example. Step 6 can select either one: durable memories appear as
entityKind: "memory", while a live-admitted unlinked excerpt appears as
entityKind: "evidence_span" with evidenceSpanId, session and line-range
provenance, and no fabricated memoryId. The import does not retroactively
give the manual rule CASS provenance. context_evidence_hit_unhydrated is
reported only when a matching evidence hit fails current live admission (for
example, because its source row is stale or no longer pack-eligible).
The flow runs locally with no daemon and no cloud. On a typical project, the interactive steps are fast enough to use before ordinary agent work.
Design Philosophy
eeis the durable memory layer your agent harness calls. The harness still owns tools, approvals, and the prompt loop.
The code and tests back these contracts where they can.
1. Local First
All primary data lives on your machine. No cloud dependency is required. Remote APIs stay explicit opt-in; the default local embedding model is a pinned, verified Frankensearch download cached under ee's data directory, with deterministic hash fallback for offline runs.
2. Harness Agnostic
ee is callable from any shell: Claude Code hooks, Codex shell-outs, custom
scripts, plain humans, and MCP adapters. Agents push evidence in and pull
context out.
3. CLI First, Daemon Later
Core workflows run as one-shot CLI commands. The daemon (ee daemon) is opt-in
for supervised foreground maintenance and write-owner work; bounded job and
maintenance commands handle explicit steward work from the shell.
4. Deterministic By Default
Given the same database, indexes, config, profile, budget, seed, and query, the JSON output is byte-stable, ranking ties resolve deterministically, and context pack hashes reproduce exactly. Golden tests assert this.
Mechanized proof artifacts now live alongside the test suite: proofs/lean4/pack_determinism.lean models the pack-hash determinism invariant, and proofs/tla/agent_mail_coordination.tla models exclusive Agent Mail reservation safety. The proof-check report schema is registered as ee.proof_check.v1 and is checkable via ee verify proofs.
5. Explainable Retrieval
Every returned memory answers six questions:
- Why selected? Score components per stage.
- What supports it? Provenance URI(s).
- How fresh? Recency decay term.
- How reliable? Confidence, evidence count, harmful-feedback weight.
- What scores mattered? Final ranking
score,scoreKind, normalizedrelevanceScore, and raw component breakdown. - What would change the decision? Counterfactual hint when available.
relevanceScore is the only cross-source comparison surface. Lexical-only
search min-max normalizes the returned BM25 pool through Frankensearch while
retaining raw BM25 as lexicalScore; semantic results identify their raw
score as cosine_similarity; results from an executed hybrid fusion identify
it as rrf_fused even when only one arm contributed; deliberate hybrid
short-circuits retain the native lexical or semantic scale; and reranked results
use reranked. Relevance floors, score summaries, calibration intervals, and
context packing all consume the normalized relevance projection rather than
comparing those native scales.
Optional reranking has a 20-second inference budget. If it cannot complete,
search preserves the fusion results and reports rerank_model_unavailable
with the runtime reason. Reduce search.rerank_top_k for expensive documents,
or set search.rerank = "off" to skip inference. Cancellation or expiration of
the overall search request still cancels the request.
These projections rank results; they are not probabilities that a result answers
the task. Retrieval metrics report qualityAssessment: "unknown" when results
exist and "empty" when none survive. honestQualityScore is null: score size,
result count, and interval coverage do not establish task-level correctness.
Use the returned content, provenance, and evidence to assess usefulness.
6. Search Indexes Are Derived Assets
FrankenSQLite + SQLModel hold the source of truth. Frankensearch indexes,
embeddings, graph snapshots, and caches are rebuildable from scratch. If the
index directory is lost, run ee index rebuild.
7. Graceful Degradation
| If this is missing | These still work |
|---|---|
| Semantic model | Lexical BM25 + FTS5 fallback |
| Graph snapshot | Retrieval without graph boosts |
cass binary |
Explicit ee remember records |
| Network | Everything (we are local-first) |
Each degradation surfaces in the JSON degraded array with a repair command.
8. Evidence Before Promotion
A procedural rule with no source session, no feedback events, and no validation stays low-confidence. Promotion to high-confidence requires evidence. Harmful feedback demotes faster than helpful feedback promotes.
9. No Silent Memory Mutation
Every promotion, consolidation, replacement, and tombstone produces an audit entry. The steward proposes; it does not silently rewrite procedural memory.
Comparison
| Feature | ee |
Vector DB (Chroma, Qdrant) | MCP memory server | Plain notes / CLAUDE.md |
|---|---|---|---|---|
| Local-first by default | ✅ | varies | varies | ✅ |
| Hybrid lexical + semantic | ✅ | ❌ vector-only | partial | ❌ |
| Provenance per fact | ✅ | ❌ | partial | manual |
| Procedural rules with decay | ✅ | ❌ | ❌ | ❌ |
| Anti-patterns + harmful feedback | ✅ | ❌ | ❌ | manual |
| Explainable scores | ✅ | ❌ | partial | n/a |
| Graph analytics (PPR, HITS, PageRank, proximity, causal paths) | ✅ | ❌ | ❌ | ❌ |
| Deterministic JSON output | ✅ | varies | varies | n/a |
| CASS session corpus import | ✅ | manual ETL | ❌ | manual |
| Works without daemon | ✅ | ❌ | ❌ | ✅ |
| Single-binary install | ✅ | ❌ | ❌ | n/a |
| No Tokio in dependency tree | ✅ | rarely | rarely | n/a |
| Audit log of curation events | ✅ | ❌ | ❌ | git only |
| Backup + side-path restore | ✅ | ❌ | ❌ | git only |
Hard Requirements
Hard constraints. CI fails if any of them break.
- Binary is named
ee. Single CLI binary. - Implementation is Rust 2024, nightly toolchain.
- Runtime is
/dp/asupersync. No Tokio. Anywhere. Ever. - Database is
/dp/frankensqlitethrough/dp/sqlmodel_rust. Norusqlite, no SQLx, no Diesel, no SeaORM. - Search is
/dp/frankensearch. No custom RRF/BM25/vector code. - Graph is
/dp/franken_networkx. Nopetgraph. - Procedural-memory concepts come from
/dp/cass_memory_system(concepts only). - Every machine-facing command supports stable JSON output.
- Every generated context includes provenance and score explanation.
Installation
Installation status
| Method | Status | Evidence |
|---|---|---|
| GitHub release installer | v0.15.0 available for six targets; public assets verified | v0.15.0 release |
| Homebrew tap | v0.15.0 available for Apple Silicon, Intel Mac, Linux ARM64 and Linux x86-64 | Dicklesworthstone/homebrew-tap |
| crates.io | v0.15.1 publication in progress; requires nightly Rust | publication progress |
| Source build | available now | this README |
For v0.15.0, rebuild each workspace's semantic index with
ee index rebuild --workspace . and reinstall managed hooks for the new snippets.
Inspect Claude Code settings before and after reinstalling: existing EE hooks
without eeManaged metadata can be duplicated, and ee hook status does not
detect those duplicates (#41).
Release installer
Starting with v0.14.5, the GNU/Linux release builds target glibc 2.28 or newer on x86-64 and ARM64. Build hosts verify the finished binary's glibc symbol requirements before packaging. The x86-64 musl archive is available for systems without glibc.
f=""
||
if [; then ; else ; fi
Fetched from the jsDelivr CDN mirror first, falling back to raw.githubusercontent.com.
Both serve identical bytes; jsDelivr is a separate host with its own limits, so a
GitHub rate-limit or incident does not block the install.
Do not add a cache-busting query string (e.g. ?$(date +%s)). A unique URL
per request defeats the CDN and forces an origin fetch every time, which is the
pattern GitHub's anti-scraping limiter penalises: a real client install failed
with 429: Too Many Requests on raw.githubusercontent.com for exactly this
reason. The plain URL is CDN-cacheable and re-reads pick up a new main within
the cache TTL anyway. To force an exact revision instead, pin a commit SHA in
the path (.../eidetic_engine_cli@<sha>/install.sh), which is both immutable
and cacheable.
The [ -s "$f" ] guard matters: without it a failed download is followed by a
confusing shell error from running a file that was never written (or is empty),
which reads like two unrelated faults instead of one.
This downloads the latest release binary for your platform, always verifies its
SHA-256 checksum, verifies its Sigstore bundle when one is published and
cosign is available, drops ee into ~/.local/bin, installs shell
completions, repairs writable zsh/bash startup files (creating the active
shell's file for a fresh home), and runs ee --version plus ee doctor --json.
The informational agent scan prints setup guidance without changing agent settings. Open a new shell (or source its rc file) afterward.
Re-running the command repairs PATH and completions and re-verifies a matching version without downloading or rebuilding it.
Pass --require-provenance to require both a verified release signature and a
verified SLSA provenance attestation; otherwise a missing bundle is reported
and the checksum-verified install continues.
Release binaries
cover macOS (aarch64, x86_64), Linux (aarch64 and x86_64 GNU,
with musl where published), and Windows (x86_64). On x86_64 Linux the
installer prefers the portable musl build, then automatically retries the
compatible GNU build when that release does not include musl.
Windows (PowerShell)
$f = Join-Path $env:TEMP 'install-ee.ps1'
try {
Invoke-WebRequest -UseBasicParsing "https://cdn.jsdelivr.net/gh/Dicklesworthstone/eidetic_engine_cli@main/install.ps1" -OutFile $f
} catch {
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/Dicklesworthstone/eidetic_engine_cli/main/install.ps1" -OutFile $f
}
if (Test-Path $f) { & $f -Verify } else { Write-Error "Installer download failed - retry in a few minutes" }
Fetched from the jsDelivr CDN mirror first, falling back to raw.githubusercontent.com.
Both serve identical bytes; jsDelivr is a separate host with its own limits, so a
GitHub rate-limit or incident does not block the install.
Do not add a cache-busting query string (e.g. ?cache=<guid>). A unique URL
per request defeats the CDN and forces an origin fetch every time, which is the
pattern GitHub's anti-scraping limiter penalises: a real client install failed
with 429: Too Many Requests on raw.githubusercontent.com for exactly this
reason. The plain URL is CDN-cacheable and re-reads pick up a new main within
the cache TTL anyway. To force an exact revision instead, pin a commit SHA in
the path (.../eidetic_engine_cli@<sha>/install.ps1), which is both immutable
and cacheable.
The Test-Path guard matters: without it a failed download is followed by a
second, confusing is not recognized as the name of a cmdlet error from running
a file that was never written, which reads like two unrelated faults.
Downloads the current installer to a temporary file before running it. This
keeps the script inspectable and avoids fragile Invoke-Expression and
content-type behavior. The script SHA-256-verifies and installs ee.exe
into %LOCALAPPDATA%\ee\bin, updates your user PATH, installs PowerShell completions, and runs the same version/doctor self-test. Add
-RequireProvenance, or set EE_REQUIRE_PROVENANCE=1, to also
enforce Sigstore signature verification.
The Windows installer conformance contract is tracked in
tests/CONFORMANCE.md.
Homebrew (macOS / Linux)
Cargo
Install the ee binary using nightly Rust and the published lockfile:
Version 0.15.1 is the first registry-only release. Its publication status is
recorded in the installation table above and in UPGRADE_LOG.md.
From source
Requires a nightly Rust toolchain. Dependencies resolve from crates.io using
the committed Cargo.lock; sibling repositories are no longer required.
install.sh --from-source and install.ps1 -FromSource use the same locked
Cargo build. Their dependency checkout helpers return immediately for this
registry-only manifest. franken-stack.lock retains the
source revisions used to qualify the upstream package releases.
Verify
ee doctor reports database health, schema version, index posture, embedding
model posture, cass binary detection, workspace identity, mesh posture,
capabilities, and repair actions. Useful focused modes:
Quick Start
Start read-only: ee resume reports the recent session end-state, open
decisions, queued work, provenance/redaction posture, and safe next commands.
If the addressed workspace has no store, it does not initialize one; it can
instead point at a nearby populated store with an executable retarget command.
# 0. Resume an existing campaign without mutating or initializing the store
# 1. Open a workspace when this is genuinely a new campaign (idempotent)
# 2. Optionally import cass history, then build the derived evidence index
# 3. Get context from durable memories for a task
# 4. When you learn something durable, capture it
# 5. Preview CASS-backed candidates, then persist and apply a reviewed candidate
# 6. Search at any time
That is the core loop.
Development & Verification
To run the full verification suite before committing or pushing:
This runs all readiness gates in order, stopping at the first failure:
| Stage | Gate |
|---|---|
| 1 | Forbidden dependency audit |
| 2 | Closure linter |
| 3 | Snapshot proposal guard |
| 4 | Untracked work audit |
| 4.5 | Bridge staleness advisory |
| 4.6 | Plan drift advisory |
| 4.7 | Fuzz target audit |
| 5 | Vision coverage |
| 5.5 | Proof verification |
| 6 | Unit, contract, golden, binary, test, and example targets |
| 6 | Basic E2E |
| 6.06 | Replay lab smoke E2E |
| 6.5 | Overhaul integration when VERIFY_OVERHAUL is enabled |
| 6.6 | Fake Tailscale harness |
| 6.7 | Fake OIDC happy-path, defect, and deterministic capability/privacy/time matrix harnesses |
| 7 | Advanced E2E |
| 8 | Boundary migration |
| 8.5 | ee doctor safety harness |
| 9 | Benchmarks when --include-bench is passed |
The runner reports exit code, elapsed time, and artifact directories. In agent sessions, route heavy Cargo stages through RCH rather than using local fallback.
Command Reference
ee has core commands and command groups. Run ee <command> --help or
ee <group> --help for full details.
Current top-level groups:
| Group | Commands |
|---|---|
| Core memory loop | init, remember, decide, search, ask, pack, why, status, doctor, capabilities, check, health |
| Memory lifecycle | memory, rule, journal, curate, review, playbook, procedure, workflow, outcome, outcome-quarantine |
| Packing and retrieval | recall, timeline, similar, lens, context-show, show, link, tag, history, proximity, insights, subscribe |
| Graph and structure | graph, causal, economy, focus, learn, lab, rehearse, rationale, situation, task-frame |
| Storage and derived assets | db, migrate, index, model, schema, backup, export, artifact, config, workspace |
| Diagnostics and release gates | diag, eval, perf, preflight, tripwire, verify, verification, audit, claim, certificate, demo |
| Agent integration | agent, agent-docs, hook, mcp, support, swarm, handoff, recorder, completion |
| Optional adapters and operations | daemon, job, maintenance, mesh, team, share, serve, install, update, version, introspect, plan |
Core workflow
| Command | Purpose |
|---|---|
ee help [command path] |
Show top-level help or help for nested commands such as ee help memory show |
ee init [--workspace .] |
Create or open a workspace, run migrations, prepare indexes |
ee status [--json] |
DB generation, index generation, degraded capabilities, recent jobs |
ee doctor [--json] |
Health checks with repair commands for every failure |
ee capabilities [--json] |
Feature, schema, renderer, env-var, and capability posture |
ee resume [--sessions N] [--json] |
The read-only "where was I" bundle: last N episodic sessions newest-first (N is 1–64; stable session-* identity survives interleaved/backfilled rows), public-redacted items and decisions with provenance/redaction posture, bounded revisit/queue lanes with exact totals and truncated flags, staleness from a strictly newer same-kind memory sharing a non-control subject tag (session-* and open-loop tags never establish identity; staleCount deduplicates memory IDs across projections), and nearby populated stores when the addressed store is empty (ee.resume.v1) |
ee orient "<task>" --fast --json |
Fast read-only session-start bundle: bounded swarm brief, install/path posture, workspace hygiene, and explicit follow-up commands for full doctor/pack surfaces |
ee primer [--tokens N] [--refresh] [--json] |
Deterministic, cached workspace charter (~600 tokens): top rules, unresolved warnings, key decisions, load-bearing memories, every line provenance-backed (ee orient --include-primer folds it into orientation) |
ee export agentsmd [--file AGENTS.md] [--create] [--dry-run] |
Render the primer rules+warnings into a marker-delimited managed block; never edits outside its markers, backs up before mutating, refuses hand-edited blocks without --force-managed-block |
ee import agentsmd [--apply] [--json] |
Parse rule-like statements outside the ee markers into curation candidates (trust capped at agent_assertion, file://<path>#L<n> provenance); dry-run by default |
ee diag agentsmd-drift [--json] |
Read-only audit of AGENTS.md vs memory: stale export, file-vs-memory contradictions, missing rules, suggested commands |
ee pack "<task>" [--profile <p>] [--max-tokens N] [--format <fmt>] |
Assemble a task-specific context pack (the canonical headline command; ee context "<task>" remains a soft-deprecated compatibility alias) |
ee lens list --json / ee lens explain <id> --json |
Inspect named task lenses such as bugfix, code-review, and release-readiness before applying them |
ee search "<query>" [--limit N] [--explain] [--json] |
Hybrid retrieval over memories, sessions, rules, evidence |
ee search --family <family-id> [--memory-scope <scope>] [--strict-scope] [--json] |
Queryless, workspace-scoped retrieval of every recorded attempt-family member, including rejected attempts |
ee search "<query>" --all-workspaces [--json] |
Inspection-only fan-out over registered workspaces plus the user-global lane (bounded, per-row workspaceId and lane labels); never mutates any store |
ee similar <memory-id> [--limit N] [--min-score T] [--explain] [--json] |
Find embedding-native nearest-neighbor memories for a seed memory; degrades to lexical similarity with an explicit degraded note when semantic vectors are unavailable |
ee ask "<question>" [--require-confidence T] [--json] |
Direct extractive answer from stored memories, with citations, conflict sides, calibrated abstention, and exit 6 fail-closed mode |
ee recall --path <glob> / --symbol <name> / --diff <ref> |
Fetch memories anchored to a code surface before editing; returns ee.recall.v1 under the standard response envelope |
ee timeline "<topic>" --as-of <RFC3339> --json |
Reconstruct read-only memory state for a topic at a historical timestamp; returns ee.timeline.v1 under the standard response envelope |
ee remember "<text>" --level <l> [--kind <k>] [--tags a,b] [--sentinel <kind>:<target>] [--revive-when <kind>:<target>] |
Capture a durable memory with optional Gate and Revive sentinel predicates; both forms are fully validated before any memory, idempotency, or dry-run write |
ee journal append "<text>" [--source hook|manual] --json |
Append a working-tier observation that can later be distilled; JSONL batches use ee journal append --stdin --json |
ee journal distill [--dry-run|--apply] --json |
Turn repeated or surprising journal entries into reviewable curation candidates; dry-run is the safe default |
ee journal list / ee journal show <entry-id> |
Inspect append-only journal entries, truncation/redaction state, and distillation bookkeeping |
ee remember --batch --stdin --json |
Record a JSONL batch of curated memories with independent per-line results and quarantine reporting |
ee remember "<text>" --reinforce --json |
Corroborate an existing near-duplicate memory through bounded reinforcement instead of creating a redundant row |
ee decide record "<topic>" --chosen <x> --alternative <y> --rationale "<why>" [--revisit-by <RFC3339|+ND>] |
Record a decision-kind memory with typed fields and fork protection |
ee decide list [--about <text>] [--include-superseded] --json |
Review current decision heads or full supersede history before proposing architecture changes |
ee decide revisit [--warning-days N] --json |
Find decisions whose revisit horizon is due or near due |
ee outcome <id> --signal helpful|harmful [--reason "<reason>"] |
Record feedback, updating utility/confidence |
ee outcome --batch --stdin --json |
Record a JSONL batch of outcome events with independent quarantine and rate-limit handling per line |
ee outcome --pack <pack-id> --item <n> --signal helpful|harmful --json |
Grade a specific persisted pack item without manually copying its memory id |
ee outcome trace <memory-id> --json |
Read the feedback events, posterior updates, and trust transitions that affected a memory |
ee audit timeline --target <id> --json |
Inspect the audit rows for a memory, pack, candidate, or other target id in one bounded call |
ee why <memory-id> [--json] |
Explain why a memory was selected, scored, or curated the way it was |
ee why-not <memory-id> --task "<task>" [--json] |
Counterfactual reverse of ee why: explain why a memory was not selected for a task's context pack, with the minimal change that would include it (read-only) |
ee pack build --query-file task.eeq.json --max-tokens N --format toon |
Build a pack from an explicit EQL query document |
ee pack replay <pack-id> --json |
Inspect the persisted, redaction-safe selection ledger for a historical pack |
ee pack diff <old-pack-id> <new-pack-id> --json |
Compare two persisted pack ledgers and explain selection, freshness, redaction, or derived-asset changes |
ee support bundle --out <dir> --json |
Create a redacted diagnostic bundle, including pack replay and swarm-brief summaries without raw query, mail body, memory, or full file-listing content |
ee preflight check --cmd "<shell command>" --json |
Retrieve advisory risk, failure, and anti-pattern memory for a command; never block execution |
ee verify proofs --json |
Check committed Lean4 and TLA+ proof artifacts |
Agent integration
| Command | Purpose |
|---|---|
ee hook claude-code --print|--install|--undo --json |
Preview, install, or undo managed Claude Code recall hooks; report schema ee.hook.harness_install.v1 |
ee hook codex --print|--install|--undo --json |
Preview, install, or undo managed Codex recall hooks; unsupported targets report capability gaps instead of mutating settings |
JSON output and exit codes
Machine readers should inspect the JSON contract before trusting a result:
{
"schema": "ee.response.v2",
"success": true,
"data": {},
"degraded": []
}
{
"schema": "ee.error.v2",
"error": {
"code": "migration_required",
"message": "Database schema migration is required.",
"severity": "high",
"repair": "ee migrate run --workspace .",
"details": {
"recovery": [
{
"priority": 0,
"kind": "migration",
"rationale": "Apply pending local schema migrations.",
"command": "ee migrate run --workspace ."
}
]
}
}
}
| Check | What to read |
|---|---|
| Envelope | schema and success |
| Exit status | 0 clean, 6 degraded-required, 7 policy denied, 8 migration required |
| Degradations | degraded[] for issues that affected this response |
| Recoveries | error.details.recovery[], which is structured for agents |
| Posture | ee status --json uses data.posture.overall; ee doctor --json returns a doctor-specific posture view |
| Provenance | provenance[], evidence_spans[], and trustClass on memory and pack items |
| Typed fields | data.memory.typedFields on memory show, typedFields/metadata.typed_field.* on search-derived memory results when present |
| Pack identity | data.pack.hash for batch packs; packHash on stream trailer frames |
| Graph explanation | data.pack.packDna when ee pack --explain --json is used |
| Feature gaps | ee capabilities --json at data.unimplemented[], not command degraded[] |
| Output budget | meta.tokensEstimated is stamped whenever --max-output-tokens / EE_MAX_OUTPUT_TOKENS governs the response; never above the ceiling unless the response failed closed with output_budget_unsatisfiable |
| Truncation + resume | output_truncated_budget in degraded[] carries details.droppedCount and details.continuationCursor; resume with --cursor <token> — a rejected cursor (cursor_invalid / cursor_stale) is an EMPTY page, never a restart. See docs/agent-ux/output-budgets.md |
| Streams | ee.pack.stream.v1 NDJSON frames: header, item, terminal trailer, error, or cancelled |
Severity vocabulary:
| Order | Values |
|---|---|
| Low to high | info < low < warning < medium < high < critical |
Status and doctor posture are separate contracts:
| Command | Field | Values |
|---|---|---|
ee status --json |
data.posture.overall |
ok, degraded_recoverable, degraded_required, blocked, unimplemented, initializing |
ee doctor --json |
data.posture |
ready, degraded, needs_attention |
Exit code vocabulary:
| Code | Meaning |
|---|---|
0 |
success |
1 |
usage error |
2 |
configuration error |
3 |
storage error |
4 |
search/index error |
5 |
import error |
6 |
degraded-required |
7 |
policy denied |
8 |
migration required |
10 |
workspace store missing (the addressed workspace has no initialized store) |
Common red flags:
| Signal | First response |
|---|---|
data.posture.overall = "blocked" |
Run ee doctor --json and follow the failing check repair |
data.posture.overall = "degraded_required" |
Read degraded[] and error.details.recovery[] |
search_index_stale |
ee index rebuild --workspace . |
embed_model_unavailable |
Continue lexical fallback, inspect bundled-model cache/download posture, or run ee index reembed --workspace . |
graph_snapshot_stale |
Continue retrieval, then refresh graph snapshots when graph scores matter |
pack_budget_too_small |
Raise --max-tokens or switch to --profile compact |
output_budget_unsatisfiable |
Raise --max-output-tokens or narrow the --fields preset; the page failed closed rather than lie |
cursor_stale |
A write advanced the DB generation mid-pagination; re-run without --cursor for a fresh sequence |
data.workspace.diagnostics[].severity = "warning" |
Workspace selection conflict; use ee workspace list, then pass an explicit workspace or alias |
exit 7 |
An ee operation refused its own requested mutation; inspect that command's error details. Advisory ee preflight check never emits this status and never has an approval or allowlist path. |
exit 8 |
Run ee migrate run --workspace . --json |
Context pack controls
ee pack and ee pack build expose three layers of control:
| Layer | Flags | Use |
|---|---|---|
| Retrieval profile | --profile compact|balanced|grounding|orientation|thorough|submodular |
Choose the memory mix and graph bias |
| Task lens | --lens <id>, --no-lens; inspect with ee lens list --json and ee lens explain <id> --json |
Apply a named, hash-stable policy overlay for common tasks such as bugfix, code-review, release-readiness, dependency-update, schema-contract, performance-investigation, or coordination-handoff |
| Output profile | --pack-profile lean|standard|verbose |
Trim or expand JSON metadata |
| Resource profile | --resource-profile lean|standard|swarm_heavy |
Pick pack assembly SLO posture |
| Retrieval source | --source-mode lexical_only|semantic_only|hybrid, --strict-source-mode |
Force lexical-only, semantic-only, or hybrid retrieval before packing; strict mode fails instead of falling back |
| Size | --max-tokens N, --candidate-pool N |
Bound prompt budget and candidate pool |
| Output format | --format markdown|json|toon, --stream --json |
Token-tight prompt text (markdown), parser output (json), stable-field structured output (toon — not smaller than json for packs), or NDJSON frames |
| JSON diet | --no-rendered-text, --no-skipped, --no-meta, --no-pack-dna |
Suppress bulky sections for structured consumers |
| Persistence | --read-only, --no-persist |
Assemble prompt context without writing pack records, audit rows, or L2 cache entries |
| Coordination | --coordination-snapshot <path>, --coordination-stale-after-ms N |
Embed a redacted coordination snapshot |
| Code-change hints | --changed-symbol <selector>, --changed-symbols-from-git |
Bias toward memories linked to changed symbols |
| Time windows | --as-of <RFC3339>, --include-expired, --include-future, --include-stale, --include-tombstoned |
Inspect validity-window behavior |
| Trust lane | --memory-scope self|team|global|workspace|verified|swarm, --strict-scope |
Bound which trust lane can contribute. On ee pack/pack build an explicit value overrides any task-lens scope overlay; omitted keeps lens-then-swarm behavior. self/swarm are agent scopes; team covers explicit local-origin ownership plus receiver-derived member projections (no trust.team_members nickname compatibility) |
| Privacy | --redaction none|minimal|standard|strict|paranoid |
Tune output redaction where the command allows it |
Examples:
Task-lens runs persist the lens id, version, and stable lens hash in the pack
replay ledger. Use ee pack replay <pack-id> --json to audit which lens shaped
a historical pack, and rerun with --no-lens when you need an un-lensed
comparison.
When [pack] adaptive_budget = true, omitted --max-tokens lets ee compute
a budget from retrieval entropy, graph fanout, and task keywords. Passing
--max-tokens N pins the budget for prompt caches, eval fixtures, CI gates, or
multi-pack composition.
When [pack] memory_tier_admission = true, ee pack treats hot/warm/cold
memory tiers as advisory candidate signals. Hot and warm candidates can receive
small deterministic ranking boosts, but cold items are not filtered; explicit
query matches and safety/failure evidence remain eligible for the pack.
Graph-derived insights
Graph views show relationships between memories for navigation, packing, curation, and triage; they do not replace provenance from the memory records themselves.
| Command | Purpose |
|---|---|
ee insights --json |
Bundle graph-derived findings such as top memories, bridges, contradiction clusters, proximity hotspots, load-bearing memories, HITS hubs/authorities, and skyline posture |
ee insights --section <name> --json |
Return one deterministic section when a full bundle is too broad |
ee pack "<task>" --explain --json |
Include a Pack DNA block that explains pack composition with dominators, communities, ego subgraphs, and PPR neighbors when available |
ee why <memory-id> --causal-explain --json |
Add a causalExplanation block with causal ancestry and min-cost path evidence |
ee insights --section causalBottlenecks --json |
Inspect causal bottleneck findings across failure-oriented causal evidence |
ee health --robot-insights --json |
Surface structural health through k-truss and contradiction-cluster summaries |
ee health scorecard --json |
Summarize memory-store health across coverage, freshness, trust, redundancy, and graph structure with trend and top actions |
ee insights --section knowledgeSkyline --json |
Summarize portfolio-level memory posture across onion layers, communities, trust, age, and graph support |
Worked example: inspect bridge memories before curation.
|
Worked example: debug a surprising context pack.
|
Worked example: inspect tightly connected memory pairs before editing related
records. Use proximityHotspots to find ranked pairs worth reviewing, then use
ee proximity for the pairwise min-cut explanation.
|
Start with docs/agent-ux/insights-onboarding.md
for the agent workflow, docs/configuration/graph.md
for graph feature flags and thresholds, and
docs/architecture/graph-snapshots.md
for snapshot lifecycle rules.
Pack replay evidence
Use ee pack replay <pack-id> --json when you need to explain what a historical
pack actually selected from its persisted ledger. Replay is forensic: it reads
the stored ledger only after its hash, shape, invariants, and containing-record
bindings pass, then emits a current-policy-redacted public projection. Missing
or untrusted ledgers produce empty replay selections rather than falling back
to denormalized item rows. Replay does not claim that a fresh search would make
the same choices today. Use a new ee pack run when you want
live re-retrieval against current memories, indexes, graph snapshots, and trust
state.
Use ee pack diff <old-pack-id> <new-pack-id> --json when a later pack changed
and you need to separate selection, freshness, redaction, trust, or derived-asset
causes. Freshness states and degradation codes identify evidence that was
changed, missing, stale, or unavailable at replay time; treat those as repair or
revalidation signals instead of silently dropping the memory from the story.
For bug reports and handoffs, attach
ee support bundle --out <dir> --json. The bundle includes
pack_replay_summary.json, which keeps pack IDs, pack hashes, ledger hashes,
freshness counts, degradation codes, redaction classes, and derived-asset
metadata, plus a compact attestation status and bundle hash for every summarized
pack. It hashes query and actor text, nulls record metadata that was not
integrity-verified, reports truncation explicitly, and omits raw memory content,
why text, provenance text, and full ledger payloads.
Bundles also include swarm_brief_summary.json, a compact coordination posture
snapshot for support and handoff triage. It keeps source statuses, ready/blocked
work counts, active-conflict counts, resource-pressure posture, degraded codes,
top recommendation IDs, and hashes/provenance for the underlying brief. It
omits raw Agent Mail bodies, raw query text, raw provenance text, and full file
listings. Treat it as diagnostic context. Before claiming work or coordinating
edits, run a fresh ee swarm brief.
Bundles and handoff capsules also carry
environment_attestation_summary.json, a redaction-safe source-authority
projection. It separates RCH proof admission from source-test verdicts, keeps
verdicts, degraded codes, recovery-action posture, first-failure diagnosis, and
hashed evidence references, and omits raw mail bodies, source snippets, command
argv, and host-private absolute paths. Treat embedded attestation summaries as
handoff context only; rerun
ee diag environment-attestation --workspace . --include-rch --json before
claiming, closing, or relying on proof posture.
Swarm brief workflow
ee swarm brief is the read-only coordination preflight for crowded repos. Run
it before claiming a bead, after large dirty-state or reservation changes, and
before using handoff or support-bundle evidence as the basis for new work.
Start with a summary view when a routine agent preflight needs compact,
budget-friendly output. The --fields flag may appear before the command or
after swarm brief:
If either summary form (ee swarm brief --fields summary ... or
ee --fields summary swarm brief ...) returns an ee.error.v2 usage failure
such as usage_unknown_field, and error.details.presetsAvailable still lists
summary, treat the installed binary as stale relative to the current
source/docs contract. For read-only inspection, fall back to
ee swarm brief --workspace . --json. That fallback does not authorize Beads
mutation: claim work only after the work-packet claim gate succeeds, and
coordinate for an approved RCH/release-path rebuild if compact field projection
is required.
Use the complete output when a harness needs every source array, including
file-surface risks and resource-pressure hints. This output is intentionally
larger; keep it behind an explicit --fields full in agent loops:
Require selected live coordination sources when degraded output is unacceptable:
If live Agent Mail is unavailable, provide a redacted snapshot instead of raw
mail bodies. When no snapshot is configured, ee swarm brief also does a tiny
bounded probe of 127.0.0.1:8765/health; a reachable probe means Agent Mail
looks live, but ee still needs an explicit redacted snapshot for deterministic
briefs.
SNAPSHOT_PATH=/private/tmp/ee-agent-mail-snapshot.json
Use a canonical, non-symlink snapshot path. On macOS, /tmp is normally a
symlink to /private/tmp, and ee swarm brief --agent-mail-snapshot /tmp/...
refuses the file before reading it. scripts/swarm_coordination_health.sh
emits health evidence only; it is not a full reservation, roster, inbox, or
thread snapshot.
When the claim gate stops on missing Agent Mail evidence, bridge it with a snapshot before mutating Beads:
CANDIDATE=bd-example.1
|
|
The first response is ee.swarm.work_packet.claim_gate.v1; if it reports
agent_mail_unavailable, safeToClaim=false, or
sourceAuthority.agentMailStatus as unavailable, skipped, or
degraded_read_only, do not claim. The retry is still read-only: a fresh
snapshot may change agentMailStatus to fresh and make reservation and inbox
evidence authoritative, but it does not authorize Beads mutation by itself.
Keep coordinating through Agent Mail when unsafeReasons still name an active
reservation, tracker stale state, a BV/Beads disagreement, or an RCH blocker.
Useful JSON checks:
|
|
|
|
|
|
Operator workflow for crowded repos:
- Run
ee swarm brief --workspace . --json. - Inspect recommendations, blocked beads, degraded sources, and file-surface risks.
- Choose a candidate from the fail-closed Beads queue first:
The wrapper reports open, unassigned, non-epic rows after retrying transient Beads JSONL read races. Treat[]as no safe claimable leaf. The full broad inspection commandbr ready --limit 0 --json --no-auto-import --no-auto-flush --allow-staleis still useful, andbv --robot-triageis still useful for ranking, but BV claim commands are advisory until the candidate also appears in the actionable queue and passes the read-only claim gate. - Run the read-only claim gate before any mutation:
If the installedeerejects--claim-gateor--candidateas an unexpected argument, treat that binary as stale relative to the current source/docs contract. Stop at inspection, coordinate for an approved RCH/release-path rebuild, run no BV claim command, and do not use local Cargo install as a workaround. When the gate, support-bundle summary, or handoff evidence disagrees about source authority, run the read-only environment attestation for the per-source explanation:
Seedocs/environment_attestation.mdforsourceAuthority, verdict, severity, and recovery-action interpretation. - Reserve edit surfaces through Agent Mail and mark the bead with
br update <id> --status in_progress --jsononly when the gate reportssafeToClaim=true,verdict=safe_to_claim,selectedCandidate.ownership=unassigned,selectedCandidate.editScope.state=knownwith nonempty paths, and a structuredclaimCommandActionfor that candidate. Self-owned work reportscontinue_owned_workand deliberately emits no second claim. If the only blocker is missing Agent Mail evidence, generate a redactedee.agent_mail.snapshot.v1file and retry the same claim-gate command with--agent-mail-snapshotbefore deciding. A snapshot is read-only evidence, not authorization; remainingunsafeReasonsstill require coordination. The RCH authority fields are intentionally separate:sourceAuthority.rchRemoteOnlyRequired=truerequiressourceAuthority.rchSafeToLaunchCargoVerification=true. Harnesses fail closed when remote-only verification is required and the positive RCH proof is missing or false; a green local compile posture is not enough to claim Rust work. The reference consumer output schema isdocs/schemas/ee.agent.work_packet_gate_decision.v1.json. - Use RCH for Cargo verification, especially when the brief reports
rec.resource_pressure.use_rch_for_cargo. - Rerun the brief after large edits, after reservation changes, and before handoff.
The brief sits beside the existing tools. The scripts/br_retry.sh actionable --json
command is the safe claim queue for open, unassigned, non-epic leaves. Raw
br ready --limit 0 --json --no-auto-import --no-auto-flush --allow-stale
remains the complete broad source of ready-work records and can include parent
epics or rows that should not be claimed without cross-checking.
bv --robot-triage remains the graph-aware ranking engine. The
ee swarm work-packet --claim-gate --json command is the claim-safety gate
that must agree before an agent uses a BV copy-paste claim command or mutates
Beads in a shared checkout. Agent Mail remains the authority for reservations
and coordination messages. Handoff capsules and support bundles carry
diagnostic snapshots such as swarm_brief_summary.json and
environment_attestation_summary.json, but a live brief, live attestation when
source authority is disputed, and claim gate are still the preflight before new
claims. Profile reports and performance forensics diagnose host behavior in
detail; the brief only carries enough posture to steer choices such as routing
Cargo through RCH.
Raw bv --robot-* probes are liveness-sensitive. Run them only with an
explicit external timeout, or route work selection through ee swarm brief /
ee swarm work-packet, which converts timeout or no-output cases into
bv_command_timeout / bv_no_output degradations. Those degradations make
BV ranking advisory only: continue from bounded stale-safe Beads evidence such
as br ready --limit 0 --json --no-auto-import --no-auto-flush --allow-stale,
cross-check with
scripts/br_retry.sh actionable --json, and do not use a BV claim command
unless the same candidate is present in the actionable queue and the claim gate
later reports safeToClaim=true with a structured claimCommandAction.
The command never claims work, never reserves files, never releases files, never sends mail, never runs builds, never edits files, never mutates Beads, never mutates the EE store, never mutates git, and never schedules agents.
Privacy is intentionally conservative. The redaction status
paths_counts_subjects_only_no_content means the brief and support-bundle
summary keep paths, counts, source statuses, subject-like metadata, hashes, and
recommendation identifiers while omitting raw mail bodies, raw query text, raw
memory content, raw provenance text, environment dumps, and full file listings.
Attach swarm_brief_summary.json in support bundles and handoffs when you need
coordination posture without leaking content; attach fresh live output only when
the recipient is allowed to see the underlying repo and coordination metadata.
Workspace hygiene and commit readiness
ee workspace hygiene is a read-only dirty-checkout classifier for agents and
pre-commit hooks.
| Bucket | Meaning |
|---|---|
stage_candidate |
Regular source, tests, and docs after content review |
do_not_commit |
Generated files, scratch files, local-machine state, or secret risk |
needs_human_review |
Large diffs, dependency changes, infrastructure changes, or schema migrations |
ignore_for_now |
Known transient state, such as logs or peer-owned churn |
| Kind | Examples |
|---|---|
source, test, docs |
Normal tracked code surfaces |
beads_metadata |
Beads state and workflow files |
generated, scratch, local_machine |
Build output, temp logs, editor config, local env |
secret_risk |
API keys, private keys, .env files, cloud credentials, tokens |
binary, unknown |
Large binaries or paths without a known class |
Useful checks:
|
The report can include Agent Mail reservations and Beads links, so an agent can see whether a path is risky because of content, ownership, or current work coordination.
Use the commit-hygiene classifier after staging and before source commits in
crowded checkouts. A mixed_full_tracker_export_churn verdict means split the
source/docs/test commit from the tracker-only .beads/issues.jsonl sync; an
intentional mixed commit needs the classifier JSON pasted into the Beads or
Agent Mail handoff.
Handoff and resume
Use a handoff capsule when another agent or another machine should resume a mid-task state.
| Command | Purpose |
|---|---|
ee handoff create --workspace . --out <capsule.json> --json |
Write a signed capsule |
ee handoff inspect <capsule.json> --workspace . --json |
Inspect capsule contents without consuming it |
ee handoff preview <capsule.json> --workspace . --json |
Show resume effects before consuming it |
ee handoff resume <capsule.json> --workspace . --json |
Consume the capsule and re-warm context |
ee handoff rotate-key <capsule.json> --workspace . --json |
Re-sign after suspected exposure |
Capsules carry bead context, recent commits, reservations, last pack ID,
posture, next steps, redaction summary, and content hashes. They are
HMAC-signed files, so treat the capsule path as a credential. Use ee support bundle for bug reports and ee export for memory transfer; handoff is for
resuming work.
Swarm schema contracts
Swarm-scale JSON contracts live in docs/schemas/swarm/
with companion agent-facing notes in docs/swarm/. The catalog
covers producer metadata, trust lanes, verification evidence, coordination
snapshots, resource profiles, pack SLOs, recommendations, consensus, conflicts,
fixture manifests, and planned handoff memory-set fingerprints.
The replay-lab workflow is documented in
docs/agent-ux/workload-replay.md and
docs/agent-ux/swarm-replay-contracts.md.
Use ee lab swarm replay --trace <workload.json> --dry-run --json for the
side-effect-free smoke path. ./scripts/verify.sh runs the no-Cargo smoke
script, while standard and large-host replay proofs stay behind RCH-only
scripts/rch_verify.sh commands.
Every schema carries an x-ee-status marker. Agents should treat
"shipped": false as documentation for a future surface, not runtime
availability. The schema catalog does not turn ee into a scheduler, web
service, mail sender, Beads mutator, or agent loop.
Mesh and Tailscale
Mesh is optional. Local-first operation is the default. Use mesh when a trusted tailnet or local file-exchange path is part of the agent workflow.
On Unix, live EE-to-EE team sync is shipped. ee team create / invite /
join run a signed TCP ceremony and enroll both sides. ee mesh hello-responder run
and ee daemon --foreground bind inbound (Tailscale LocalAPI when present;
loopback TeamJoinLocalApi when every enrolled endpoint is loopback or
tailscaled is absent). Production ee mesh sync --once and
ee team steward once use TcpMeshForegroundSyncTransport for EventFetch
plus grant-gated BodyFetch. Authorized bodies hydrate into local memories so
ee search / ee pack --memory-scope team recall teammate text with
teamProvenance. Policy-governed file export/import remains available.
What the v1 remainder set covers (all closed 2026-08-17, see
docs/mesh/verification_matrix.md): a live
two-host Tailscale tailnet soak (bd-tc-epic-qzk7o.3.8 — two hosts, not yet two
distinct human operators), a Windows-host inbound crash/restart soak
(bd-tc-epic-qzk7o.12), and an explicit fail-closed decision that fake-IdP
RS256 + live identity_attest is the v1 identity ceiling (bd-tc-epic-qzk7o.8.8;
vendor tenant is a post-v1 epic). The opt-in
scripts/e2e_overhaul/mesh_tailscale_smoke.sh still proves local Tailscale
observation, enrollment, policy, and file export/import; it is not the
two-human live-sync gate, which remains a recorded follow-up.
| Command | Purpose |
|---|---|
ee mesh init --json |
Inspect foreground mesh readiness without starting a daemon |
ee mesh status --json |
Report local mesh posture, cache counts, and repair commands |
ee mesh peers --json |
List configured peers, including the opaque peerId used by lane-consent commands, and anti-entropy cursors |
ee mesh peer add|list|show|rotate|revoke|unknown-attempt |
Manage app-level mesh peer records after explicit consent |
ee mesh auto-enroll --json |
Materialize Tailscale-discovered peers from fresh autodiscovery |
ee mesh discovery-policy [set|allow|deny] --json |
Inspect or update caller/responder discovery policy |
ee mesh hello-responder status --json |
Inspect the local hello responder lifecycle job |
ee mesh preview-grant <peer-id> --lane <lane> --json |
Emit the deterministic, token-free ee.mesh.lane_grant_preview.v2 snapshot without mutating policy |
ee mesh preview-grant <peer-id> --lane <lane> --issue-approval-token --json |
Explicitly issue a sensitive, short-lived approval bearer bound to the canonical preview |
ee mesh grant <peer-id> --lane <lane> --preview-token-stdin --json |
Verify a bearer from bounded stdin, advance the target generation, grant the lane, and audit atomically |
ee mesh revoke-lane <peer-id> --lane <lane> --json |
Deny one lane, always advance its generation, invalidate prior previews, and audit atomically |
ee mesh export --peer <peer-id> --out <file> --json |
Write a redaction-safe artifact for an enrolled, enabled peer; use ee export or ee backup for local backups |
ee mesh import --file <file> --json |
Import a foreground artifact; peer rows require exact prior local consent, and cursors advance only through locally durable contiguous accepted replay |
ee mesh sync --once --json |
Run one foreground supervisor cycle through TcpMeshForegroundSyncTransport (hello, EventFetch, grant-gated BodyFetch). No eligible peer degrades honestly; it does not fake contact |
Mesh command mode can be selected per command or through EE_MESH_MODE:
Lane consent targets the opaque enrolled peerId, not a raw Tailscale node
key. Inspect an ordinary preview first. For a non-interactive JSON grant, issue
the approval bearer explicitly and pipe only that field into the bounded stdin
surface so it is not stored in a shell variable:
PEER_ID=peer_example123
| |
Ordinary previews remain deterministic and contain no bearer. Explicitly issued approval tokens are secrets: do not log, persist, echo, or place them in arguments. They expire after 15 minutes and become stale when the target, policy, generic memory/mesh-ledger candidate revisions, source-derived redaction-scanner generation, redacted sample, or grant generation changes. Opted-in issuance necessarily writes the bearer to stdout. ee-controlled sinks scrub it, but external or third-party stdout/session recorders outside ee's control may retain it until the 15-minute expiry. Revocation stops future serving but cannot erase bytes a peer already cached or copied.
Related docs:
| Doc | Purpose |
|---|---|
docs/adr/0037-optional-mesh-memory.md |
Optional mesh design |
docs/adr/0041-mesh-anti-entropy-model.md |
Anti-entropy model |
docs/mesh/operator_onboarding.md |
Operator workflow |
docs/mesh/command_modes.md |
off, cache, revisable, and blocking modes |
docs/agent-ux/auto_enrollment_onboarding.md |
Agent auto-enrollment checklist |
Team confederation
Trusted 2–20 person teams share origin-owned memory over the mesh. Local
ee pack / ee search stay the default. After a granted BodyFetch or
ee team steward once, teammate text is a local memory: search, pack, ask,
and why carry teamProvenance. See docs/team/quickstart.md
and docs/agent-ux/team.md.
| Command | Purpose |
|---|---|
ee team create --name <name> --json |
Create the origin team and turn mesh on unless explicitly disabled |
ee team invite [--wait] --json |
Mint a one-use invite; --wait stays until the joiner's first sync |
ee team join --invite <code> --json |
Redeem the invite over live TCP and import origin genesis |
ee team status --json |
Members, pending invites, budgets, last-sync, and reachability |
ee team members list --json |
Receiver-derived membership; not a config nickname list |
ee team doctor --json |
Team health: broker port, admission, invites, projects, rematerialize |
ee team steward once --json |
Apply pending EventFetch/BodyFetch, hydrate stubs, enqueue index jobs |
ee team share history --json |
Preview or share signed origin history (metadata) |
ee team share bodies --json |
Token-free preview; --confirm --token-stdin publishes bodies |
ee team fetch body --key <cache-key> --json |
Retry a grant-gated BodyFetch into local cache |
ee team activity --as-of <rfc3339> --json |
Explicit-as-of teammate activity with member/project attribution |
ee team projects reconcile --json |
Rematerialize origin teamProjectShared rows |
ee search "<q>" --memory-scope team --json |
Recall hydrated teammate text with teamProvenance |
ee pack "<task>" --memory-scope team --json |
Pack the same teammate memories with provenance |
Import & ingestion
| Command | Purpose |
|---|---|
ee import cass --workspace . [--limit N] [--dry-run] |
Pull session evidence from coding_agent_session_search |
ee import jsonl --source <file> |
Restore from a JSONL records file, including backup record exports |
ee import eidetic-legacy --source <path> --dry-run |
One-time migration of legacy Eidetic Engine artifacts (read-only) |
Curation & rules
| Command | Purpose |
|---|---|
ee journal append "<text>" [--source hook|manual] [--json] |
Append one working-tier observation for later review; --stdin accepts JSONL batches |
ee journal distill [--dry-run|--apply] [--json] |
Distill journal observations into pending curation candidates without applying them as memories |
ee journal list / show <entry-id> |
Inspect journal entries, redaction/truncation state, and whether an entry has been distilled |
ee review session <id> --propose [--dry-run] |
Distill imported CASS session evidence into proposed memories/rules |
ee curate candidates [--workspace .] |
List pending curation candidates |
ee curate doctor [--limit N] [--trend] [--json] |
Read-only memory-debt report with ranked suggested repairs for stale anchors, unresolved contradictions, never-retrieved or orphan memories, low-trust high-rank items, and decay-imminent high-utility rows |
ee curate validate <id> |
Run validation (specificity, duplication, scope, evidence) |
ee curate apply <id> / accept <id> / reject <id> / snooze <id> / merge <a> <b> |
Lifecycle transitions |
ee curate disposition |
Evaluate TTL disposition policy without silent mutation (--apply is required to write) |
ee learn gaps [--since <RFC3339>] [--limit N] [--json] |
Cluster retained search/ask miss demand into redacted representatives, nearest existing evidence, and remember templates; clusters flip to likely_covered (with coveredBy) once a newer memory satisfies the demand |
ee playbook extract [--since <RFC3339>] [--dry-run] |
Propose procedural-rule candidates from repeated semantic memories |
ee playbook list [--limit N] |
List procedural rules in portable playbook form |
ee playbook export --out <file> [--dry-run] |
Write a no-overwrite portable playbook artifact |
ee playbook import --source <file> [--apply] |
Dry-run or apply a portable playbook import through audited rule writes |
ee rule add / list / show <id> / mark <id> / protect <id> / update <id> |
Direct rule management |
Outcome signal vocabulary:
| Signal | Use |
|---|---|
helpful |
Memory directly changed the result for the better |
harmful |
Memory misled the operator or agent |
confirmation |
Independent evidence supported the memory |
contradiction |
New evidence conflicts with the memory |
stale |
Convention or fact was superseded |
inaccurate |
Body contains a factual error |
outdated |
Version-specific fact no longer applies |
positive |
Useful but weaker than helpful |
negative |
Unhelpful but weaker than harmful |
Targets can be memories, packs, or curation candidates:
Memory inspection
| Command | Purpose |
|---|---|
ee memory show <id> [--json] |
Full record with provenance, links, audit trail |
ee memory list [--workspace .] [--level <l>] [--tag <t>] |
Filtered listing |
ee memory history <id> |
Audit trail for a memory |
ee memory level <id> --to <level> --reason <why> [--dry-run] |
Manual adjacent level transition with memory.level_transition audit |
ee memory expire <id> [--dry-run] |
Audited soft expiration without deleting memory rows |
ee memory link <id> [target-id] --relation <type> [--dry-run] |
Deterministic memory link listing and audited explicit link creation |
ee memory tags <id> [--add <tags>] [--remove <tags>] [--set <tags>] [--clear] |
Deterministic audited tag listing and mutation |
ee memory promote-global <id> [--dry-run] |
Evidence-gated copy-with-link promotion of a workspace memory into the user-global lane; refusals are typed exit-7 plans (ee.global_promotion.plan.v1) |
ee memory demote-global <global-id> |
Audited tombstone of a promoted global row (ee.global_demotion.report.v1); tombstoned rows never re-enter candidate pools |
ee memory outcome-global <global-id> --signal helpful|harmful [--dry-run] |
Feedback on a global row with clamped confidence backflow to the origin workspace row (ee.global_promotion.backflow.v1) |
Graph
| Command | Purpose |
|---|---|
ee graph pagerank [--limit N] |
Compute PageRank scores over memory links |
ee graph betweenness [--limit N] |
Compute betweenness centrality over memory links |
ee graph hits [--limit N] |
Compute HITS hub and authority scores |
ee graph louvain [--resolution R] |
Compute Louvain communities |
ee graph communities [--limit N] |
Compute label-propagation communities |
ee graph k-core [--k K] |
Extract a k-core, defaulting to the main core |
ee graph articulation [--limit N] |
List articulation points for structural-decay and bridge analysis |
ee graph path <src> <dst> |
Find the shortest memory-link path between two memories |
ee graph explain-link <src> <dst> |
Explain direct and path-based graph evidence between memories |
ee graph export [--workspace .] |
Export a deterministic graph snapshot artifact |
ee graph snapshot refresh --graph <type> |
Refresh typed snapshots: memory_links, causal, revision, rules, contradictions, or all |
ee graph neighborhood <id> [--direction both] [--limit N] |
Expand around a memory/session/rule |
ee graph centrality [--algorithm <name>] |
Read persisted centrality scores, including pagerank, betweenness, authority, hits-hubs, and hits-authorities |
ee graph centrality-refresh [--dry-run] |
Refresh PageRank / betweenness metrics |
ee graph feature-enrichment [--dry-run] |
Compute bounded graph-derived retrieval features |
ee graph suggest-links [--limit N] [--min-score S] [--propose] |
Typed link prediction (related/supports/contradicts) with blended, explained scoring; --propose writes curation candidates, never links directly (ee.graph.suggest_links.v1) |
ee graph diff [--graph <family>] [--from ID] [--to ID] [--since RFC3339] |
Temporal structural diff between two persisted snapshots: content-hash-keyed add/remove sets, fingerprint-matched community deltas, persisted-centrality movers (ee.graph.diff.v1) |
ee insights [--section <name>] [--explain <id>] --json |
Inspect graph-derived findings and memory-centric topology |
ee proximity <memory-a> <memory-b> --json |
Explain Gomory-Hu min-cut proximity between two memory nodes |
ee economy report [--artifact-type TYPE] [--min-utility SCORE] [--include-debt] [--include-reserves] --json |
Report memory utility, cost, maintenance debt, tail-risk reserves, and attention-budget posture without mutating ranking state |
ee economy score <artifact-id> [--artifact-type TYPE] [--breakdown] --json |
Explain the economic-value score for one memory, procedure, tripwire, or situation |
ee economy simulate --budget TOKENS [--budget TOKENS ...] [--baseline-budget TOKENS] --json |
Compare alternate attention budgets and pack profiles without changing durable state |
ee economy prune-plan --dry-run [--max-recommendations N] --json |
Produce a bounded report-only plan to retire, compact, merge, demote, or revalidate low-value artifacts; omission of --dry-run is refused |
Conflicts
| Command | Purpose |
|---|---|
ee conflict list / explain <id> / cluster |
Read-only ranked contradiction surface: conflicting pairs with both bodies + the preferred side, and k-truss/Louvain clusters (ee.conflict.v1) |
ee conflict resolve <a> <b> --verb supersede|reject-one|scope-split|both-valid [--keep ID] [--reason "..."] [--apply] |
Audited resolution against the LIVE surface; dry-run plan by default. Every mutation maps onto existing audited atoms and the rationale persists as a kind=decision memory (ee.conflict.resolve.v1) |
Resolution is terminal: a tombstoned side (superseded or rejected) drops the
pair from the actionable surface, and re-running against a moved surface
refuses with conflict_resolve_stale_surface plus the focused live state.
See docs/agent-ux/graph-intelligence.md
for the full densification and resolution loop.
Index
| Command | Purpose |
|---|---|
ee index status / rebuild / reembed |
Manage derived search indexes (Frankensearch owns model selection) |
ee index vacuum |
Preview reclaimable derived search-index artifacts without deleting or rewriting files |
Index intake never mutates active Frankensearch tiers in place. The previous
generation remains readable while a complete replacement is built and
validated; a failed commit restores it and preserves the unpublished generation
in a non-recoverable rejected quarantine. See docs/indexing.md for the cancellation,
equivalence, fallback, and RCH-only E2E contracts.
Workspace, models, schemas
| Command | Purpose |
|---|---|
ee workspace resolve / list / alias <name> |
Identity, monorepo subscopes, and aliases |
ee workspace hygiene [--mode report|precommit] --json |
Dirty-path hygiene, secret-risk, generated/scratch/local-machine classification, and commit-readiness guidance |
ee migrate status / run / shard-fanout --dry-run |
Migration posture and shard-fanout planning |
ee db status / inspect <table> / check-integrity / reindex --dry-run |
Inspect FrankenSQLite schema, table rows, integrity, and derived-index rebuild plans without bypassing ee |
ee model status / list |
Inspect embedding model registry posture |
ee schema list / export <schema-id> |
Inspect stable machine-output schemas |
Focus and memory bias
Focus state is a small workspace-local bias for the next task family. It changes ranking, not trust class or stored content.
| Command | Purpose |
|---|---|
ee focus set <mem...> --workspace . --json |
Replace the active focus set |
ee focus show --workspace . --json |
Inspect active focus |
ee focus add <mem> --workspace . --json |
Add one memory |
ee focus remove <mem> --workspace . --json |
Remove one memory |
ee focus clear --workspace . --json |
Clear the focus state |
ee focus explain --workspace . --json |
Explain focus and per-agent bias effects |
EE_AGENT_NAME lets ee attribute outcomes to an agent identity. After enough
outcome events, per-agent bias can nudge familiar memories while keeping the
base retrieval signal dominant.
Backup & restore
| Command | Purpose |
|---|---|
ee export [--output-dir <dir>] [--redaction standard] |
Export redacted JSONL records as a portable side-path artifact |
ee backup create [--label <name>] [--include-graph-cache[=bool]] |
Create a hashed portable backup and report exact migrated-table recovery coverage; graph-cache derived assets are included by default |
ee backup list / verify <id> / inspect <id> |
Audit artifact integrity and the manifest recoveryInventory |
ee backup restore <backup-id> --side-path <path> |
Restore into an isolated side path |
ee backup keys export --output-dir <new-dir> --passphrase-stdin |
Encrypt current and retired store-authentication keys into a separate recovery artifact |
ee backup keys import --input <file> --passphrase-stdin |
Recover authentication keys into a workspace that has no existing keys |
Backups include saved pack selections, direct evidence selections, omissions,
impressions, and agent baselines even when optional caches are excluded. Restore
preserves their historical scores and provenance, rebinds replay data to the
destination workspace, and applies the backup's requested redaction. Packs that
predate replay ledgers remain explicitly without one. Restoring pack history
requires the source workspace's authentication keys, available directly or
recovered with ee backup keys import; the
manifest's recoveryInventory still identifies other durable tables that are
not yet covered.
Import checkpoints are also included by default. Restore preserves their IDs, progress counters, diagnostics, and historical timestamps, and rebinds canonical CASS query keys to the destination workspace. Interrupted imports become pending with their active-attempt start/completion timestamps cleared. The next import of the same query reuses that checkpoint. Redacted noncanonical source keys remain distinct opaque history entries; they do not become live queries. Import-checkpoint recovery requires the source authentication keys.
Curation proposals, review decisions, snoozes, merge references, and TTL policies
are included in the same authenticated snapshot. Proposals remain reviewable
after restore and apply through the normal curation checks. Rebinding memory IDs
alone does not revoke approval; operations whose identity is derived from the old
workspace and source IDs can still require re-proposal. If redaction changes a
live proposal or its evidence, restore records an audit entry and returns it to
needs_evidence
with its automatic TTL policy cleared. Terminal decisions stay historical.
Derived-source hashes retain their original values so normal curation validation
can detect changed evidence. Curation recovery also requires the source keys.
Reusable procedures and their lifecycle events are included by default, with
their evidence URIs, feedback counters, retirement state, and timestamps.
Restored procedures work with the normal ee procedure show and retirement
commands. If redaction changes a procedure's instructions or evidence, restore
audits the change and clears its validation and promotion timestamps; active
procedures return to provisional, while retired procedures stay retired.
This history requires the source authentication keys. External verification
files referenced by evidence URIs must still be available for revalidation.
Learning observations, quarantined feedback, and outcome evidence are also
included in authenticated backups. Restore preserves observation timestamps,
review decisions, evidence weights, and distinct evidence references. Pending
feedback remains reviewable through ee outcome quarantine; released or rejected
entries stay reviewed. Valid payload hashes are rebound to the restored workspace
and redacted data with an audit linking the original hash. Invalid quarantine
payloads remain untrusted. Recovery does not reapply feedback or rerun scoring.
Recorder runs, recorder events, and verification history are included by default in authenticated backups. Restore preserves event-chain hashes (including broken chains), counts, timestamps, verification results, and blocker history. Recorder listing and verification queries work against the recovered database. Active recordings become abandoned with an audit entry because their processes are not restored. Verification hashes continue to identify the original evidence; any redaction of display text is audited. Machine labels retain secret scanning so bead filters and blocker classification still work under full redaction.
Error fingerprints and their repair links are included in authenticated backups. Restored error diagnosis recalls helpful and harmful repairs and their proof links, with memory references remapped to the recovered store. Link identities, outcomes, and timestamps are preserved; free text follows the backup's redaction level. Ordinary error codes remain searchable under full redaction. Recovery does not execute repairs or claim that historical proofs were rerun.
Artifact registry metadata, snippets, and evidence links are also recovered before the search index is rebuilt. Artifact inspection, listing, and lexical search work against the restored store. Original file hashes and timestamps are retained; valid snippet hashes follow redaction with an audit trail. Invalid hashes are retained in that audit and cleared from changed snippets, so redaction cannot turn a bad hash into apparent proof. Registry recovery preserves references to external files and does not copy or verify their raw bytes. Backup metadata redaction scans both JSON keys and values, including short or numeric credentials identified by their field names, preserving distinct fields or rejecting a collision.
Authenticated learning-history backups also retain per-agent context profiles: helpful, harmful, and ignored counts, cached weights, and last-seen timestamps. Restored packs use these learned counts immediately; recovery does not replay feedback. Agent keys use the same redaction mapping as pack baselines, with distinct opaque names when redacted. Full redaction changes those names, so a harness must use the restored identity to retrieve its profile. Conflicting identities or profile links outside the recovered workspace reject recovery. This uses learning-history format v2; recreate backups containing v1 learning history before relying on the new recovery path.
Default backups also retain authenticated rationale traces, their extra evidence
links, and causal contribution records. Restored ee why and ee causal trace
commands use this history immediately, with original confidence, scores, and
timestamps. Summaries, authors, and external references follow the selected
redaction level. Recovery preserves recorded claims; it does not validate them
or replay decisions. Missing memory references, conflicting records, and unsafe
rationale summaries reject recovery. These records require the source signing
keys, just like the other authenticated history above.
Diagnostics, eval, ops
| Command | Purpose |
|---|---|
ee doctor --quick|--robot-triage|--capabilities|--gc-plan <days> |
Focused repair and operator triage surfaces |
ee health scorecard [--record-snapshot] --json |
Trend-aware memory-health scorecard with coverage, freshness, trust, redundancy, graph, and top-action signals |
ee curate doctor --trend --json / ee learn gaps --json |
Content-health diagnostics: memory-debt queue, steward trend snapshots, and demand-driven gap templates |
ee preflight run "<task>" / show / close |
Task risk assessment, tripwire context, and post-run feedback |
ee preflight check --cmd "<command>" --json |
Advisory command-risk memory lookup; use --stdin or --cmd-base64 to keep command text off argv when needed. ee never denies execution |
ee tripwire list / check |
Inspect and check preflight tripwires |
ee tripwire check --revivals [--limit 1..=100] --json |
Evaluate a bounded, deterministic prefix of current workspace-local Revive specs and return those whose predicate passes; the default limit is 25 and capped responses include a higher-limit repair. This explicit revival-sentinel evaluator may run allowlisted ee --help introspection under strict wall-time and redacted output caps. The implicit revival-sentinel evaluator used inside ee orient uses only local read-only predicates and does not execute command-help processes; this is not a claim that every other orient component is process-free. Both evaluator modes exclude Gate specs, replace raw targets with domain-separated digests, and perform no automatic result, trust, or tombstone mutation… |
ee diag plan-cache |
EQL query plan-cache counters and integration posture |
ee diag contention [--use-daemon] [--json] |
Read-only swarm hot-path contention posture: write-lock, read-pool, single-flight (plus group-commit / incremental-index / L2 when present), with a severity-ranked topContention list (see docs/agent-ux/contention-observability.md) |
ee diag environment-attestation --workspace . --include-rch --json / disk-pressure / build-admission / artifacts |
Read-only environment source-authority, storage, artifact, and build-admission diagnostics |
ee diag graph / graph-snapshot / search |
Graph, snapshot, and retrieval diagnostics |
ee diag integrity / dependencies / streams |
Integrity, dependency, and stdout/stderr stream checks |
ee verify ingest / ee verify rch ingest / ee verify rch blockers / ee verify rch runs / proofs / broker lookup / closure-guidance |
Verification evidence, durable RCH proof ledger queries, proof checks, reusable RCH evidence, and closeout guidance |
ee maintenance run / status / wal-checkpoint / graph-snapshot-prune / graph-witnesses-prune |
Explicit maintenance jobs and retention helpers |
ee job run / list / show |
Durable steward job history and explicit job execution |
ee install check / plan and ee update |
Agent-safe install/update checks and dry-run plans |
ee eval run / list |
Run or list retrieval-quality evaluation fixtures |
ee eval report [fixture] |
Summarize fixture IDs, data hashes, aggregate retrieval metrics, and the first failing query |
ee eval run <fixture> --pack-quality --json |
Check whether deterministic fixtures still select required context-pack evidence |
ee ask "<question>" --workspace . --json |
Answer a narrow question extractively from stored memories, with citations, conflict sides, and calibrated abstention |
ee perf compare --baseline <baseline.json> --candidate <candidate.json> --json |
Compare normalized performance artifact summaries without mutating state |
ee perf budget check --profile <name> --report <artifact.json> --json |
Check one normalized performance artifact against a profile budget |
ee perf explain-latency --surface search|context --report <artifact.json> [--log <j1.jsonl>] --json |
Explain deterministic latency stages and cache posture from normalized search/context artifacts and optional J1 timing evidence |
ee analyze science-status --json |
Report optional science analytics feature posture and degradations |
ee capabilities / check / health |
Inspect feature availability and readiness |
ee daemon --foreground |
Optional supervised maintenance daemon |
Use pack-quality evaluation when a canonical task should keep selecting specific
memories across retrieval or packing changes. The report is a deterministic
ee.eval.pack_quality_report.v1 result with selected and omitted memory IDs,
degradation posture, redaction status, artifact paths, and stable failure
reasons for fixture triage. See
docs/pack-replay.md for operator and fixture-authoring
guidance.
Use ask-quality evaluation for direct answers that must stay extractive and
citation-backed. ee eval run ask_v1 --json gates citation precision, answer
exactness, calibrated abstention, and conflict recall against the committed
Project Zephyr fixture corpus; scripts/e2e_ask.sh exercises the same public
CLI path end to end.
Configuration
ee reads config in this precedence order (highest wins):
- CLI flags
- Environment variables (
EE_*) - Project config:
<workspace>/.ee/config.toml - User config:
~/.config/ee/config.toml - Built-in defaults
Unknown TOML keys are rejected rather than silently ignored. The error names the full key path and, when there is one unambiguous close match among sibling keys, includes that key as a conservative suggestion.
Full annotated example:
# ~/.config/ee/config.toml
[]
= "~/.local/share/ee/ee.db"
= "~/.local/share/ee/indexes"
= false # auto-export memory.jsonl on each commit
[]
= false # one-shot CLI mode
= 5000 # cancel any in-process job after this
= 200
[]
= true
= "cass" # path or PATH lookup
= "90d" # CASS lookback for import planning and policies
= 30 # wall-clock budget per cass subprocess call
# (raise for large corpora; env override: EE_CASS_TIMEOUT_SECS)
[]
= "balanced" # fast | balanced | thorough
= 0.45
= 0.45
# Wired for default hybrid retrieval. `semantic_weight` applies to the
# neural-local Model2Vec arm when the bundled model is available; it
# deterministically renormalizes to lexical scoring when hash fallback is active.
= 0.10
# Query-plan cache sizing is environment-only: EE_QUERY_PLAN_CACHE_ENTRIES=1024
= 30 # retained hash-only miss demand for `ee learn gaps`
[]
= "balanced"
= "markdown"
= 4000
= false
= 0.7
= 100
= false
[]
= 0.92
= 2.5 # harmful feedback hits harder than helpful
= 60
[]
= true
= 14 # applied only by the explicit journal-retention steward job
[]
= 0.55 # average-linkage merge floor for `ee learn cluster`
[]
= 0.05
= 0.01
= 1
= 30
= 90
= 180
= 365
= 30
[]
= 5 # excess harmful events are quarantined
= 3600
[]
= true
= ["api_key", "jwt", "password", "private_key", "ssh_key"]
[]
= "agent_assertion" # bumped on validation, demoted on contradiction
= true
[]
= 250
= 100
[]
= 30
[]
= true
= 1073741824
[]
= false
= "off" # off | cache | revisable | blocking
# Discovery/responder policy is NOT config.toml: it lives in workspace-local
# TOML files (<workspace>/.ee/discovery_policy.toml plus the
# discovery_allowlist / discovery_denylist / respond_allowlist files),
# managed by `ee mesh discovery-policy set|allow|deny`, with
# EE_TAILSCALE_DISCOVERY_MODE / EE_TAILSCALE_RESPOND_MODE as env overrides.
Environment variable overrides:
| Variable | Equivalent |
|---|---|
EE_DATABASE_PATH |
[storage].database_path |
EE_INDEX_DIR |
[storage].index_dir |
EE_PROFILE |
[pack].default_profile |
EE_MAX_TOKENS |
[pack].default_max_tokens |
EE_AGENT_NAME |
agent identity for outcome attribution and per-agent bias |
EE_SECURITY_PROFILE |
workspace/import security posture; it does not govern shell commands |
EE_JOURNAL_ENABLED |
[journal].enabled capture gate; false makes journal surfaces report journal_disabled |
EE_JOURNAL_RETENTION_DAYS |
[journal].retention_days for the explicit journal-retention steward job |
EE_HARMFUL_PER_SOURCE_PER_HOUR |
[feedback].harmful_per_source_per_hour |
EE_HARMFUL_BURST_WINDOW_SECONDS |
[feedback].harmful_burst_window_seconds |
EE_QUERY_PLAN_CACHE_ENTRIES |
query-plan cache size (environment-only; no TOML key) |
EE_QUERY_MISS_RETENTION_DAYS |
[search].query_miss_retention_days for hash-only search/ask miss demand retained by ee learn gaps |
EE_PPR_CACHE_ENTRIES |
PPR prefetch cache size |
EE_L2_PACK_CACHE_BYTES / EE_L2_PACK_CACHE_DIR / EE_L2_PACK_CACHE_DISABLE |
pack L2 cache controls |
EE_READ_POOL_SIZE / EE_READ_POOL_ACQUIRE_TIMEOUT_MS / EE_READ_POOL_MAX_PIN_SECONDS |
read-pool controls |
EE_GRAPH_MEMORY_SNAPSHOT_CAP_MB / EE_GRAPH_MEMORY_PER_ALGORITHM_CAP_MB |
graph working-set admission controls |
EE_MESH_ENABLED / EE_MESH_MODE |
[mesh].enabled / [mesh].command_mode |
EE_TAILSCALE_DISCOVERY_MODE / EE_TAILSCALE_RESPOND_MODE |
Tailscale discovery and responder policy |
EE_TAILSCALE_PEER_PROBE_TIMEOUT_MS / EE_TAILSCALE_DISCOVERY_BUDGET_MS |
Tailscale peer-discovery budgets |
EE_FLIGHT_RECORDER / EE_FLIGHT_RECORDER_DIR / EE_FLIGHT_RECORDER_RETENTION_DAYS |
flight-recorder controls; see docs/agent-ux/flight-recorder.md |
EE_WORKSPACE_HYGIENE_ALWAYS_REVIEW_PATTERNS / EE_WORKSPACE_HYGIENE_GENERATED_PATTERNS / EE_WORKSPACE_HYGIENE_LOCAL_MACHINE_PATTERNS / EE_WORKSPACE_HYGIENE_SCRATCH_PATTERNS |
workspace hygiene classifier overlays |
EE_SCIENCE_BACKEND_PATH |
optional science analytics backend health path |
EE_DISABLE_REMEMBER_SEARCH_NEIGHBORS |
disables Frankensearch neighbors for remember-time curation proposal |
EE_DISABLE_TOON |
disables TOON capability reporting and auto-selection |
EE_NO_COLOR |
disables ANSI styling on stderr |
EE_TRACE |
enables structured tracing to stderr |
The full registry is docs/env_vars.md and the code source
is src/config/env_registry.rs.
Feature flags:
| Flag | Status | Notes |
|---|---|---|
default |
active | fts5, json, embed-fast, lexical-bm25, graph |
fts5 |
active | Frankensearch FTS5 lexical fallback |
json |
reserved | JSON output is unconditional today; flag is reserved for a minimal profile |
embed-fast |
active | Frankensearch model2vec semantic embedder plus the asupersync-backed model download path |
lexical-bm25 |
active | Frankensearch BM25 scorer |
graph |
active | Default-on graph analytics surface |
differential-networkx |
active test gate | Heavy Python NetworkX differential suite |
mcp |
active optional adapter | Stdio adapter module; default builds keep manifest discovery |
serve |
reserved | The loopback-only ee serve adapter is compiled unconditionally; the flag only changes how ee capabilities reports the feature |
science-analytics |
reserved | Future analytics subsystem; current CLI reports degraded/unavailable posture |
See docs/feature_flag_registry.md for the
tracked owner and status of each flag.
Architecture
┌─────────────────────────────────────────────────┐
│ Coding Agent (Claude Code · Codex · Cursor …) │
└──────────────────────┬──────────────────────────┘
│
ee pack · search · remember · import · curate
▼
┌─────────────────────────────────────────────────┐
│ ee-cli │
│ Clap commands · process I/O · output rendering │
└──────────────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────────────┐
│ ee-core │
│ use-cases · services · runtime wiring · policy │
└──┬──────┬──────┬──────┬──────┬──────┬──────┬───┘
▼ ▼ ▼ ▼ ▼ ▼ ▼
┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌─────┐
│ db │ │srch│ │cass│ │grph│ │pack│ │cura│ │stwd │
└─┬──┘ └─┬──┘ └─┬──┘ └─┬──┘ └─┬──┘ └─┬──┘ └──┬──┘
│ │ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼ ▼
FrankenSQ Franken- CASS Franken- Pack Steward
+ SQLModel search robot/ NetworkX records jobs
(truth) (lex+sem) JSON (graph) + audit (opt
daemon)
Source of truth ──► Derived assets (rebuildable)
One source of truth. FrankenSQLite + SQLModel hold every durable fact. Indexes, embeddings, graph snapshots, and caches are derived and reproducible from the DB plus config.
Strict dependency direction. cli → core → { db, search, cass, graph, pack, curate, policy, output } → models. No upward edges. Repositories never render output. Command handlers never write SQL.
Native Asupersync. Runtime-facing async APIs take &Cx, return Outcome<T>, and preserve budget/cancellation semantics where wired.
Additional runtime-adjacent modules:
| Module | Role |
|---|---|
mesh |
Optional peer exchange, Tailscale autodiscovery, hello responder, anti-entropy, policy, authenticated lane consent, and revocation |
obs |
Flight recorder, structured tracing, posture helpers, and diagnostic evidence |
hooks |
Memory-oriented agent harness helpers for recall, orientation, journaling, and capture |
steward |
Bounded maintenance jobs, spec packs, and optional daemon work |
shadow |
Read-only shadow/diagnostic support paths |
Storage Layout
~/.local/share/ee/
├── ee.db # FrankenSQLite source of truth (WAL mode)
├── indexes/
│ └── combined/
│ ├── manifest.json # generation, model id, lexical+vector files
│ └── ... # Frankensearch artifacts
├── cache/ # transient, safe to wipe
└── logs/ # tracing-subscriber JSON logs
<workspace>/.ee/ # optional project artifacts (git-friendly)
├── config.toml # checked-in project overrides
├── backups/ # default `ee backup create` root
├── index/ # default workspace index dir for local runs
├── discovery_policy.toml # optional mesh discovery/responder policy
├── discovery_allowlist.toml / discovery_denylist.toml / respond_allowlist.toml
├── auto_enroll_overrides.toml # reviewed mesh auto-enrollment overrides
├── playbook.yaml # human-editable rules promoted into the project
├── memory.jsonl # optional auto-export
└── README.txt
Workspaces are first-class rows inside the user-global DB. A project can opt into a project-local DB via [storage] database_path = "./.ee/db.sqlite" when isolation matters more than global recall.
Memory Model
ee distinguishes four memory levels, each with its own scoring tilt and packing quota:
| Level | Examples | Decay | Packing priority |
|---|---|---|---|
working |
Active task notes, scratch, in-progress facts | fastest | low (suppressed across sessions) |
episodic |
"On 2026-03-12 the release failed because…" | medium | medium |
semantic |
Project conventions, architectural facts | slow | high |
procedural |
Rules, anti-patterns, playbooks | slowest, decays only on contradiction | highest |
Level changes are explicit lifecycle transitions, not silent rewrites. Automatic
paths include workflow close (working -> episodic), curate apply for repeated
observations (episodic -> semantic), curate apply for validated rules
(semantic -> procedural), memory expire for time-bound facts
(semantic -> episodic), and decay/tombstone maintenance. Manual transitions
use ee memory level <id> --to <level> --reason <why> and are restricted to the
same adjacent edges: working -> episodic, episodic -> semantic,
semantic -> procedural, and procedural -> semantic. Every successful
transition writes a memory.level_transition audit row with previous level, new
level, event, reason, evidence references, and a stable details hash.
Memory kind is orthogonal: rule, fact, decision, failure, command, convention, anti-pattern, risk, playbook-step, …
Every memory carries: id, level, kind, content, content_hash, tags[], confidence, utility, importance, created_at, last_seen_at, access_count, source_type, source_uri, evidence_spans[], links[], trust_class.
Registry-backed kinds can also carry a typed sidecar with schema
ee.memory.typed_fields.v2. Use repeatable --field NAME=VALUE on
ee remember or ee note, or let ee extract explicit labels such as
Family:, Chosen:, Command:, Condition:, or Scope: from the body.
Explicit assignments override same-name extracted values. Bare prose stays
bare; ee does not fabricate machine fields.
| Kind | Typed fields |
|---|---|
failure |
cause, regression_surface, reverted_at_sha, family |
decision |
options, chosen, rationale, supersedes, revisit_by |
command |
command, when_to_use, exit_meaning |
rule |
condition, action, exceptions |
convention |
scope, pattern |
risk / anti-pattern |
trigger, blast_radius, safer_alternative |
ee search filters typed fields with --kind <kind> plus repeatable --field
operators: name=value for exact, name~value for contains, and name^value
for prefix. The full registry, bounds, indexed-field status, and v1-to-v2
compatibility notes live in
docs/memory-typed-fields.md.
Attempt-family multiplicity is a separate source-of-truth ledger, not the
free-form typed family field. Record each sibling with the same --family
and declared denominator plus a unique slot/outcome, then retrieve the whole
family without a dummy query or an index rebuild:
Decision memories have a dedicated micro-ADR workflow through ee decide.
record creates or supersedes a decision chain head, list reviews current
heads, and revisit surfaces due or near-due decisions. See
docs/agent-ux/decide.md.
Memory lanes: workspace and user-global
Memories live in one of two lanes. The workspace lane is the default:
every row belongs to the workspace whose .ee store holds it. The
user-global lane is a separate store under the user data root
($XDG_DATA_HOME/ee/global, falling back under $HOME) that shares
procedural knowledge across all of one user's workspaces — house rules,
hard-won anti-patterns, cross-project playbooks. It never crosses the mesh.
Rows enter the global lane two ways: authored directly
(ee remember --global), or promoted from a workspace
(ee memory promote-global <id>). Promotion is copy-with-link — the
origin workspace keeps its row and audit history; the global copy carries
derived_from provenance and its own feedback life — and it is
evidence-gated: only human_explicit or agent_validated memories
qualify, everything else gets a typed exit-7 refusal plan
(--dry-run previews the verdict without writing).
Precedence at retrieval is fixed: global rows compete in the same
pack/recall/primer/search sections as workspace rows, always labeled
(storeLane=global, provenance source_type=global_store); an
exact-content twin resolves workspace-wins; a genuine contradiction defers
to the operator via global_lane_conflict_deferred with both sides kept
visible. Two [memory] config keys control participation:
include_global = false stops reading the lane in a workspace, and
participate = false isolates a workspace in both directions. When the
lane is off or empty, retrieval says so with global_lane_disabled
instead of silently narrowing. See the
trust model for how the lane
sits in the trust taxonomy.
Context Profiles
Different tasks need different memory mixes. --profile currently selects one of the shipped context-packing profiles without bypassing trust or privacy:
| Profile | Bias |
|---|---|
compact |
Prioritizes procedural rules and known failure modes in a tight budget |
balanced |
Default mix across rules, decisions, failures, evidence, and artifacts |
grounding |
Uses balanced quotas and boosts HITS authority evidence when graph scores are available |
orientation |
Uses balanced quotas and boosts HITS hub memories when graph scores are available |
thorough |
Expands evidence and artifact coverage for higher-recall work |
submodular |
Uses the facility-location objective with thorough section quotas for deterministic diversity |
Output formats:
| Format | Use |
|---|---|
markdown |
The token-tight prompt format for packs — prepend text for agents and humans (smallest output) |
json |
Full structured contract for parsers |
toon |
Structured output with stable field order for parsers; not smaller than JSON for packs |
jsonl with --stream |
Incremental ee.pack.stream.v1 frames |
For a context pack, prefer markdown when you want the most token-efficient
prompt material: a pack is a deeply nested structure, and TOON only compresses
uniform tabular arrays, so --format toon is typically larger than --format json for packs and several times larger than --format markdown. TOON's token
savings apply to flat/tabular command outputs (e.g. ee status, ee health),
not to packs.
Stream consumers should read until a terminal frame. kind: "cancelled" can
still carry emitted items; kind: "error" is the hard failure path.
CASS Integration
ee consumes coding_agent_session_search (cass) as the raw session source;
it does not duplicate the underlying store. An imported evidence span keeps
the source session and exact line range as provenance.
# Discover what cass has
# Real import (idempotent, resumable, ledger-tracked); read fields under .data
|
# Apply data.indexRequiredAction (the default workspace form is shown here)
# Imported excerpts are now directly retrievable as evidence
# The same live-admitted excerpt can enter a pack without a synthetic memory
# Preview curation candidates without writing
# Persist proposals only after review, then validate and apply one
Fresh imported spans have no memory link, but remain searchable and directly
packable when their live source row passes current admission. In JSON packs
they are typed as entityKind: "evidence_span", retain their exact session and
line-range provenance, and never receive a synthetic memoryId. Curation is
still how an excerpt becomes a durable memory or procedural rule; rebuilding
the derived index after curation makes that new linkage visible to retrieval.
Required cass commands consumed (all with stable contracts):
cass health --jsoncass search "<q>" --robotcass view <path> -n <line> --jsoncass expand <path> -n <line> -C <ctx> --jsoncass capabilities --json
If cass is missing, ee runs in degraded mode. Explicit ee remember records still work fully, and ee status clearly reports the missing capability with the install command.
Beyond Coding
The same memory model works outside software when the work has durable facts, recurring decisions, and cited sources.
| Domain | Useful memories | Typical source URI |
|---|---|---|
| Investment research | Thesis revisions, valuation methods, failed screens, peer sets | sec-filing://..., earnings-call://..., analyst-note://... |
| Legal work | Case rules, drafting conventions, negotiation outcomes, due-diligence steps | case://..., pacer://..., westlaw://... |
| Marketing analysis | Campaign retrospectives, A/B results, channel rules, segmentation methods | ga4://..., mixpanel://..., campaign://... |
| Product management | User research, launch retrospectives, personas, prioritization rules | interview://..., linear://..., notion://... |
| Security and incident response | IOCs, TTPs, response playbooks, detection-rule outcomes | cve://..., mitre://..., incident://... |
| Medicine or clinical operations | Guideline facts, near misses, differential-diagnosis procedures | pubmed://..., guideline://..., emr://... |
| Sales and account work | Call notes, objection patterns, account maps, qualification playbooks | crm://..., salesforce://..., gong://... |
For privileged domains, isolate by workspace, and take the workspace out of the user-global lane entirely — a matter-confidential or patient-adjacent workspace should neither read shared memories nor leak its own into them:
With memory.participate = false, retrieval in that workspace reports
global_lane_disabled honestly instead of silently narrowing, and
ee memory promote-global refuses to move anything out.
cass is specific to coding sessions. For other domains, use direct ee remember calls or
structured imports through ee import jsonl --source <file>.
Negative Evidence Ledger
For long-running optimization work, record failed attempts before they disappear
into a revert. The useful artifact is the attempt, why it lost, and the smallest
measurement or source that proves it lost. Failure memories now use typed
memory fields as the formal machine-readable convention: write Family:,
Cause:, and Reverted at SHA ... in the body so ee remember --kind failure
can populate the typed sidecar. Legacy tags remain useful for broad grouping,
but ee search --kind failure --field family=<name> --json is the precise
filtering surface. The canonical v2 field table and bounds are documented in
docs/memory-typed-fields.md.
| Loop step | ee surface |
|---|---|
| Start a campaign | ee init --workspace ./optimization/<campaign> --json |
| Capture a failed attempt | ee remember "...what lost and why... Family: <name>. Cause: <root>. Reverted at SHA <sha>." --level episodic --kind failure --source <artifact-uri> --json |
| Cluster repeated failures | ee playbook extract --workspace ./optimization/<campaign> --dry-run --json |
| Promote a validated anti-pattern | ee curate validate <candidate-id> then ee curate apply <candidate-id> |
| Prime the next attempt | ee pack "<next hypothesis>" --workspace ./optimization/<campaign> --profile thorough --format markdown |
Example capture:
Useful tag prefixes:
| Prefix | Meaning |
|---|---|
family-<name> |
Approach family, such as family-aggressive-prefetch; canonical typed field is family |
regression-<surface> |
Where it lost, such as regression-tail-latency |
cause-<root> |
Inferred root cause, such as cause-cache-pollution; canonical typed field is cause |
reverted-at-<sha> |
Decision point or revert commit; canonical typed field is reverted_at_sha |
Shadow Policy Inventory
Shadow policy surfaces are side-effect-free by default. The public inventory
contract is ee.shadow_policy_inventory.v1; it lists stable policy IDs,
domains, maturity, required inputs, supported cohorts, known degraded modes, and
whether the policy can be shadowed without changing user-visible output.
Initial inventoried policies include:
| Domain | Incumbent | Candidate |
|---|---|---|
| Pack selection | incumbent.pack.mmr_redundancy |
candidate.pack.facility_location |
| Cache admission | incumbent.cache.no_cache |
candidate.cache.s3_fifo |
| Verification admission | incumbent.verification.rch_only |
candidate.verification.environment_attestation |
| Retrieval weights | static [search] config weights (not a shadowable policy id) |
candidate.retrieval.outcome_tuned_weights |
Unsupported decision surfaces must abstain instead of promote or reject. The
current inventory records unsupported.resource_profile_budget_admission with
abstentionReason=unsupported_policy_domain until that decision plane has a
safe shadow implementation.
Use --shadow compare --policy <policy-id> only to collect comparison evidence.
Shadow mode does not promote candidates, mutate live policy, or replace the
incumbent result without an explicit future apply step.
The retrieval-weights domain is the first with a full runnable loop:
ee shadow run --policy candidate.retrieval.outcome_tuned_weights --json
evaluates outcome-labeled evidence offline and persists an
ee.shadow.retrieval_tuning_report.v1 report (abstaining honestly below the
evidence gate); ee shadow promote [--dry-run] applies a promotable winner
as an audited [search] config overlay carrying the full prior bytes, and
ee shadow demote restores those bytes exactly. Determinism is preserved
because adaptation is an explicit, reviewable config change — see
docs/agent-ux/retrieval-adaptation.md.
Agent Harness Integration
Claude Code
Add to your AGENTS.md or hook setup:
Before starting substantial work, run:
ee swarm brief --workspace . --json
ee swarm work-packet --workspace . --include-rch --claim-gate --candidate <id> --json
ee pack "<task>" --workspace . --read-only --max-tokens 4000 --format markdown
Before editing known files or a diff:
ee recall --path <path> --workspace . --budget-tokens 400 --format markdown
ee recall --diff HEAD --workspace . --budget-tokens 400 --json
When you discover a durable project convention:
ee remember --workspace . --level procedural --kind rule "<rule>"
To retrieve relevant risk memory before a shell command:
ee preflight check --cmd "<shell-command>" --workspace . --json
printf '%s' "$cmd" | ee preflight check --stdin --workspace . --json
After a remembered rule helps or harms:
ee outcome <id> --signal helpful
ee outcome <id> --signal harmful
Managed hooks inject recall, orientation, journal, and capture context only. They never intercept or deny shell commands. Preview the managed memory hooks before installation:
The ee pack, ee recall, and hook-install JSON outputs are stable and parseable.
Managed SessionStart and pre-edit hooks try the workspace daemon first, then
fall back to local retrieval if it is unavailable. Start it explicitly with
ee daemon start --workspace . --json; each workspace has its own socket.
These memory reads remain available while the neural model warms. Use
ee hook status --workspace . --json to inspect the last invocation and its
degradation messages. Stop an idle daemon with ee daemon stop --workspace .;
a daemon retaining a neural model can use more than 1 GB of RAM.
Codex
Codex shells out, so the same calls work. ee pack "<task>" --json can be
inserted directly into a system or developer message. Use ee recall --path
as the pre-edit surface and preview managed hooks with:
MCP
The MCP manifest is available so agents can discover the CLI contract from default builds:
When the mcp feature is not enabled, the manifest succeeds and reports
capabilityGap.code=mcp_feature_disabled for the stdio adapter. Build with
cargo build --release --features mcp from source when you need the adapter.
The feature gates the in-tree synchronous JSON-RPC stdio adapter; it does not
link rust-mcp-sdk because that SDK currently requires Tokio, which is outside
this crate's allowed runtime stack.
The manifest mirrors the CLI contracts for tools such as ee_context, ee_search,
ee_remember, ee_outcome, ee_curate_candidates, and ee_memory_show.
Default builds keep ee mcp serve-stdio --json discoverable and return the
same mcp_feature_disabled capability gap instead of starting an adapter.
Feature-enabled builds use ee mcp serve-stdio to run the JSON-RPC stdio
server; MCP clients should then speak the protocol over stdin/stdout.
ee mcp validate --json checks that manifest contract against the public schema
without starting the stdio adapter. Schemas match CLI JSON exactly; the CLI is
the compatibility contract.
Plain humans
Use it from a shell.
Privacy & Trust
Redaction
Secrets are detected before storage. Default redaction classes: api_key,
jwt, password, private_key, ssh_key, aws_secret, oauth_token.
Redacted spans are replaced with stable placeholders; the original is not
written to disk.
# stored as: "DATABASE_URL=postgres://user:***REDACTED:password***@host/db"
Redaction levels:
| Level | Typical use |
|---|---|
none |
Local inspection only |
minimal |
Storage and context JSON default posture |
standard |
Export and handoff artifacts |
strict |
Shared artifacts with body truncation |
paranoid |
Support bundles and public diagnostics |
Trust classes
Memories carry a trust class that affects packing priority:
| Class | Source | Initial confidence |
|---|---|---|
human_explicit |
User-typed ee remember |
0.85 |
peer_human_attested |
Signed origin from an active team member whose store declared human_explicit; this attests the member's declaration, not who typed it |
0.75 |
agent_validated |
Agent assertion + outcome confirmation | 0.65 |
agent_assertion |
Agent assertion, no validation | 0.50 |
cass_evidence |
Imported session span | 0.45 |
legacy_import |
Old Eidetic Engine artifact | 0.30 (caps until validated) |
Advisory priority at retrieval time:
| Tier | Packing behavior |
|---|---|
blocked |
Excluded because of policy, secret risk, or prompt-injection match |
quarantined |
Held for curation review |
degraded |
Lower rank because freshness, contradiction, or evidence is weak |
advisory |
Low-confidence hint |
clear |
Normal ranking |
Lifecycle rules, advisory priority, and prompt-injection handling are specified
in docs/trust-model.md; ADR 0009 as amended by ADR 0086
TC-D7 remains the canonical trust taxonomy.
Prompt-injection guard
Before packing, EE screens stored memories for role overrides, hidden-prompt requests, credential requests, and authority claims. Matching memories are omitted with policy explanations; their stored contents remain available for inspection. The check also covers graph, focus, and global memory inputs.
This is a conservative pattern check: quoted or negated override phrases can also be omitted. Ordinary command-risk notes remain recallable, and EE never uses these matches to deny shell execution. See the trust model for the boundary and its limitations.
Mesh sharing posture
Outbound sharing goes through policy and an authenticated canonical preview
before lane grants. Lane-consent commands use the opaque enrolled peerId, not
a raw Tailscale node key.
| Surface | What to use |
|---|---|
| Deterministic preview | ee mesh preview-grant <peer-id> --lane metadata --json |
| Explicit JSON grant | Pipe .data.preview.approvalToken.value from preview-grant --issue-approval-token --json into ee mesh grant <peer-id> --lane metadata --preview-token-stdin --json |
| Narrow one lane | ee mesh revoke-lane <peer-id> --lane metadata --json |
| Discovery consent | ee mesh discovery-policy --explain --json |
| Share preview | ee share preview --peer <peer> --json |
| Trusted-team product | ee team create / invite / join, then ee team steward once |
| Operator docs | docs/team/quickstart.md, docs/mesh/share_preview.md, docs/mesh/peer_policy.md |
Backup & Restore
# Create a hashed backup, including graph snapshots, witnesses, and result-cache rows
# Portable redacted JSONL export
# List
# Inspect contents without restoring
# Restore to an isolated side path, replaying graph cache by default
The portable record stream currently preserves the workspace, memories, tags,
memory links, attempt-family lineage, and audit rows. It does not yet claim
lossless recovery of every durable table. Each create/export response and
manifest.json includes recoveryInventory, reconciled against the live
migrated schema with an exact row count and disposition for every table. If a
required table has non-empty rows that are not represented in restore
artifacts, creation returns status: "partial", verification posture is
incomplete_source_coverage, and degraded[] names the affected tables. Do
not treat that artifact as a complete recovery point.
New backups include authenticated audit-history chunks with all audit columns, including global events and nullable targets. Restore loads them before appending new import events and preserves the durable workspace ID while binding it to the side path. Unchanged rows retain their IDs, timestamps, and original chain hashes. Redaction produces a transformed local chain; the signed chunks retain the source hashes separately as historical evidence. Learning proposals retain their full source-memory references so normal validation and recipe promotion can continue after recovery. The portable JSONL importer alone does not replay audit history. Backups created before audit-history capture must be recreated; verification rejects an archive that lacks this required asset.
The signed manifest also carries the selected workspace's stored name, original
timestamps, and repository/subproject scope. Restore preserves that metadata
and binds the workspace ID to the new side path; ee workspace resolve reads
the restored identity. Repository metadata describes the source checkout:
restoring memory does not recreate a Git checkout. Metadata follows the backup's
redaction policy. Archives missing this metadata must be recreated. A backup of
one workspace in a database containing additional workspace rows remains partial.
Authenticated backup assets also preserve memory seals (including reveal history), source quarantine and release history, certificate records, and the durable agent registry. Restore retains their original chronology. Sealed content remains withheld and excluded from search and packs even under full redaction. Restoring a certificate preserves a historical claim; it does not verify its payload or signature. Referenced certificate files are not copied. Source quarantines retain their diagnostic and release state. Redaction that would merge distinct source identities is rejected rather than dropping history.
Backups also preserve sentinel specifications, tripwires and their check history,
reflection request replay state, adopted situations, debt snapshots, and stored
plan recipes. Restore preserves consumed reflection requests without issuing new
challenges or copying reflection keys. Sentinel results start cold: run fresh
checks against the restored workspace before requesting a pack with
--require-fresh-sentinels. A redaction level that would change an operational
sentinel predicate or tripwire condition is refused before backup publication.
Historical report hashes retain their original meaning after text redaction.
Stored plan recipes are available through ee plan recipe list, ee plan recipe show <id>, ee plan explain <id>, and ee plan recommend "<task>", scoped to
the selected workspace. Recommendations use Frankensearch text and semantic
retrieval with maturity, recorded recency, and evidence components. JSON includes
scores and provenance; --min-score filters ranking scores, not calibrated
confidence. Missing semantic models fall back to lexical retrieval with a
degraded entry. Stored instructions have unknown effects and are never executed
by recommendation. Native procedural rules from the selected workspace also
participate, with their recorded maturity, source memories, and scope. Deprecated,
superseded, and tombstoned rules are excluded. Directory and file-pattern rules
retain their scope restriction; a text match does not prove that the task's files
fall within that scope.
To save instructions explicitly, initialize the workspace and create a draft:
save --dry-run previews redacted instructions without writing. A saved recipe
starts at draft maturity with no earned confidence; saving commits the recipe
and its audit record together and never runs the supplied instructions.
Learning proposals can use the same store after normal validation:
Recipe promotion accepts rule and procedure candidates. The proposal content
becomes one instruction, retaining its source references. The recipe, candidate
transition, and audit commit together; replay returns the existing recipe.
Review does not establish execution success, so the recipe starts as a draft
with zero earned confidence. ee plan explain <id> --task "..." uses the same
explanation path: current matching score, rank, provenance, up to five ranked
alternatives, and an explicit no-match result when applicable. Without --task,
the explanation describes stored instructions and evidence only.
By default, ee backup create also includes graph-cache derived assets: graph
snapshots, graph algorithm witnesses, and graph algorithm result-cache rows.
Use --include-graph-cache=false when those rebuildable assets are unnecessary,
and use ee backup restore --skip-graph-cache when restore should leave that
cache cold and re-warm it on first use. Missing index manifests are reported as
degraded. ee backup verify <backup-path> --workspace <source-workspace>
authenticates the complete manifest and checks every listed artifact's hash.
The selected workspace supplies the trusted keys; the manifest cannot choose
them. Restore uses the same check and validates copied records before import.
It assembles the restored store in a private staging directory and publishes
.ee only after every restore phase succeeds. A failed attempt preserves its
staging artifacts for inspection and does not expose a partially restored DB.
Existing destination stores are never replaced. Restore rebuilds search indexes
from the complete staged corpus before publication, so the restored memories
are searchable immediately.
Failed verification returns exit code 5 and success: false, retaining the
individual issues in data.issues; warning-only verification stays exit-zero.
Unsigned manifests, including older backups, cannot pass verification or be
restored; recreate them with the source keys available. If authentication is
unavailable, a memory-only emergency export remains visibly partial and
unverified. Recovery requires the original signing keys, either from the source
workspace or from an explicit encrypted key export. recoveryInventory separately
states source coverage, so authenticated integrity does not imply completeness.
Export authentication keys while the source workspace is still available. Keep the encrypted artifact separately from ordinary data backups and retain its long, unique passphrase in your password manager. Passphrases are accepted only on stdin (12–1024 characters); a terminal newline is removed, but spaces are preserved. For example, redirect a protected passphrase file into each command:
# After losing the source, recover keys without initializing a new database.
Both key commands support --dry-run without creating files or directories.
Export refuses an existing output directory; import refuses any existing key
file. The envelope uses PBKDF2-HMAC-SHA256 (600,000 iterations) and
ChaCha20-Poly1305 with random salt and nonce. It contains the current key and up
to four retired keys; export again after rotation before relying on backups
signed by a new key. It cannot recover keys already evicted from that window.
Recovered keys are published with owner-only permissions. Ordinary redacted
data backups contain neither plaintext keys nor the recovery envelope. Mesh
enrollment credentials are a separate recovery concern.
JSONL import and backup restore replay memory relationships with their weights,
confidence, evidence counts, origin, metadata, and original timestamps. Redacted
endpoints map to the corresponding restored memories. JSONL reports include
linkRecords, linksImported, linksSkippedDuplicate, and
linksSkippedConflict. Repeating an import adds no duplicate links; conflicting
IDs, edges, or endpoint memories preserve existing state and produce an issue.
Invalid memory IDs, levels, kinds, content, secret-bearing bodies, scores,
Bayesian posteriors, and link records reject the import before creating storage,
including in --dry-run. The preview validates the archive payload; native-trust
authentication, destination conflicts, and index publication are checked during
the applied import. Rejected JSONL
imports return exit code 5 and success: false, with details in data.issues.
Native artifact authentication covers the exact emitted memory, tag, and link
records in order; changing, appending, removing, or reordering these records
invalidates the authentication required to preserve local human trust. Other
durable families still follow the coverage limitations above.
Memory imports preserve the original creation and modification timestamps, including after restoring Bayesian posteriors or tombstones. Missing modification times use the tombstone time when present, otherwise the creation time; missing validity starts use the creation time. Temporal fields are checked before storage is created. Reimport preserves existing rows and reports conflicting timestamps.
Exports also carry each memory's logical_id, preserving revision chains and
attempt-family membership across restoration. Redacted roots resolve to the
corresponding restored memory IDs. A revision archive must include its root,
with at most one live head per chain. Missing or inconsistent roots reject the
preview before storage is created; conflicting destination chains reject the
applied import before any memory or link is inserted. Records without a
logical_id describe singleton memories.
Performance
Canonical hardware class: mac-m3-pro (benches/baselines/hardware_classes.toml).
Measured on a 2024 MacBook Pro M3 against a workspace with 25 projects, 14k
memories, 8k imported CASS sessions, and about 120k indexed documents. CI and
release tooling should only update these rows with artifacts from the same
hardware class.
These rows are historical (last synced 2026-05-13) and are not currently
reproduced by release tooling. A 2026-09-02 probe of the public v0.14.4
binary measured roughly 2 s wall for ee search, ee pack, and ee status
on a 9-memory workspace, because every process re-verifies and fully loads
the Model2Vec model before answering. That probe ran on an Apple M4 host,
which is not the mac-m3-pro class the table above was measured on, so
it does not refute those numbers on their own hardware; it does show the
per-command fixed cost the table omits. Treat the table as a
target until bd-reality-core-convergence-1azkt.6 regenerates it from
attested raw samples.
| Operation | Hardware class | p50 | p99 |
|---|---|---|---|
ee remember (single record) |
mac-m3-pro |
8 ms | 22 ms |
ee search "<q>" (hybrid) |
mac-m3-pro |
38 ms | 110 ms |
ee pack "<task>" (markdown, 4k tokens) |
mac-m3-pro |
95 ms | 240 ms |
ee why <id> |
mac-m3-pro |
25 ms | 100 ms |
ee init --workspace <dir> (clean) |
mac-m3-pro |
100 ms | 250 ms |
ee audit timeline --limit 1000 |
mac-m3-pro |
35 ms | 100 ms |
ee import cass --limit 50 (cold) |
mac-m3-pro |
4.1 s | 11 s |
ee graph centrality-refresh (PageRank, 5k links) |
mac-m3-pro |
350 ms | 2.0 s |
ee index rebuild (full) |
mac-m3-pro |
18 s | 41 s |
| 4 concurrent audited memory writers | mac-m3-pro |
120 ms | 350 ms |
| Last synced: 2026-05-13T12:52:12Z from sha256:84433f76b5ae84ba96bb3546a75d432175c2fd0f1c477dff03cb59a31b7ab7e6 |
Benchmark profiles are explicit so agents and CI can pick the right cost tier:
# Small no-mock smoke run, suitable for agent closeout through rch
TMPDIR=/tmp RCH_REQUIRE_REMOTE=1
# Broader nightly profile over all benchmark groups
# Exploratory large-machine run for 256GB+/64-core hosts
# J9 broad regression wrapper pinned to benches/baselines/perf_v0_2.json
# SRR6.46 auto-enroll performance baseline contract
EE_BENCH_BASELINE_FILE=benches/baselines/auto_enroll_perf_v0.json \
Budgets are currently advisory while deterministic scale fixtures stabilize.
The harness emits ee.perf.v1 JSON with profile, workload, artifact paths,
latency fields, resource fields when available, and regression status. A J10
coverage test keeps every row in the table above tied to a benchmark/baseline
or an explicit advisory marker. Profiles can become release-blocking once their
fixture variance is low enough for CI.
Performance and resource posture commands:
| Command | Use |
|---|---|
ee perf compare --baseline <baseline.json> --candidate <candidate.json> |
Compare normalized perf artifacts |
ee perf budget check --profile <name> --report <artifact.json> |
Check one artifact against a host profile |
ee perf explain-latency --surface search|context --report <artifact.json> |
Explain search/context latency stages and cache posture |
ee diag host-profile --json |
Redacted host/resource profile inputs |
ee diag plan-cache --json |
EQL query plan-cache counters |
ee status --skyline --json |
Knowledge skyline posture when graph support is available |
Codex RCH Workaround
Some Mac Codex sessions may still find an older rch on PATH or report the
Codex hook as not installed. Until that local installation is upgraded, keep
using the repo wrapper and pass the current RCH client as the wrapper binary:
RCH_VISIBILITY=summary \
Do not use /Users/jemanuel/projects/remote_compilation_helper/target-local/release/rch
directly from this Mac; that path can contain a Linux worker artifact and fail
with exec format error.
RCH rewrites the local USB-NVMe CARGO_TARGET_DIR to a worker-local target path
for remote execution, so the external-drive setting is safe for both local
artifact retrieval and remote Linux workers. TMPDIR=/tmp is still required:
the Mac USB scratch path is not present on Linux workers, and Rust tests using
tempfile inherit TMPDIR.
Troubleshooting
error: search index is stale
The DB has advanced past the index generation. Rebuild:
error: cass binary not found
Either install cass or disable CASS import:
# Install
# Or disable in your config file
# [cass]
# enabled = false
ee continues to work without cass; explicit ee remember is unaffected.
error: migration required
The schema version on disk is older than the binary expects. Run initialization again to apply the migration path:
Failed migrations leave clear recovery instructions in stderr and stop before a partial apply.
error: workspace ambiguous (3 candidates)
The current path resolves to multiple registered workspaces. Disambiguate it explicitly:
error: embed model not loaded
The semantic stack is in degraded lexical-fallback mode because the bundled
local Model2Vec model could not be loaded or an explicit fault-injection path
was set. Default installs use the pinned potion-multilingual-128M model from
Frankensearch. Resolution checks EE_EMBED_MODEL_DIR first, then the verified
local source_uri of a matching available workspace model-registry row, then
the machine registry layout under models/model2vec/, then the legacy cache,
and only then permits a one-time download. Registry selection verifies the
pinned model identity, frozen manifest, dimension, cosine metric, and persisted
content hash. EE_EMBED_DOWNLOAD=off forbids that network step without
disabling a verified local model. Pre-populate either supported cache layout or
register another verified local path for an air-gapped host, then re-embed:
You can also keep running lexical fallback; ee status and ee doctor --full
show the degraded capability. EE_EMBED_MODEL_PATH is a diagnostics/fault
injection knob, not the model loader.
Sharing the embedding model with other tools
ee pins exactly one local embedder: minishlab/potion-multilingual-128M
(Model2Vec static embeddings, 256-d, revision a28f4eeb…, ~531 MB). What is
on disk, how it is verified, and what can and cannot be shared:
Registry layout. ee model fetch embedding-default downloads into
<root>/potion-multilingual-128M/ and writes exactly three entries:
<root>/potion-multilingual-128M/
├── model.safetensors # 512,361,560 bytes, pinned SHA-256
├── tokenizer.json # 18,616,131 bytes, pinned SHA-256
└── .verified # receipt: manifest fingerprint + per-file size/mtime/inode
<root> is EE_EMBED_MODEL_DIR when set, otherwise $XDG_DATA_HOME/ee/models
(~/.local/share/ee/models on Linux/macOS, %LOCALAPPDATA%\ee\models on
Windows). The models/model2vec/potion-multilingual-128M/ layout mentioned
above is read (and preferred when it already verifies) but never written by
ee model fetch, so a fresh machine always ends up with the layout shown here.
Verification. Frankensearch owns the pinned manifest: each file is checked
against its pinned size and SHA-256, and the .verified receipt lets later
loads skip re-hashing the 512 MB weights while sizes, mtimes, and inodes still
match. (The blake3: hash printed by ee model fetch and stored on the
registry row is a fingerprint of the loaded embedder, not a file digest.) The
loader additionally rejects a directory that contains any unregistered file
with a semantic role — config.json, tokenizer_config.json,
special_tokens_map.json, vocab.txt, model.onnx, … — because it will not
consume inputs the manifest did not verify. ee model status and embedder
discovery apply that same rule.
Pointing ee at a shared directory. EE_EMBED_MODEL_DIR may name either
the root (…/models) or the model directory itself
(…/potion-multilingual-128M); when set it takes precedence over the
workspace model registry. The supported recipe is to let ee populate the
shared location once, then reuse it everywhere:
# root; the model lands in /shared/models/potion-multilingual-128M
# on every other machine/user with the same EE_EMBED_MODEL_DIR:
EE_EMBED_DOWNLOAD=off
What is not supported: a raw Hugging Face snapshot of the same repo. It
carries config.json, tokenizer_config.json, special_tokens_map.json,
vocab.txt, and onnx/, so the loader refuses it even though its
model.safetensors and tokenizer.json are byte-identical to the pinned
files. If you must hand-provision, copy only those two files into
<root>/potion-multilingual-128M/; they verify by full SHA-256 on every
process start until a receipt exists, and only ee model fetch mints one.
Set EE_EMBED_DOWNLOAD=off whenever EE_EMBED_MODEL_DIR points at a
hand-managed directory: under the default auto policy an unloadable
directory triggers a fresh ~531 MB download, and an existing
potion-multilingual-128M/ at the destination is moved aside to
potion-multilingual-128M.backup.<stamp> rather than overwritten.
Other tools. cass-memory
(cm) embeds with Xenova/all-MiniLM-L6-v2 (384-d ONNX via transformers.js),
a different model family from ee's pinned Model2Vec artifact. No file is
byte-compatible between the two local caches, and vectors from one are not
comparable with vectors from the other. Sharing a file is therefore not
possible — but sharing a server is.
The shared-server recipe. Point both tools at one OpenAI-compatible
/v1/embeddings endpoint. One local Ollama serving all-minilm is enough, and
neither tool then downloads a model of its own:
# once, on the machine that will host the embeddings
# ee: switch to the remote backend and re-embed
On the cm side set embeddingBackend: "ollama" (and embeddingModel: "all-minilm") in its config; cm talks to the same daemon. The two tools keep
separate indexes — they are separate products — but there is now one model
artifact, one download, and one process holding it in memory.
Accepted URL forms are the base (http://127.0.0.1:11434/v1) and the full
endpoint (http://127.0.0.1:11434/v1/embeddings); only http and https are
supported. EE_EMBED_REMOTE_API_KEY adds an Authorization: Bearer header for
a hosted endpoint that needs one — a local Ollama does not. The dimension is
discovered from the first response; set EE_EMBED_REMOTE_DIMENSION to pin it
and skip that round trip.
What the remote backend does and does not promise. These vectors are
trusted because you pointed ee at the endpoint, not because the endpoint
proved anything: ee records no verified embedding identity for them (a stock
Ollama signs nothing, and Frankensearch's ApiEmbedder fail-closes without a
pinned producer key, which is why ee implements this backend itself). What
ee does guarantee is that the space cannot be silently mixed. The index
stamps the embedder id (remote-api:all-minilm) and the dimension into
meta.json, and changing the model, the dimension, or the backend makes the
existing index incompatible with a named error rather than blending two
embedding spaces:
index metadata '.../meta.json' was built at 384d by embedder
'remote-api:all-minilm', but the active embedder 'potion-multilingual-128M'
produces 256d vectors; embedding dimensions cannot be mixed and a full index
rebuild is required
ee model status reports the active Backend: (neural_local, remote_api,
or hash_fallback), and ee doctor carries a remote_embedding_endpoint
check that probes the endpoint whenever EE_EMBED_BACKEND=remote. If the
endpoint is unreachable, retrieval degrades to the deterministic-hash tier and
both surfaces say so — it never silently pretends to be semantic. Because the
remote model can change underneath you, ee model status reports
deterministic=false for this backend.
ee doctor reports a repair plan
Start with the agent-oriented triage view, then inspect one finding:
Use --fix and --undo <RUN_ID> only after reviewing the generated plan.
Mesh or Tailscale is unavailable
Mesh is optional. Local memory commands can stay on --mesh off.
For trusted-team create/invite/join, see
docs/team/quickstart.md. For fake-tailnet and
operator workflows, see
docs/mesh/operator_onboarding.md.
The live Unix proof ledger is
docs/mesh/verification_matrix.md.
Inspect command-risk memory
Ask ee for relevant risk history and provenance without changing whether the
command runs:
|
The response is advisory. ee does not install a command-denial hook, return a
policy-denied process status, or require a workspace allowlist for Cargo/RCH.
For a syntactically valid check, missing or unhealthy optional memory/token
storage is reported in degraded[] while both exitCode and the process status
remain 0.
A crowded checkout has unknown dirty files
Use the read-only hygiene report before staging anything:
The report classifies generated, scratch, local-machine, review-needed, and secret-risk paths without changing the worktree.
Limitations
Boundaries to know:
| Boundary | Practical meaning |
|---|---|
| Concurrent writes | FrankenSQLite uses single-process MVCC WAL. Many agents can read at once; heavy write swarms should route through job locks or the optional daemon write owner. |
| Agent loop | ee stores and retrieves memory. Claude Code, Codex, or another harness still owns tools, approvals, and the prompt loop. |
| Mesh | Unix live EE-to-EE is shipped (TcpMeshForegroundSyncTransport). The v1 remainder set closed 2026-08-17: two-host tailnet soak, Windows-host crash/restart soak, and the fake-IdP-as-v1-ceiling decision (see docs/mesh/verification_matrix.md); a two-distinct-human soak is the recorded post-v1 follow-up. FrankenSQLite remains the local source of truth. |
| Retention model | Forgetting and decay are product features. Export JSONL into git when you need sealed long-term records. |
| Model choice | Embeddings are delegated to Frankensearch. Default installs use the pinned local potion-multilingual-128M fast tier; semantic quality follows that model and the derived index unless the operator explicitly changes Frankensearch posture. |
| MCP | MCP sits above the CLI. The CLI has the richest contract surface. |
| Release distribution | Multi-platform GitHub release binaries use mandatory SHA-256 verification via the release installer. Homebrew (Dicklesworthstone/tap/ee) is refreshed by hand after asset verification. Starting with 0.15.1, Cargo builds resolve the complete dependency graph from crates.io using Cargo.lock. Releases are cut outside GitHub Actions and ship checksums and a manifest without Sigstore bundles or SLSA provenance; --require-provenance therefore fails by design. See the installation table for current publication status and the release notes for validation and remaining limits. |
| Reserved adapters | science-analytics reports a capability gap until its adapter matures. The loopback-only serve adapter is compiled into every build; the serve Cargo feature flag only changes how ee capabilities reports it. |
| Doctor repairs | Start with ee doctor --fix-plan --json; use --fix only after reviewing the run summary and undo path. |
FAQ
Does this replace Claude Code, Codex, or my agent harness?
No. It is the durable memory those harnesses call. The harness owns the loop; ee owns memory.
Does it phone home or call any external API?
By default, ee uses Frankensearch's local Model2Vec backend. It may perform
one pinned, verified download into the local model cache and runs from disk
afterward. An OpenAI-compatible remote embedding backend is available only
when explicitly configured; the normal memory workflow requires no paid API.
Why no Tokio?
The runtime is Asupersync, which gives us structured concurrency, capability narrowing, deterministic tests via LabRuntime, and an Outcome lattice. Tokio is forbidden in the dep tree, audited by CI.
Why no rusqlite?
The storage layer is FrankenSQLite via SQLModel. rusqlite is forbidden in the dep tree, audited by CI.
Can I use ee without cass?
Yes. cass is an evidence source, not a hard dependency. Without it, ee remember, ee pack, ee search, curation, graph, and packing all work normally.
Can two teammates share memory?
Yes on Unix. ee team create → send the invite → ee team join, then run
ee mesh hello-responder run or ee daemon --foreground on the origin and
ee mesh sync --once / ee team steward once on the joiner. Search and pack
with --memory-scope team. The v1 remainder set (two-host tailnet soak,
Windows-host crash/restart soak, fake-IdP-as-v1-ceiling decision) closed
2026-08-17 per docs/mesh/verification_matrix.md; a two-distinct-human soak
remains a recorded post-v1 follow-up.
How big does the database get?
On a typical multi-project developer machine, expect 50-500 MB after a year.
Cold/warm/hot tiering keeps the hot path small. ee backup create produces
portable, hashed record archives; inspect recoveryInventory before relying on
one as a complete recovery point.
What happens if my index gets corrupted?
ee index rebuild reproduces it from the DB. Indexes are derived assets, so
losing them is annoying but recoverable.
Does it work on Windows?
Yes. It is a single CLI binary, with a PowerShell installer script in the repo.
Paths follow platform conventions (%APPDATA%, %LOCALAPPDATA%).
Can multiple agents on the same machine share one database?
Yes. Reads are concurrent. Writes serialize through a job lock. For heavy
multi-writer swarms, run ee daemon and let the daemon own the write side.
Should I use the curl installer?
Yes — it's the recommended install. It fetches the binary for your platform
from the latest GitHub release, always verifies the checksum, verifies Sigstore
when the release includes a bundle and cosign is available, repairs PATH,
installs shell completions, and verifies the installed binary. It prints agent
integration guidance without changing agent settings. Use --require-provenance
for fail-closed signature and provenance verification. Build from source if you
want a local debug build or are hacking on ee itself.
Should I enable mesh?
Usually no. Mesh helps trusted peers exchange redaction-safe posture and memory
metadata, but single-machine local-first usage works with --mesh off.
What should an agent run first in a crowded checkout?
Start with ee swarm brief --workspace . --json and
ee workspace hygiene --workspace . --json, use Beads/BV to identify a
candidate, and run
ee swarm work-packet --workspace . --include-rch --claim-gate --candidate <id> --json
before any Beads claim mutation. Use Agent Mail for the actual reservation and
coordination workflow once the gate is safe.
How do I inspect current command contracts?
Use ee --help, ee help <command path>, ee --help-json, ee schema list,
and ee capabilities --json.
How do I integrate with my CI?
Run ee pack "<the task this CI run is doing>" --json and pipe relevant
rules into your agent's system prompt. JSON output is stable across patch
versions.
Does ee ever rewrite my memories silently?
No. The steward proposes; you approve. Promotions, consolidations,
replacements, and tombstones each produce recorded entries visible via
ee why <id> and the curation queue commands.
Where do I see the architectural decisions?
docs/adr/. Every major subsystem has an ADR with rejected alternatives and verification hooks.
Documentation
| Doc | Purpose |
|---|---|
CHANGELOG.md |
Reconstructed release history and current release posture |
CHANGELOG_RESEARCH.md |
Evidence ledger behind the changelog reconstruction |
docs/query-schema.md |
EQL-inspired request schema for ee pack |
docs/trust-model.md |
Memory advisory priority, trust classes, prompt-injection defenses |
docs/agent-outcome-scenarios.md |
North-star agent journey matrix and acceptance scenarios |
docs/agent-ux/insights-onboarding.md |
Agent workflow for graph-derived insights, Pack DNA, skyline, and proximity surfaces |
docs/agent-ux/auto_enrollment_onboarding.md |
Agent workflow and use/no-use checklist for optional Tailscale mesh, auto-enrollment, drift handling, and safety previews |
docs/agent-ux/ee-doctor-first-aid-precedence.md |
Doctor-first repair workflow for agents |
docs/agent-ux/memory-hygiene.md |
Weekly content-health workflow for curate doctor, learn gaps, and debt trends |
docs/agent-ux/journal-capture.md |
Append-only journal capture, end-of-session distillation, reinforcement, and pack-item grading workflow |
docs/agent-ux/flight-recorder.md |
Redacted workload flight-recorder operator and agent reference |
docs/agent-ux/workspace-hygiene.md |
Dirty-checkout and commit-readiness workflow |
docs/mesh/operator_onboarding.md |
Operator guide for optional mesh usage, trust/redaction posture, revision tokens, and troubleshooting |
docs/mesh/command_modes.md |
Optional mesh command modes and degraded behavior |
docs/mesh/anti_entropy.md |
Mesh anti-entropy workflow |
docs/mesh/peer_policy.md |
Mesh peer-policy and lane semantics |
docs/cli-reference/graph-flags.md |
Aggregated graph-related CLI flags by command, including implemented and pending surfaces |
docs/configuration/graph.md |
Graph feature flags, thresholds, and tuning guidance |
docs/configuration/cache.md |
Pack and query cache configuration |
docs/configuration/storage.md |
Read pool, snapshot pin, and storage configuration |
docs/architecture/graph-snapshots.md |
Graph snapshot families, lifecycle, locks, budgets, and degraded behavior |
docs/architecture/shard-fanout.md |
Shard-fanout architecture and migration posture |
docs/search/plan-cache.md |
EQL plan-cache behavior and diagnostics |
docs/env_vars.md |
Complete EE_* environment variable registry |
docs/feature_flag_registry.md |
Cargo feature flag status and owner tracking |
docs/degraded_code_taxonomy.md |
Degraded-code classification and severity vocabulary |
docs/dependency-contract-matrix.md |
Franken-stack integration contracts and version pins |
docs/testing-strategy.md |
Test categories, verification gates, golden test structure |
docs/command_classification.md |
Command effect taxonomy and read/write classification |
docs/migration-guide.md |
DB schema migrations and upgrade paths |
docs/toon-output.md |
TOON (Text-Only Object Notation) output format |
docs/pack-replay.md |
Pack replay, support-bundle safety, pack-quality operator guidance, and fixture authoring |
docs/agent-ux/regression-causality.md |
Regression-causality capsule workflow, redaction rules, and failed-gate operator examples |
docs/adr/0025-replayable-context-pack-selection-ledgers.md |
Pack replay/diff ledger contract, freshness states, and support-bundle safety rules |
docs/adr/0038-auto-enrollment-zero-touch.md |
Optional zero-touch Tailscale mesh auto-enrollment design, invariants, and rejected alternatives |
docs/adr/ |
Architectural decision records |
About Contributions
About Contributions: Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other "stakeholders," which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via gh and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.
License
MIT License (with OpenAI/Anthropic Rider). See LICENSE.
© 2026 Jeffrey Emanuel