Access Logs
Track reads and writes performed by agents.
Every tool call that touches memory creates a row in mx_access_log. Unlike revisions, access logs include reads.
What an access log stores
| Column | What it stores |
|---|---|
id | Unique log ID |
file_id | Foreign key to mx_file, nullable |
physical_path | Full path at access time |
operation | list, read, write, patch, search, or smart_read |
actor | Who performed the access |
user_id | The user whose memory was accessed |
tool_call_id | The LLM tool call ID |
created_at | Timestamp |
Access logs do not store file content. Revisions store content for writes.
Access logs vs observation events
Access logs answer: "What memory did the agent touch?"
Observation events answer: "How did the memory call behave?"
Every core tool execution records a root observation event in mx_observation_event with trace_id, span_id, duration_ms, status, tool name, operation, and sanitized attributes. Internal phases such as database reads, BM25 search, hybrid search, embedding, LLM generation, revision writes, and access-log writes are recorded as child spans when they run inside a traced tool call.
Tool responses include traceId, memory_trace_id, toolCallId, and durationMs. Search and agentic calls also include best-effort searchStats and provider token usage when available.
MemexAI keeps this trace data locally because memory-native observability is part of the product: admin tools can join traces back to access logs, revisions, and time-travel snapshots. Optional OpenTelemetry export should mirror sanitized spans for external systems, not replace the local record.
Why access logs matter
Revision history tells you what changed. Access logs tell you what happened.
With access logs you can reconstruct the agent activity around a session:
- It listed visible files.
- It read
user/profile.md. - It searched for relevant memory.
- It patched
user/profile.md.
That sequence is not visible from revisions alone.