Whose machines this runs on, and what reaches them.
Sub-processors · 2026-08-04
A sub-processor is a company Verbatim hands your data to so that Verbatim can run. There is one: Anthropic, which receives the contents of the workspace every time somebody uses the assistant. There are still no customers and no customer documents, so what reaches it today is a demonstration workspace of invented and public-record filings — but the mechanism is live, and this page names it rather than describing a plan. It also names the companies whose machines the product sits on, and says what each one gets.
Verbatim is a pre-production build by one person. It has no customers, and the data in the demonstration carries two corpora, and both are labelled. One is invented -- a fictional commission, a fictional docket, a fictional company -- and the eval numbers are measured against it, because its traps were built on purpose. The other is 102 real public filings retrieved from eight state commissions, each with the URL it came from and a hash of the bytes; one pair of them is loaded into the demonstration workspace. Public record either way. Nobody's customer documents are here.
Nothing here is a contract. No data processing agreement is signed with any company named below, because there is no legal entity to sign one.
The short answer
No company processes a customer's documents for Verbatim today, because there are no customers. That is a narrower statement than it looks, and this page used to lean on it harder than it deserved. Two things are true at once and both matter.
First, the application is deployed. It has been since 2026-08-04.
verbatim.citelocal.ai serves the landing page and the policy pages at the root, and
nginx proxies a named list of paths to the application container behind it. Ask that host for
/healthz and it answers 200 with the row counts of a loaded corpus; ask for
/projects and it answers 303 to the login page, which is the session guard doing
its job. The privacy page describes tables that now exist on a
rented machine as well as on a developer's own.
Second, the assistant sends text to Anthropic. Every turn of the chat panel goes to Anthropic's API where a key is set, carrying the question, who is asking, and whatever the model looked up. The section below says exactly what that is.
What is still true, said more carefully than it was: no document here is confidential, and no document here belongs to a customer. An earlier version of this line said nobody has an account with real documents in it, which contradicted the sentence beside it — public record documents are real, and 102 of them are registered in the demonstration workspace with one pair loaded. "Real" and "confidential" are not the same word and this page had been using them as one. The two corpora are an invented proceeding and filings the commissions themselves publish. Nobody has entrusted us with anything, because there are no customers.
This page earlier argued at length that Anthropic was not a sub-processor, on four grounds — no deployed application, no engine module, nothing loading the environment file, no key. All four have reversed. The page stated its own trigger: Anthropic becomes a real sub-processor the first time a key is set and a call is made. That has happened, so the argument is gone and the listing replaces it.
The companies that run the site
Three, plus Anthropic in the section after this one. None of the three receives a customer's documents today, because there are none. What the first of them holds changed when the application was deployed behind the site.
What they hold. The whole machine, and since
2026-08-04 that means the product and not only the pages. The static
pages, the video on the landing page, the certificate's private key, the request log nginx
writes — and now the SQLite database on the host disk: every account and password hash, every
session row, every document loaded into the demonstration workspace, every claim, and the
whole audit chain. Why. The site and the application run on a virtual machine rented
from them. Where.
DigitalOcean, LLC is a United States company; the address is 143.198.140.28,
which their own registration record shows as theirs. Which region the machine sits in is not
stated here, because it was not checked.
Two things a buyer should know about that machine. It is shared. The original plan gave Verbatim its own disposable box; no credential existed to create one, so it went onto a droplet that already serves another of the author's projects, alongside that project's commercial data. That is a smaller boundary than the plan asked for, and ADR-10 in the decision record sets out what was traded and what would move it back. And nginx logs every request by default — the address it came from, the page asked for, the time and the browser's user-agent line. How long the host keeps that log is not claimed here, because the host's log settings were not read.
What they hold. The domain sudama.ai
and the name servers that answer for it, ns29 and
ns30.domaincontrol.com. What reaches them. The lookups that turn
verbatim.citelocal.ai into an address: the name asked for and the resolver that asked.
Not the page you then read, and nothing you type into it. Why. The domain was
registered there. Where. GoDaddy.com, LLC is a United States company.
What they hold. The certificate that makes
this page arrive over HTTPS, issued to the name verbatim.citelocal.ai and to nothing
else. What reaches them. The host name, and a proof that this server controls it. No
person's data goes into a certificate request. Worth saying out loud. Every
certificate is published to public transparency logs, so the host name is public whether or
not anything on it is. Where. Issued by the Internet Security Research Group, a
United States non-profit.
Anthropic, which is a sub-processor now
It receives real company context on every turn of the assistant. Here is the path, what goes down it, what is held back, and what is not agreed.
The assistant panel is on every screen and posts to
/chat. app/web/views/chat.py resolves
app/chat/engine.py, which calls run_turn in
app/chat/agent.py, which builds an AnthropicTransport and calls
messages.create against the model claude-opus-5. The key comes from
ANTHROPIC_API_KEY: app/config.py reads it out of .env
into the process at start, and deploy/compose.yml passes an environment file into
the container. With no key the transport is never built, the assistant says it is unavailable,
and nothing is sent — that refusal is tested, and it is not a canned answer dressed up as a
real one.
Three things, per turn. The question, as typed.
A short prompt naming the person's display name, the company's name, and the permission
codes they hold. The results of any tool the model chose, from
app/chat/tools.py. There are ten tools and they read the record: projects with
their jurisdiction, docket reference, status and owner; obligation titles with the owner's
display name and account id; open escalations with their ids, claim ids and the reason each
one is withheld; the approval route step by step, with the label of each step and who it falls
to; claim statements whose citation verifies, with the quoted source that earned them; and up
to 600 characters of the stored filing text on each side of a change. Two tools write rather
than read: one opens a project, one files a note against one. This is company context, not
only public filing text.
A claim whose citation does not verify never
reaches the model as a statement. One function turns a withheld claim into wire form —
_withheld_payload in app/chat/tools.py — and it emits the reason,
the reason code and the ids, never the statement, never the quote, never the source excerpt.
The object carrying a withheld claim has no statement field to read. Also not sent: the
session token, the cookie, any password hash, and the API key itself. The model is never
given the company id or the identity it is acting under — those are injected by the server,
and a model that supplies one halts the turn and leaves a row in the audit chain.
Bounded per call, not per conversation. One call carries at most 25 rows from a tool, 600 characters of filing text on each side of a change, and at most four rounds of tool calls in a turn. Prior turns are not resent — the shim drops the history the screen offers it. But nothing caps how many turns a person takes, so the total that reaches Anthropic over a conversation, or over a day, has no ceiling in this build.
app/interpretation/propose.py asks a
model what changed between two versions of a filing, and it is also written against
Anthropic's API. Nothing in the application calls it: outside its own test it has no caller in
this repository. So it is a second door onto the same vendor, and today only the chat door is
open.
Nothing. There is no data processing agreement, no commercial terms, no zero-retention arrangement and no statement about training on inputs — because there is no legal entity here to sign one and nobody has negotiated anything. The calls run against an ordinary API key on whatever terms Anthropic publishes for one, and this page has not read those terms into a promise on their behalf. The minimisation described above is what the code does; it is not a contract, and nobody outside this repository is bound by it. A buyer should treat this as the largest open item on the page.
Anthropic is a United States company. Which region a request is served from is not stated here, because it was not checked.
What is not a sub-processor, and where the line is
The line is this: a sub-processor handles your data so that Verbatim can run for you. A tool the operator uses for his own work is not one, however much it holds about him. Padding this page with the second kind would make it longer and less useful, and it would blur the question a procurement team is actually asking.
Gmail. Mail sent to the address at the foot of these pages lands in an ordinary personal Gmail mailbox, and Google's terms govern it — the privacy page says the same. That is the operator's mailbox for correspondence, not somewhere Verbatim puts your documents. The environment file also names Gmail credentials for a user-research outreach script; no such script exists in the repository, and no code in it sends mail.
GitHub. The source lives in a private
repository at github.com/jsahasi/verbatim. It holds the code, both corpora
and a set of public filings downloaded from state commissions' own document systems. It
holds nobody's documents.
Traefik and Coolify. These appear in the decision record and they are programs on the same rented machine, not companies that receive anything. The repository's nginx configuration listens on plain HTTP only, and the public address answers over HTTPS, so a proxy in front of nginx holds the certificate; ADR-11 records which one and why it is not the one originally chosen. Nothing leaves the machine through them except the certificate request already listed above.
The software libraries. FastAPI, uvicorn, SQLAlchemy, Pydantic, Jinja, httpx and the Anthropic SDK run inside the process on the same machine. A library is not a company receiving data. The only one of them that sends anything anywhere is the Anthropic SDK, and the section above says what it sends and to whom.
Things that are simply absent. No analytics, no error tracking, no content delivery network, no external fonts or scripts, no customer support tool, no marketing platform, no payment processor — nothing is for sale — and no off-host backup: the repository's backup script writes a verified snapshot to a directory on the same disk and has no remote destination anywhere in it. No page here fetches anything from another host, which is checkable by reading the source.
What changed when the application shipped
An earlier version of this page predicted two changes for the day the product ran. Both happened on 2026-08-04, and the page did not move with them for most of that day. Kept here as a record rather than rewritten away, because a page that quietly forgets what it promised is a page nobody can hold to anything.
- DigitalOcean stopped holding static pages and started holding everything. Done. The SQLite file with every document, every claim and every audit row is on that machine now. One company, one disk, no encryption at rest beyond what the disk gives — the security page says so and does not soften it.
- Anthropic became a real sub-processor the first time a key was set and a call was made. Done. The section above says what it gets.
- Anything else appears here before it runs, not after. That is the promise that was not kept, and it is the one worth keeping. Mail sending, error tracking, a backup target, a payment processor: this page first.
How this list was checked
Every row above came from a command or a file, not from memory. Run them yourself; they are all read-only.
dig +short verbatim.citelocal.ai Areturns143.198.140.28, andwhois 143.198.140.28names DigitalOcean.dig +short sudama.ai NSreturns thedomaincontrol.comname servers, andwhois sudama.ainames GoDaddy as registrar.openssl s_client -connect verbatim.citelocal.ai:443shows the issuer as Let's Encrypt and the subject as this host name.curl https://verbatim.citelocal.ai/healthzreturns 200 and a JSON body with the row counts of a loaded corpus, and/projectsreturns 303 to the login page. Both are the application answering, not nginx.- The path from the chat screen to Anthropic was read module by module —
app/web/views/chat.py,app/chat/engine.py,app/chat/agent.py,app/chat/tools.py— and the key's route into the process fromapp/config.pyanddeploy/compose.yml. What each tool returns was read out of the tool functions themselves.
Where a check was not run, this page says so instead of rounding up — the machine's region, Anthropic's serving region and the request log's retention are all marked that way above.
Questions to jsahasi@gmail.com. This page changes when the list does, and the date at the top moves with it.