Files
resolutionflow/legal/attorney-review-checklist.md
Michael Chihlas 41f5519916
All checks were successful
Mirror to GitHub / mirror (push) Successful in 6s
docs(legal): add baseline legal documents (privacy, ToS, DPA, subprocessors, cookies)
Generated by the resolutionflow-legal skill from a code scan of the FastAPI
backend + React frontend on commit 0564646. Each document is a starting
point for attorney review, not legal advice.

Includes:
- privacy-policy.md, terms-of-service.md, cookie-policy.md (public-facing)
- dpa.md (contractual; signed with MSP customers)
- subprocessor-list.md (Railway, Anthropic, Voyage, Stripe, Resend, Sentry,
  PostHog, Google Fonts — confirmed live as of scan)
- data-inventory.md + classification.md (Phase 1/2 working files)
- attorney-review-checklist.md (consolidated [LEGAL REVIEW] punch list)
- implementation-verification.md (claim-by-claim audit vs. actual code)

Three blocking issues filed before public publication:
- #175 deletion-on-offboarding (or rewrite retention claims)
- #176 narrow Sentry send_default_pii + Session Replay config
- #177 EU/UK consent for PostHog + Google Fonts

Public-facing documents intentionally route physical-mail requests through
support@ rather than publishing the LLC's registered address.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:51:19 -04:00

155 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Attorney Review Checklist
Generated: 2026-05-14
Documents in scope:
- [privacy-policy.md](privacy-policy.md)
- [terms-of-service.md](terms-of-service.md)
- [dpa.md](dpa.md)
- [subprocessor-list.md](subprocessor-list.md)
- [cookie-policy.md](cookie-policy.md)
This checklist consolidates every `[LEGAL REVIEW]` tag and every issue surfaced by the scan that needs attorney judgment, with enough context that an attorney can bill efficiently.
---
## A. Highest-priority items (block publication)
### A1. Implement deletion-on-offboarding OR rewrite retention claims
**Where:** Privacy Policy §6 (retention table + deletion paragraph); DPA §6.2 (return/deletion).
**Issue:** Today, account "deletion" only soft-deletes the user row and revokes refresh tokens. The account row, audit logs, session content (`ai_sessions`, `sessions`, conversation transcripts, ticket snapshots, escalation packages), uploaded files in Railway Object Storage, AI usage records, sales leads, beta feedback, and notification history are **not** automatically purged.
**Why this matters:** GDPR Art. 5(1)(e) "storage limitation" + DPA §6.2 require ResolutionFlow to delete or anonymize Customer Data after the export window. The current draft claims this happens. The code does not enforce it.
**Two acceptable paths:**
1. **Build the deletion job** (preferred): add a scheduled task that purges all account-scoped Customer Data 30 days after account deletion (or sooner on customer request), and revise the language only if the implementation differs from what's drafted.
2. **Rewrite the language** to describe the actual behavior — "deletion on request, processed within X days" — and commit to an SLA the team can hit manually.
### A2. Sentry data-protection posture is broader than typical defaults
**Where:** Privacy Policy §3.2 ("Information we collect automatically" — error/performance monitoring paragraph); DPA Annex B; Subprocessor List Operational table.
**Issue:**
- Backend Sentry SDK is initialized with `send_default_pii=True` ([main.py:18](../backend/app/main.py#L18)) — user IDs and request fragments flow to Sentry by default.
- Frontend Sentry Session Replay runs with `maskAllText: false, blockAllMedia: false` ([instrument.ts:9-12](../frontend/src/instrument.ts#L9-L12)) — replays may contain visible page text and media.
**Why this matters:** Customer Data (ticket bodies, conversation content) can land in Sentry replays and error reports. Disclosing this is one option; the better path is narrowing the config first.
**Recommended:** mask text on routes that render Customer Data; set `send_default_pii=False`; add Sentry data-scrubbing rules for `intake_content`, `conversation_messages`, `ticket_data`, `escalation_package`. Then the existing disclosure narrows naturally.
### A3. EU/UK consent banner is required before PostHog / Google Fonts can fire
**Where:** Privacy Policy §4 (legal-basis table), §10 (cookies); Cookie Policy §2.3, §3.1.
**Issue:** PostHog is initialized unconditionally in [main.tsx:17-23](../frontend/src/main.tsx#L17-L23) with `persistence: 'localStorage+cookie'`. Google Fonts loads on every public page. For EU/UK visitors, both require prior consent under ePrivacy Directive Art. 5(3) / UK PECR.
**Action:** implement a consent management mechanism (or geo-gate) before launching public-landing EU traffic, OR confirm the product is geo-blocked from EU/UK. The Cookie Policy already references a consent mechanism — wire it up or remove the reference.
### A4. Article 27 representative designation
**Where:** Privacy Policy §2 ("Who we are"), §13 ("Contact us — EU/UK").
**Issue:** ResolutionFlow LLC has no EU or UK establishment. If EU/UK Data Subjects are reachable, GDPR Art. 27 / UK GDPR Art. 27 require designation of a written representative in the EU and (separately) in the UK.
**Action:** either appoint representatives (commercial services exist for ~$500$2,000/year per region) and update the contact section, or document a decision not to offer the Services to EU/UK Data Subjects and add a geo-gate.
### A5. Liability cap, indemnification, dispute resolution
**Where:** Terms of Service §10 (disclaimers), §11 (limitation of liability), §12 (indemnification), §13 (dispute resolution).
**Issue:** All four sections contain industry-standard defaults but are commercial-risk decisions that depend on revenue, insurance, and counterparty appetite.
**Specifically to calibrate:**
- §11(b): "fees paid in the preceding 12 months" cap is a SaaS default; confirm.
- §11(c) carve-outs: confirm the list (confidentiality, indemnity, DPA breach, gross negligence, willful misconduct, statutory non-limitable) matches insurer expectations.
- §12.2: IP indemnity scope is US patents/copyrights/trademarks; confirm geographic and IP-type scope.
- §13.1: governing law set to Georgia (LLC's state). Counsel may prefer Delaware.
- §13.2: chose Cobb County, Georgia for venue (matches LLC location). Counsel may prefer arbitration (JAMS/AAA) for enterprise neutrality and cost predictability.
### A6. Address withholding on public docs
**Where:** Privacy Policy §2; ToS §14.7; DPA §9.4.
**Issue:** User asked that the LLC's registered address (716 Hearthstone Xing, Woodstock, GA 30189 — home address) **not** appear on the website. The Privacy Policy and ToS therefore route physical-mail requests through `support@resolutionflow.com`. This is acceptable for routine inquiries but:
- **CAN-SPAM** requires a physical postal address in every marketing email — flag if marketing emails are sent.
- **Service of legal process** may require disclosure on demand; some states (e.g., DE) require a registered agent address publicly.
**Recommendation:** retain a registered agent (Northwest, ZenBusiness, Harbor Compliance — ~$100-$250/year) and update all three documents to use the registered-agent address. This solves the privacy concern without compromising legal-process service.
---
## B. Important items (calibrate before contracting with enterprise)
### B1. Sub-processor notice period
**Where:** DPA §3.4.2.
**Default chosen:** 30 days.
**Note:** Enterprise MSP buyers often demand 60-90 days. Decide what you will accept.
### B2. Breach notification SLA
**Where:** DPA §3.7.
**Default chosen:** 72 hours (GDPR baseline).
**Note:** Some enterprise buyers demand 24-48 hours. Verify ResolutionFlow can detect and report within the chosen window.
### B3. SCC governing law / forum / supervisory authority
**Where:** DPA Annex D.
**Default chosen:** Ireland (DPC) — most common.
**Note:** Counsel may prefer another EU member state depending on Customer base.
### B4. Audit rights cost allocation
**Where:** DPA §3.8.2.
**Default chosen:** Customer bears its own audit costs.
**Note:** Some enterprise buyers will request a free audit or one funded by ResolutionFlow if findings are material.
### B5. Export window
**Where:** ToS §9.4; DPA §6.2.
**Default chosen:** 30 days.
**Note:** Confirm the export tooling actually supports a 30-day window. If not, reduce.
### B6. Refund / proration policy
**Where:** ToS §5.2.
**Default chosen:** Non-refundable except where required by law.
**Note:** Common alternatives: 14-day satisfaction window; prorated refund on annual plans; no refund on monthly plans. Decide and update.
### B7. Anthropic and Voyage no-training claims
**Where:** Privacy Policy §4 (no model training note); Subprocessor List AI section.
**Status as of 2026-05-14:** Anthropic's commercial API tier does not train on customer data by default. Voyage AI's embedding API is similarly transactional.
**Action:** before publication, re-verify each subprocessor's current public terms. Re-verify each time this list is republished.
---
## C. Documentation gaps to fix in the product before claiming
These are claims in the documents that aren't fully backed by code today. See [implementation-verification.md](implementation-verification.md) for the line-by-line picture. Pick "fix the code" or "rewrite the claim" for each:
| Claim in documents | Reality today | Recommended path |
|---|---|---|
| Account deletion deletes personal information within a defined window | Soft-delete of user only; account-scoped content retained indefinitely | **Fix the code** (A1) |
| Audit logs retained for a defined period | Retained indefinitely; IP addresses included | **Fix the code** (add 12-month purge) or rewrite to "retained indefinitely for security purposes" |
| Refresh / verification / password-reset tokens are purged after expiry | Rows persist; no cleanup job | Fix the code (add nightly purge of `WHERE expires_at < now() OR revoked_at IS NOT NULL`) |
| File uploads are deleted on account deletion | No lifecycle policy on Railway Object Storage | Fix the code or document the actual retention |
| Sales leads / beta feedback / survey responses purged on schedule | No purge job | Fix the code or document |
| Encryption at rest (broad claim) | Railway encrypts at infra layer; only PSA credentials encrypted at app layer | Already disclosed accurately — verify Railway's attestation and keep the language as drafted |
| Multi-factor authentication | Not implemented for direct logins; SSO available via Google/MS | Acceptable as drafted; consider requiring MFA for admins |
| Microsoft Learn MCP no Customer Data egress | Verified: integration retrieves docs only | Disclosed accurately |
---
## D. Items left out by design (confirm)
- **Gemini (Google AI):** code path exists, no key in prod — omitted from Subprocessor List. Add when activated, with 30-day notice.
- **Autotask, HaloPSA:** code stubs in `services/psa/` only — not active and not disclosed. Add when activated.
- **OpenAI:** no key/code path detected — omitted.
- **Microsoft Learn MCP:** disclosed as a non-subprocessor (read-only doc lookup, no Customer Data egress).
- **ConnectWise:** correctly classified as customer-authorized data source, not a sub-processor.
---
## E. Sign-off checklist
Before publishing:
- [ ] A1 — deletion on offboarding implemented or language adjusted
- [ ] A2 — Sentry config narrowed (or disclosure expanded)
- [ ] A3 — EU/UK consent banner implemented (or geo-gate confirmed)
- [ ] A4 — Art. 27 representatives appointed (or geo-gate confirmed)
- [ ] A5 — liability / indemnity / dispute resolution calibrated with counsel
- [ ] A6 — registered-agent address obtained; addresses updated
- [ ] B1B6 — commercial decisions confirmed
- [ ] B7 — Anthropic + Voyage AI no-training stance re-verified within 30 days of publication
- [ ] Implementation gaps in §C resolved (build or revise)
- [ ] Effective Date and Version bumped on every material change going forward