Skip to content

feat(privacy): Datenschutz + Privacy pages (Phase B.3)#9

Merged
blackbrowed-labs merged 5 commits into
mainfrom
dev
Apr 28, 2026
Merged

feat(privacy): Datenschutz + Privacy pages (Phase B.3)#9
blackbrowed-labs merged 5 commits into
mainfrom
dev

Conversation

@larsweiser
Copy link
Copy Markdown
Collaborator

Summary

  • DE /datenschutz (legally authoritative) + EN /en/privacy (courtesy translation), copy verbatim from BASELINE_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 via src/lib/cloudflare-facts.ts for two build-time substitutions per page: cwa.retentionAggregatesMonths (= 6 months) + verifiedDate formatted via Intl.DateTimeFormat per locale ("28. April 2026" / "April 28, 2026").
  • scripts/check-cloudflare-facts-freshness.mjs — 90-day build-guard wired into the build chain ahead of astro build. Manual-era "no silent failures" mechanism per backlog feat(legal): Impressum + Legal Notice pages (Phase B.2) #8.
  • 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.

Phase D Cloudflare-fact-verifier (backlog #8) will overwrite cloudflare-facts.json automatically; 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 errors
  • astro 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")
  • Build-guard verified PASS at fresh date and FAIL at stale date (>90d)
  • Per-task code-quality reviews (G B.3.2.a + G B.3.2.b) — both approved
  • Final integration review of full B.3 diff (e1a474c..4a1772f) — approved for PR open
  • Visual walk on staging — TOC anchors land below sticky header; counterpart switch round-trips; light + dark + 360/768/1024/1440 all clean
  • Production smoke after merge

🤖 Generated with Claude Code

blackbrowed-labs and others added 5 commits April 28, 2026 16:06
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 blackbrowed-labs merged commit 9e4eb0f into main Apr 28, 2026
2 checks passed
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants