# ADR 0032. Demo Bucks unlink notice and alias reconcile

## Status

Accepted.

## Context

Unlink commits on PlayerPal (`revoked_at`) and may notify the partner asynchronously
(spec §36.6.5). Failure of that notice must not fail Unlink. Play at the partner
continues. ADR 0030 allowed casino chrome to stay stale-linked until Bucks knew.

Demo Bucks only read a local alias row. `notifyRevoked` was a no-op, so Account and
Game kept showing Connected after PlayerPal Unlink. Casino chrome must not wait on
Unlink, must not call PlayerPal on every wager, and must never send the private
player UUID. Audience for partner APIs comes from authenticated client headers,
not from an untrusted `operator_id` body field.

## Decision

PlayerPal pushes a fire-and-forget status delta to demo Bucks after Unlink
(`POST /v1/player-link-notices` with `MACHINE_API_KEY`, lookup by `pp_plr_opr_…` /
`pp_plr_prv_…`). Unlink HTTP success does not wait on that POST.

Bucks does not expose `DELETE /v1/player-links/:playerRef`. Casino Account/Game
still refresh `GET /v1/player-links/:playerRef`. After a local hit, Bucks
reconciles once with PlayerPal `GET /v1/aliases/:playerAlias` (operator or
integration header). `revoked` or `404` applies the same cache update as the
notice. PlayerPal network/5xx keeps last known (stale-linked).

Delete Account still does not command partner erasure.

Demo routing uses `BUCKS_UNLINK_NOTICE_URL` for `pp_opr_01DEMOBUCKS` and
`pp_int_ORBIT_BUCKS` only. Per-party webhook URLs and OAuth machine clients are
later.

## Consequences

- Connect returns on Bucks when the notice lands or the next status refresh
  reconciles a missed notice.
- Stale-linked remains when the notice fails and PlayerPal is unreachable.
- Compose Nest reaches host Bucks via `host.docker.internal:3002` unless
  `BUCKS_UNLINK_NOTICE_URL` is set otherwise.
