# Navigation Translation Adapter

Audience: AI coding agents first.

- **ID:** IPZ-NAVIGATION-TRANSLATION-ADAPTER-2026-08-14
- **Status:** DONE
- **Task:** SC-ADAPTER-02
- **Source request:** Implement next dependency-correct multilingual Site Content slice: dormant `wp_navigation` runtime resolution. Owner then directed this worktree session to continue remaining multilingual slices through session end.
- **Execution owner:** Current isolated worktree session. Task #1 owns verification/publication; Task #2 owns next-slice continuation.

## Outcome

Add dormant `NavigationTranslationAdapter` library code and deterministic focused tests. It may resolve a `wp_navigation` post request-locally, applying ready/current segment translations and internal-link mapping. It must not register hooks, bootstrap, or activate any runtime behavior.

## Dependencies

Consume the published/dormant Site Content identity, request-context, catalog, repository, and block-segment codec contracts. Preserve canonical WordPress navigation retrieval/render seams for later wiring; do not use block-template filters.

## Acceptance

- Only `wp_navigation` objects are eligible; always return a fresh clone and never alter caller or canonical cache objects.
- Overlay the current catalog source, only when an explicit public-frontend or plugin-preview context and matching canonical target language permit it.
- Require active, ready, source-revision-current, positive-revision, bounded valid JSON segment data. Missing, stale, malformed, oversized, or codec-invalid input falls back to current source.
- Translate navigation labels using `BlockSegmentCodec`; preserve structure and external URLs.
- Provide an injected internal-link mapper with fixed call-count, URL-byte, and traversal-depth limits. Map only normalized same-site URLs: preserve scheme security, effective port equivalence, and current WordPress home-path boundary. Any unavailable, invalid, cross-site, downgraded, or over-limit mapping preserves original URLs and translated labels.
- Diagnostics contain only bounded reason/type/key/language fields and cannot alter fail-closed behavior.
- No effects in Site Editor, generic REST, admin, cron, CLI, management AJAX, feeds/background paths, or canonical/process-global caches; no registration, endpoint, UI, feature flag, scheduled work, or write path.
- Remain compatible with WordPress 6.0 and PHP 8.0.
- Ship as `includes/SiteContent/NavigationTranslationAdapter.php`. Production archives exclude Composer `vendor/`, and the fallback PSR-4-style autoloader cannot load WordPress-style lowercase `class-*.php` names; focused tests must exercise the shipped PascalCase path.

## Preserved WIP and constraints

- Publication candidate: `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/navigation-adapter-warning-free`; exact base `63469315818909d90d4b21e57ad3bf6c4f7beba4`. Preserve all seven staged files together.
- Original reviewed worktrees remain preserved; the publication candidate is the only delivery source.
- Remaining verification MUST use the normal installed applicable commit gate plus remote Composer audit and dormancy proof. Do not rerun already clean focused/full suites unless a candidate source file changes.
- Every gate MUST run through canonical `/ipz-e2e` / `e2e-remote` on registry-selected `debian1`/`debian2`/`debian3`. Workstation is inspection/editing only.
- Adapter remains dormant and independently revertible.

## Allowed paths

- `includes/SiteContent/NavigationTranslationAdapter.php`
- navigation-only focused tests/fixtures below `tests/Unit/SiteContent/` and `tests/Fixtures/SiteContent/`
- `phpunit.xml.dist` for normal-suite registration
- this plan, `docs/plans/INDEX.md`, and the multilingual continuation index/plan

## Execution

1. Reconcile against current source and `origin/master` seams, especially the dormant template adapter and Site Content contracts.
2. Implement the detached, request-local navigation resolver plus deterministic fixtures/tests.
3. Run every focused/full applicable gate on registry-authorized `debian1`/`debian2`/`debian3` through canonical `/ipz-e2e` remote execution. NEVER run gates in local environment.
4. Run independent correctness/security review; fix confirmed findings and rerun affected gates.
5. Commit, publish through repository delivery controller, and verify exact `origin/master` tree. Keep adapter dormant.
6. Update multilingual continuation receipt and begin next dependency-correct slice automatically.

## Rollback

Remove the adapter and its focused tests/fixtures together. No persisted state or runtime registration is introduced.

## Current receipt

Added the dormant resolver, its navigation-only diagnostic/database fixtures, and seven deterministic focused tests. The resolver uses the catalog's bounded persisted-post lookup as authoritative source, applies only codec-validated ready/current records to fresh `WP_Post` clones, and remaps only same-site/relative `core/navigation-link` URLs through an injected mapper after the request-local label cache. External URLs and link IDs remain unchanged; mapping errors/invalid target URLs retain the translated-label document without exposing URL/provider data. It contains no hook, route, bootstrap, cache API, write, feature flag, UI, or runtime construction.

Final clean verification ran only through canonical `e2e-remote` on registry-selected `debian1`; no local fallback ran in that verification sequence. During later staging inspection, `git diff --check` was mistakenly executed on the workstation; it passed, but this violated the owner's remote-only gate rule. No local test, lint, static-analysis, build, smoke, browser, screenshot, or diagnostic command ran. Shipped fallback autoload passed. Direct and candidate-aware PHPCS passed. Focused PHPUnit passed with `18 tests, 252 assertions`; focused PHPStan passed with no errors; all three candidate PHP files passed syntax checks. Full PHPUnit passed with `98 tests, 550 assertions`; full baselined PHPCS passed; full PHPStan passed with no errors at its required 2G memory limit. Composer audit found no security advisories. Remote whitespace and dormancy checks passed. Fresh independent security review found no remaining defect. Trivy is unavailable on the selected remote host, so repository delivery's required secret-scan floor MUST complete before publication. Owner authorizes full delivery and continuation. Adapter MUST remain dormant: no hooks, routes, bootstrap, feature activation, scheduled work, or writes.

Remote-only gate infrastructure was published as `2c33fa64c33af6133a6a65edb28e60cafbc07d36`. The first normal navigation commit attempt then failed closed before remote dispatch because this candidate branch predates the published tracked gate contracts, so its final staged tree could not match the trusted installation. Do not weaken or bypass that check. Preserve this worktree unchanged as reviewed source WIP. Recreate the exact navigation slice in a fresh worktree from current `origin/master`, merge only the two overlapping registration/index files with current upstream content, and commit there through the installed gate.

The first fresh delivery candidate reached the canonical remote gate and exposed a real transport-state incompatibility: `local-gate` creates `.rb-epoch` and `.rb-origin` and may retain `.rb-lockhash`, while the remote helper rejected all three before analyzer setup. The fail-closed repair now validates, hashes, and monitors only those exact runner metadata paths while preserving global rejection of unrelated untracked state. Its complete remote fixture suite passed `151/151`; normal repair commit `7ae90453b5b236002cd18e36247bc59217e1db73` is installed and published with exact `origin/master` commit/tree parity. No bypass or local gate was used.

The exact seven-file navigation patch from the preserved reviewed candidate was staged in `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/navigation-adapter-final` on exact base `7ae90453b5b236002cd18e36247bc59217e1db73`. Upstream changed only the gate repair since the first fresh candidate, so the seven-file patch applied cleanly without conflict or content reconstruction. The original reviewed worktrees remain preserved.

Remote navigation verification on that exact content passed focused PHPUnit with `18 tests, 252 assertions`, the main PHPUnit suite with `108 tests, 588 assertions`, the standalone runner's established `discovered=63` contract, and syntax checks for all 273 PHP files. The main suite emitted one warning from pre-existing REST test-double alias interactions between `PostsControllerSiteRolesTest.php` and `ScopedExceptionsTest.php`; the navigation test neither defines nor loads those aliases, so no unrelated source change belongs in this slice. A first PHPCS dispatch failed transiently with remote supervisor `ETXTBSY`; the retry reached the real gate and failed closed because the synthetic remote snapshot does not expose `origin/master`. The required repository-specific comparison base is `HEAD^`; rerun remotely with `UI_GATE_BASE=HEAD^` rather than weakening the gate.

The second canonical transport repair was published on `origin/master` as `478e929044665a231a13ba2653a1284b2320ad5f`, exact tree `8291969ae9daede4a567a6ce31ae9acbcfd56ac2`. It narrowly admits and monitors the lock-owned `.dev-config/node_modules` cache, passed `154/154` remote fixtures, committed through installed enforcement, and landed with exact commit/tree parity. The exact seven-file navigation patch was then staged without conflict in `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/navigation-adapter-publish` on that exact master. No local gate, bypass, direct SSH, host override, or fallback was used.

Peer forensics and a direct canonical main-coordinator probe then proved the live runner writes `.rb-epoch` and `.rb-origin` as owner/group `1000:1000`, mode `664`; the metadata validator had accepted only `600|644`. The corrected helper retains those modes and admits `660|664` only for the effective primary group, still rejecting foreign-group and world-writable metadata. The complete remote suite passed `157/157`; all three enforcement sources were reinstalled with exact hashes and restrictive modes; normal commit `fe0fe34529af40cd90c2e8c9b9e0e94d2a70caa1` landed with exact `origin/master` commit/tree parity. The exact navigation patch is now staged in `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/navigation-adapter-release` on that master. A separate PHPCS dispatch before this correction failed closed on `debian3` because its fresh snapshot lacked `vendor/bin/phpcs`; no local fallback ran. The normal installed applicable commit gate performs its own hardened Composer install before PHPCS/PHPStan and is now the authoritative live-path proof.

The first remote Composer audit invocation correctly refused to audit an empty fresh install and directed use of its lockfile mode. The corrected canonical `composer audit --locked --no-interaction` run completed on registry-selected `debian2` with `No security vulnerability advisories found.` No local fallback ran. Candidate source content remains unchanged from the previously clean focused/full verification; only this plan receipt changed after those runs.

The first normal applicable navigation commit on the corrected mode-`664` path completed hardened Composer installation, then failed closed when PHPCS exited `3`: disabling Composer plugins correctly prevented `dealerdirect/phpcodesniffer-composer-installer` from registering the lock-owned WordPress standards. Direct canonical remote diagnosis confirmed `WordPress`, `WordPress.Files.FileName`, `WordPress.WP.I18n`, and `WordPress.NamingConventions.PrefixAllGlobals` were unavailable. The trusted helper now validates and explicitly registers only `vendor/wp-coding-standards/wpcs`, `vendor/phpcsstandards/phpcsextra`, and `vendor/phpcsstandards/phpcsutils`, then verifies `WordPress` before analysis while keeping Composer scripts and plugins disabled. Its complete remote fixture suite passed `161/161`; all trusted enforcement sources were reinstalled hash-identically with restrictive modes; normal repair commit `989ca292acec45bf2a2a4fbc7cd2176dad8e85a7`, exact tree `2d452683e795f7fdd0b7d5fb8dd1e65feab4f9f8`, landed with exact `origin/master` parity. The exact seven-file navigation patch is staged in `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/navigation-adapter-ship` on that exact base. No candidate source changed, no local gate ran, and every failed attempt stopped before navigation commit creation.

The unchanged navigation candidate then passed Composer setup and explicit PHPCS registration, but PHPStan failed with 21 unknown WordPress symbol errors because disabled `phpstan/extension-installer` had not loaded the lock-owned WordPress extension. The trusted helper now validates the exact regular non-symlink `vendor/szepeviktor/phpstan-wordpress/extension.neon`, rejects missing/symlinked/escaped copies, safely replaces any internal generated-config symlink, and uses a monitored generated config that includes both immutable project policy and that extension. The complete remote fixture suite passed `166/166`; exact tested enforcement was installed; normal repair commit `e13b3732e0c78a94860b9acd539ec680a4f4adbf`, exact tree `eb9ea00c61c9bd4f14f8c1cb3b58c7d79e83c0c4`, landed with exact `origin/master` parity. No candidate source changed, no local analyzer or fallback ran, and no failed navigation attempt created a commit.

The unchanged navigation candidate then passed hardened Composer, PHPCS, PHPStan, and exact completion binding, but slopgate returned zero while warning that `ast-grep` was absent and bucket-B rules were skipped. That warning made the gate incomplete. Local commit `40c641ecf` is rejected source evidence only and MUST NOT land. The trusted gate now owns and confines `@ast-grep/cli` through exact `.dev-config` package manifests, hardened remote npm setup, manifest digest binding, and fail-closed availability/mutation checks. Its complete canonical remote suite passed `176/176`; exact tested enforcement was installed; normal repair commit `491fac8558a70f4064262bd092083c5738e0d3cb`, exact tree `d9317f5dff3c6f6bee8decc9bde5685880a4297b`, landed with exact `origin/master` parity. Trusted helper SHA-256 is `3a7ddc5850d613cb45cad80285a5c7ed09e28cd25471c8187e83895496823aad`.

The exact seven-file navigation diff was recreated unchanged in `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/navigation-adapter-publish-final` on exact base `491fac8558a70f4064262bd092083c5738e0d3cb`. It applied cleanly while retaining current upstream plan-index content. No local gate, fallback, direct SSH, host pin, or bypass ran.

Normal commit `9e6c061c8` ran hardened remote npm and Composer setup, PHPCS, PHPStan, slopgate, exact-tree binding, and final reference authorization, but its output contained two unresolved AST warnings: the disabled postinstall forced wrapper runtime resolution, and slopgate classified the PATH binary as unpinned. Exit zero does not make that clean. The commit MUST NOT land. Preserve it only as exact source evidence. Keep scripts disabled; repair the trusted gate to expose the lock-owned platform-native binary through slopgate's repository-local pinned seam, prove warning-free remote execution, publish infrastructure first, then recreate this navigation content unchanged.

The native AST repair passed `179/179` canonical remote fixtures, was installed exactly, normally committed as `63469315818909d90d4b21e57ad3bf6c4f7beba4`, scanned without leaks, and published with exact `origin/master` tree `5a3c96d39ff71e5bb6929eaa7c7797c13237ff6a`. It invokes only the lock-owned native executable through slopgate's monitored repository-local seam; npm scripts remain disabled and the warning wrapper is never invoked. This exact seven-file candidate, including the rejected-warning receipt, was recreated unchanged on that exact base in `/home/user/Projects/Press.zone/wordpress/wp-content/.worktrees/navigation-adapter-warning-free`. No source or test behavior changed.

Normal commit `45ee7ef347747ab0ac1cd5e3ba18387f0edec2b0` then ran native `ast-grep` 0.45.1, hardened Composer setup, explicit PHPCS registration, PHPCS, explicit PHPStan WordPress extension loading, PHPStan, warning-free slopgate, exact-tree sentinel, and one-use final reference authorization. The disabled Composer-plugin messages are expected hardening confirmations; the helper supplies the required registrations explicitly. JavaScript, root Composer audit, and local Trivy notices were non-applicable scope reports; the unchanged candidate already had a clean lockfile audit and `/home/user/.claude/bin/land` supplied the required leak scan. Landing found no leaks and published exact tree `1bac029c7567ab44205ad8eb4cb2e025520f19e8`; fresh fetch proved exact `origin/master` commit and tree parity.

Canonical `e2e-remote` dormancy proof ran on registry-selected `debian1`. The only production occurrence of `NavigationTranslationAdapter` is its class declaration; the source contains none of the registration, route, scheduler, or WordPress write calls checked; and the lowercase duplicate path does not exist. All three checks exited zero. The adapter is published and remains completely dormant.

## Next executable action

Continue the highest dependency-correct non-overlapping multilingual Site Content slice from `2026-08-09-multilingual-site-entry-and-layout.md`.
