Technical detail: what we store, field by field
Last updated: 5 September 2026This page is the third layer of our privacy documentation. It exists because
"an identifier for your deployment" is the right level of detail for a privacy
notice, and the wrong level for someone who wants to check what we actually do.
- The sign-in notice is four sentences.
- The Privacy Notice describes categories, purposes and your rights.
- This page names the fields.
Nothing here is a commitment you are agreeing to — the Privacy Notice is the
document that binds us. This is the evidence behind it, published so the claims
in it can be checked rather than trusted.
What the product sends us
Product analytics — off unless you turn them on
Two events. mcp_startup when the software starts, mcp_session when a session
ends. Neither is sent unless Usage analytics is enabled under Manage → Settings.
| Field | Example | Why |
| ------- | --------- | ----- |
client_id | a fresh random value each time the process starts | Required by Google Analytics. Not derived from anything about you, and not reused after a restart, so events cannot be joined together |
version | 0.1.0 | Version adoption |
platform, os, arch | Darwin-arm64 | Which platforms matter |
tier | free / pro | Conversion |
source | mcp-stdio | Which AI clients launch Suvadu |
memory_count band | 11-50 | Usage scale, as a range rather than a number |
memories_recalled band, never_recalled band, heavily_used band | 1-10 | Whether stored memories are ever read back — the figure that shows the product working or not |
recall_tool_count | 3 | How many different AI tools recalled. The product's central claim, previously never measured |
| feedback tallies, banded | used / ignored / incorrect | Whether results were any good |
previous_session_unclean | true | Whether the last run died badly. A crash used to send nothing at all |
stores, recalls | 7, 12 | Engagement |
recall_zero_count | 1 | Recall quality |
dedup_count, limit_hits | 2, 0 | Deduplication, free-tier friction |
tools_total | 23 | Tool calls in a session |
session_id, engagement_time_msec | — | Required by Google Analytics |
duration_minutes | 45 | Session length |
client_id is not random on Cloud. It is derived from your deployment's
installation identifier, which we also hold alongside your email — so we can
connect these events to you. That is why the notice calls them pseudonymous
rather than anonymous.
Never included: memory content, query text, conversation content, your emailaddress, or file paths.
Diagnostics — opt-in, and identified
Separate from the anonymous statistics above: a different setting
(SUVADU_DIAGNOSTICS), off unless you turn it on, and it carries your
deployment's installation identifier — which we hold beside your email, so this
one is attributable to you. That is why it is a second consent rather than
a checkbox on the first.
| Field | Why |
| ------- | ----- |
| installation identifier | The point of it — lets us look at *your* deployment when you ask for help |
| version | What you are running |
| the same lifecycle figures as the anonymous statistics | Whether memories are being read back, and how the run ended |
Sent once when a session ends. We keep the last 30 runs, and the whole
record is deleted when you delete the deployment. It goes to us, not to Google —
deliberately, because "deleted when your deployment is deleted" is one delete we
perform, rather than an asynchronous request to a system we do not control.
The startup status check — always on
Sent every time Suvadu starts, whether or not analytics are enabled, because it
is how a purchase reaches your deployment and how a revoked licence stops
working.
| Field | Why |
| ------- | ----- |
| installation identifier | Identifies which deployment is asking |
| version | Serves the right update |
| one-way hash of your licence key | Confirms the licence, and checks it has not been revoked |
Because it reaches our server, the request also carries your IP address. It is
not recorded as an analytics event.
What we store, and for how long
| Store | Contents | Retention |
| ------- | ---------- | ----------- |
| Deployment record | Google sign-in email, project id, region, service URL, tier, licence-key hash, your analytics choice | Indefinite, including after deletion — see below |
| Purchase record | Email, order reference, licence key | While the licence is live; erased on refund, less any minimum record required for tax, accounting or fraud prevention |
| Sign-in session | Encrypted Google access and refresh tokens, email, Google account id | Deleted on sign-out, and after 24 hours without use. The clock is idle time, not total age — a session you keep using is not expired on a schedule |
| Sign-in index | Your Google account identifier | Removed at sign-out. Until 6 September 2026 it could survive one, on servers that had not handled your sign-in |
| Deployment cache | Project id, region, endpoint | 3 days |
| Audit relay | Truncated IP, user agent, redacted URL | 7 days |
| Operational logs (Google Cloud) | Diagnostic lines. Email addresses are hashed and IP addresses truncated before they are written | 30 days, then deleted by Google |
| Recovery links | Email, licence key | Expire automatically |
| Rate-limit counters | A hash of your email | 1 hour |
licence covers, and how licensing history stays accurate across a refund or a
recovery. Deleting your deployment destroys everything inside it — the server,
the storage, every trace, every secret — but our record that it existed
survives. Ask us and we will remove it manually.
What never leaves your deployment
No Manage operation returns memory content. Verified route by route:
| Route | What it returns |
| ------- | ----------------- |
| Connected clients | Tool registrations — client id, client name, scopes, last used, redirect URIs, and when the registration was issued |
| Audit log — refused attempts only | Timestamp, which registered tool tried, a hashed account identifier, the token id, how it authenticated, the operation (always the literal auth_check), the endpoint it tried to reach, the status code, how long it took (always zero, since nothing ran), and why it was refused. Your IP address is stored truncated to a /24. Successful requests are never recorded, so nothing here can reveal what you stored or recalled |
| Figures | Integer counts, and counts by trace type |
| Diagnostics | Configuration variable names, never their values |
| Connection test | Whether it answered, and how fast |
what you did with your deployment; it is a record of what was turned away from
it. operation is a closed enum with one value, auth_check, so a tool name
cannot appear there, and no successful read or write is written at all. That is
a stronger guarantee than the one we were trying to make: there is no
per-request log for a subpoena or a breach to reach, because it does not exist.
About the audit log, corrected twice before that. This page first said the audit recordhad *"no content field at all"*. It then said the opposite — that it carried a
free-text details field we could not vouch for. Both were wrong, and for
the same reason: they described a record shape our own website had invented,
never the one the deployment sends.
The real record has no free-text field. Every column is typed, the account
identifier is a one-way hash, and your IP address is truncated before it is
written. There is nowhere in it for memory content to go.
The separate security log — and here the guarantee is absolute. Tokenlifecycle, client-revocation and audit-erase events carry a small set of extras.
That set is closed at exactly seven keys:
older_than · deleted_shards · revoked_families · actor_sub ·
old_client_id · new_client_id · reason
The schema rejects anything else, both when a record is written and when it
is read back, so a record written before the vocabulary existed cannot slip
through either. This is not a description of our habits. It is enforced, and a
test fails if a key is added.
Until 5 September 2026 that field was an open dictionary, and it was carrying an
account email address in clear text. It was found because we asked our backend
for a constraint rather than a reassurance — a reassurance would have been given
honestly and been wrong. The address is now the same one-way hash used
everywhere else: a record naming who erased audit records is worth keeping;
their address is not needed to keep it.
revoked_families was the seventh key, added on 27 September 2026. Revoking a
tool's access used to remove its registration and nothing else, so the tool kept
working for up to an hour; revoking also had no entry in this log at all, which
meant you could not check. Both are fixed, and the new key is the count of token
families the revocation reached — a number, like deleted_shards. The count is
here because a revocation you cannot verify is not much of a control.
Where things are hosted
| Service | What it holds or receives |
| --------- | -------------------------- |
| Google Cloud | Everything we store, and the infrastructure your own deployment runs on |
| Vercel | Website and API traffic, including IP addresses and operational logs |
| LemonSqueezy | Payment details and email. Merchant of record. |
| Resend | Your email, when we send a recovery or reclaim message |
| Google Analytics | Product analytics if enabled; website analytics if you accept cookies |
| Tally | Survey responses, if you complete one |
| GitHub | Bug reports you choose to send, filed under your own GitHub account |
| HuggingFace | A model download on first run. Nothing about you or your memories is sent; the download itself reveals the requesting IP address to them, as any download does. |
Corrections
Things this page previously got wrong, kept visible rather than quietly edited:
- Analytics were described as anonymous. They are pseudonymous — the
identifier is linkable to you by us.
- The audit log was described three times from a record that does not
exist — first as having no content field, then as having a free-text one,
then as a per-request log of operations. It records refused authentication
attempts and nothing else. Both were written
from the columns on our own screen rather than the record the deployment
sends. The real fields are now listed, and the security log's extras are
named exhaustively because the schema enforces the list.
- Connected clients were listed as four fields. There are six.
- The payment processor was named as Stripe. It has always been
LemonSqueezy.
- The startup status check was not disclosed at all.
- Log retention was stated as 24 hours. We could not verify that figure and
have removed it rather than repeat it.