Files
lage-chat-control/migration/inventory/diff-report.md
T
Aurealibe 8ebc1da9e4 Rebuild du site sur Astro : i18n multilingue, faits verifies, Docker, CI, tests
- Astro statique, EN par defaut + /fr/ + /nl/, detection langue navigateur
- i18n par fichiers JSON, ajouter une langue = ajouter des traductions
- Contenu original porte a l'identique (diff d'inventaire par langue)
- Chronologie legislative corrigee sur sources primaires (PE, Conseil, votes)
- Timeline 23 precedents + observatoire 35 items + annuaire 66 outils FOSS,
  chaque affirmation verifiee et sourcee
- Zero requete tierce (teste), lisible JS coupe, axe WCAG AA x2 themes
- Version offline monofichier par langue a chaque build
- Docker multi-stage vers nginx + CSP stricte auto-generee
- CI GitHub Actions (SHA-pinnees) + verification hebdo des liens
- CONTRIBUTING : divulgation d'affiliation obligatoire, allowlist de
  domaines testee en CI
2026-07-10 03:52:49 +01:00

159 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Content-migration diff report
Legacy monolith `index.html` (591 tri-lingual span lines / 659 `data-l` spans per
language) → per-locale MDX under `src/content/sections/{en,fr,nl}/` + `src/data/tools.json`.
## How the inventories were produced
- `legacy-<lang>.txt` — the FULL legacy document reduced to one language
(every `data-l` run resolved), one line of whitespace-collapsed text per
block-level element. Chrome (topbar, hero, status banner, TOC, footer) is
included so nothing is hidden from this audit.
- `built-<lang>.txt` — same dump algorithm over `dist/index.html`,
`dist/fr/index.html`, `dist/nl/index.html` after `pnpm build`.
One deviation: `<noscript>` is skipped because parse5 exposes its children
as raw text (it is new chrome, absent from the legacy page anyway).
- `<b class="lbl">` / `<b class="tool-label">` elements are flushed to their
own line on both sides so tool-card prose lines stay comparable.
- Non-breaking spaces are folded into plain spaces on both sides.
- `node migration/compare.mjs` then segments each file into
head-chrome / narrative window / tail-chrome (narrative = first `PART 00 ·`
line through the manifesto paragraph) and walks the two narrative windows
**in order, line by line**. Every line must either match exactly or fall in
one of the categories below; anything else exits non-zero.
## Result
| lang | legacy narrative lines | built narrative lines | unexplained differences |
| ---- | ---------------------- | --------------------- | ----------------------- |
| en | 789 | 991 | **0** |
| fr | 789 | 991 | **0** |
| nl | 789 | 991 | **0** |
`991 = 789 6 (deferred legislative rows) + 208 (tool-card labels)` in every
language. Full machine output: `compare-report.json`.
## Explained differences, exhaustively
### 1. Tool-card labels are now real text (+208 lines per language)
In the legacy page the field labels ("What it's for / Why it matters /
For whom & when", `À quoi ça sert / Pourquoi / Pour qui & quand`,
`Waarvoor dient het / …`) and the `Install & use` summary were **CSS
`::before`/`::after` generated content**, so they never appeared in the DOM
text. `ToolCard.astro` renders them as real, accessible text:
54 cards × 3 field labels + 46 install summaries = 208 new lines per language.
The label strings are byte-identical to the legacy CSS `content` values.
### 2. Deferred legislative-status claims (6 lines per language)
Per the migration plan, adopted/extended claims are being rewritten from
verified sources separately. Dropped from the `#menace` comparison table
(rows 4 and 5), verbatim:
- EN: `Duration` / `Temporary, extended to 3 April 2028` / `Permanent` /
`Status (Jul 2026)` / `Adopted 9 July 2026` / `Under negotiation, 5th trilogue failed 29 June`
- FR: `Durée` / `Temporaire, prolongé jusqu'au 3 avril 2028` / `Permanent` /
`Statut (juil. 2026)` / `Adopté le 9 juillet 2026` / `En négociation, 5e trilogue échoué le 29 juin`
- NL: `Looptijd` / `Tijdelijk, verlengd tot 3 april 2028` / `Permanent` /
`Status (juli 2026)` / `Aangenomen op 9 juli 2026` / `In onderhandeling, 5e trialoog mislukt op 29 juni`
The status banner ("Dernière minute : 9 juillet 2026" block) was excluded
wholesale with the chrome (see §4); it is replaced by `StatusBanner.astro`
fed from verified sources in the parallel workstream.
Two borderline in-prose date claims were **kept** (judgment call — they are
narrative argument, not adopted/extended status): the 19 March 2026 joint
appeal, and the "kept scanning after the legal basis lapsed on 4 April 2026"
sentence, both in `#menace`.
### 3. Typographic quotes (smartypants)
Astro's default markdown pipeline (`markdown.smartypants`, ON by default)
typesets `"` as `“ ”` and `'` as `` in the rendered pages
(en: 138 lines affected, fr: 225, nl: 70). No other smartypants rule fires:
the legacy prose contains no ASCII `...` or `--` (its 3 `…` are literal and
pass through unchanged). This is the **only character-level transformation**
in the entire narrative.
It could not be disabled from inside this migration's ownership
(`astro.config.mjs` is off-limits). If byte-identical glyphs are required,
the config owner can add `markdown: { smartypants: false }` — one line — and
the compare gate can then drop its quote normalization.
### 4. Chrome not migrated (rebuilt separately)
Legacy head-chrome (36 lines/language) and tail-chrome (8 lines/language)
deliberately not migrated to MDX:
- topbar: brand `◆ EXIT CHAT CONTROL`, FR/NL/EN buttons, theme toggle;
- hero: stamp (`Mass surveillance · EU · 2026`), eyebrow, `Exit Chat Control_`
h1, lede paragraph, three profile meta tags;
- status banner: `Breaking: 9 July 2026` + the vote paragraph
(superseded content, see §2);
- TOC (24 lines) — duplicates the section titles that ARE migrated;
- footer: Resources / Sources / Act link lists, GitHub link, disclaimer
(`Facts last updated: 9 July 2026`).
The built pages already contain replacement chrome from the parallel
rebuild workstream (TopBar/Footer/StatusBanner components, new hero h1 +
description, skip-link, noscript note, rewritten source lists citing
official roll-call results). That text intentionally differs from the
legacy chrome and is **not** part of this migration's fidelity claim; it
sits outside the compared narrative window (built head-chrome: 6 lines,
tail-chrome: 9 lines).
- The legacy inline JS (lang/theme toggles, simpleicons CDN loader) was not
migrated by design. Icon rendering will be rebuilt offline later; the
legacy CDN slugs are preserved in `tools.json.iconSlug` (validated, §6).
### 5. NL gaps
None. Every one of the 649 `data-l` runs carries all three languages
(en/fr/nl counts are equal in every run), so the EN-fallback path never
fired. `extract-log.json → nlGaps: []`.
### 6. tools.json notes (language-neutral facts)
- 54 entries; every entry has `url` (first neutral footer link), full `links`
array (21 cards have 23 links), `monogram`, `color`, `profiles`
(the 🟢🟡🔴 footer note), `level` where the legacy card carried a level tag
(34 cards; the other 20 never had one).
- `iconSlug` was validated against the installed `simple-icons` package.
Renamed upstream and mapped: `tutanota → tuta`, `aegis → aegisauthenticator`.
Removed upstream and therefore set to null (6): `briar`, `molly`, `ivpn`,
`protonpass`, `nostr`, `standardnotes`. 5 cards never had an icon in the
legacy map (`t-bitchat`, `t-databrokers`, `t-mailbox`, `t-website`,
`t-yunohost`).
- 7 cards have localized display names (e.g. `Firefox (durci/hardened/gehard)`,
`Sauvegardes chiffrées / Encrypted backups / Versleutelde back-ups`).
`tools.json.name` stores the EN plain text; the localized display name is
rendered through the ToolCard `name` slot from each locale's MDX.
- One presentational attribute dropped: `style="margin:.6rem 0 .4rem"` on the
warning box inside `t-bitchat` (styling is rebuilt later; text intact).
### 7. Anchors
`anchors.json` lists all 82 `id=` values of the legacy file. 78 exist in
every built page: 23 section ids on `<section>` wrappers, 54 tool ids on
ToolCard `<article>` roots, `top` on the hero h1. The 4 missing are the
legacy control-widget ids `lang-fr`, `lang-nl`, `lang-en`, `theme`
(toggle buttons, never used as link targets — chrome rebuilt separately).
### 8. External domains for the allowlist review
The migrated content links to 75 unique external hostnames
(`external-domains.txt`). The parallel workstream's
`tests/unit/dist-links.test.ts` fails until these are reviewed and added to
`src/data/domains-allowlist.json` — that file requires review and is outside
this migration's ownership, so it was left untouched.
## Reproduce
```
node migration/extract.mjs # MDX + tools.json + anchors + legacy dumps
pnpm build
node migration/extract.mjs --built # built-page dumps
node migration/compare.mjs # exits non-zero on any unexplained diff
```