Atrytone — data processing agreement (GDPR Art. 28)
DRAFT, unsigned. Written by the session on 2026-10-04 from what the code actually does, re-read against the cockpit at 303ea537, for a business customer who needs a written Art. 28 agreement before connecting a repository. A lawyer has not seen it. It assumes two things the operator has not yet confirmed: that Atrytone is acting as a GDPR processor for the customer's repository content and the data the customer types into the product, and that the free alpha or a paid plan needs this paper at all — both are open lawyer questions in docs/legal/changes-2026-09-24.md ("Questions for a lawyer", items 1-2). Sign this only after that question is answered. Amended 2026-10-07 against the GDPR specialist's reading (docs/readings/gdpr-2026-10-07.md, Appendix C): the controller/processor split in §3, Annex 2's sub-processors, the storage truth in §4 and §5(c), the deletion list in §5(g), a 30-day deletion after termination in §9, and the citation to the current terms file. This replaces docs/legal/dpa-draft-2026-10-04.md, kept in the tree, unreferenced, as evidence of what changed.
This agreement is an addendum to the main terms (docs/legal/terms-draft-2026-10-05.md, or its paid successor, once one is signed). If the two disagree on data protection, this one controls.
The Customer ("Controller"): the business that signs the main agreement.
The Processor: [OPERATOR: the provider's name and postal address]. The provider may be a natural person acting in business, or a company; this agreement reads the same either way, and nothing below assumes a company exists. Contact for data protection matters: hello@atrytone.ai.
1. Subject matter and duration
The Processor processes personal data on the Controller's behalf so that the Controller can use Atrytone: a control plane that reads a copy of the Controller's repository at a commit the Controller signs for, has models the Controller chose write and test code against it, opens pull requests, and keeps an append-only record of every act.
Processing lasts for as long as the main agreement runs, and for however long the Processor holds any of the Controller's data after that — which §9 of this agreement, and §3 of the data note, both bound.
2. Nature and purpose of the processing
- Reading the repository. Once a signature exists, or once a draft is being prepared for one to sign, the Processor's worker downloads the repository at one commit and shows its models the part a task needs.
- Running the Controller's own tests in a throwaway, no-network container, so a plan that cannot pass shows before money is spent.
- Sending prompts built from repository content and the Controller's instructions to the model provider the Controller names, using the Controller's own key (bring-your-own-key). The Processor does not choose that provider and is not a party to the Controller's contract with it.
- Recording every act — what was signed, what was read, what was written, what was spent, what was merged — as one append-only, hash-chained row per act.
- Storing files the work produces (run transcripts, screenshots, a goal's reference picture, uploaded code kept as a hosted git repository) in one private storage bucket, and the Controller's own secrets (model keys) in an encrypted vault.
- Checking the repository at rest, once connected and then nightly, for committed keys, tables a stranger could read, and parts with published flaws — reading the tree in memory, never writing it to disk, and making no model call.
- Providing export and deletion tools on the Controller's request. (§8 below.)
The Processor makes no model calls of its own on the Controller's data: every role a run uses, and every fallback of that role, must name a model provider the Controller's own vault holds a key for, or the signature is refused before any run starts (src/lib/conductor/project-ready.ts).
3. Categories of data subjects
- People named inside the Controller's own repository content, uploaded files, reference pictures, test output, and what the Controller's members type about the Controller's app — authors, reviewers, e-mail addresses in commit metadata, anything a test prints. The Processor does not choose what is in the Controller's repository and has no way to list these people in advance; the Controller is responsible for what it connects.
- The Controller's own workspace members (people it invites to use Atrytone), for their account data. The Processor is the controller for this category in its own right — it is not processed on the Controller's behalf — and the privacy note, not this agreement, states what is done with it.
- People the Controller invites into its workspace, before they accept: an e-mail address, where the request came in from, a hashed network address and browser identification.
4. Categories of personal data
- Repository content (source files, commit messages, issue text, test output, anything the Controller's own repository contains): read at run time into a working copy on the Processor's server in Vienna for the job. That copy is deleted when the job ends, and a daily sweep removes any copy left behind once it is 14 days old (since 2026-10-07, gap P0-2,
docs/readings/gdpr-2026-10-07.md). A snapshot of the files the job read and wrote is kept inruns.saved_stateso a stopped job can resume, until the project is deleted. - What the Controller's members type: asks, goals, conditions, answers — kept with the project; quoted in the ledger's titles and conditions (§5(g)).
- Secrets (the Controller's own model-provider key): encrypted at rest in the vault, AES-256-GCM, never in the ledger beyond a name and version.
- Messages (text the Controller writes through "Write to us"): one table, visible to the Controller's own workspace and the operator.
- Operational metadata (IP address, hashed on invitation requests; browser identification; access logs): the
invitation_requeststable, where the address is held only as a keyed hash, and the request is deleted after 12 months; the edge's access log, with each address cut to its network since 2026-10-07 and kept at most 30 days.
5. Processor duties (GDPR Art. 28(3))
(a) Processes only on documented instructions. Nothing is written to the Controller's repository, and no model call is made on the Controller's behalf, without a signature: the Controller's own, or a goal the Controller signed acting inside what is left of its ceiling. Every act is checked against this before it runs — the policy ladder, which names every rung it climbs and refuses an unknown action rather than guess (src/lib/conductor/policy.server.ts).
A transfer outside this agreement's terms (for example, to train a model the Processor itself operates) is not an instruction the Processor will follow; none exists in the product today — the Processor runs no model of its own.
(b) Confidentiality. The people who can read a Controller's rows through the operator's own access are bound to confidentiality as a condition of that access: today that is one person, the operator, plus the AI coding assistant they direct at an administrative task (named in (c) below). Open (gap P0-8, docs/readings/gdpr-2026-10-07.md): whether that assistant's provider (Anthropic) may be told to keep what it reads under confidentiality terms of its own depends on which Anthropic plan the operator uses for this administrative work, which is not yet confirmed. The operator confirms this before signing.
(c) Security of processing (Art. 32). The measures in force today:
- Row-level security, per tenant. Every table a signed-in browser can read is scoped by the signed-in person's workspace; a live drill found no row of another workspace readable, across every table tested (
tools/check-rls.mjs). - Encryption of secrets at rest. Model-provider keys are sealed with AES-256-GCM before they reach a table, keyed and versioned, never logged by value (
src/lib/conductor/vault-crypto.ts). - An append-only, hash-chained ledger. The database roles the application uses cannot UPDATE, DELETE or TRUNCATE a ledger row; each row carries the hash of the row before it, and the chain's running head is published where a removed or altered row would show.
- No-network execution. A customer's test suite runs with no network access; installing its dependencies has network with install scripts turned off.
- Transport and edge hardening. TLS, HSTS, a content-security policy derived from what the serving build actually loads, and the machine API refused from the public internet entirely.
- Backups. The whole database is copied once a day to a server the Processor controls, fourteen copies kept; the hosting database's own provider keeps backups of its own on the plan the project is on. An off-box, encrypted copy is built and drilled but not yet switched on, waiting on the operator's own storage account and encryption key.
- Secret-shaped files are withheld from the model by name — a file that looks like a credential is never put in a model's prompt, though it sits on the server's disk with the job's working copy if the Controller's own installer or suite needs it there, for as long as that copy exists (see §4 above).
(d) Sub-processors. The Processor may not engage a new sub-processor to process the Controller's personal data without the Controller's prior authorisation. The Processor gives general authorisation for the sub-processors named in Annex 2, and will tell the Controller, by e-mail to the workspace members' sign-in addresses, at least 14 days before adding or replacing one, giving the Controller the chance to object on reasonable data-protection grounds and to end this agreement if the objection is not resolved.
(e) Assistance with data-subject requests. The Controller's own members read their workspace's ledger on the Record page, and download it as CSV or JSON, a week at a time, or ask for a complete export — a tool (tools/export-tenant.mjs) that derives which tables and columns belong to that workspace from the live schema itself, so a table added later is still included.
Where a request concerns a person who is not a workspace member (someone named inside the Controller's own repository content), the Processor has no independent way to find or act on that person's data without the Controller's help, because the Processor does not read repository content except to do the work the Controller asked for.
(f) Assistance with security obligations. The Processor keeps the Controller's workspace behind row-level security and the append-only ledger described in (c), gives the Controller an incident channel ("Write to us", with an incident flag that pages a person directly), and will provide the Controller the information in Annex 2 and in docs/legal/data-note-draft-2026-09-24.md on request, to support the Controller's own Art. 32-36 duties.
(g) Deletion or return at the end of provision of services. On the Controller's request, after an export, a person erases the workspace in one transaction — the GitHub installation link, the invitation, lessons written from its runs, its epics and projects and every row that cascades from them, its budget reservations and ceiling extensions, every version of its secrets, and the workspace itself — re-counted to zero before it commits, or rolled back whole. The Controller's files in the storage bucket are then deleted and the bucket re-read to confirm it. Code uploaded instead of a GitHub connection (a "hosted home") is deleted from the server's disk by a second tool once the first names it. The job's working copy of the repository (§4) is deleted when the job ends; the copy of a job that was still paused when the workspace was erased is removed by the daily sweep once it is 14 days old. Reskin work directories on the server's disk are not yet reached by this tool, a tracked gap; and the export handed to the Controller before the erasure is the Controller's own copy to keep or delete.
What cannot be deleted: the ledger's own rows describing what was done — titles, criteria, file paths, amounts, verdicts — because deleting them would break the published hash chain the ledger exists to be. The Controller instructs the Processor to keep these rows after a deletion request, as the record the Controller itself relies on to verify what was done and what was charged; this is a lawful instruction for processor data, resting on the Processor's own legitimate interest in an intact, verifiable record (Art. 6(1)(f)) and on establishing or defending legal claims about the work (Art. 17(3)(e)). (Not yet reviewed by a lawyer.)
(h) Audits and information. The Processor will make available the information in this agreement and in the data note on request, and will allow and contribute to audits, including inspections, conducted by the Controller or an auditor it mandates, on reasonable notice — scheduled by mutual agreement, each side bearing the cost of its own participation, at most once a year unless a specific concern requires another. The Controller's own ledger (self-verifying: every row's hash is checkable against the one before it) and its own export are the Controller's standing evidence of what was done with its data; they do not depend on trusting the Processor's word.
The public page at atrytone.ai/proof publishes nothing of the Controller's: it shows only the Processor's own opted-in project, never a customer's.
6. International transfers
Processing happens, and the Controller's data is stored, on:
- The application server, rented from netcup, in its data centre in Vienna, Austria. Vienna is inside the EEA, so no transfer mechanism is needed for this one.
- The database and file storage, a hosted Supabase project in region eu-central-1 (inside the EEA). Supabase Inc. is a US company; its own data processing terms and Standard Contractual Clauses apply to that part of the relationship, alongside its EU data-residency commitment.
Where a sub-processor in Annex 2 is established outside the EEA and no adequacy decision covers it, the Processor relies on the European Commission's adequacy decision for the EU-US Data Privacy Framework where that sub-processor is certified under it, and otherwise on the EU Standard Contractual Clauses (the Controller-to-Processor module, or Processor-to-Processor as the relationship requires) in that sub-processor's own data processing terms. On the tree's current reading, the following are outside the EEA and need one of these: GitHub (Microsoft, United States), Anthropic and Resend (both United States), and, if the Controller's own model-provider key resolves to a non-EEA endpoint, the Controller's chosen model provider — though that relationship is the Controller's own, not a sub-processing arrangement the Processor creates on the Controller's behalf (§2 above). Ask and the Processor names, for each sub-processor, which mechanism applies, and sends a copy of the clauses.
7. Personal data breach
The Processor notifies the Controller without undue delay, and in any case within 48 hours of becoming aware that a confirmed personal data breach affects the Controller's data, so the Controller has time left to meet its own 72-hour duty to its supervisory authority under Art. 33. The notice names what is known at the time — what happened, which data, how many data subjects, what has been done — and is updated as more becomes known. This is the clock the Processor's own breach procedure (docs/legal/breach-procedure-draft-2026-10-04.md) is being aligned to; that procedure names the response steps, the regulator and the 72-hour duty, and a filled register of past incidents.
8. Assistance and cooperation
The Processor will give the Controller reasonable assistance, at the Controller's cost beyond what is already built into the product (the Record page, export and deletion tools), with data protection impact assessments and prior consultations with a supervisory authority, to the extent the nature of the processing requires it.
9. Term and survival
This agreement runs for as long as the main agreement does, and survives it for as long as the Processor holds any of the Controller's data under §5(g). Absent a request, the Processor deletes the Controller's data 30 days after the Controller's workspace is closed or the main agreement ends, and tells the Controller 14 days before.
10. Liability
Liability under this agreement follows the main agreement's liability clause (terms §6), which the operator and a lawyer have not yet reviewed for whether a data-protection breach needs its own, uncapped or differently capped term — common in Art. 28 agreements, and the main terms' general exclusion may not be appropriate here.
---
Annex 1 — processing details (summary)
- Subject matter: §1.
- Duration: for the main agreement's term, plus deletion handling under §5(g) and §9.
- Nature and purpose: §2.
- Categories of data subjects: §3.
- Categories of personal data: §4.
Annex 2 — sub-processors
- GitHub (Microsoft) — hosts the Controller's repository; the Processor reads it only through the Controller's own App installation token. United States; SCCs needed (§6).
- Supabase — the database (rows) and the private file bucket. eu-central-1 (database); the storage bucket's region is the same project. Database: in the EEA. Corporate entity: US — see §6.
- netcup — rents the virtual server the cockpit and worker run on. Vienna, Austria (EEA).
- Anthropic — the Processor's own administrative assistant (Claude), which can read the Controller's rows when the operator directs it to an administrative task (§5(b)). United States; mechanism per §6, confirmed once the operator's plan is confirmed (gap P0-8).
- Resend — sends the Processor's e-mails, including notices that may name the Controller's apps and goals. United States; mechanism per §6.
- Backblaze — an encrypted off-box copy of the database, once switched on. EU region; not yet live.
- Vercel — answers DNS lookups for atrytone.ai; no Controller content passes through it. Not applicable (no content).
- Tailscale — relays GitHub's webhook deliveries to the server; transport only, no content read or stored by Tailscale beyond the relay. United States (corporate); traffic encrypted end to end; transport only.
- Telegram / ntfy.sh — sends the operator short operational alerts ("a run parked", "a customer wrote"): ids, counts and moments only, never the Controller's content (since 2026-10-07, gap P1-2). Telegram: outside the EEA.
- ImprovMX — forwards mail sent to an @atrytone.ai address to the operator's mailbox. Location to confirm.
- Google — only if the Controller's own members choose to sign in with Google. United States, if used.
- osv.dev (run by Google) — the nightly check sends it package names and versions from the Controller's lockfiles — never code, never personal data. Not applicable.
- The Controller's own chosen AI model provider — receives prompts built from repository content, under the Controller's own contract with it, on the Controller's own key. Wherever the Controller's chosen provider is; the Controller's own relationship, not the Processor's sub-processing (§2, §6).
This table is built from docs/legal/data-note-draft-2026-09-24.md §2's "Other services your data passes through" and needs the operator's confirmation line by line; several locations are marked unconfirmed there too.
Annex 3 — technical and organisational measures (Art. 32)
See §5(c) above. In one line each: per-tenant row-level security; secrets encrypted at rest (AES-256-GCM) and never logged by value; an append-only, hash-chained audit ledger with a publicly anchored head; no-network test execution; TLS and hardening headers at the edge; the machine API closed to the public internet; daily database backups, with an off-box copy built but not yet switched on; a bot check (Cloudflare Turnstile) on the sign-in pages, planned on for launch and not yet switched on.
---
Open before this is signed: whether Atrytone is in fact a GDPR processor here, and whether this agreement is needed at all (the lawyer's own question); the provider's name and address; Annex 2's unconfirmed locations (ImprovMX, ntfy.sh); which Anthropic plan backs §5(b) and Annex 2 (gap P0-8); §10's liability term, for a lawyer; and the job's working copy and reskin directories named in §5(g), which stay on the server until the gaps named there are closed.
DRAFT, unsigned. The provider signs it before it is in force.