The matters system for an AI agent
I run a Nanoclaw agent as an executive assistant. With access to a filesystem, everything goes into a markdown file. But flat files are far from deterministic. With stale states and fragmented context, it's hard for the agent to reliably answer "what's true right now?". I realized it was often dropping the ball on some things or overindexing on others. This was supposed to be the unlock for me - the agent taking care of the scattered, moving parts of my life so I don't have to.
To address this, I created a matters system and decided to share the technical details below:
Overview
A matter is a persistent, database-backed record that tracks the current state of a workstream. It is the single source of truth for any ongoing task, project, or coordination effort. Email threads, calendar events, and conversations are inputs to a matter — the matter is where they converge.
Matters are stored in a SQLite database and accessed via MCP tools. They are not markdown files. Multiple agents and groups read and write to the same matter database simultaneously.
Data Model
Each matter has the following fields:
| Field | Type | Description |
|---|---|---|
id | Integer | Auto-incremented unique identifier |
title | String | Short descriptive title |
status | Enum | Current lifecycle status (see below) |
context | Text | Living summary of current state (see below) |
artifacts | Array | Linked external items (see below) |
tracking_file | String | Optional filename in group notes/ folder for supplementary detail |
updated_at | Timestamp | Last updated datetime (UTC) |
Statuses
| Status | Meaning |
|---|---|
active | Work is in progress |
waiting | Blocked on an external party or condition |
escalated | Waiting on the principal's input or decision |
paused | Intentionally on hold |
resolved | Complete — no further action needed |
Default list view shows: active, waiting, escalated. To see paused and resolved, filter explicitly.
Artifacts
Artifacts are external items linked to a matter. Each artifact has a type and an id.
| Type | ID Format | Example |
|---|---|---|
email_thread | Gmail thread ID | abc1234def5678gh |
calendar_event | Google Calendar event ID | calid_base_20260401T170000Z |
task | NanoClaw task ID | task-1234567890123-abc123 |
doc | Google Drive document ID | 1AbCdEfGhIjKlMnOpQrStUvWxYz123456789 |
Artifacts are a full replacement list — when updating artifacts, the entire array is replaced.
The Context Field
The context field answers one question: what is true right now about this workstream?
It is a current-state snapshot, not a log. It is rewritten on each update — not appended to.
What belongs in context
- Current state of all key facts (location, timing, participants, decisions)
- Source and time tag on every fact:
Location: TBD (principal, Mar 5) - Agent actions taken:
Emailed organizer with available slots (Soji, Mar 5 9am) - Open items and who owns them
- Any directives from the principal
What does NOT belong in context
- Historical log of every prior state
- Duplicate entries for the same fact
- Superseded information (remove it or mark
(superseded)) - Analysis or interpretation
Format convention for facts
Fact description (source, date)Examples:
Location: TBD (principal, Mar 5)Filing target: Q3 2026 (vendor, Jun 10)Soji followed up on pending deliverable (Soji, Mar 8 9am)
Information Authority Hierarchy
When information conflicts across sources, resolution follows this order (highest to lowest):
- Principal's word — anything said directly by the principal is final
- Current system state — what the API returns right now (live calendar event, live email thread)
- Matter context — prior decisions and facts stored in the matter (verify against #2 before relying on it)
- Third-party communication — emails, calendar invites, or messages from external parties
Recency is not a reliable proxy for authority. A more recent calendar invite from a third party does not override an instruction from the principal.
When conflict is resolved, the matter context is updated to reflect the authoritative fact. The superseded fact is removed.
Before-Acting Protocol
Before taking any action on a workstream that has a matter:
- Read the matter — get prior context, decisions, and what actions have already been taken
- Fetch fresh source data — pull the live email thread, live calendar event, or other primary source from the API
- Compare and reconcile — if the live source contradicts the matter context, update the context using the authority hierarchy above
- Act — take the action
- Record — add a timestamped entry to the context field documenting what was done
This protocol prevents two failure modes: acting on stale context (e.g., a meeting was moved but the matter wasn't updated), and duplicate actions (e.g., an email was already sent in a prior run but the matter doesn't reflect it).
When to Create a Matter
Create a new matter when:
- The principal assigns a new workstream that will involve multiple steps or interactions over time
- A coordination effort spans multiple external parties
- Something needs to be tracked across multiple sessions or agent runs
Do not create a new matter when:
- A new email arrives about an existing workstream — add the thread as an artifact on the existing matter
- A calendar event is created for an ongoing project — link it as an artifact on the existing matter
- The task is one-off and complete in a single action
Before creating a new matter, check if one already exists via find_matter (by artifact ID) or list_matters (by scanning titles).
The Matter as Broadcast Channel
Matters are the mechanism by which state changes propagate across agents and groups. When the principal gives an instruction that changes a workstream — a new location, a revised deadline, a dropped participant — the agent updates the matter context. Other agents or groups that subsequently read the matter will see the updated state.
There is no separate notification mechanism. The matter itself is the broadcast.
Tracking Files
A matter can reference an optional tracking file stored in the group's notes/ folder. Tracking files hold supplementary depth: research, timelines, detailed checklists, post-mortems, or context that doesn't fit in the matter's context field.
The matter is always authoritative. The tracking file supplements it. If they conflict, the matter wins.
Tracking files are referenced by filename only (e.g., project-tracker.md). They live at /workspace/group/notes/{filename}.
MCP Tools
| Tool | Purpose |
|---|---|
mcp__nanoclaw__list_matters | List matters by status. Default shows active, waiting, escalated. Pass status: "all" to include paused and resolved. |
mcp__nanoclaw__get_matter | Get full details of a specific matter by ID, including context and artifacts. |
mcp__nanoclaw__create_matter | Create a new matter with title, status, context, and optional artifacts. |
mcp__nanoclaw__update_matter | Update any field. Only provided fields change — omitted fields stay the same. Context should be a full rewrite, not an append. |
mcp__nanoclaw__find_matter | Find a matter by linked artifact. Pass artifact_type and artifact_id. Useful for checking if an email thread or calendar event is already tracked. |
Context Hygiene Rules (Summary)
- Reconcile, don't append. New information replaces what it supersedes.
- Tag every fact.
Fact (source, date)— so any agent can assess authority and recency. - Record actions. Document what was done and when, to prevent duplicate actions.
- Prune stale facts. Remove superseded information. Stale facts cause wrong conclusions.
- Rewrite on update. Pass the full updated context string — not a delta.