Barazo default frontend barazo.forum
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(legal): align privacy policy with updated decisions (#92)

* chore: add .worktrees to gitignore

Prevent worktree contents from being tracked.

* fix(legal): align privacy policy with updated decisions

Sync privacy policy page with decisions/legal.md (Anonymize Don't Purge,
cookie clarification, federation transparency) and brand/privacy-manifesto.md
(AI features, age declaration, per-community preferences).

- Replace generic "session data" with specific refresh token cookie details
- Add age declaration and per-community preferences to data collected
- Add device fingerprinting and third-party trackers to not-collected list
- Add AI-generated summaries to legitimate interest legal basis
- Rewrite deletion section for anonymize-on-delete approach (tombstone +
personal data stripping + anonymized content retention)
- Specify reasonable deletion steps (AT Protocol events + Google Search
Console removal requests)
- Add new AI Features section (no training, local-first, anonymized summaries)
- Fix GitHub issue tracker link to point to barazo-workspace

* style(legal): format privacy policy files with Prettier

authored by

Guido X Jansen and committed by
GitHub
e96e15ed f500becb

+107 -11
+3
.gitignore
··· 25 25 .DS_Store 26 26 *.pem 27 27 28 + # worktrees 29 + .worktrees 30 + 28 31 # debug 29 32 npm-debug.log* 30 33 yarn-debug.log*
+37
src/app/legal/privacy/page.test.tsx
··· 46 46 expect(screen.getByText(/AT Protocol identifiers/i)).toBeInTheDocument() 47 47 }) 48 48 49 + it('describes authentication cookie instead of generic session data', () => { 50 + render(<PrivacyPolicyPage />) 51 + expect(screen.getByText(/Authentication cookie/i)).toBeInTheDocument() 52 + expect(screen.getByText(/HTTP-only, Secure, SameSite=Strict/i)).toBeInTheDocument() 53 + }) 54 + 55 + it('lists age declaration and per-community preferences', () => { 56 + render(<PrivacyPolicyPage />) 57 + expect(screen.getByText(/Age declaration/i)).toBeInTheDocument() 58 + expect(screen.getByText(/Per-community preferences/i)).toBeInTheDocument() 59 + }) 60 + 49 61 it('describes what data is not collected', () => { 50 62 render(<PrivacyPolicyPage />) 51 63 expect(screen.getByRole('heading', { name: /what we do not collect/i })).toBeInTheDocument() 64 + expect(screen.getByText(/device fingerprinting/i)).toBeInTheDocument() 65 + }) 66 + 67 + it('describes anonymize-on-deletion approach', () => { 68 + render(<PrivacyPolicyPage />) 69 + expect( 70 + screen.getByRole('heading', { name: /data retention and deletion/i }) 71 + ).toBeInTheDocument() 72 + expect(screen.getByText(/deleted by author/i)).toBeInTheDocument() 73 + expect(screen.getByText(/personal data.*is stripped/i)).toBeInTheDocument() 74 + expect(screen.getByText(/anonymized content.*may be retained/i)).toBeInTheDocument() 75 + }) 76 + 77 + it('describes AI features', () => { 78 + render(<PrivacyPolicyPage />) 79 + expect(screen.getByRole('heading', { name: /ai features/i })).toBeInTheDocument() 80 + expect(screen.getByText(/No training on your content/i)).toBeInTheDocument() 81 + expect(screen.getByText(/Local-first processing/i)).toBeInTheDocument() 82 + expect(screen.getByText(/Anonymized summaries/i)).toBeInTheDocument() 52 83 }) 53 84 54 85 it('lists user rights under GDPR', () => { 55 86 render(<PrivacyPolicyPage />) 56 87 expect(screen.getByRole('heading', { name: /your rights/i })).toBeInTheDocument() 57 88 expect(screen.getByText(/right to be forgotten/i)).toBeInTheDocument() 89 + }) 90 + 91 + it('links to barazo-workspace for issue tracking', () => { 92 + render(<PrivacyPolicyPage />) 93 + const link = screen.getByRole('link', { name: /github issue tracker/i }) 94 + expect(link).toHaveAttribute('href', 'https://github.com/barazo-forum/barazo-workspace/issues') 58 95 }) 59 96 60 97 it('mentions GDPR compliance', () => {
+67 -11
src/app/legal/privacy/page.tsx
··· 59 59 purposes. 60 60 </li> 61 61 <li> 62 - <strong>Session data</strong> -- OAuth tokens for authentication. 62 + <strong>Authentication cookie</strong> -- a single HTTP-only, Secure, SameSite=Strict 63 + refresh token cookie used to maintain your session. Access tokens are held in memory 64 + only and never stored in cookies or browser storage. 63 65 </li> 64 66 <li> 65 67 <strong>Moderation records</strong> -- actions taken by moderators on your content or 66 68 account. 67 69 </li> 70 + <li> 71 + <strong>Age declaration</strong> -- stored in the forum database only (deliberately 72 + kept off your PDS to avoid broadcasting age data on a public network). 73 + </li> 74 + <li> 75 + <strong>Per-community preferences</strong> -- notification settings and content 76 + maturity overrides, stored locally in the forum database (not on your PDS) to protect 77 + your browsing patterns. 78 + </li> 68 79 </ul> 69 80 </section> 70 81 ··· 80 91 </li> 81 92 <li>We do not collect payment card details (processed by our payment provider).</li> 82 93 <li>We do not use tracking cookies or analytics that profile your behavior.</li> 94 + <li>We do not use device fingerprinting.</li> 95 + <li>We do not load third-party trackers, pixels, or analytics scripts.</li> 83 96 </ul> 84 97 </section> 85 98 ··· 95 108 </li> 96 109 <li> 97 110 <strong>Legitimate interest</strong> -- indexing public AT Protocol content, spam 98 - prevention, platform security, and moderation. 111 + prevention, platform security, content moderation, and AI-generated discussion 112 + summaries. 99 113 </li> 100 114 </ul> 101 115 </section> ··· 121 135 <h2 className="text-lg font-semibold text-foreground">Data Retention and Deletion</h2> 122 136 <p className="text-sm leading-relaxed text-muted-foreground"> 123 137 Your indexed data is retained while the source exists on your AT Protocol PDS. When you 124 - delete content or your account via the AT Protocol, we process the deletion event and 125 - remove the indexed data from our systems. 138 + delete content or your account via the AT Protocol, we process the deletion event 139 + immediately: 126 140 </p> 141 + <ul className="list-inside list-disc space-y-2 text-sm text-muted-foreground"> 142 + <li> 143 + Your post is removed from public view and replaced with a &quot;deleted by 144 + author&quot; notice. 145 + </li> 146 + <li> 147 + Your personal data (DID, handle, AT Protocol URI) is stripped from the database 148 + record. 149 + </li> 150 + <li> 151 + The anonymized content (with no link to your identity) may be retained to preserve 152 + community knowledge and enable AI-generated discussion summaries. This anonymized data 153 + falls outside GDPR scope (Recital 26) because it can no longer identify you. 154 + </li> 155 + </ul> 127 156 <p className="text-sm leading-relaxed text-muted-foreground"> 128 - You may also request deletion directly by contacting us, independent of AT Protocol 129 - signals. We respond to deletion requests within one month (GDPR Art. 12(3)). 157 + You may request full content deletion (including anonymized content) by contacting us 158 + directly, independent of AT Protocol signals. We respond to deletion requests within one 159 + month (GDPR Art. 12(3)). 130 160 </p> 131 161 <p className="text-sm leading-relaxed text-muted-foreground"> 132 - Please note that Barazo cannot guarantee deletion from external systems such as AT 133 - Protocol relays, other AppViews, search engine caches, or web archives. We take 134 - reasonable steps including propagating AT Protocol delete events and requesting removal 135 - from search engines. 162 + Barazo cannot guarantee deletion from external systems such as AT Protocol relays, other 163 + AppViews, search engine caches, or web archives. Our reasonable steps include: 164 + propagating AT Protocol delete events, submitting Google Search Console removal requests 165 + for deleted content URLs, and documenting which systems confirmed deletion. 136 166 </p> 137 167 </section> 138 168 139 169 <section className="space-y-3"> 170 + <h2 className="text-lg font-semibold text-foreground">AI Features</h2> 171 + <p className="text-sm leading-relaxed text-muted-foreground"> 172 + Barazo offers optional AI features including thread summaries, semantic search, and 173 + content moderation assistance. Here is how they work: 174 + </p> 175 + <ul className="list-inside list-disc space-y-2 text-sm text-muted-foreground"> 176 + <li> 177 + <strong>No training on your content.</strong> We do not use member posts to train AI 178 + models, and we do not provide member content to others for training. 179 + </li> 180 + <li> 181 + <strong>Local-first processing.</strong> The default AI configuration uses local 182 + inference (Ollama) -- your content never leaves the server. Your forum administrator 183 + may choose a different AI provider; in that case, content is sent to that provider for 184 + processing. 185 + </li> 186 + <li> 187 + <strong>Anonymized summaries.</strong> AI-generated thread summaries are designed to 188 + exclude usernames, handles, and verbatim quotes. Summaries capture the 189 + discussion&apos;s substance, not who said what. Summaries may persist after individual 190 + content deletion because they contain no personal data. 191 + </li> 192 + </ul> 193 + </section> 194 + 195 + <section className="space-y-3"> 140 196 <h2 className="text-lg font-semibold text-foreground">Content Labels</h2> 141 197 <p className="text-sm leading-relaxed text-muted-foreground"> 142 198 We subscribe to content labeling services (such as Bluesky&apos;s Ozone) for spam ··· 165 221 <p className="text-sm leading-relaxed text-muted-foreground"> 166 222 To exercise these rights, contact us through our{' '} 167 223 <a 168 - href="https://github.com/barazo-forum/barazo-web/issues" 224 + href="https://github.com/barazo-forum/barazo-workspace/issues" 169 225 className="text-primary underline hover:text-primary/80" 170 226 target="_blank" 171 227 rel="noopener noreferrer"