# Frequently asked

<!-- Canonical: https://www.atlaso.ai/docs/faq -->

**Does atlaso send any data over the network?**
No. v0.1 is local-only — no outbound HTTP calls exist under `src/atlaso`. The only runtime dependency is `httpx`. `ATLASO_TELEMETRY` is a name-reserved no-op; setting it truthy emits one `UserWarning` to confirm the no-op. v0.2 will introduce an *opt-in* remote backend.

**Why is v0.1 retrieval lexical (BM25) and not semantic?**
Fast, deterministic, no embedding service required, reproducible across machines. The dispersion layer doesn't require semantic recall — it requires *structured* recall grouped by scope. The roadmap adds an optional embedding-backed path behind the same `recall()` signature; the BM25 path stays.

**Can I share one `Memory()` instance across users?**
Yes. Construct one per process. On each request, call `memory.for_user(authenticated_id)` for a `UserHandle` scoped to that user. The handle pre-fills `user_id` on every method call. Per-user data lives at `<base>/users/<sha256(user_id)[:16]>/field.db` — one SQLite file per tenant, isolation enforced at the filesystem.

**Why does `Memory(transport=httpx.Client(...))` raise?**
`httpx.Client` holds Authorization headers; sharing one across tenants risks silent leaks. Atlaso accepts only `httpx.BaseTransport` (the connection layer, no headers). For tests, use `httpx.MockTransport`. The rejection happens at construction with `ConfigValidationError`.

**Where does atlaso store data?**
Storage resolves lazily on the first write, in this order: (1) `path=` kwarg to `Memory()`, (2) `ATLASO_PATH` env var, (3) the nearest ancestor that already contains a `.atlaso/` directory, (4) the nearest ancestor with a project marker (`pyproject.toml`, `package.json`, `.git`, `Cargo.toml`, `go.mod`) — creates `.atlaso/` there, (5) cwd as a last resort. The walk stops at `$HOME` or the filesystem root. **There is no `~/.atlaso/` fallback for field data** — a global home-dir store would silently merge memories across projects.

**How is `is_confident` computed?**
For a scope bag: `bag_precision >= 0.99` AND not `is_single_sample` AND no `has_conflict`. All three must hold. A single observation, even with high evidence grade, is never confident.

**Can I update a deposit?**
No — deposits are immutable. `m.update(...)` raises `AttributeError` with a pointer at `contradict()`. From a `Memory` instance call `m.contradict(new_text, contradicts=[old_id], reason=..., user_id=...)`; from a bound `UserHandle` call `user.contradict(new_text, contradicts=[old_id], reason=...)` (the handle pre-fills `user_id`). Atlaso writes the new deposit and records contradiction edges from old → new so the audit chain is preserved.

**Difference between `retract()` and `contradict()`?**
`contradict()` writes a **new** deposit and records a `contradicts` edge from the new one to each superseded id — both remain queryable for audit; the recall pipeline doesn't hard-filter contradicted targets but surfaces the edge so your agent can branch on it. `retract()` removes a deposit from `recall` (soft tombstone by default; `hard_delete=True` is irreversible) without writing a replacement.

**Why was my `add()` rejected with `DepositRejectedError`?**
The gate refused the write. `e.gate_reason` tells you which rule fired. Usually fix is a higher evidence grade, a narrower scope, or provenance (`artifact_refs`, `scope.env`, `scope.version`).

**Does atlaso work with Claude Code / Cursor / Codex / Windsurf / Cline?**
Yes via MCP. `pip install "atlaso[mcp]"`, run `atlaso mcp`, wire into your client's MCP config. The server exposes nine tools (full `Memory()` surface). Claude Code also has `atlaso install-hooks` which registers a synchronous `UserPromptSubmit` recall hook and an async `Stop` deposit hook in `settings.json`.

**Should I use `Memory` or `AsyncMemory` in a web app?**
Use `AsyncMemory` inside any async runtime (FastAPI, Starlette, asyncio loops). v0.1's async backend wraps the sync SQLite engine in `asyncio.to_thread`, so calls don't block the event loop. Calling synchronous `Memory` from an async handler emits `SyncInAsyncWarning` once — silence with `Memory(suppress_async_warning=True)` or `ATLASO_ASYNC_WARNINGS=0` if intentional. `for_user()` stays sync on `AsyncMemory`; only the data methods are awaitable.

**What should I pass to `for_user()` — and what does `validate_user_id` do?**
An *authenticated* identity: whatever your auth middleware returned after verifying the user. The shape constraint is `^[A-Za-z0-9_\-:.@]{1,128}$`; spaces and slashes are rejected. **Never pass a value from a request body.** For a single audit point, pass `validate_user_id=` to the `Memory()` constructor: it runs inside every `for_user(...)` and every lower-level call. Raise from it to block.

**How does `add_many()` handle partial failures and duplicate keys?**
Skip-and-report. Each `AddItem` requires an `idempotency_key`. Items that pass the gate land in `result.committed`; items where the key + identical content were seen in the last 24 hours land in `result.duplicates` (no second write); items the gate rejects land in `result.failed` as `BulkReject(item, error, index)` so you can retry the subset after fixing metadata. Same-key + *different* content raises `IdempotencyKeyConflict` with `.existing_id`.

**Will the API change before v1.0?**
Public API is design-locked. New methods may be added. Existing signatures, return types, and exception classes follow semver inside the alpha track. Read the release notes before each upgrade.

---

<!-- atlaso:doc-trailer -->
**Source:** <https://www.atlaso.ai/docs/faq>  
**Edit on GitHub:** <https://github.com/imashishkh21/atlaso/tree/main/docs/faq.md>  
**Updated:** 2026-05-12
