Skip to content

Privacy Pipeline

Every prompt passes through three stages before it is sent to the LLM:

Ki! checks the prompt against any regex rules you have defined in Settings → Custom Rules. These fire first so that project-specific identifiers (e.g. PROJ-[0-9]+, employee IDs, internal codenames) are masked before general NER runs.

Community users can define rules manually per-device. Sovereign users can push rules to all seats via Policy Sync.

Before NER runs, Ki! checks each detected candidate against your allowlist. Allowlisted terms — product names, public company names, benign technical jargon — are left unmasked. This prevents over-masking that breaks the coherence of the reply.

The final pass uses the ocultar Named Entity Recogniser (an embedded Go sidecar). It detects:

  • Names (persons and organisations)
  • Email addresses
  • Phone numbers
  • Dates and date ranges
  • Monetary amounts
  • Physical addresses
  • National ID numbers

Each detected entity is replaced with a typed token: [PERSON_abc3], [EMAIL_7f2a], etc. The token includes a short hash derived from the original value — the same value always maps to the same token within a session, so the LLM can refer to entities consistently.

StepCommunitySovereign
Custom RulesUp to 10 rules, device-localUnlimited, policy-synced across team
AllowlistDevice-localPolicy-synced, Ed25519-signed
NER backendocultar cloud NERocultar + local SLM (air-gap mode)

Tokens are stored in a local SQLite vault (vault.db) on your device. The vault is encrypted with AES-256-GCM; the key lives in your OS keychain. The vault is never synced to Ki!‘s servers.

After the LLM responds, Ki! scans the response for tokens matching the current session’s vault. Each token is replaced with its original value. The process is deterministic — if a token appears multiple times in the response, all occurrences are restored.

If a token appears in the LLM response that is not in the vault (e.g. the LLM invented a token-like string), it is left as-is.