# Prod Env Bootstrap — Task 2.5 (Sentry) + Task 2.8 (Backups) — 2026-05-11

Prod-side activation run. Host: Math-2025 (152.42.223.228).
Authorized one-time CLAUDE.md exception used for prod `.env` write
(see `sentry-dsn-recovery-2026-05-11.md`) and root crontab edit.
Read-only-prod resumes after this run.

## Env var NAMES confirmed present on prod

`grep -E '^(SENTRY_LARAVEL_DSN|BACKUP_S3_)' /var/www/html/mathapi/.env | cut -d= -f1 | sort | uniq -c`:

    1 BACKUP_S3_BUCKET
    1 BACKUP_S3_ENDPOINT
    1 BACKUP_S3_KEY
    1 BACKUP_S3_REGION
    1 BACKUP_S3_SECRET
    1 SENTRY_LARAVEL_DSN

All 6 expected keys present, no duplicates. Values not echoed.

Note: at run start, `SENTRY_LARAVEL_DSN` value was the literal placeholder
`PASTE_REAL_DSN_HERE`, which broke `php artisan config:cache` and took prod
to HTTP 500 for ~90s after `config:clear`. Recovered by pasting the real
DSN; see `ops/sentry-dsn-recovery-2026-05-11.md`.

Note: `BACKUP_S3_KEY` and `BACKUP_S3_SECRET` went through two iterations
this session: a first paste yielded `InvalidAccessKeyId` from DO Spaces
even after `config:clear`+`config:cache` confirmed the value was loaded
verbatim (key 20 chars, secret 43 chars, no whitespace, matching prefix
in `.env` vs runtime). Pam edited `.env` manually with a second set of
credentials and the upload succeeded. Root cause of the first failure
was DO-side (wrong/revoked key ID), not prod config.

## Crontab status

Pre-run: no `schedule:run` line present in root's crontab (`grep -c` → 0).

Post-run, `crontab -l`:

    * * * * * cd /var/www/html/mathapi && php artisan schedule:run >> /dev/null 2>&1

Added by this run (root had no prior crontab entries).

## Sentry verification

    curl https://mathapi.allgifted.com/api/_sentry-test  →  500

Test event confirmed by Pam in Sentry dashboard within ~30s. Task 2.5
activation complete.

## Backup verification (Task 2.8)

After Pam re-pasted real DO Spaces credentials and a final
`config:clear`+`config:cache`+`chown`:

    $ php artisan backup:run --only-db --disable-notifications
    Starting backup...
    Dumping database api...
    Determining files to backup...
    Zipping 1 files and directories...
    Created zip containing 1 files and directories. Size is 2.54 MB
    Copying zip to disk named backups...
    Successfully copied zip to disk named backups.
    Backup completed!

    $ php artisan backup:list
    +--------------------+---------+-----------+---------+--------------+----------------------+--------------+
    | Name               | Disk    | Reachable | Healthy | # of backups | Newest backup        | Used storage |
    +--------------------+---------+-----------+---------+--------------+----------------------+--------------+
    | AllGifted Math API | backups | ✅        | ✅      |            1 | 0.00 (3 seconds ago) |      2.54 MB |
    +--------------------+---------+-----------+---------+--------------+----------------------+--------------+

Task 2.8 activation complete.

## Deferred to next session

- **Task 2.9 restore drill** — verify a backup zip can be downloaded
  from `allgifted-mathapi-backups` and restored to a scratch DB.
  Out of scope for this activation run.

## Side artifact

- `/var/www/html/mathapi/.env.bak-pre-task2-bootstrap` — pre-edit
  snapshot, retained for now. Safe to delete once the daily scheduled
  backup has run successfully at least once (overnight 2026-05-11/12).
