<!-- CANONICAL server-registration step for /changes/ pages.
     Included by: generate-changes-page.md, apply.md — every prompt
     that writes a /changes/ page ends with this call. KEEP IN SYNC with the tool
     (src/tools/register-change-items.ts) and the API route
     (apps/api POST /me/projects/:slug/change-items). -->

### ⚠️ MANDATORY — register the page's items with the server

The `/changes/` page does NOT register itself. Client-side
self-registration was removed on 2026-07-05 (the public endpoint refuses
writes) — registration is YOUR job, through the authenticated MCP tool.
**Skip this call and the whole review surface is dead data-side:** no
decision bars on the page, no in-page review chip on source pages, and
reviewer rejections spawn duplicate CRs instead of transitioning the
originals.

After the landing step resolves and the `/changes/` page file is part of
the outcome (any option that keeps the file — branch, commit, or
stage-only), call:

```
pinappai_register_change_items({
  project: "<resolved-slug>",
  page_path: "/changes",   // this page's own route, e.g. "/tr/changes" for a locale variant
  items: [                 // EVERY [data-pp-item] on the page, in DOCUMENT ORDER
    {
      id: "<data-pp-item>",
      title: "<data-pp-title>",
      target_page_url: "<data-pp-page-url>",
      target_source_selector: "<data-pp-source-selector>",
      target_source_files: "<data-pp-source-files, when present>",
      before_text: "<the .change-row.b .val text, verbatim>",
      after_text: "<the .change-row.a .val text, verbatim>",
      applied_cr_id: "<data-pp-applied-cr-id — ONLY when the markup carries it>",
    },
    // …one entry per item
  ],
})
```

Rules:

- **Mirror the markup exactly.** Same ids, same attribute values, same
  document order (order drives the cross-page review queue), verbatim
  `.val` texts — read them back from the file you just wrote, don't
  retype from memory.
- **The list is the FULL active set** for that `page_path` — items you
  leave out are deactivated server-side. That makes re-registration after
  a regen self-cleaning: resolved items disappear because you no longer
  send them.
- **One call per page.** Locale variants (`/tr/changes`, …) each register
  under their own `page_path`.
- **If the user dropped the page from the batch** ("skip the changes
  page" at landing / deleted the file), do NOT call the tool — never
  register items for a page that isn't shipping.
- On `forbidden`: the API key's workspace role is below editor. Tell the
  user to ask their workspace admin for an editor-or-above API key (minted
  at app.pinappai.com → API keys), then re-run just this registration call
  — the page file itself is already correct and needs no changes.
- Report the tool's response in one line, e.g.
  `Registered N items with the server (M stale dropped).` A non-zero
  `dropped_stale` means some items referenced CRs that no longer exist —
  surface that count, don't hide it.
