# Airbridge Universe v2 deployment

This release replaces the temporary passkey-only overlay with one Ceri flow
for self-service joining, returning-member sign-in, categorized instance
launching, and public discovery. The previous monolithic page is preserved
locally as `ceri-legacy-pre-universe.html`; it is not required in production.

## 1. Back up production

Back up `/home/airbridg/public_html/s` and export the `airbridg_airbridge`
database before applying the migration. Do not overwrite production
`ceri-auth/config.php` or anything in `ceri-auth/keys/`.

## 2. Confirm the first Weddings public ID

The local Daniel & Alexys record currently has `publicId = demo-wedding`.
The migration therefore seeds:

* Ceri instance ID: `wedding-demo-wedding`
* Weddings instance reference: `demo-wedding`

If the production database uses a different `publicId`, edit those two values
in `ceri-auth/database/002_universe_identity_and_instances.sql` before import.
The display name may remain `Daniel & Alexys Wedding`.

## 3. Apply the database migration

In cPanel phpMyAdmin, select `airbridg_airbridge`, choose **Import**, and import:

`ceri-auth/database/002_universe_identity_and_instances.sql`

This is additive. It retains existing users, sessions, passkeys, app registry
rows, and launch keys.

## 4. Upload Ceri public files

Upload these files to `/home/airbridg/public_html/s/`:

* `.htaccess`
* `ceri.html`
* `ceri-launcher.css`
* `ceri-launcher.js`
* `ceri.webmanifest`
* `ceri-sw.js`
* `images/abicon.png`
* `images/abicon-192.png`
* `images/abicon-512.png`

Upload this backend file to
`/home/airbridg/public_html/s/ceri-auth/public/index.php`:

* `ceri-auth/public/index.php`

Keep production `ceri-auth/config.php` permission `600`. The uploaded public
PHP file may be `644`. The `.htaccess` file selects the already-approved
`ea-php84` runtime.

## 5. Configure the Weddings launch secret

After the migration creates the `weddings` registry row, SSH from the Mac:

```sh
cd /home/airbridg/public_html/s/ceri-auth
php bin/set-app-secret.php weddings
```

Copy the one-time printed secret into the production Weddings configuration:

`/home/airbridg/public_html/ceriapps/Airbridge/Events/Weddings/server/config/ceri.php`

Use this shape (with the real secret, never committed or placed in JS):

```php
<?php
return [
    'appId' => 'weddings',
    'appSecret' => 'PASTE_THE_ONE_TIME_SECRET_HERE',
    'verifyUrl' => 'https://ceri.us/ceri-auth/api/launch/verify',
    'timeoutSeconds' => 10,
];
```

Set `ceri.php` permission to `600`.

## 6. Associate the initial GodHost

First join through the new Ceri screen. Then use phpMyAdmin to find the new
user and assign Daniel & Alexys:

```sql
SELECT u.id, u.display_name, i.identifier_type, i.identifier_value
FROM ceri_users u
JOIN ceri_user_identifiers i ON i.user_id = u.id
ORDER BY u.id DESC;
```

Using the correct returned numeric `id` only inside the database, run:

```sql
INSERT INTO ceri_user_instance_relationships
    (user_id, instance_id, relationship, favorite)
VALUES
    (YOUR_CERI_USER_ID, 'wedding-demo-wedding', 'godhost', 1)
ON DUPLICATE KEY UPDATE relationship = 'godhost', favorite = 1;
```

The numeric ID is never sent to Weddings. Its launch receives a pairwise
opaque subject, the signed instance reference, and role.

## 7. Test in this order

1. Open a private browser window at `https://ceri.us`.
2. Confirm the visible, favicon, and installed-PWA icons use `abicon`.
3. Choose **Join Airbridge**, enter first name, last name, and a custom
   Airbridge ID, accept the terms, and create the passkey with device security.
4. Confirm the empty personalized launcher appears (not every public app).
5. Open **Discover**, save/open Modem or Analyzer, and confirm it then appears
   in Tools.
6. Add the GodHost relationship SQL above, reload Ceri, and confirm Daniel &
   Alexys appears under Events > Weddings.
7. Launch it and confirm the browser POSTs to
   `/events/weddings/auth/ceri/callback`, then redirects to the `demo-wedding`
   page with a Weddings session and no token in the URL.
8. Log out, then choose **Continue with Touch ID or device security** and
   confirm the saved Ceri passkey returns to the same launcher.

## Provider follow-up

Google and Apple controls are present but disabled until their production
OAuth client IDs, redirect URIs, secrets, and account-linking rules are
configured. Email/SMS verification likewise requires a mail/SMS provider.
Basic privacy-first membership does not depend on any of them: name + unique
Airbridge identifier + passkey is fully functional in this release.
