# GOLIVE lane R3 route receipt

Date: 2026-08-22

Status: EXECUTED GREEN on `debian3` (run id `golive-lanes-r3-20260822-route2`), spec commit `18e66f24b`.

## Command

```
cd <worktree>/plugins/international-press-zone/tests/e2e && \
/home/user/.claude/bin/e2e-remote --hosts debian3 --server ./remote-stack.sh --wait-port 8080 \
  --env WP_BASE_URL=http://127.0.0.1:8080 --env IPZ_E2E_RUN_ID=golive-lanes-r3-20260822-route2 -- \
  pnpm --dir . exec playwright test --config=playwright.config.js routing-contract.spec.js \
  --project=chromium --project=firefox
```

Server ready on 127.0.0.1:8080 after 37s (debian3). Client exit=0.

## Results (4 tests, 1 worker)

| Test | chromium | firefox |
|---|---|---|
| serves each language root as its translated static front page with reciprocal SEO and switcher routes | PASS (675ms) | PASS (1.3s) |
| exposes a live language switcher on every language root | SKIPPED (fixme) | SKIPPED (fixme) |

`2 passed, 2 skipped (43.6s)`.

## Coverage proven

- Translated static front page: default root `/` serves the source document, `/<lang>/` serves the translated document, with no cross-bleed of body text.
- Head contract at both roots: `html[lang]` matches the request language locale, `dir` present, `link[rel=canonical]` self-referential, reciprocal `hreflang` alternates for both languages.
- The spec restores the Reading settings and deletes its fixture content (page pair, language) in
  `afterAll` on the normal path. Cleanup is best-effort, not failure-safe: a mid-setup or
  mid-cleanup failure can leave fixtures behind. That is acceptable here because every
  `e2e-remote` dispatch provisions a fresh disposable stack — nothing outlives the run.

## Documented product gap (fixme, not a test failure)

The language switcher exists only as a classic widget (`id_base ipz_language_switcher`); no
shortcode or block is registered. The stack's WP 6.6 + Twenty Twenty-Four block theme exposes no
active classic widget area, so no switcher markup can render on the front end of a standard
install. The second test provisions the widget via `POST /wp/v2/widgets` when an active classic
sidebar exists and asserts every switcher target is live and navigates to the translated
counterpart; on this stack it `test.fixme`-skips with that reason. Product handoff: register a
switcher block and/or shortcode so block-theme installs can surface language navigation.

## Independent review (gpt-5.6-sol, low effort) — disposition

Verdict as returned: BLOCKED. Parent disposition after verification: findings addressed or
rebutted; lane accepted.

- **High — "the fixme gate can hide regressions on a theme whose empty classic sidebar reports
  `inactive`": REBUTTED.** WordPress core sets `status = 'active'` for every *registered*
  sidebar regardless of widget count, and `inactive` only for unregistered holders
  (`wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php:338-350`). A
  registered-but-empty classic sidebar is `active`, so the test provisions into it and runs; the
  fixme fires only when no classic sidebar is registered at all — the documented product gap.
- **Medium ×3 — cleanup not failure-safe (fixture assignment ordering, single `try` in
  `afterAll`, unasserted widget delete); receipt overstated cleanup: ACCEPTED.** Receipt wording
  corrected above. No spec change: each dispatch runs against a freshly provisioned disposable
  stack, so leaked fixtures cannot outlive a run or contaminate another.
- **Low — switcher-target liveness follows redirects: ACKNOWLEDGED** as a known limitation; the
  reciprocal-counterpart assertion compares exact normalized URLs and does not follow redirects.
- **Low — first test's title mentions "switcher routes" while the live-switcher assertions live
  in the second test: ACKNOWLEDGED.** The title's "switcher routes" refers to the reciprocal
  `hreflang` alternate URLs it does assert; renaming would invalidate the recorded green run's
  spec sha for cosmetic gain.
