Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
efa3359
feat(web): fix satellite map + Windows flag rendering
Apr 28, 2026
62cad41
docs(plan): krill-watch refonte spec + 3 phases × 8 tasks (multi-agen…
Apr 28, 2026
2ca5a7a
chore(plan): launch prompts for 4 parallel sessions (alpha/beta/gamma…
Apr 28, 2026
f51fef6
chore(plan): pick P1-T01 (alpha)
Apr 28, 2026
4ea9d70
feat(P1-T01): design system tokens & primitives [alpha]
Apr 28, 2026
d5e7d73
chore(plan): pick P1-T06 [alpha]
Apr 28, 2026
a031c0e
feat(P1-T06): hero hybride home + i18n agg target [alpha]
Apr 28, 2026
a8df268
chore(plan): pick P1-T03 [beta]
Apr 28, 2026
dafd74b
feat(P1-T03): fleet sidebar [beta]
Apr 28, 2026
bd7c4d6
chore(plan): pick P1-T04 [gamma]
Apr 28, 2026
6dc3c47
feat(P1-T04): vessel drawer [gamma]
Apr 28, 2026
93a2a72
chore(plan): pick P1-T02 [delta]
Apr 28, 2026
e1967f4
feat(P1-T02): live tracker map react component [delta]
Apr 28, 2026
e525a80
chore(plan): pick P1-T05 [alpha]
Apr 28, 2026
6bb02b0
feat(P1-T05): /live cockpit assembly + URL state [alpha]
Apr 28, 2026
f4bf118
chore(plan): pick P1-T07 [alpha]
Apr 28, 2026
bfd6005
feat(P1-T07): mobile responsive layouts for /live [alpha]
Apr 28, 2026
c187404
chore(plan): pick P1-T08 [alpha]
Apr 28, 2026
4374dd9
feat(P1-T08): legacy cleanup + mobile switch + phase 1 checkpoint [al…
Apr 28, 2026
6247d1b
fix(P1-T02,P1-T05): drawer close + maplibre controls visibility
Apr 28, 2026
1f48922
fix(P1-T01,P1-T03,P1-T05): URL state for ?q + ?bucket; tab padding
Apr 28, 2026
a0ab2c4
chore(plan): pick P2-T01 [alpha]
Apr 28, 2026
631f568
feat(P2-T01): backend endpoint historical positions [alpha]
Apr 28, 2026
e1726ee
chore(plan): pick P2-T02 [alpha]
Apr 28, 2026
e12877b
feat(P2-T02): vessel trail component with severity coloring [alpha]
Apr 28, 2026
83e74bc
chore(plan): pick P2-T03 [alpha]
Apr 28, 2026
ecfd815
feat(P2-T03): timeline scrubber + range selector + playback hook [alpha]
Apr 28, 2026
a5e67ba
chore(plan): pick P2-T05 [alpha]
Apr 28, 2026
f5633d2
feat(P2-T05): campaign hub routes + 6 components [alpha]
Apr 28, 2026
10610b2
chore(plan): pick P2-T07 [alpha]
Apr 28, 2026
14f2e2c
feat(P2-T07): glossary +6 terms + tap-friendly Acronym popover [alpha]
Apr 28, 2026
c8f4d26
chore(plan): pick P2-T04 [alpha]
Apr 28, 2026
0ffb3d5
feat(P2-T04): vessel page history map + scrubber integration [alpha]
Apr 28, 2026
31d20eb
chore(plan): pick P2-T06 [alpha]
Apr 28, 2026
906f7c1
feat(P2-T06): editorial content for 4 campaigns FR + EN [alpha]
Apr 28, 2026
e9c3b97
feat(P2-T08): campaign hubs discoverability + i18n agg + checkpoint […
Apr 28, 2026
f8cfc81
chore(plan): pick P3-T01 [alpha]
Apr 28, 2026
baa0d6c
feat(P3-T01): incident emitter webhook + auto-incidents schema [alpha]
Apr 29, 2026
e459026
feat(P3-T02): /incident/[slug] ISR page + map + context + sources [al…
Apr 29, 2026
fb11301
feat(P3-T03): dynamic OG images for incidents/vessels/campaigns [alpha]
Apr 29, 2026
9217055
feat(P3-T04): ShareButton component + intent URLs [alpha]
Apr 29, 2026
a77da74
feat(P3-T05): public contribution form + DuckDB storage [alpha]
Apr 29, 2026
7cc9275
feat(P3-T06): /digest index + /digest/[isoweek] route [alpha]
Apr 29, 2026
00c0201
feat(P3-T07): pipeline → incident emitter wiring [alpha]
Apr 29, 2026
fc4f7b6
feat(P3-T08): SupportCTA partout + ShareButton coverage + phase-3 che…
Apr 29, 2026
3a59092
chore(plan): sync P3-T01..T08 frontmatter to completed [alpha]
Apr 29, 2026
7bc8a9e
fix(P3-T05): add python-multipart to requirements-core
Apr 29, 2026
fac0da4
Merge refonte/phase-1: krill-watch unified app (3 phases × 8 tasks)
Apr 29, 2026
296a812
docs(refonte): visual verification screenshots from phase 3 UAT
Apr 29, 2026
632bf8a
docs(refonte): manual test checklist (12 sections, 60-75 min)
Apr 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,17 @@ GAP_CRITICAL_HOURS=24

# Default lookback window for analyses (days)
LOOKBACK_DAYS=90

# ============================================================
# Auto-detected incident pages (P3 — Viralité)
# ============================================================
# Base URL of the Next.js front-end (the Python pipeline POSTs here
# to revalidate /incident/<slug> ISR pages):
NEXTJS_BASE_URL=http://localhost:3000
# Shared secret between FastAPI emitter and Next.js /api/revalidate.
# Generate with: python -c "import secrets;print(secrets.token_urlsafe(32))"
KRILL_REVALIDATE_SECRET=
# Internal secret for the pipeline → FastAPI POST /api/internal/incident
# (X-Internal header). Different from the revalidate secret so that an
# external client compromising the front-end cannot inject incidents.
KRILL_INTERNAL_SECRET=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ web/.vercel
web/.turbo
web/next-env.d.ts
web/*.tsbuildinfo

# Superpowers brainstorming working directory (mockups, server state)
.superpowers/
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@

- **Multi-mission vessel tracker** — four CPWF campaigns share the same pipeline: krill (CCAMLR-licensed Antarctic trawlers), whaling (Kangei Maru + Icelandic Hvalur), Galápagos (Chinese DWF squid jiggers), West Africa (Chinese + Russian super-trawlers in Senegal/Mauritania/Guinea EEZs). Vessels are grouped by mission on the catalogue page with mission-coloured badges.
- **Live AIS triage dashboard** — a Next.js investigator UI at `web/` that aggregates fleet positions, zone transitions, and severity alerts on a per-vessel basis. Home page surfaces CRITICAL and SUSPICIOUS vessels immediately; vessel detail shows a full-bleed MapLibre track with a configurable time window (24 h → 90 d).
- **Live alerting** — Discord and Slack webhooks fire on CRITICAL events (zone entry into MPA / IWC sanctuary / EEZ, severity escalation). Rich embeds carry a clickable deep link straight to the vessel detail page. Per-mission webhook routing supported (whaling alerts → separate channel from krill).
- **Bilingual campaign hubs** — `/[locale]/campagnes/<slug>` for each of the four CPWF campaigns: editorial intro, legal frame, fleet roster, season calendar, and source list. Hreflang fr↔en across the whole site.
- **Auto-generated incident pages** — every protected-zone entry by a tracked vessel triggers an ISR page at `/[locale]/incident/<slug>` with severity chip, headline, 7-day map trail centred on the event, campaign context, and sources. Detection → live page in under 5 s via a FastAPI → Next.js revalidate webhook.
- **Dynamic OG images** — `/api/og/incident/<slug>`, `/api/og/vessel/<slug>`, `/api/og/campaign/<slug>` render 1200×630 PNGs at the edge for Twitter/Bluesky/Mastodon/LinkedIn share previews.
- **Public contribution form** — `/[locale]/contribuer` accepts vessel sightings, transhipment tips, AIS anomalies, and free-form testimony, with optional photo upload (5 MB max). Discord webhook notifies admins of new submissions without leaking submitter PII.
- **Weekly digest route** — `/[locale]/digest` exposes the existing transhipment-review HTML reports under stable Next.js URLs, with optional ISO-week deep links (`/digest/2026-W17`).
- **Live alerting** — Discord and Slack webhooks fire on CRITICAL events (zone entry into MPA / IWC sanctuary / EEZ, severity escalation). Rich embeds carry a clickable deep link straight to the vessel detail page **and the auto-generated `/incident/<slug>`** when applicable. Per-mission webhook routing supported (whaling alerts → separate channel from krill).
- **Multi-signal transhipment scorer** — for every GFW encounter event in a rolling window, six weighted signals (unauthorized reefer, AIS gap, IUU/sanctions hit, spatial anomaly, FOC flag, long duration) are evaluated and summed into a 0.00–0.90 score. Calibration frozen at **v0.4.2** — see [`calibration.md`](calibration.md) for the weight justifications and validation cases.
- **Weekly HTML review report** — a self-contained three-section report (§1 CRITICAL, §2 FLAGGED, §3 transparency) that can be forwarded as an email attachment. Generated automatically every Monday by GitHub Actions and (in production) by `scripts/run_weekly_report.sh` on the deployment VM.
- **FastAPI backend with DuckDB persistence** — positions, zone-transition events, and vessel status land in a local DuckDB file. No external database required. A background SSE stream (`/api/stream`) pushes live updates to connected UIs.
- **FastAPI backend with DuckDB persistence** — positions, zone-transition events, vessel status, auto-incidents, and contributions land in a single DuckDB file. No external database required. A background SSE stream (`/api/stream`) pushes live updates to connected UIs.

---

Expand Down
226 changes: 226 additions & 0 deletions docs/superpowers/specs/2026-04-28-krill-refonte-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
# krill-watch · refonte unifiée — design spec

> **Status** : draft validé · brainstorming 2026-04-28
> **Owner** : @breaching
> **Spec ID** : 2026-04-28-krill-refonte
> **Approbation** : pending user review of this document
> **Companion artefacts** : `2026-04-28-krill-refonte/` (orchestration + phase plans + tasks)

---

## 1. Contexte & motivation

`krill-watch` exploite aujourd'hui **deux frontends parallèles** : un tracker dense (HTML/JS vanilla servi par FastAPI sur `127.0.0.1:8000`) et un site Next.js bilingue (`localhost:3000`). Il n'y a aucune synergie entre les deux : design systems divergents, navigation séparée, le tracker n'est pas mobile-friendly, les pages Next.js ne tirent pas parti des données live.

L'utilisateur veut une refonte qui :
1. **Unifie** les deux apps en un seul produit cohérent (Next.js).
2. **Ajoute un historique satellite** des bateaux ("comme Google Maps") : timeline scrubber + trail cumulatif coloré.
3. **Sert simultanément** quatre audiences — activistes Sea Shepherd / CPWF (primaire), journalistes d'investigation, lanceurs d'alerte, et public général curieux.

Décisions prises pendant le brainstorming :
- **Persona primaire** : activiste CPWF — toute friction UX se résout en sa faveur (mobile-first, partage, urgence visuelle, CTA "soutenir / signaler").
- **Architecture** : app Next.js unifiée, le tracker legacy `frontend/app.js` est réécrit en composants React puis supprimé.
- **Historique satellite** : timeline scrubber + trail cumulatif coloré (sévérité = couleur). Pas d'imagerie Sentinel-2 réelle au MVP (gardée pour phase ultérieure).
- **Home** : hero hybride — phrase-choc tirée du live + 3 stats sévérité + 2 CTA + mini-map preview.
- **Atomes partageables** : pages incident, dossiers navires, hubs de campagne (les trois ont URL stable + OG image dédiée). Digest hebdo exposé en route depuis le HTML existant.
- **Scope** : refonte complète activiste, 5-7 semaines, 3 phases livrables (chacune utile en standalone).

---

## 2. Vision & promesse

> *Un seul tracker open-source qui rend visibles les flottes industrielles en zones protégées — vivant pour les activistes, citable pour les journalistes, accessible pour qui veut comprendre.*

**Ton** : sobre + précis. L'activisme transparaît par le choix du sujet (et la sévérité visuelle des incidents), jamais par la rhétorique. Pas de "pillage", "scandale", "honte" — la donnée parle.

**Bilingue FR/EN** maintenu en parité totale. Pas d'autres langues au MVP.

**Mobile-first** sur les surfaces critiques (`/`, `/live`, `/incident/[slug]`). Le cockpit `/live` a un layout mobile *redessiné* (BottomSheet pour les filtres, drawer pour le navire sélectionné), pas un shrink desktop.

---

## 3. Architecture cible

### 3.1 Couches

```
┌─────────────────────────────────────────────────────────────┐
│ Next.js 15 App Router · port 3000 · TypeScript / React 19 │
│ Tailwind 4 · MapLibre 5 · flag-icons · @vercel/og │
└──────────────┬──────────────────────────────────────────────┘
│ REST + SSE
┌──────────────┴──────────────────────────────────────────────┐
│ FastAPI · port 8000 · Python 3.11+ │
│ inchangé sauf : webhook revalidate + endpoint trail-historique
│ + endpoint contributions │
└──────────────┬──────────────────────────────────────────────┘
┌──────────────┴──────────────────────────────────────────────┐
│ DuckDB (data/krill_watch.duckdb) · GeoJSON config │
└─────────────────────────────────────────────────────────────┘
```

### 3.2 Routes Next.js cibles

| Route | Type | Phase | Description |
|---|---|---|---|
| `/[locale]` | static + ISR | 1 | Home (hero hybride, alerts strip, missions, méthode) |
| `/[locale]/live` | client | 1 | Tracker absorbé (cockpit) |
| `/[locale]/live/v/[slug]` | client | 1 | Deep-link vers un navire dans le cockpit |
| `/[locale]/vessels` | static | 1 | Liste flotte (existant — adapté DS) |
| `/[locale]/vessels/[slug]` | ISR | 2 | Dossier navire + trail + scrubber |
| `/[locale]/campagnes/[slug]` | ISR | 2 | 4 hubs de campagne |
| `/[locale]/incident/[slug]` | ISR | 3 | Pages incident auto-générées |
| `/[locale]/digest/[isoweek]` | static | 3 | Digest hebdo depuis HTML existant |
| `/[locale]/about` | static | — | Existe déjà |
| `/[locale]/contribuer` | client | 3 | Formulaire contribution |
| `/api/og/[type]/[slug]` | edge | 3 | OG images dynamiques |
| `/api/revalidate` | route | 3 | Webhook FastAPI → revalidate |
| `/api/contribute` | route | 3 | Endpoint formulaire contribution |

### 3.3 Composants critiques mutualisés

- **`<KrillMap>`** — composant map unique remplaçant `FleetMap` actuel, prend `mode` (`live | vessel | incident | campaign`) et configure layers/sources en conséquence. Déjà partiellement présent.
- **`<VesselTrail>`** — layer GeoJSON line avec gradient de couleur selon sévérité. Phase 2.
- **`<TimelineScrubber>`** — slider temporel avec keyboard a11y. Phase 2.
- **`<LiveAlertsStrip>`** — strip d'alertes critiques, réutilisable home + campaign hub.
- **`<ShareButton>`** — copy-link + intents Twitter/Bluesky/Mastodon + download OG image. Phase 3.
- **`<SupportCTA>`** — bouton "Soutenir CPWF" cohérent. Phase 3.
- **`<Flag>`, `<SeverityBadge>`, `<MissionBadge>`, `<Acronym>`** — déjà existants, restent en place.

### 3.4 Data layer

- `web/lib/krill-watch.ts` (existe) — wrap REST + SSE. Étendu en phase 2 avec `getVesselTrail(slug, days)`.
- Génération statique pour pages stables (about, vessels, vessels/[slug] ISR, campagnes/[slug] ISR).
- `/live` et `/incident/[slug]` server-rendered (pour OG images correctes).

---

## 4. Surfaces UX

### 4.1 Home (`/`)

**Above-the-fold** (hero hybride) :
- Tag mono : `● MAINTENANT · CCAMLR 48.1` (zone la plus chaude détectée)
- Headline : `11 chalutiers industriels en zone protégée antarctique.` (généré depuis l'API : nombre + zone + qualifieur)
- 3 stats par sévérité (CRITIQUE / SUSPECT / SURVEILLÉ)
- 2 CTA : "Voir la carte live →" (primary, krill orange) et "Comprendre la cause" (ghost)
- Mini-map preview à droite (180×120 desktop) avec dots clignotants

**Below-the-fold** : LiveAlertsStrip (3 cartes alerte) → Grille 4 missions (cards cliquables vers `/campagnes/[slug]`) → Méthode 3 étapes → Footer.

### 4.2 Cockpit (`/live`)

**Desktop** : layout 3 colonnes — sidebar gauche (filtres + liste fleet collabsible) · map plein viewport · drawer droit (détails navire sélectionné, fermable). Toggle DARK / SATELLITE en flotte top-left de la map.

**Mobile** : map plein écran. BottomSheet remontante pour filtres + liste. Drawer plein écran pour détails. FAB pour toggle satellite.

URL state : `?severity=CRITICAL&zone=48.1&v=antarctic-endurance` (deep-linkable, copiable).

### 4.3 Dossier navire (`/vessels/[slug]`)

**Header** : drapeau (Flag SVG) + nom + sévérité badge + flag CPWF si friendly + IMO/MMSI mono.

**Section map historique** : `<KrillMap mode="vessel" historicalRange="30d">` avec `<VesselTrail>` rendu en gradient color (vert → orange → rouge selon sévérité instantanée). En bas : `<TimelineScrubber>` avec marqueurs (entrées/sorties zones, AIS gaps).

**Sections suivantes** : Tableau identité · Log événements · Incidents documentés (liens vers `/incident/[slug]` en phase 3) · Sources · `<ShareButton>` + Embed code.

### 4.4 Page incident (`/incident/[slug]`)

**Above-the-fold** : map zoomée sur la violation + headline auto-générée (`{vessel} entered {zone} at {ts}`) + score transhipment (si applicable) + sources (3-5 liens externes).

**Below-the-fold** : contexte campagne (hub link) · trail du navire 7 jours autour de l'incident · `<SupportCTA>` · `<ShareButton>`.

URL slug : `<YYYY-MM-DD>-<vessel-slug>-<event-type-slugified>-<zone-slug>` (ex: `2026-04-28-antarctic-endurance-zone-entered-48-1`). Idempotent — si réémis, met à jour la même page. Voir [P3-T01](./2026-04-28-krill-refonte/phase-3-viralite/P3-T01-revalidate-webhook.md) pour la fonction `makeIncidentSlug` partagée TS/Python.

### 4.5 Hub campagne (`/campagnes/[slug]`)

**Hero éditorial** : image satellite teaser (statique en MVP, Sentinel-2 plus tard) + 3 chiffres-clés + CTA Soutenir.

**Sections** : Cadre légal & enjeu · Liste flotte filtrée par mission · Incidents récents (live) · Calendrier saison · Sources documentaires.

Contenu éditorial : MD bilingue par mission (`web/data/campaigns/<slug>.{fr,en}.md`).

---

## 5. Plan de phasage

3 phases livrables. Chacune fournit de la valeur en standalone (`/live` à parité après phase 1, dossiers enrichis après phase 2, viralité après phase 3).

| Phase | Durée | Tâches | Livrable principal |
|---|---|---|---|
| **1 · Fondation** | 10 jours | 8 tâches | `/live` à parité fonctionnelle dans Next.js, mobile-friendly. Hero hybride home. Legacy supprimé. |
| **2 · Historique & contenu** | 10 jours | 8 tâches | Trail + scrubber sur dossiers navires. 4 hubs de campagne. Glossaire enrichi. |
| **3 · Viralité & contribution** | 12 jours | 8 tâches | Pages incident auto-générées + OG dynamiques. Boutons partage. Formulaire contribution. Digest en route. |

Détail dans `2026-04-28-krill-refonte/phase-N-*/README.md`.

---

## 6. Risques & questions ouvertes

### Risques techniques

- **MapLibre + React StrictMode** : double-init en dev. Pattern ref + cleanup déjà en place dans `FleetMap.tsx` à conserver.
- **SSE dans Next.js App Router** : pas de support natif streaming SSE dans les Route Handlers pour l'instant. Solution : EventSource côté client (`'use client'`), fallback polling 30s.
- **OG images dynamiques** : `@vercel/og` (Satori) prend du SVG / éléments React simples. Une carte raster MapLibre ne s'y intègre pas. Solution prévue : pré-render côté serveur Python qui retourne PNG basique (tile statique + dot vessel + headline), ou mock SVG avec `<VesselTrail>` simplifié dans Satori.
- **Performance trail 30j × 23 navires** : 50k-100k points GeoJSON potentiels. Mitigation : downsample côté API (1 point / 15 min suffit visuellement), cluster côté client si > 5k.
- **Webhook revalidate FastAPI → Next.js** : nécessite un secret partagé + une URL publique. En dev local on peut utiliser ngrok ; en prod ça dépend de l'hébergement.

### Questions ouvertes (à trancher pendant l'exécution)

- **Hébergement Next.js** : Vercel (gratuit, OG natif) ou auto-hébergé (Docker compose avec FastAPI) ? *Décision recommandée : Vercel pour simplicité.*
- **Newsletter** : intégrée (Buttondown/Substack embed) ou simple lien externe ? *Décision recommandée : externe pour MVP.*
- **Storage formulaire contribution** : DuckDB (réutilise infra existante) ou GitHub Issues (auditabilité publique) ? *Décision recommandée : DuckDB + admin export.*
- **CTA Soutenir CPWF** : redirige vers `paulwatsonfoundation.org/donate` directement ou page intermédiaire krill-watch ? *Décision recommandée : redirige direct, ne pas créer un funnel.*

---

## 7. Critères de succès globaux

À la fin des 3 phases, le produit livré doit valider :

1. **Synergie** : un seul header / footer / DS / locale switcher pour TOUT le produit.
2. **Mobile** : un activiste sur smartphone peut consulter `/live`, sélectionner un navire, et voir un incident détaillé sans frustration.
3. **Viralité** : partager une URL `/incident/<slug>` sur Twitter génère un preview avec OG image lisible (carte + headline + drapeau).
4. **Citabilité** : un journaliste peut citer `/vessels/<slug>` comme référence stable pour un article ; la page existait à la même URL il y a 6 mois.
5. **Pédagogie** : un random qui arrive sur `/` comprend en 30 secondes ce qu'il regarde et où il peut agir.
6. **Accessibilité** : Lighthouse a11y score ≥ 90 sur toutes les pages critiques.
7. **Performance** : Lighthouse perf ≥ 80 sur mobile, LCP < 2.5s, CLS < 0.1.

---

## 8. Hors scope (explicite)

- Imagerie Sentinel-2 réelle alignée AIS (gardée pour phase ultérieure post-MVP).
- Flux lanceur d'alerte chiffré bout-en-bout / Tor-friendly (gardé pour phase ultérieure).
- API publique versionnée avec auth journaliste.
- Widget embeddable `<iframe>` pour intégration presse.
- i18n élargi (ES, PT, JP).
- Refonte du backend Python (FastAPI/DuckDB inchangé sauf 2 endpoints + 1 webhook).
- Ajouts de nouvelles missions au-delà des 4 actuelles.
- Tests visuels Playwright / Storybook (pas dans les conventions du projet).

---

## 9. Comment lire les artefacts associés

```
docs/superpowers/specs/
├── 2026-04-28-krill-refonte-design.md ← ce fichier
└── 2026-04-28-krill-refonte/
├── README.md ← orchestration globale, dependency graph
├── CONVENTIONS.md ← règles de coexistence multi-agent
├── phase-1-fondation/
│ ├── README.md ← objectifs phase 1, ordre d'exécution, vagues
│ ├── P1-T01-design-system.md
│ ├── P1-T02-tracker-map-migration.md
│ ├── ... (8 tâches)
│ └── P1-T08-legacy-cleanup.md
├── phase-2-historique/
│ └── ... (8 tâches)
└── phase-3-viralite/
└── ... (8 tâches)
```

Chaque tâche porte un frontmatter explicite (`files_owned`, `depends_on`, `parallelizable_with`) qui permet à plusieurs instances de Claude Code de travailler en simultané sans collision. Voir `CONVENTIONS.md` pour le protocole.
Loading