What cannot happen by construction — not by policy.
The answer engine cannot generate novel text. Every answer is a human-authored string frozen at configuration time. The document extractor cannot send your files to an AI model. The extraction pipeline is deterministic arithmetic with no external calls. These are structural properties, not configuration choices. A misconfiguration cannot change them.
| Field | Purpose | Stored? |
|---|---|---|
| Question text | Routing decision | Yes — query log (see below) |
| Routing outcome | route / ask / refuse | Yes — query log |
| Menu selection | Improve future routing | Yes — selection log |
| IP address | — | No |
| User-agent | — | No |
| Session or user identity | — | No |
The query log records question text and routing outcome. It is a capped ring buffer — oldest entries are evicted automatically. It is not a permanent store. We recommend that users not enter personal data (name, email, account number) into the widget; the UI does not prompt for it.
When a visitor picks from a disambiguation menu, their choice is recorded. This is protected by an HMAC token issued by the prior response — a selection can only be recorded for a menu the engine itself generated. The fold step that improves routing runs offline, produces a gated proposal, and requires human review before anything changes. Question text is never sent to an AI model. The fold step reads routing outcomes (was this routed, asked, or refused?), not the question text itself.
| Leg | Protocol | Notes |
|---|---|---|
| Browser → Fly.io | HTTPS / TLS 1.2+ | TLS terminated at the Fly edge |
| Fly edge → app | WireGuard (Fly private network) | Encrypted in transit |
| App → database | Local disk I/O | Fly persistent volume, same region |
Region: fra (Frankfurt, EU). All data is stored and processed in the EU. No data is transferred to third-party AI services at runtime — the serve path is arithmetic, with no external model calls.
PDFs you upload are stored temporarily on the API server for the duration of your session. They are deleted within 24 hours. They are not backed up, archived, or copied elsewhere. We do not use uploaded documents to train, fine-tune, or evaluate any model. We do not share them with third parties.
The extraction pipeline is fully deterministic and runs on our own infrastructure. No third-party AI service is invoked for the standard extraction flow.
API server: Fly.io, San Jose region (United States). Uploaded PDFs: Fly.io tmpfs on the API container, deleted within 24 hours. Free-tier usage counter: Fly.io persistent volume, San Jose region.
The answer engine applies a regex pre-filter before routing. Detected prompt-injection attempts receive a flat refusal and are never processed. Because the serve path has no generation step, a successful injection cannot cause the engine to produce a novel harmful string — the structural limit is stronger than the filter.
Menu selections require an HMAC token issued by the preceding response. Rate limiting is applied per source. The selection log uses a capped ring buffer. Single-source spam is inert; meaningful learning requires independent sources.
Every answer response carries a corpus_version (the exact configuration that produced it) and a state hash (the in-memory engine state at serve time). Any answer is reproducible by restarting the engine at the same corpus_version.
All code changes are deployed via GitHub Actions on push to the main branch. No code reaches production uncommitted. API tokens are stored as scoped GitHub Actions secrets.
We are a small company. We are honest about what we hold and what we don't.
| Certification | Status |
|---|---|
| SOC 2 Type II | Not certified. Our infrastructure provider (Fly.io) is. doloop as a company is not yet. |
| ISO 27001 | Not certified. |
| GDPR | Controls in place (EU hosting for the answer engine, limited retention, DPA available on request). Not independently audited. |
| Penetration test | Not conducted by a third party. Internal adversarial review completed 2026-06-14. |
Clients with mandatory certification requirements should contact us to discuss timelines or alternative deployment arrangements.
For clients who embed the answer engine widget on their own site: the client is the data controller (they determine the purpose and means of their website and the widget's deployment); doloop is the data processor. The query log does not link questions to an identified individual (no user ID, no session ID, no IP). A Data Processing Agreement is available on request.
Security issues: hello@doloop.io with subject line Security. We aim to respond within 24 hours on business days.
Compliance and DPA enquiries: hello@doloop.io.
Infrastructure provider: Fly.io legal & compliance.
Routes you to a real page, asks when ambiguous, or refuses. No model on the answer path, so it never invents.
Routes you to a real doloop page, asks when your question is ambiguous, or tells you when there is no answer. No model runs on the answer path, so it cannot invent one.