# PG-46 backend dependency receipt — 2026-08-22

Status: **BLOCKED**

Plugin release: `0.9.80`  
Canonical configured production base: `https://api.press.zone` (`international-press-zone.php:33-35`).

This is the plugin-side dependency check required by PG-46. It does not make
claims about backend implementation or deployment. The route inventory below
comes from executable plugin code only. `BackendContract` keeps both the
legacy contract (the default) and the selectable platform contract, so both
branches are recorded. Dynamic `{job_id}` and `{site_id}` path segments were
probed with the inert literal `pg46-probe`.

## Probe rules and result

Every request was unauthenticated and read-only: `GET`, no request body, and
no credentials or API keys. For paths the plugin normally mutates with `POST`
or `PATCH`, the probe remains `GET`; a `405`, `401`, `403`, `400`, or `422`
would have established the route without causing a mutation. Each connection
failure received exactly one retry, except `/api/connect/status`: an
interrupted batch had already started its first 10-second attempt before the
recorded two-attempt batch ran, so it has three observed connection timeouts.
No further requests were made to that endpoint. The first `/connect` attempt
used a 10-second connect timeout; all subsequent attempts used a 3-second
connect timeout. Every completed attempt failed with curl exit `28`
(connection timed out), which curl renders as HTTP code `000`.

`/api/packages` is the only catalog endpoint the plugin reads
(`includes/Connect/ConnectRestController.php:187`). Its response body could
not be captured because neither of its two connection attempts reached an HTTP
server. The plugin source does not read a backend health or version endpoint.
The update package URL is supplied dynamically by `/api/updates/check`; there
is no static package-download path in the plugin source to invent or probe.

| Endpoint path | Plugin method | Plugin source requirement | Probe method | HTTP observed | Verdict |
| --- | --- | --- | --- | --- | --- |
| `/connect` | GET | `includes/Connect/ConnectService.php:85` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/oauth/token` | POST | `includes/Connect/ConnectService.php:118` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/connect/status` | GET | `includes/Connect/ConnectService.php:163` | GET | `000` (three curl 28 timeouts; see probe note) | CONNECTION FAILURE |
| `/api/connect/checkout-session` | POST | `includes/Connect/ConnectRestController.php:146` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/connect/portal-session` | POST | `includes/Connect/ConnectRestController.php:165`; `includes/Connect/ConnectService.php:218` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/connect/disconnect` | POST | `includes/Connect/ConnectService.php:186` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/packages` | GET | `includes/Connect/ConnectRestController.php:187` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/translate` | POST | `includes/Integration/TranslationAPI.php:35,488` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/translate/bulk` | POST | `includes/Integration/TranslationAPI.php:36,617` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/jobs` | POST | `includes/Translation/BackendContract.php:55`; `includes/Translation/TranslationJobDispatcher.php:459` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/jobs/bulk-strings` | POST | `includes/Translation/BackendContract.php:55`; `includes/API/TranslateController.php:866` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/jobs/{job_id}` | GET | `includes/Translation/BackendContract.php:67`; `includes/API/TranslateJobsController.php:402` | GET (`pg46-probe`) | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/jobs/{job_id}/cancel` | POST | `includes/Translation/BackendContract.php:77`; `includes/API/TranslateJobsController.php:1720` | GET (`pg46-probe`) | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/estimate` | POST | `includes/Translation/BackendContract.php:87`; `includes/Translation/CharacterEstimator.php:265` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/sites/register` | POST | `includes/Translation/BackendContract.php:96`; `includes/Translation/SiteRegistrar.php:64` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/v1/sites/{site_id}` | PATCH | `includes/Translation/BackendContract.php:96`; `includes/Translation/SiteRegistrar.php:137` | GET (`pg46-probe`) | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/plugin/international` | POST | `includes/Integration/TranslationAPI.php:29,488` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/plugin/international/jobs` | POST | `includes/Translation/BackendContract.php:57`; `includes/Translation/TranslationService.php:382` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/jobs/{job_id}` | GET | `includes/Translation/BackendContract.php:67`; `includes/Translation/TranslationService.php:580` | GET (`pg46-probe`) | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/jobs/{job_id}/cancel` | POST | `includes/Translation/BackendContract.php:77`; `includes/API/TranslateJobsController.php:1720` | GET (`pg46-probe`) | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/estimate` | POST | `includes/Translation/BackendContract.php:87`; `includes/Translation/CharacterEstimator.php:265` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/sites/register` | POST | `includes/Translation/BackendContract.php:96`; `includes/Translation/SiteRegistrar.php:64` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/sites/{site_id}` | PATCH | `includes/Translation/BackendContract.php:96`; `includes/Translation/SiteRegistrar.php:137` | GET (`pg46-probe`) | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/exceptions/sync` | POST | `includes/Translation/ExceptionSync.php:21,79` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/updates/check` | POST | `includes/SiteServices/UpdateChecker.php:192,422` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |
| `/api/updates/verify` | POST | `includes/SiteServices/UpdateChecker.php:341,422` | GET | `000` (two curl 28 timeouts) | CONNECTION FAILURE |

## Exact curl commands

The following commands were run once for each listed endpoint, with the same
command run one additional time only after curl reported exit `28`; see the
probe note above for the one interrupted-batch exception.

```bash
curl -sS --connect-timeout 10 --max-time 30 -X GET -o /dev/null -w '%{http_code}' https://api.press.zone/connect

for path in \
  /oauth/token /api/connect/status /api/connect/checkout-session \
  /api/connect/portal-session /api/connect/disconnect /api/packages \
  /v1/translate /v1/translate/bulk /v1/jobs /v1/jobs/bulk-strings \
  /v1/jobs/pg46-probe /v1/jobs/pg46-probe/cancel /v1/estimate \
  /v1/sites/register /v1/sites/pg46-probe /api/plugin/international \
  /api/plugin/international/jobs /api/jobs/pg46-probe \
  /api/jobs/pg46-probe/cancel /api/estimate /api/sites/register \
  /api/sites/pg46-probe /api/exceptions/sync /api/updates/check \
  /api/updates/verify; do
  curl -sS --connect-timeout 3 --max-time 6 -X GET -o /dev/null -w '%{http_code}' "https://api.press.zone${path}"
done
```

## Findings / gate decision

- 26 of 26 source-derived plugin dependency endpoints are unproven because
  production connection attempts timed out before receiving HTTP.
- No `404`, `410`, or `5xx` was observed: no HTTP server response was reached.
- No credentials, API keys, request bodies, or non-read-only methods were
  sent. No hosts other than `https://api.press.zone` were contacted.
- **PG-46 remains `[ ] [UNVERIFIED]` in `GOLIVE.md`.** It cannot be flipped to
  `[x] [WORKS]` until every route has an existence response under the defined
  interpretation.

## Addendum — canonical-host corroboration (2026-08-22, main session)

The timeouts above are NOT sandbox egress artifacts. Re-probed from the
canonical workstation (single read-only requests, `--max-time 10-15`):

```text
GET  https://api.press.zone/health                          -> 200 in 0.99s
GET  https://api.press.zone/v1/estimate                     -> 000 (timeout, exit 28)
OPTIONS https://api.press.zone/v1/estimate                  -> 000 (timeout, exit 28)
HEAD https://api.press.zone/v1/estimate                     -> 000 (timeout, exit 28)
GET  https://api.press.zone/v1/definitely-not-a-route-xyz   -> 000 (timeout, exit 28)
```

Interpretation: the backend is alive (`/health` 200), but the production edge
holds ALL `/v1/*` connections open without responding — including nonexistent
routes and every method. Endpoint existence therefore cannot be proven
externally by unauthenticated probes at all; the 26 unproven rows above are an
edge-layer property, not per-endpoint evidence of absence.

Dependency note: production `api.press.zone` is mid-restoration/cutover
(press-zone-core CF Workers backend; cutover blocked on owner-held Stripe
sandbox secrets and social OAuth credentials). PG-46 should be re-run with the
paired backend release deployed, ideally via an authenticated plugin-shaped
health/catalog read, before any flip to WORKS.
