# YachtMemory Source Catalog v2 — Atomic Receipts 0.1.0 (REVIEW ONLY)

This is **not** a production receiver. The combined test receiver is restricted to **`yachtmemory_catalog_v2_test`** and called by CLI only. `measurement_aggregate` deliberately remains unsupported. Do not modify the productive sync controller, sync receiver, Wildbad, or `SilentMessDB`.

## Design

- Incoming v2 outbox envelope is validated against an **independently trusted `--authenticated-vessel` argument** (currently synthetic and supplied by the operator; eventual production authentication needs a trusted SSH peer mapping).
- Check `sync_receipts` by `(vessel_id, outbox_seq_no)` and content hash under a vessel row lock. Exact duplicates return `already_received`; sequence/hash conflicts fail.
- Catalog `header`, `chunk`, `finalize` operations and receipt insertion share **one MySQL transaction**. To achieve this in the test receiver, the previous standalone catalog implementation's internal transaction boundaries are replaced with assertions that an outer transaction exists. SQL operations and data validation otherwise derive from the already-tested receiver 0.1.0.
- `finalize` revision is compared against the persisted manifest under lock. An `incomplete` finalization returns `{ok:false,status:"incomplete"}` with no receipt, allowing retry after the missing chunks are delivered.
- Fault injection in this **test program only** supports `throw-before-commit`, `kill-before-commit`, and `exit-after-commit`. Note that the included one-shot MySQL integration script exercises exception rollback and lost-ACK recovery; `SIGKILL` rollback has already been tested in the earlier fault-test package, not in this combined receiver script.
- The example response `status=received` is **not supported by production controller 0.1.0**. It must not be wired into existing production flow; a future versioned dispatcher/controller change is needed.
- `--validate-only` checks the envelope in an offline manner without attempting database access. It does not prove atomic behavior.
- Existing `sync_receipts` primary key structure is duplicated verbatim in `sql/receipts_test_only.sql`. **Execute it only with an explicit database argument `yachtmemory_catalog_v2_test`.**

## Step 1: offline checks, safe

```bash
cd /var/www/app.yachtmemory.net/YM-Source-Catalog-v2-Atomic-Receipts-0.1.0-REVIEW
php -l receiver/ym-sync-catalog-v2-atomic-review.php
python3 -m unittest discover -s tests -v
bash -n tests/mysql_atomic_test_review.sh
sha256sum receiver/ym-sync-catalog-v2-atomic-review.php sql/receipts_test_only.sql
```

## Step 2: MySQL integration, only after review

Test DB `yachtmemory_catalog_v2_test` already exists. Check that `sync_receipts` does not already exist and that the DB has the seven existing tables. Create one new test table with:

```bash
sudo mysql yachtmemory_catalog_v2_test < sql/receipts_test_only.sql
```

Run the one-shot integration test:

```bash
bash tests/mysql_atomic_test_review.sh
```

This creates one synthetic vessel UUID (`4b4fba28-49b7-4d18-87fb-63a1a5c1930e`) and its snapshot. It aborts on a second invocation; **do not delete existing rows merely to rerun**. Existing Wildbad and prior fault-test fixtures are not modified.

## Remaining before production

No live central controller integration, no real authenticated peer-vessel mapping, no dedicated DB account, no reworked onboard outbox producer, no production receipt/ACK change. Additional adversarial, concurrency, reboot, and `SIGKILL` tests are necessary. The reference implementation still needs an explicit policy for stalled/incomplete snapshots and outbox ordering, so `finalize` cannot cause head-of-line blocking in the central controller.
