# Evidence capture — www.assen.nl (Gemeente Assen)

Forensic snapshot of three pages on the municipal website of **Gemeente Assen**,
captured as evidence for the TT Festival privacy investigation. Assen is the
municipality that hosts the TT Festival, and these pages link the public to the
official **TT Festival App** (`app.ttfestival.nl`).

The capture is **self-contained and reproducible**: it includes the exact raw
server responses, the fully JavaScript-rendered DOM, full-page screenshots, all
referenced photos, response headers, tool logs, and SHA-256 checksums of every
file. The bulky browsable offline `wget` mirror lives in the companion
**private** repo
[`GraafG/tt-festival-app-evidence`](https://github.com/GraafG/tt-festival-app-evidence);
its byte-for-byte integrity is recorded here in `mirror-manifest.sha256`.

## Reason for capture

The decisive line is on **`/heeft-u-nog-vragen`** (captured verbatim, see
`screenshots/03_heeft-u-nog-vragen_fullpage.png` and the rendered DOM):

> *"Meer weten over het TT Festival? **Download de officiële TT Festival App via
> app.ttfestival.nl (externe link)** of neem contact op met de organisatie via
> info@ttfestival.nl."*

Why this matters as evidence **against Gemeente Assen** (not only the app vendor):

1. **The municipality calls it "de officiële TT Festival App" and hands out the
   download link itself.** On an official `www.assen.nl` government page, this
   reads as a municipal endorsement of the app.
2. **The lines are blurred about who actually runs it.** Even reading carefully
   it is hard to tell that the app is **not** operated by Gemeente Assen but by a
   separate party (the organising *stichting* / the commercial platform
   **Appmiral**). The `app.ttfestival.nl` link `301`-redirects to
   `ttfestival2026.deeplink.appmiral.com` — third-party Appmiral/AWS
   infrastructure — yet it is presented under the municipality's own banner and
   wording. (That redirect and the app's pages are captured in the sibling
   snapshot [`../appmiral.com_2026-06-26_232241/`](../appmiral.com_2026-06-26_232241/).)
3. **The municipality is on notice.** Given that Gemeente Assen is aware of the
   privacy/tracking concerns documented in this repository, actively steering
   residents and visitors to "the official app" while obscuring the third-party
   operator and its data processing is evidence relevant to the municipality's
   own responsibility — not just the app maker's.

This snapshot freezes that municipal endorsement at a fixed point in time so it
can be cited and reproduced even if the page is later edited.

## Snapshot summary

| Field | Value |
|-------|-------|
| Captured (local) | **2026-06-26 23:12:42 CEST (UTC+02:00)** |
| Captured (UTC) | **2026-06-26 21:12:42Z** |
| Capture host | Microsoft Windows 11 Pro (build 10.0.26200) |
| Server `Date` header | `Fri, 26 Jun 2026 21:13:24 GMT` |
| Platform observed | Next.js (SSR) behind Varnish 7.4 + Azure Front Door |
| Pages captured | 3 (all `HTTP/1.1 200 OK`) |
| Total size | ~13.4 MB |
| User-Agent used | `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36` |

> The capture timestamp is encoded in the folder name
> (`assen.nl_2026-06-26_231242`, format `YYYY-MM-DD_HHmmss` local time) and stored
> in `.capture-timestamp`. Re-running the capture creates a new timestamped folder
> rather than overwriting this one.

## Pages captured

| # | URL | Page title | HTTP | HTML bytes (`Content-Length`) |
|---|-----|-----------|------|-------------------------------|
| 1 | <https://www.assen.nl/> | Home \| Gemeente Assen | 200 | 237017 |
| 2 | <https://www.assen.nl/tt> | TT \| Gemeente Assen | 200 | 210254 |
| 3 | <https://www.assen.nl/heeft-u-nog-vragen> | Heeft u nog vragen? \| Gemeente Assen | 200 | 133578 |

### Why these pages matter

- **`/tt`** — the municipality's TT page: *"Het TT Festival is van 20 juni tot
  en met 28 juni in Assen."* Covers accessibility/road closures during the TT
  Nachten (25, 26, 27 June).
- **`/heeft-u-nog-vragen`** ("Do you have any questions?") — directs residents
  and visitors to **download the official TT Festival App via
  `app.ttfestival.nl`** and to the TT Loket at the Stadhuis. This is the
  municipal endorsement / distribution funnel for the app under investigation.
- **`/`** (home) — establishes the municipal context and the prominent TT
  promotion block linking to `/tt`.

## Folder layout

```
assen.nl_2026-06-26_231242/
├── README.md                 ← this capture log
├── SHA256SUMS.txt            ← SHA-256 of every file in THIS (public) folder
├── mirror-manifest.sha256    ← SHA-256 of every file in the offline mirror,
│                               which lives in the private companion repo
├── .capture-timestamp        ← machine-readable capture timestamp
├── raw/                      ← EXACT unmodified server responses (curl)
│   ├── home.html / .headers.txt
│   ├── tt.html / .headers.txt
│   └── heeft-u-nog-vragen.html / .headers.txt
├── rendered-dom/             ← fully JS-rendered DOM after hydration (Chrome)
│   ├── home.dom.html
│   ├── tt.dom.html
│   └── heeft-u-nog-vragen.dom.html
├── screenshots/              ← PNG screenshots @1440×900, desktop
│   ├── 01_home_*_fullpage.png / _viewport.png
│   ├── 02_tt_*_fullpage.png / _viewport.png
│   └── 03_heeft-u-nog-vragen_fullpage.png / _viewport.png
├── mirror/  → MOVED to private repo GraafG/tt-festival-app-evidence
│              (browsable offline wget clone; links converted. Integrity of
│               every file is recorded above in mirror-manifest.sha256.)
│   └── www.assen.nl/...      ← HTML + JS + CSS + fonts + SVG/icon assets
├── assets-extra/             ← the 14 distinct Next.js-proxied photos (see note)
│   ├── img-001.jpg … img-014.jpg
│   └── manifest.tsv          ← filename ↔ source image ↔ sha256 ↔ original URL
└── logs/
    ├── wget-home.log / wget-tt.log / wget-heeft-u-nog-vragen.log
    └── tool-versions.txt
```

### Note on `assets-extra/` and the wget mirror

The site serves photos through the Next.js image optimizer
(`/_next/image?url=...&w=...&q=75`). Those proxy URLs decode to filenames longer
than the Windows 260-character path limit, so **wget could not write the photo
files** (logged as `Bad file descriptor` in the wget logs; this is the only
reason `wget` exited non-zero for the home and TT pages — all HTML, JS, CSS,
fonts and SVGs were saved fine).

To make the evidence complete, every distinct source photo referenced by the
three pages was downloaded separately at its largest width into `assets-extra/`
with short filenames. `assets-extra/manifest.tsv` maps each `img-NNN.jpg` back to
its original `/_next/image` URL, the decoded backend source path, byte size and
SHA-256.

## Response headers (captured)

Full headers per page are in `raw/<page>.headers.txt`. Common to all three:

```
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Security-Policy: frame-ancestors 'none';
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer-when-downgrade
Strict-Transport-Security: max-age=31622400; includeSubDomains
x-nextjs-cache: ...            (Next.js incremental cache)
Via: 1.1 varnish-assen-... (Varnish/7.4)
X-Varnish-Backend: dvg-frontend-assen:3000
x-azure-ref: ...               (Azure Front Door)
Set-Cookie: oo-session=...; Path=/; Secure; HttpOnly
```

No cookie-consent wall blocked access; pages render server-side without
interaction.

## How this was captured

All commands were run from the capture host on 2026-06-26. Tool versions are
recorded in `logs/tool-versions.txt`:

- **GNU Wget 1.21.4** — offline mirror:
  ```
  wget --page-requisites --convert-links --adjust-extension \
       --restrict-file-names=windows -e robots=off \
       --user-agent="<UA above>" <URL>
  ```
- **curl 8.20.0** — exact raw response + headers (`curl -s -D <headers> -o <html>`).
- **Google Chrome 149.0.7827.197** (via Chrome DevTools) — full-page PNG
  screenshots and rendered-DOM dumps at a 1440×900 desktop viewport.
- **Node.js v24.12.0** — deduped download of the `/_next/image` photos.

## How to verify integrity

From inside this folder:

```bash
# Linux / macOS
sha256sum -c SHA256SUMS.txt
```

```powershell
# Windows PowerShell
Get-Content SHA256SUMS.txt | ForEach-Object {
  $h,$p = $_ -split '  ',2
  if ((Get-FileHash -Algorithm SHA256 -LiteralPath $p).Hash.ToLower() -ne $h) { "MISMATCH: $p" }
}
```

## How to reproduce what we saw

- **Visual:** open any PNG in `screenshots/`.
- **Offline browse:** clone the companion private repo
  [`GraafG/tt-festival-app-evidence`](https://github.com/GraafG/tt-festival-app-evidence)
  and open `assen.nl_2026-06-26_231242/mirror/www.assen.nl/index.html` (home),
  `.../mirror/www.assen.nl/tt.html`, or
  `.../mirror/www.assen.nl/heeft-u-nog-vragen.html` in a browser. Verify those
  bytes against this folder's `mirror-manifest.sha256`.
- **Exact bytes:** the files in `raw/` are the verbatim server responses and
  match the `Content-Length` headers above.
- **Rendered state:** files in `rendered-dom/` are the DOM after JavaScript
  hydration, matching the screenshots.
