# Evidence

Timestamped, reproducible web captures collected for the TT Festival privacy
investigation. Each snapshot folder keeps the lighter forensic artifacts — exact
raw server responses, JavaScript-rendered DOM, full-page screenshots, response
headers, tool logs, and a `SHA256SUMS.txt` integrity manifest. The heavy
browsable offline `wget` **mirrors** live in the companion **private** repo
[`GraafG/tt-festival-app-evidence`](https://github.com/GraafG/tt-festival-app-evidence);
each snapshot here records the SHA-256 of every mirrored file in
`mirror-manifest.sha256`. Folder names encode the local capture time as
`<host>_<YYYY-MM-DD_HHmmss>`.

> **Browsing tip:** open [`index.html`](index.html) for a human-navigable
> overview of every snapshot, page and screenshot (works offline).
>
> **Findings & methods:** [`../docs/web-and-email-evidence.md`](../docs/web-and-email-evidence.md)
> is the analyst's index — every web/email finding (with IDs), the techniques and
> prerequisites used, and step-by-step reproduction.
>
> **Adding evidence?** See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the exact
> folder layout, capture commands, checksum rules and a pre-commit checklist.

## The evidence chain

```
Gemeente Assen (official municipal website)
  www.assen.nl/heeft-u-nog-vragen
   │  "Download de officiële TT Festival App via app.ttfestival.nl"
   ▼
app.ttfestival.nl  ──301──▶  ttfestival2026.deeplink.appmiral.com   (Appmiral / AWS, a third party)
   │                                   │
   │                                   ├─▶ Google Play  com.appmiral.ttfestival
   │                                   └─▶ Apple App Store  id 6744364695
   ▼
app.appmiral.com/ttfestival2026/privacy-policy
   "All data … stored within the EU (AWS eu-west-1)"  ← testable against this repo's us-east-1 finding
   "location shared … with Crowd Connected (UUID, coordinates, push token)"
```

The municipality presents the app as "the official TT Festival App" under its own
banner, while the app and its data processing are actually run by a separate
party (the organising *stichting* / Appmiral). See each snapshot's `README.md`
for the full reasoning and verbatim quotes.

## Snapshots

| Folder | Captured (local) | Pages | Source |
|--------|------------------|-------|--------|
| [`assen.nl_2026-06-26_231242/`](assen.nl_2026-06-26_231242/) | 2026-06-26 23:12 CEST | `www.assen.nl/`, `/tt`, `/heeft-u-nog-vragen` | Gemeente Assen (municipal site) |
| [`appmiral.com_2026-06-26_232241/`](appmiral.com_2026-06-26_232241/) | 2026-06-26 23:22 CEST | deeplink landing page, app privacy policy | Appmiral (app vendor) |
| [`ttfestival.nl_2026-06-26_234242/`](ttfestival.nl_2026-06-26_234242/) | 2026-06-26 23:42 CEST | **full site — 174/174 sitemap pages** (5 key pages with raw + DOM + screenshots) | TT Festival (event site) |

## App-cohort capture (APK harvest + tracking audit)

A different kind of evidence: not a web page but the **installed Android apps**
themselves. Every Appmiral / Appstrakt app on the investigator's phone was pulled
byte-for-byte as APKs, statically scanned against Appmiral's advertised
[integrations](https://appmiral.com/features/integrations), and — for every app
carrying the Crowd Connected location SDK — read for its live, server-pushed
config (active km range + remote kill-switch on/off).

| Folder | Captured (local) | Cohort | What it shows |
|--------|------------------|--------|---------------|
| [`appmiral-apks_2026-06-28_154246/`](appmiral-apks_2026-06-28_154246/) | 2026-06-28 15:42 CEST | **140 apps, 375 APK files (~7.08 GB)** | Advertised-vs-actually-embedded integration matrix; **30 apps** request background location; live config for 6 apps — **TT Festival kill-switch ON @ 60 km**, the rest armed (40–80 km) but toggled OFF by the backend |

The APK **bytes** are in the private companion repo
(`apks_2026-06-28_154246/`); this public folder holds the checksummed
[`apk-manifest.sha256`](appmiral-apks_2026-06-28_154246/apk-manifest.sha256)
(identical to the private `SHA256SUMS.txt`) plus the machine-readable
identification, integration and config tables. Analysis:
[`07-apk-harvest-and-identification`](../docs/appmiral-comparison/07-apk-harvest-and-identification.md),
[`08-integration-matrix`](../docs/appmiral-comparison/08-integration-matrix.md),
[`09-active-config-km-killswitch`](../docs/appmiral-comparison/09-active-config-km-killswitch.md);
reproduce from scratch:
[`10-apk-harvest-reproduction`](../docs/appmiral-comparison/10-apk-harvest-reproduction.md).

## Correspondence (notice to the responsible parties)

Beyond the web captures, the repo preserves the **email correspondence** in which
the responsible parties were notified of these findings and the replies they sent.

| Folder | Dates | Parties | What it shows |
|--------|-------|---------|---------------|
| [`email-correspondence/`](email-correspondence/) | 2026-06-07 → 06-25 | Gemeente Assen (`s.gils2@assen.nl`, `info@assen.nl`); Stichting TT Festival (`ranco@ttfestival.nl`) | Both the municipality and the organisation were **put on notice**. The organisation, relaying Crowd Connected, **confirms in writing** that location data is processed via **AWS us-east-1 (USA)** — contradicting the app's "EU-only" privacy policy. A municipal safety adviser acknowledges the concern and undertakes to escalate. |

Each message is preserved byte-exact as the original `.eml` (in `raw/`) plus a
readable `.txt` rendering and extracted attachments; see
[`email-correspondence/README.md`](email-correspondence/README.md) for the full
timeline and analysis.

## Companion private repo (the heavy mirrors)

The complete `wget` mirrors are large — the `ttfestival.nl` mirror alone is ~1.16 GB
(mostly WordPress image size-variants). Committing that into this public repo would
permanently bloat its history for everyone who clones it, and re-hosting entire
third-party sites publicly raises copyright concerns. So the bulky `mirror/` clones
live in the **private** companion repo
[`GraafG/tt-festival-app-evidence`](https://github.com/GraafG/tt-festival-app-evidence).

Chain of custody is preserved: each snapshot here ships a `mirror-manifest.sha256`
listing the SHA-256 of **every** file that was moved, and the private repo ships an
identical `SHA256SUMS.txt` per snapshot. The two lists are byte-for-byte the same, so
this public repo independently attests to exactly what the private mirror contains.

## Verifying any snapshot

Run inside a snapshot folder:

```bash
sha256sum -c SHA256SUMS.txt
```

`SHA256SUMS.txt` covers every captured artifact in that public folder. The
folder's own `README.md`, `SHA256SUMS.txt` and `mirror-manifest.sha256` are the
only files not listed in it (the capture log, the manifest itself, and the
separate mirror manifest). To verify the moved mirror bytes, clone the private
companion repo and run `sha256sum -c SHA256SUMS.txt` in its matching snapshot
folder — that list equals this folder's `mirror-manifest.sha256`.

## Method (common to all snapshots)

- **curl** — exact, unmodified server response bodies + full response headers.
- **GNU Wget** (`--page-requisites --convert-links --adjust-extension`) — a
  browsable offline mirror with assets. The mirrors are stored in the private
  companion repo (see above); their checksums are kept here.
- **Google Chrome** (via Chrome DevTools) — full-page PNG screenshots and the
  JavaScript-rendered DOM at a desktop viewport.
- A consistent desktop browser User-Agent is used across tools so all artifacts
  reflect the same rendering path. Exact tool versions are in each snapshot's
  `logs/tool-versions.txt`.

> These captures mirror **public** pages for fixed-point, reproducible reference.
> URLs are preserved unmodified. The full, checksummed `ttfestival.nl` site mirror
> is the `ttfestival.nl_2026-06-26_234242` snapshot (bytes in the private companion
> repo). An earlier, uncommitted local-only mirror is noted in
> [`../SITE-MIRROR.md`](../SITE-MIRROR.md).
