# What we hold, where it lives, and who can reach it

**Every statement here is about code in a repository rather than an
intention** — and where something is not settled it says so rather than being
written as though it were.

**It must agree with [the privacy notice](privacy.html) exactly.** That is a
test rather than a promise: the supplier table below is read out of the notice
when this page is built, so the two cannot drift. Where this page says more, it
is for a reviewer rather than for a customer — the same facts, ordered for
somebody filling in a questionnaire.

## The short version

| | |
|---|---|
| **what we hold of a message** | the **sentence a promise was made in, up to 1,000 characters**. Not the rest |
| **what we never hold** | a mailbox, a message body, a password, a card number |
| **where it lives** | your own application and your own volume, in London |
| **how long** | 24 months, with an unclosed commitment never deleted on age, and every deletion recorded |
| **at rest** | encrypted storage **provided by Fly.io** — their encryption, their keys. We do not claim it as ours |
| **encrypted by us** | the credentials for systems you connect, and every backup |

## What we hold of what your agents say

**The sentence, and the decision — not the message.** When an agent asks
whether an action is permitted, what we keep is the shape of the action, the
answer, and where the action carried a promise, **the one sentence that promise
was made in, capped at 1,000 characters**. The cap is in the record schema, and
a test reads it from there rather than from this page.

**We do not say we never hold message text, because that would be false.** That
sentence is message text. What is true is that we hold that sentence and
nothing else of the message, and the cap is what makes the claim checkable.

**One thing can be sent to a language model, and only while your workspace's
AI model reader is on.** What you give us to read when you set up an agent is
sent to Anthropic to propose the lines your agents could say, at most 40,000
characters of one document; we keep the lines and never the text. With the
reader off, nothing is sent to a model and the text is read by rules on your
own deployment. The [privacy notice](privacy.html) quotes Anthropic's own words
on what they keep. Claude is also used to build Reynforce.

## Who holds what

<!-- suppliers:start — generated by website/build.py; do not hand-edit -->
| | what they hold | where |
|---|---|---|
| **Fly.io** | the deployment, and the volume your data is on; also Fly's own copies of that volume | London (`lhr`) for the deployment and the volume. **Fly's own copies of the volume and its control-plane records are held in the United States**, whatever the region, by Fly's own security questionnaire |
| **WorkOS** | sign-in, and the directory a role is read from | not yet confirmed |
| **Resend** | email in flight, and 30 days of logs | **United States** |
| **Stripe** | billing details and invoices, once payments are live | not yet confirmed |
| **Cloudflare** | this website, and a nightly backup of your store, encrypted by us before it is sent | backups running every night; the storage region is **not yet confirmed** |
| **GitHub** | the code, and the workflows an operator runs | — |
| **Anthropic** | what you give us to read when you set up an agent, while your workspace's AI model reader is on — see above. Also Claude, used to build the product | not yet confirmed |
<!-- suppliers:end — generated by website/build.py; do not hand-edit -->

## How long we keep it

**24 months**, counted from the month a record was written. Two conditions:

- **An unclosed commitment is never deleted on age.** A month is held back by
  the records still in it, and that is **derived** rather than stored — a
  stored flag would become false the moment the promise it was about was
  closed, and the month would then be kept for ever with nothing able to say
  why.
- **Every deletion is itself recorded**, with the count taken off the file
  before it goes, because that is the one number a deletion cannot recover
  afterwards.

**Nothing deletes yet, and the three mechanisms exist before the sweep that
will use them.** A claim about retention is not made true by a sweep that first
runs in two years. `reynforce/records/retention.py` imports neither `os` nor
`shutil`, so there is nothing in reach to delete with — asserted on the syntax
tree.

## How sign-in works

**Through WorkOS, and a role is read from your own directory rather than
maintained by us.** If your identity provider already holds the fact that
somebody is in the deal desk group, that group becomes the role a mandate
names. Connecting a directory **replaces** our manual list rather than sitting
beside it.

- **Sessions are signed and stored nowhere.**
- **Nobody is deleted.** A deactivation suspends, because a name that no longer
  resolves is worse than one that resolves to somebody who has left.
- **A person in no group reads as: we looked and they hold none.** That is a
  different answer from *we did not look*, and a third from *this directory
  cannot tell us*. All three are kept apart, because a finding that blamed a
  person for their directory's limitation would be the wrong finding.

## How one customer is kept from another

**Three boundaries, and they are three because each catches what the others
miss.**

1. **One deployment per customer.** Your register, your record and your
   directory are on your own application and your own volume. Secrets and
   networks are isolated per application — which is Fly's own recommendation
   for the same reason.
2. **A credential from another customer is refused at the door**, before any
   tool exists to it — not inside a tool, because then the tool list has
   already been shown and the next tool added is the one somebody forgets.
   An **unconfigured** deployment refuses **everybody**, and the refusal names
   the setting that would let them in.
3. **The destination checks too.** A request routed to your deployment carrying
   another workspace's prefix is refused by yours, which is the receiving end
   deciding rather than trusting the router.

**The front door in front of all of it reads no store and never reads a request
body.** It routes on the shape of one path segment, so there is nothing for it
to leak and nothing of yours held in the one component everybody shares.

## Questionnaire answers

Draft answers, and each is checkable against the repository rather than being
a form of words.

**Do you encrypt data at rest?**
Yes, on storage provided by Fly.io — their encryption with their keys, in
London. We additionally encrypt, with our own keys, the credentials you give us
for connected systems and every backup before it leaves.

**Do you encrypt data in transit?**
Yes, TLS throughout.

**Is customer data sent to a large language model?**
Only what you give us to read when you set up an agent, and only while your
workspace's AI model reader is on: it is sent to Anthropic, at most 40,000
characters of one document, and we keep the lines it proposes rather than the
text. With the reader off, nothing is sent to a model.

**Where is data processed and stored?**
Your deployment is in London. Email in flight passes through Resend, whose
stored data is in the United States and whose logs are kept 30 days — their
own published figures. Sign-in is WorkOS; their region is **not yet
confirmed** and is on our own unsettled list rather than answered here.

**Can you delete my data on request?**
The register, the record and the directory are on one volume we can destroy,
and a destruction is recorded against the customer rather than in the ledger it
destroys. **The automatic retention sweep does not exist yet**, so deletion
today is an operator action rather than a scheduled one — which is why that row
says what it says.

**Who at your company can access my data?**
**One person.** Access to a deployment is a Fly
credential and a terminal, and the back office an operator uses serves **counts
only** — never a list of customers and nothing read off a customer's record.
That is a design decision rather than a policy: the one surface that can see
every customer at once is the one that must not show any of them.

**Do you have SOC 2 or ISO 27001?**
No. Neither is held, neither is in progress, and we will not imply otherwise.

**What happens if you stop trading?**
This is the honest gap and it is written down rather than answered: there is a
restore test on record, it was run, and **two of three repositories failed it**.
Until a restore has succeeded, treat continuity as unproven. See
[the continuity note](#what-is-not-settled) below.

## What is not settled

| | |
|---|---|
| a solicitor's review of the notice | not done. One will review it before Reynforce is sold to more than a handful of customers |
| WorkOS's and Stripe's regions | not confirmed, and not guessed |
| the retention sweep | the policy, the exemption and the deletion record exist; nothing runs on a schedule |
| a successful restore | the test exists and has been run. Two of three repositories failed it |
| SOC 2, ISO 27001 | not held, not in progress |
