# EU PET Observatory — setup

## Requirements

- Node.js 22.13 or newer.
- pnpm 11.25.0, as pinned in `package.json`.
- Python 3 for the optional workbook audit (standard library only).

The app uses React, TypeScript, Vinext/Vite and a Cloudflare Worker with D1 review storage. Evidence and exports use included data; institutions are not scraped at runtime.

## Run a local copy

Extract `EU_PET_Observatory_Source.zip`, enter `EU_PET_Observatory`, and run:

```bash
pnpm install --frozen-lockfile
pnpm build
pnpm exec wrangler d1 execute DB --local --persist-to .wrangler/state --config dist/server/wrangler.json --file drizzle/0000_past_ken_ellis.sql
pnpm dev
```

The development URL is `http://localhost:5173`. The SQL command initializes a **new local database once**. Do not rerun that initial migration against an existing database. Local reviews stay in `.wrangler/state` and are excluded from source downloads/publication. Local data access and reviews require no credentials.

For the production build locally, stop development and run `pnpm start`; use Wrangler's printed local URL. The build outputs a Worker under `dist/server` and assets under `dist/client`.

The ZIP includes capability-only `.openai/hosting.json` with `DB` enabled and no remote project identity. Register a new Site to publish this as a separate app. For the existing hosted Site, use its source repository and preserve its project ID. Sites applies the checked-in Drizzle migrations during deployment. Do not publish local D1 files.

## Verify

```bash
pnpm exec tsc --noEmit
python3 scripts/audit-workbook.py
node scripts/verify-dashboard.mjs
```

The audit fails on evidence/scoring cell mismatches. Functional checks cover original rankings, eligibility, deduplication, equal file weighting, missing/neutral values, ties, provisional status, reviews, filters, PET distinctions, profile metadata and XLSX/CSV. Reports are written to `.sites-runtime/verification`.

Re-extract the authoritative workbook without changing it:

```bash
python3 scripts/extract-workbook.py public/EU_PET_scored_mapping.xlsx .sites-runtime/verification/workbook-raw.json
python3 scripts/audit-workbook.py .sites-runtime/verification/workbook-raw.json
```

## Using the dashboard

1. Search or combine selectors. More filters includes dates, legal stages, institutions, source techniques, roles, scores, confidence, transfer relevance, country and current group. MEP, country, group and role must match the same person; a role-only search may also find collective evidence without a named person.
2. In Current MEPs, choose overall scores or `Score within filters`. Competition ranks reflect that scope; filtered tables may show a subset of those ranks.
3. MEP names open verified official profiles. `View evidence` opens the internal assessment. `Print evidence summary` opens browser printing; choose Save as PDF if needed.
4. Excel contains seven related sheets. Evidence and MEP-score CSVs are separate. `Scored Excel` downloads the unchanged supplied workbook.
5. A review requires a reason and appends a timestamped record while preserving the original. `Apply saved reviews` switches original/reviewed results. Exports reject stale review revisions.

## Comparing amendments

In Evidence Explorer, use `Compare` on an amendment row or `Compare amendments` above the table. The detail panel also has `Compare this amendment`. Choose a second amendment using the same provision locator, or broaden to the same legislative file. Search the second selector by amendment number, provision or proposer.

Both cards show baseline/proposed workbook summaries, optional summary-word differences, separately labelled exact PET excerpts, verified proposers, scores/rationales, safeguards and official sources. Matching locators are a navigation aid; they do not prove identical baselines or adoption outcomes. Summary highlights are not a legal redline. Missing verbatim text is explicitly identified.

The comparison uses the selected original/reviewed state. It does not change filters or scores; evidence outside the active filters is labelled. Related rows in the same deduplicated scoring proposal remain linked and retain their own signatories.

## Maintaining evidence

Preserve original fields/scores, source locators, bridge attribution, deduplication groups, scope notes, aliases and URLs. Do not infer authorship from committee roles or score unverified current members. Internal keys support reconciliation and are hidden from visible labels.

For membership refreshes, download `https://www.europarl.europa.eu/meps/en/full-list/xml`, match verified IDs to official profile identities and resolve ambiguous/renamed identities through Parliament records. Record a new date. Exclude former/unresolved members from personal scores; retain their archives.

For source checks, follow redirects and match the cited document identifier/title/content. Record date, status, final URL and unresolved details. Successful HTTP responses alone do not prove identity. Restrictions and empty responses are not confirmed broken links. Do not fabricate replacements.

Keep exact source terminology separate from analytical technology families and transfer-navigation tags. New legal research needs its own source/date/coverage review; link refreshes must not advance the research cut-off.

For intentional schema changes, run `pnpm db:generate` and inspect the migration before deployment. Regenerate the downloadable source after edits with `python3 scripts/package-source.py`.

## Browsing the observatory

Use the left navigation on desktop or **Browse section** on mobile. **Legislation** contains 58 adopted-legislation evidence rows. **Legislation in development** contains 43 proposal/draft rows and 246 amendment rows, with one-click choices between them. **Guidelines** contains 57 official-material rows, including a separate choice for two judgments/enforcement decisions. **Archive** preserves 74 historical, superseded or withdrawn legislative rows. These categories use workbook types and statuses; they do not update or infer legal outcomes. Counts are evidence rows, not numbers of laws.

**MEP positions** retains the current-member PET amendment support view and score-scope switch. **Evidence Explorer** searches all 478 rows. Search and other filters carry across sections; **Clear filters** removes those selections while keeping the current section. Excel/CSV exports use the selected section and filters. On phones, use **More filters** for file, technology, people and other detailed choices.
