<!-- source: openspec/changes/publish-legal-bundle/design.md -->

# Design — Publish Legal Bundle

> Companion to `proposal.md`. All decisions ratify as `D-LB-N`; open questions as `Q-LB-N`. Each decision encodes a research-backed recommendation; reverting one requires re-opening the linked counsel discussion.

---

## Inputs

This change is grounded in three parallel research reports produced 2026-05-13 by domain-specialist agents. Reports are parked in `research/` next to this design:

- [`research/01-commercial-lawyer.md`](research/01-commercial-lawyer.md) — Commercial Services / SaaS Counsel: 24-section ToS structure, scope, IP, liability, governing law, draft clauses, 10 open questions, 22 sources.
- [`research/02-ai-governance-counsel.md`](research/02-ai-governance-counsel.md) — AI Governance & EU AI Act Counsel: 14 AI-specific clauses (AI-1…AI-14), EU AI Act exposure analysis (deployer role), draft clauses, 8 open questions, 16 sources.
- [`research/03-privacy-dpo.md`](research/03-privacy-dpo.md) — Cross-Jurisdictional Data Protection Specialist: 3-document architecture, controller/processor map (14 flows), sub-processor inventory (14 vendors), MD/RO/IL/EU jurisdictional add-ons, draft clauses, 12 open questions, ~40 sources.

The three reports converge on architecture and AI Act classification; they disagree on liability cap shape for processor breaches. Conflicts are resolved by Pavel's approved decisions below (D-LB-3, D-LB-4).

---

## D-LB-1 — Document architecture: three artefacts + sub-processor list

**Decision.** The legal bundle is composed of four artefacts:

1. **Terms of Service** at `rapoport.studio/terms` — public, unilateral website document; commercial contract scaffold.
2. **Privacy Policy** at `rapoport.studio/privacy` — public; GDPR Art. 13/14 disclosures for controller flows (marketing-site visitors, intake form, account data, engagement metadata).
3. **Data Processing Agreement** as `_legal/policies/dpa-template.md` — executed per engagement; GDPR Art. 28(3) processor obligations.
4. **Sub-processor list** at `rapoport.studio/sub-processors` — generated from `_legal/vendors/*` cards.

**Rationale.** All three research streams converged: rolling everything into a single ToS creates legal-category errors (controller-vs-processor flows treated identically; SCC modules buried in unilateral website text; sophisticated EU clients refuse to engage without a separately negotiated DPA). Splitting is the industry baseline.

**Cross-document references.** ToS references Privacy Policy and DPA by URL/filename; Privacy Policy references DPA; DPA references the sub-processor list URL. All four documents reference `_legal/policies/ai-usage-policy.md` and `_legal/policies/human-review-protocol.md` as policy backings.

---

## D-LB-2 — Governing law and dispute resolution

**Decision.**

- **Governing law:** laws of the Republic of Moldova (excluding conflict-of-laws rules and CISG).
- **Primary forum:** arbitration administered by the Chișinău International Court of Commercial Arbitration (CICA), Rules in force at the time of arbitration. Seat = Chișinău. Language = English. Arbitrators: 1 for amounts in controversy < EUR 100,000; 3 otherwise.
- **Small-claims carve-out:** for studio claims for unpaid fees < EUR 10,000, studio may bring the claim before the competent ordinary courts of Chișinău.
- **Injunctive-relief carve-out:** either party may seek interim/provisional/injunctive relief in any court of competent jurisdiction to protect IP rights or Confidential Information.

**Rationale.** From `research/01-commercial-lawyer.md` § 3.11:

1. Rome I Reg. 593/2008 Art. 3 respects party autonomy — Moldovan law is enforceable for EU counterparties.
2. Moldova is a New York Convention party — CICA awards enforce against EU/IL respondents through their courts (outbound enforcement; the slow inbound enforcement Schoenherr documents is irrelevant when studio is claimant).
3. Hague 2005 Choice-of-Court Convention entered into force for Moldova on 2024-07-01, giving exclusive-jurisdiction MD clauses recognition across Hague members (EU, UK, Switzerland from 2025, Singapore, Mexico).
4. CICA founded 2016 to UNCITRAL/ICC/SCC/VIAC standards — institutional sweet spot for typical engagement sizes EUR 50k–500k.

**Negotiation fallback** (not in the default ToS, kept as Pavel's BATNA): Romanian law + ICC Bucharest for Romanian clients who balk at MD law. Defensible because of EU-MD DCFTA alignment. Not surfaced in public ToS — applied per engagement only.

---

## D-LB-3 — Liability cap: tiered, with uncapped GDPR Art. 28 carve-out

**Decision.**

| Stream | Standard cap | IP indemnity super-cap |
|---|---|---|
| Bespoke Services | greater of (a) 100% of fees paid in the 12 months preceding the claim under the relevant Order Confirmation and (b) EUR 5,000 | 2× standard cap |
| Tooling Access | greater of (a) 100% of fees paid for the relevant Tooling Access in the 12 months preceding the claim and (b) EUR 1,000 | 2× standard cap |

**Excluded damages (mutual):** indirect, consequential, incidental, special, punitive, exemplary; loss of profits/revenue/business opportunity/goodwill/anticipated savings/data (subject to DPA carve-out below).

**Uncapped carve-outs:** fraud or fraudulent misrepresentation; wilful misconduct or gross negligence; client payment obligations; breach of confidentiality; breach of acceptable use (client side); death or personal injury caused by negligence; **breach of GDPR Art. 28 processor obligations as set out in the DPA**; any other liability that cannot be limited or excluded under mandatory law.

**Rationale.** Compromise between Commercial counsel's tiered structure (`research/01-commercial-lawyer.md` § 3.7) and Privacy specialist's flag that EU enterprise expects uncapped liability for processor data-protection breaches. Resolution: cap stands at ToS level for commercial liability; DPA carries an explicit uncapped carve-out for Art. 28 processor obligations. This matches the standard EU-enterprise processor DPA position without bloating the ToS itself.

---

## D-LB-4 — IP indemnity for AI-generated output

**Decision.** AI-generated output indemnity is **sub-capped at fees paid for the affected deliverable** (per AI Governance recommendation `02-ai-governance-counsel.md` Q5(c)). This sub-cap sits below the D-LB-3 2× super-cap — so the studio's exposure for an AI-output third-party claim never exceeds the lesser of (a) fees-paid-for-affected-deliverable and (b) the 2× super-cap.

**Rationale.** AI-generated output carries real third-party-claim risk (resemblance to training-data copyrighted material). The studio currently has no E&O policy; matching GitHub Copilot's "commercially reasonable defense" posture would over-expose. Sub-cap at fees-paid-for-affected-deliverable is the defensible v1 position; revisit when engagement values rise and E&O insurance is in place.

**Operational dependency.** Reasonable human review is the precondition for the indemnity to apply — that's what `_legal/policies/human-review-protocol.md` does (Phase 2 below).

---

## D-LB-5 — Analytics vendor

**Decision.** Plausible Analytics (EU-hosted, cookieless, GDPR-native).

**Rationale.** From `research/03-privacy-dpo.md` § 7.5:

- Plausible operates without first-party cookies in its default config → no cookie consent banner required on `rapoport.studio`.
- EU-hosted (Hetzner Falkenstein) → no third-country transfer for marketing-site analytics.
- GA4 alternative would force DPF reliance + a banner + live risk that EU DPAs revisit GA4 lawfulness (as the Austrian DPA did in 2022).

**Operational impact.** New `_legal/vendors/plausible.md` card. Marketing site adds Plausible script; no consent flow needed.

---

## D-LB-6 — Sequencing: vendor DPAs first

**Decision.** Phases run in this order (see `tasks.md`):

1. **Phase 1 (this PR):** scaffold change; park research; no operational work.
2. **Phase 2:** AI operational gates (AI usage policy v1.0; human-review protocol; legal@ mailbox; Plausible swap-in).
3. **Phase 3:** executable vendor DPAs — Anthropic → OpenAI → Supabase → Cloudflare → GitHub → Linear. Priority order = highest-PII-risk first.
4. **Phase 4:** author Privacy Policy + DPA template + ToS draft texts in `_legal/policies/`.
5. **Phase 5:** counsel review (Moldovan commercial + EU privacy/AI).
6. **Phase 6:** site implementation — three Next.js routes, footer, sitemap, i18n scaffolding.
7. **Phase 7:** publication + post-launch hygiene.
8. **Phase 8:** archive + Linear closeout.

**Rationale.** Vendor DPAs are gating because the public-facing ToS and Privacy Policy claim, by reference, that downstream processor obligations are in place. Publishing first and signing DPAs later would make those references false on publication day. Phases 3 and 4 can partially parallelize once Anthropic + Supabase DPAs (the two highest-PII vendors) are signed.

---

## D-LB-7 — Counsel review gate

**Decision.** Two counsels engaged in parallel:

- **Moldovan commercial lawyer** — owns review of: structural ToS scaffold; scope; IP; liability cap (D-LB-3); governing law and dispute resolution (D-LB-2); engagement formation; sanctions/export-controls language; controlling-language clause.
- **EU privacy/AI counsel** — owns review of: Privacy Policy; DPA template (Art. 28 + SCCs); AI-specific clauses (hallucination disclaimer, EU AI Act statement, Art. 50 transparency split); sub-processor disclosure mechanism; cross-border-transfer language; breach-notification SLAs; Israel Amendment 13 considerations.

**Gate.** No public publication of `/terms`, `/privacy`, or `/sub-processors` without sign-off from both counsels on the documents in their respective domains. Sign-off lives in `_legal/policies/<doc>.md` frontmatter as `reviewed-by:` + `reviewed-on:` + `version:` lines.

---

## EU AI Act role classification

**Decision.** Studio is classified as **deployer** under EU AI Act Art. 3(4), not provider. Risk classification = minimal/limited (no Annex III category applies).

**Rationale.** From `research/02-ai-governance-counsel.md` § 5.1: Forge/Maestro/Muse are operated by the studio's internal team for the studio's own service delivery; agents are not placed on the EU market under the studio's name as standalone AI systems; clients have no direct operational access.

**Role-escalation reservation (clause AI-14 in research/02).** ToS contains a reservation that if the studio's operating model changes — direct-API access to Forge/Maestro/Muse for clients, autonomous execution against client systems without studio review, or branded resale of the agents — additional terms apply. This prevents silent slip to dual provider/deployer status when Forge is exposed externally in the future.

**Article 4 (AI literacy) compliance.** Already in force (2025-02-02). The internal AI usage policy at v1.0 (Phase 2 task) and personnel training records discharge this obligation. ToS records the studio's posture.

**Article 50 (transparency) compliance.** In force 2026-08-02.
- **Studio-to-client disclosure:** discharged by the ToS itself (client is on notice deliverables include AI-generated output).
- **Client-to-end-user disclosure:** ToS places this obligation on the client where it redistributes AI-generated content to its own end-users in scope of Art. 50(4), to the extent the studio's human review and editorial control does not qualify the deliverable for the Art. 50(4) exemption.

---

## Sub-processor inventory & transfer mechanism matrix

Source of truth: `_legal/vendors/*` cards, kept in sync with the public `/sub-processors` page.

| Vendor | Purpose | PII categories | Location | Transfer mechanism (EU → vendor) | Status (2026-05-13) |
|---|---|---|---|---|---|
| Anthropic | LLM inference (Forge / Maestro / Muse) | Code, ticket bodies, spec text, incidental PII | US (Delaware / California) | EU-U.S. DPF + SCCs fallback; commercial DPA available | DPA execution required |
| OpenAI | LLM inference (occasional secondary) | Same as Anthropic | US (California) | EU-U.S. DPF + SCCs; Commercial DPA + ZDR option | DPA execution required |
| Supabase | Postgres + Auth + Storage | Auth (email), session JWTs, application data | AWS eu-central-2 (Frankfurt) | EEA-resident data; corp entity US → SCCs in DPA | DPA execution required |
| Cloudflare | Workers, KV, CDN, edge runtime | Request payloads in transit; access logs | Global edge; corp US | DPF + Swiss-U.S. DPF + UK Ext + SCCs (Customer DPA v6.3, 2025-06-20) | DPA auto-applies for Enterprise; verify acceptance for our tier |
| GitHub | Source-code hosting | Code, commit metadata (author email), Issue bodies | US (multi-region) | DPF + SCCs (DPA Oct 2025) | DPA execution required |
| Linear | Project/issue tracking | Ticket bodies (incidental PII), assignee emails | US (multi-region) | DPF + SCCs | DPA execution required |
| Telegram | Client comms primary | Conversation content, handles, metadata | Dubai HQ, undisclosed infra | **No published DPA; not GDPR-compliant for B2B** | **Joint controller flag** — disclose in Privacy Policy + DPA; advise EU corporates to use email/canvas alternative |
| WhatsApp (Cloud API) | Client comms secondary | Conversation content, phone numbers, metadata | Meta global; EU-pinnable via BSP | Meta DPA + Business Data Transfer Addendum + SCCs | Use only via EU-based BSP |
| n8n Cloud | Telegram/WhatsApp → studio bridges | Messages in transit | EU (Berlin) | EU-controller-to-EU-processor — no third-country issue | Sign their DPA |
| Infisical | Secrets management | Operational secrets only (no PII of clients/end-users) | EU instance | EU-to-EU | DPA optional; sign for completeness |
| Plausible | Site analytics | IP (hashed daily), UA, page-view events; no cookies | EU (Hetzner Falkenstein) | EU-to-EU | DPA included; sign |
| Vercel | (historical — confirm retired) | — | — | — | Confirm against `platform.md` § Stack — likely retired in favour of Cloudflare Workers |

---

## Open Questions

### Q-LB-1 — DPO formal designation

Privacy counsel `03-privacy-dpo.md` § 8(1) notes statutory DPO designation likely not required for current scale, but a written designation of Pavel (or successor) as the privacy-responsible function is good practice. Decide before counsel review: (a) designate Pavel formally in the Privacy Policy as "Privacy Contact"; (b) defer until headcount or processing-scale change. Recommendation: (a). Cost = a paragraph in the Privacy Policy.

### Q-LB-2 — ZDR uplift contracts with Anthropic / OpenAI

AI Governance counsel `02-ai-governance-counsel.md` § 1(7) flags that the default 30-day abuse-monitoring retention from Anthropic / OpenAI is acceptable for most engagements but may block legal/HR-adjacent client work. Decide: (a) pursue signed ZDR uplift now as part of Phase 3 vendor DPA execution; (b) defer until first client in an affected sector. Recommendation: (b) — keep ZDR as roadmap item, do not block v1 publication. Document the deferral in the ToS as `commercially reasonable efforts to procure ZDR where required by Client written instruction` (per draft clause § 6.5 in `03-privacy-dpo.md`).

### Q-LB-3 — Telegram joint-controller frank disclosure

Privacy counsel `03-privacy-dpo.md` § 8(10) notes that EU corporates will appreciate a frank disclosure of Telegram/WhatsApp as joint-controller surfaces. Decide: (a) include explicit joint-controller flag with advisory note in the Privacy Policy; (b) keep softer "client comms via various messaging platforms" language. Recommendation: (a). Frank disclosure is a trust signal and a moat against future complaints.

### Q-LB-4 — Acceptance window length alignment

AI Governance `02-ai-governance-counsel.md` § 6(1) proposes 14 days for code, 30 days for written deliverables; Commercial counsel does not specify. Decide the single value used across (i) general warranty clause, (ii) AI-7 verification-responsibility split, (iii) human-review-protocol acceptance trigger. Recommendation: 14 days for code, 30 days for written, configurable per engagement in the Order Confirmation. Counsel may consolidate.

### Q-LB-5 — Romanian-law fallback in default ToS or per-engagement

D-LB-2 keeps Romanian-law fallback out of the default ToS, applied per engagement only. Decide whether to mention the fallback explicitly in the ToS (transparent but invites negotiation friction) or keep it as silent BATNA (current decision). Recommendation: silent. Revisit if Romanian client volume materialises.

### Q-LB-6 — Linear ticket-body PII hygiene as operational rule

Privacy counsel `03-privacy-dpo.md` § 8(7) flags that Linear ticket bodies feed into AI prompts via Forge/Maestro — operational hygiene rule needed: "no client PII in Linear titles or descriptions". Decide where this lives: (a) `_legal/policies/ai-usage-policy.md` v1.0 (Phase 2); (b) a separate `_legal/policies/data-handling-runbook.md`. Recommendation: (a). v1.0 of the AI usage policy is the natural home and saves a document.

### Q-LB-7 — Beta / experimental tooling clause

Commercial counsel `01-commercial-lawyer.md` § 5(10) suggests including a placeholder Beta clause now to cover future "Forge-as-a-service" exposure. Couples with D-LB-7 role-escalation reservation. Decide: (a) include placeholder Beta clause; (b) rely on role-escalation reservation alone. Recommendation: (b). The role-escalation reservation already gates this; a separate Beta clause adds surface area without commensurate value.

### Q-LB-8 — Counsel cost budget and timeline

Operational gate, not architectural. Decide before Phase 5: (a) Moldovan commercial lawyer — referral source, budget estimate, expected turnaround; (b) EU privacy/AI counsel — same. Pavel to source candidates; design.md only flags the gate exists.

---

## Risks and mitigations

| Risk | Mitigation |
|---|---|
| Counsel review introduces drift between draft and published versions | Versioning convention: every `_legal/policies/*.md` carries `version:`, `status:`, `reviewed-by:`, `reviewed-on:` in frontmatter. Public site renders `version` + `last-updated` in document footer. Diff between counsel-reviewed version and published version is a guarded operation requiring re-review. |
| DPF invalidation during draft → publication window | DPA template carries SCC fallback language unconditionally (per draft clause § 6.3 in `03-privacy-dpo.md`). If DPF dies, switch from "DPF + SCC fallback" to "SCC primary" via a documented amendment; no DPA re-negotiation required. |
| RU/RO translation drift from EN controlling version | Translations done by professional human translator post-EN counsel sign-off; mirror documents carry explicit "EN controlling" notice and reference EN version hash. Re-translation triggered by any material EN amendment. |
| Linear epic created before OpenSpec PR merged | Per CLAUDE.md inverted workflow: OpenSpec PR opens first, Linear epic filed after PR opens, PR body does NOT contain `Closes RAP-NN` autoclose keyword. |
| Vendor DPA terms change between signing and publication | Phase 3 task includes "DPA version capture" — store the signed PDF + URL + accessed-on date in `_legal/vendors/<vendor>.md` so we know which version we relied on. Re-verification cadence in Phase 8. |
| Pavel takes on personal liability instead of SRL | Commercial counsel `01-commercial-lawyer.md` § 5(9) flags this. Engagement-letter template explicitly names "Rapoport Studio SRL" as counterparty; never Pavel personally. Verified in Phase 4 drafting. |

---

## Coordination with active changes

Two active changes overlap on the marketing-site implementation surface. They do not affect any architectural decision in this proposal, but their task lists touch the same files in `apps/web/` and `packages/i18n/`. Resolution of the file-shape risk is handled by a sibling change.

### Sibling change: `split-marketing-footer-by-column` (archived)

[`openspec/archive/2026-05-14-split-marketing-footer-by-column/`](../../archive/2026-05-14-split-marketing-footer-by-column/) refactors [`apps/web/src/components/footer.tsx`](../../../apps/web/src/components/footer.tsx) from a single flat file into per-column modules under `apps/web/src/components/footer/columns/`. Same shape problem as the dialog-registry serialization-bottleneck: every PR that adds a footer link conflicts on the same hunk because the columns render inline in one component.

**If `split-marketing-footer-by-column` lands before our Phase 6 begins** (the expected ordering — it's a pure refactor with zero DOM diff):

- Phase 6.1 footer wiring re-routes from "edit `footer.tsx`" to "edit `apps/web/src/components/footer/columns/legal-column.tsx`".
- Phase 6.2 i18n new key `common.footer.legal.subProcessors` lands in `packages/i18n/messages/{en,ru,ro}/common.json` unchanged.
- Phase 6.4 footer tests re-target to `apps/web/src/components/footer/__tests__/legal-column.test.tsx` (the split's test file) rather than the legacy `apps/web/src/components/__tests__/footer.test.tsx`.

**If our Phase 6 begins before the split lands** (acceptable fallback, just slightly noisier):

- Edit `footer.tsx` directly per `tasks.md` Phase 6.1 wording. The split, when it lands, rebases the legal-column links into `legal-column.tsx` mechanically — no semantic conflict, just a hunk relocation.

### Sibling change: `add-legacy-track`

[`openspec/archive/<date>-add-legacy-track/`](../../archive/) or [`openspec/archive/2026-05-22-add-legacy-track/`](../add-legacy-track/) — adds a third audience track. Touch-points that overlap with our Phase 6:

- **Footer.** They add a single link (`nav.legacy`); location TBD at their implementation time. Their `tasks.md` references a stale path `apps/web/src/components/shared/footer.tsx` which does not exist; the real path is `apps/web/src/components/footer.tsx` (or, after `split-marketing-footer-by-column` lands, a column module). Not our problem to fix — their implementation owner re-targets.
- **i18n `web.json`.** They add a `legacy.*` namespace; we add `pages.terms.*`, `pages.privacy.*`, `pages.subProcessors.*`. Different namespaces; no key collisions. Mechanical JSON-structure merge conflict possible if both PRs are open simultaneously — first to land wins, second rebases.
- **`sitemap.ts`.** They add one entry × 3 locales = 3 entries; we add three entries × 3 locales = 9 entries. Append-only; mechanical merge.
- **Forbidden-phrasings lint (D-L5).** Their Phase 6 plans a Python lint that scans the entire `web.json` for forbidden phrases (`AI-powered`, `move fast`, `10x`, `magic button`, `growth hack`, etc.). Our page-UI i18n strings (headings, intro text, version labels) must avoid these phrases. **This is an authoring constraint** for Phase 6.2 i18n authoring, not an architectural constraint. Phase 4 drafting of `_legal/policies/*.md` is unaffected — that content lives outside `web.json`.

### What this section does *not* do

- It does not change any decision (D-LB-1..D-LB-7) in this change.
- It does not block this change on either sibling. The proposal here is internally complete; sibling changes are accommodations, not dependencies.
- It does not promise to update sibling changes' task lists from this PR. Updates flow from the sibling's own owner.
