Privacy Archive
Last updated: May 2026. This document explains the optional training-archive feature in plain language. The binding terms live in §12 of the Terms of Service.
What we're trying to do
Kalku is built around a small fact: the way Nigerians and the African diaspora actually talk about money — in Pidgin, Yoruba, Hausa, Igbo, English, code-switching mid-sentence — is not represented well in any vendor AI model. The closer we get to launch, the more obvious it is that the difference between Kalku working well for you and working badly is understanding your phrasing, not just understanding "spent 5k on transport."
To make that work over the long run, Kalku is building toward its own AI model. That model needs training data. The diary messages you send to Kalku, stripped of anything that could identify you or anyone in your contacts, are the most valuable training data in the world for this specific problem — and you're the only person who can give it to us.
This is opt-in. Default off. Nothing is archived unless you switch the toggle on. You can switch it off at any time. You can delete every row that was ever archived for you at any time.
What gets stripped before any row is stored
Every message goes through a regex stripper before it touches the archive table.
| What | Becomes |
|---|---|
| Your first name | @SELF |
| Contact names from your diary | @CONTACT_1, @CONTACT_2, … |
| Phone numbers (NG + international) | @PHONE |
| Email addresses | @EMAIL |
| 10-digit Nigerian bank account numbers | @ACCNUM |
A row that comes out of the stripper looks like this:
"I gave @CONTACT_1 5k for transport yesterday"
We can train a model on that. We cannot identify you from it.
What we keep on purpose
Things that look like signal but actually are signal:
- Amounts and currency markers —
5k,₦5,000,$10,1m - Categories —
transport,food,data,church,school fees - Date / time references —
yesterday,last Friday,for January - The natural-language phrasing in your language —
I don gi am,mo san,na kashe,m gwara ya - Emotional / intent language —
I owe,she promised,I spent,I'll pay back
What we never archive, even with your consent
- Bank statement uploads. Skill 4 (the bank-statement parser) does not call the archive helper. This is enforced by a CI regression test that fails on every PR if
archiveIfConsentedever shows up in the skill 4 code path. - PIN entries. PIN-flow messages are intercepted before any LLM call.
- Images. Receipt photos, screenshots, profile pictures — none are archived.
- The audio file itself, for voice notes. Audio is transcribed and then discarded; it is never persisted to disk beyond the active request.
- Documents. PDFs uploaded for review are processed and discarded.
What happens with voice notes (explicit)
Voice notes follow the same archive path as typed messages, with one difference: the audio file is discarded after transcription. The PII-stripped transcript is what gets archived (when you've consented). The audio recording itself is gone. If you'd rather no transcript of your voice notes is kept either, switch the consent toggle off in Settings → Privacy — that stops both text and voice transcripts from being archived.
How access actually works
The archive table sits behind three database roles:
service_role— the app's normal role. INSERT-only on the archive. This is the only role that touches it during day-to-day operation.training_export— a separate role with SELECT-only access. Credential is rotated independently and released only at the moment of export. There is no UI that uses it. There is no/cookpage that uses it. The founder cannot browse it.training_erasure— a separate role with DELETE-only access. Used by the worker that processes erasure requests.
There is no UPDATE policy. Rows are immutable. The salt that generates the per-row user-hash is in a founder-only secret store and rotating it would permanently break the erasure path, so we don't rotate it.
Erasure
From Settings → Privacy, hit "Delete all my archive data." Behind the scenes:
- The request gets queued in
archive_erasure_requests. - A worker processes the queue, one user per minute (so we don't lock-contend a busy training-export job).
- Every row in
training_archivematching your per-row hash gets deleted. - An audit row is written so we can prove the erasure happened.
SLA: within 30 days. Typically within minutes.
What this is not
- It is not a public corpus release. The archive stays internal until Kalku has its own model to train. If we ever do open-source it, that's a separate consent flow, not implied by this one.
- It is not a way to make money on user data. We do not sell the archive. We do not share it with third parties. It is for one purpose only: training a Kalku-owned AI model that understands how you actually talk about money.
- It is not retroactive. Switching consent on now starts archiving from that point forward. Messages from before you said yes are not in the archive.
Questions
Write to hello@kalku.ai with subject "Privacy Archive". The founder reads every one.
KALKU DIGITAL SOLUTIONS LIMITED · RC 9539234 · 6, Adegbite Street, Oluyole Extension, Ibadan, Oyo State, Nigeria
Questions about this document? hello@kalku.ai
