feat(privacy): Datenschutz + Privacy pages (Phase B.3)#9
Merged
Conversation
Lands the legal-text amendment required before the Phase B.3
Datenschutz pages ship. No code, no config — text-only edits to
BASELINE_COPY.md §9.4 (DE) and §10.4 (EN).
Origin: pre-Phase-B.3 hand-verification of Cloudflare facts (run
2026-04-28) found that Cloudflare does not publish a numerical
hour-level retention figure for Web Analytics raw events. The
Web Analytics overview only commits to edge pre-processing; the
"4 hours" figure circulating in adjacent Cloudflare writing is
for edge access logs, a different product surface. Filling
{{ cwa_retention_raw_hours }} with any specific Y therefore
makes a commitment Cloudflare has not made publicly.
Path α (decided 2026-04-28): drop the Y-hour claim, preserve
the disclosure that raw events are pre-processed at the
Cloudflare edge, plus a negative commitment that no persistent
storage of raw events takes place under our control. Per
project rule §11.4 the amendment text was drafted by an isolated
reviewer cycle (sub-agent, 2026-04-28); the orchestrator session
committed verbatim.
§9.4 / §10.4 — replaced one semicolon-bridged retention sentence
with two period-separated sentences. Aggregated-data retention
clause unchanged (still placeholder-driven, value 6 to land via
data file). Verified-date clause unchanged. Surrounding paragraph
(beacon host, cookie-free, fingerprint-free, aggregate-metrics
list, identification statement, legal basis) unchanged.
The {{ cwa_retention_raw_hours }} placeholder is no longer
referenced anywhere in BASELINE_COPY and will not appear in the
src/data/cloudflare-facts.json data file shipped with B.3.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds src/data/cloudflare-facts.json with hand-verified initial values from the 2026-04-28 verification cycle (DPF Active per participant/5666; CWA aggregated retention 6 months per Web Analytics FAQ; raw-event retention placeholder removed by G B.3.1 amendment). scripts/check-cloudflare-facts-freshness.mjs runs ahead of astro build in the build script chain. Fails the build if verifiedDate is older than 90 days — manual-era 'no silent failures' mechanism per backlog item #8. Tighter than the post-verifier 120-day threshold because manual processes need stronger forcing functions than automated ones. Phase D Cloudflare-fact-verifier (backlog #8) will overwrite the JSON file via automated workflow; the consumer pattern lands here so D is purely 'automate the data source' work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DE /datenschutz (legally authoritative) + EN /en/privacy (courtesy
translation). Copy held inline (per OQ-1) and verbatim from
docs/BASELINE_COPY.md §9 / §10 — eleven numbered sections each, with
a two-column TOC desktop / single-column mobile per design bundle
(07-datenschutz.html). Stand / Last updated hardcoded as 'April 2026'
per plan §4.B.3 / D22 (bumped only on substantive changes).
Two build-time substitutions per page from src/data/cloudflare-facts.json
via src/lib/cloudflare-facts.ts: the aggregated-data retention figure
({{ cwa_retention_aggregates_months }} → 6) and the verified-date
({{ cloudflare_facts_verified_date }} → '28. April 2026' / 'April 28, 2026'
formatted via Intl.DateTimeFormat per page locale).
SiteFooter gains the Datenschutz / Privacy entry between Impressum and
GitHub. footer.privacy i18n keys, counterpart map (/datenschutz ↔
/en/privacy), and hreflang were already provisioned in earlier phases.
Text-color verification (G0 item 2.3): bundle's datenschutz.css uses
standard tokens (--color-text, --color-heading, --color-text-muted,
--color-link). Volcanic Stone is AAA on every surface per brief §4.8.
Implementation matches.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three minors flagged by the G B.3.2.b code-quality review (none
critical; gate already approved):
1. Both pages' top-of-file docstring claimed an <address> block in §5.
§5's IONOS address is rendered as prose, not as an <address>.
Correct claim: §1 + §10. One-line edit per page.
2. Add word-break: break-word to .datenschutz__p a /
.datenschutz__address a in both pages, mirroring the design bundle
CSS at design/handoff-bundle/design/styles/datenschutz.css:146-150.
Three long URLs in §3 + §10 (Cloudflare privacy, IONOS terms, ULD
web) can approach the viewport edge at 360px without overflow
protection.
3. Add .datenschutz__courtesy { max-width: none } to en/privacy.astro's
mobile media query, matching the en/legal.astro precedent. No
visual impact at 360px (52ch already exceeds the viewport) — pure
pattern parity.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
blackbrowed-labs
added a commit
that referenced
this pull request
Apr 29, 2026
…failures" design
Adds verify-cloudflare-facts.yml weekly cron workflow + scripts/checks/dpf.mjs
+ scripts/checks/cwa-retention.mjs + 6 fixtures + scripts/run-verifier.mjs
orchestrator. Extends scripts/check-cloudflare-facts-freshness.mjs to read
_meta.last_check_attempt with 30-day threshold (down from 90).
Migrates src/data/cloudflare-facts.json to verifier-era schema (schema_version
1; per-fact status + value fields; _meta block; structured cwa_retention with
integer month values; raw_events_retention_months explicitly null per
Cloudflare's documented absence). Updates src/lib/cloudflare-facts.ts type +
adds getEffectiveVerifiedDate helper (worst-case freshness signal: older of
the two per-fact verified_at). Privacy pages (datenschutz.astro, en/privacy.astro)
read via the helper.
Verifier shape per plans/active/pass-2/g-d-2/spec.md: 1/5/15-min retry budget
(21 min total, fits 30-min workflow timeout); status-return error handling
(no throws cross check boundaries); explicit registry per spec §9.6;
hand-written validator per §9.7; status-enum rename ('ok' CheckResult →
'active' JSON) per §6.2; v1-coverage smoke step inside verifier workflow only,
mode #8 deploy-triggered limitation acknowledged per §3.8.
All synthetic failure modes (#2, #4, #5, #6) verified via MOCK_SCENARIO=
fixture routing. Mode #1 (freshness gate) verified via stale last_check_attempt.
Modes #3, #7, #8, #9 deferred to controller-side post-commit per prompt's
"may defer" guidance. Outcome record at
plans/active/pass-2/g-d-7/verifier-test-matrix.md (workspace, gitignored).
Closes backlog #8.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
blackbrowed-labs
added a commit
that referenced
this pull request
May 12, 2026
Lifts ~120 LOC of CSS out of src/components/forms/ContactForm.astro's scoped <style> block into src/styles/forms.css, imported once via global.css. Closes Pass 2 backlog #9. Class names stay BEM-namespaced (.contact-form, .contact-form__*) — no markup churn, no migration to the bundle's .btn / .field global vocabulary (per docs/CSS_CONVENTIONS.md §2 the bundle vocabulary is reference-only and not adopted at runtime). The scoped <style> block is deleted in its entirety — no component-private CSS survives. Carries over Phase I.1's `margin-inline: auto` rule on .contact-form (Option B, Lars decision 2026-05-12) into the extracted module so contact-form centring is preserved through the move. forms.css documents this carry-over inline. global.css imports forms.css alphabetically before products.css per docs/CSS_CONVENTIONS.md §5. Headroom: future forms (subscribe, feedback, request-a-demo) add their own BEM-namespaced rule block to forms.css side-by-side with the existing .contact-form__* rules, per the conventions doc §3. Verified locally: npm run check 0/0, npm run build clean. Contact page class list unchanged in dist/ (DE + EN). Minified rule .contact-form{...margin-inline:auto...} confirmed in dist/_astro/BaseLayout*.css. Real-browser staging walk deferred to Wave 4 integration PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/datenschutz(legally authoritative) + EN/en/privacy(courtesy translation), copy verbatim fromBASELINE_COPY.md§9 / §10 — eleven numbered sections each with two-column TOC desktop / single-column mobile per design bundle (07-datenschutz.html).src/data/cloudflare-facts.json(hand-verified 2026-04-28) consumed viasrc/lib/cloudflare-facts.tsfor two build-time substitutions per page:cwa.retentionAggregatesMonths(= 6 months) +verifiedDateformatted viaIntl.DateTimeFormatper locale ("28. April 2026" / "April 28, 2026").scripts/check-cloudflare-facts-freshness.mjs— 90-day build-guard wired into the build chain ahead ofastro build. Manual-era "no silent failures" mechanism per backlog feat(legal): Impressum + Legal Notice pages (Phase B.2) #8.SiteFootergains the Datenschutz / Privacy entry between Impressum and GitHub.footer.privacyi18n keys, counterpart map (/datenschutz↔/en/privacy), and hreflang were already provisioned in earlier phases.Phase D Cloudflare-fact-verifier (backlog #8) will overwrite
cloudflare-facts.jsonautomatically; the consumer pattern lands here so D is purely "automate the data source" work.Includes the prior G B.3.1 BASELINE amendment (
d04cd89) that softened the §9.4 / §10.4 raw-event clause after a hand-verification cycle showed Cloudflare doesn't publish a numerical retention figure for Web Analytics raw events.Test plan
astro check— 0 errorsastro build— both routes emitted, both substitutions resolved (DE: "für 6 Monate gespeichert" + "zuletzt geprüft am 28. April 2026"; EN: "retained for 6 months" + "last verified on April 28, 2026")e1a474c..4a1772f) — approved for PR open🤖 Generated with Claude Code