CurrencyTransfer.com · Navigation 2026 · stage 2 build

Navigation 2026 PRD Review Pack

Read this page in five minutes. It tells you what we build, what you must decide, and what a human must do by hand.

24 September 2026PRD: docs/nav-audit-2026-09-22/prd-nav-2026.md (revision 5)Written in Simplified Technical English
CODEX gpt-6-astra builds it OPUS claude-opus builds it (editor-facing work) HUMAN a person does it LATER after the production switch

1. What we build

We replace the fixed header menu with a menu that editors manage in WordPress. Stage 1 already ships the agreed design as fixed HTML behind a switch. Stage 2 renders the same HTML from one WordPress menu, item by item. A checker compares both outputs link by link, so Google sees no change. When the missing pages ship, editors reveal the full design by un-hiding menu items.

STAGE 1 · IN PROGRESS

Fixed launch menu

Static header and phone sheet in the theme, behind the ctw_nav_v2 switch. Live links only. Not part of this PRD.

STAGE 2 · THIS PRD

WordPress-managed menu

The same design, rendered from one editable menu. Same links, same order, same landmarks as stage 1.

STAGE 3 · PARKED

Full four-column design

Featured cards and the refer-and-earn plaque return when their pages exist. Editors un-hide items. No new code unless the design changes.

Hover and default link states. The link-state specification (nav-link-states.md) fixes colours and hover behaviour for every width. You asked for the same behaviour at every width, so the build checks it with a script, not by eye.

2. What an editor can and cannot do

An editor can

  • Add, remove, rename and reorder any link on Appearance > Menus.
  • Set what an item is: link, group, overview row, featured card, plaque, go-further row, button.
  • Hide an item until its page is live. Hidden items do not exist in the page HTML.
  • Give a link a short description, a "New" tag, or a currency badge.
  • Pick a tile icon or a card image from the media library.
  • Set a different position for a group on phones only.
  • Restore the full design with one button, once the pages exist.

An editor cannot

  • Change colours, spacing, fonts or breakpoints. Those live in the stylesheet.
  • Show a link on desktop but not on phones, or the reverse. Google reads the phone menu.
  • Write HTML into the menu.
  • Change the number of desktop columns beyond "start a new column here".
  • Switch the new menu on or off. That is the operator's switch.
  • Upload SVG icons unless you approve the Safe SVG plugin (decision 1).

3. The stories

Twenty-one stories. One commit each. otto runs them; a person does NAV-001 and the release steps. NAV-020 runs after the production switch, in a second conversion.

IDTitleWhoDepends onDone when
NAV-001Human prerequisites: record the input-limit fix, Safe SVG plugin, Convert pause, hub row idHUMANnoneSite Health shows 3000 input variables on both servers; the other items have screenshots.
NAV-002Admin prerequisites and the test runnerCODEXnoneThe Menus screen shows custom fields and the Description box; the lint harness passes on PHP 7.2 and 8.3.
NAV-003Tree builder, roles, badges, mobile order, test scaffoldCODEX002The tree test passes on three PHP versions with zero deprecations.
NAV-004Link, tile, card and plaque markup; icon resolution; SVG sanitiserCODEX003Every repo icon renders like the bundle; hostile SVG input comes back clean.
NAV-005Per-item fields on the Menus screen with a guarded saveOPUS003A saved item shows the right meta rows; an AJAX-added item shows none.
NAV-006Media picker for icons and card imagesOPUS005, 010, 017Swapping an icon in wp-admin changes the rendered tile; clearing it removes the tile.
NAV-007Desktop panel markup (1200 px and wider)CODEX004, 014The parity checker reports zero differences against the stage-1 bundle.
NAV-008Medium panel markup (600 to 1199 px)CODEX004, 014Each tab's medium block equals the bundle's after normalisation.
NAV-009Phone sheet markup with phone-only orderingCODEX004, 014The sheet equals the bundle; a phone position moves one group without changing desktop.
NAV-010Render integration on stage 1: fragment filter, composition, test parametersCODEX007, 008, 009, 014, 016Switch off: header byte-identical to before. Switch on: the page passes the parity checker.
NAV-011Cache: build once, flush on every change, previews never cached, link parity assertedCODEX010Flush then load gives miss then hit; a page or image change empties the cache.
NAV-012Section map: nav targets feed the active-tab body classCODEX011Thirteen test URLs get the expected body class; the phone sheet opens on the matching tab.
NAV-013Cloudflare purge on every menu changeCODEX011One purge per request in the unit test; the production probe is a release step.
NAV-014Harness and baselines: fixtures, parity checker copy, states check, visual and Lighthouse toolsCODEX002Baselines exist for stage 1 and the frozen archive; the checker self-tests pass.
NAV-015Verification of the rendered menu: screenshots, link states, behaviour, LighthouseOPUS011, 012, 014, 017Every screenshot pair differs by 1 % or less; 32 of 32 state probes pass.
NAV-016Seed the menu tree from a Tools pageCODEX003, 01473 items, 21 hidden; a second run adds nothing; the seed matches the bundle's content.
NAV-017Icon import and the launch / full-design presetsCODEX016, 00415 icons uploaded once and assigned; the preset un-hides only pages that answer 200.
NAV-018Second critical-CSS set for the new headerCODEX015, 014Seven new files with no old menu rules; first paint is styled with the switch on and off.
NAV-019Launch gate: URL probe, parity, visual, Lighthouse, staging PHP 8.3 logCODEX006, 013, 015, 017, 018, 021Local and staging report FAIL 0; stage 1 versus stage 2 reports zero differences.
NAV-020Post-switch cleanup: remove the old menu code, export and retire old menusLATER019No old menu rules remain; the export is verified before any deletion.
NAV-021Full-design stylesheet (cards, plaque, footer strip)OPUS010, 014, 017The full-design preset matches the frozen archive within 1 %; the launch view does not change.

Lanes after NAV-003: markup (007, 008, 009), admin (005, 006), seed (016, 017) and harness (014) run in parallel. Then 010, 011, 012, 013 run in sequence. Then 015, 018, 021, and the gate 019.

4. Decisions you must make before the build

  1. 1. SVG icon uploads. WordPress blocks SVG uploads. Option A: install the Safe SVG plugin; editors upload SVG icons that recolour on hover. Option B: editors upload PNG or WebP only; no plugin, no hover recolour. Recommendation: A.
  2. 2. Personal column order. Phil's Personal comp puts Tools & help in the middle column. The prototype and the bundle put Send money from there. This is a drag in the menu, not code, but stage 1 should ship your choice. Recommendation: keep the bundle order.
  3. 3. The "All industries" link. It points to the Business hub page. To land on the sector strip, an editor must give that row the id industries in the page builder. Recommendation: add the row id before launch, then restore the fragment link.
  4. 4. Full-design styles. The stage-1 stylesheet has no rules for the featured cards, plaque and footer strip. Option A: stage 1 adds them to its bundle. Option B: story NAV-021 ships them as an extra stylesheet. Recommendation: B, to avoid stage-1 churn.
  5. 5. One menu, not two. Decided; veto if you disagree. Desktop and phone render from one menu. A per-item "Position on mobile" field gives you phone-only ordering. Two menus were rejected: every edit twice, the two drift (menus 13 and 49 today), and Google indexes the phone menu, so a desktop-only link is invisible to search.
  6. 6. Small differences from the frozen full-design archive. Twelve listed differences (for example the Saudi guide stays in "Why you're transferring" at every width). Recommendation: accept.
  7. 7. Two pages lose their sitewide link. Decided; veto if you disagree. The old menu links to /product and to PayPlexo. The new menu does not. Nothing else links to them from every page.
  8. 8. Convert experiments. Decided; a person does it. Experiments 100142955 and 100144149 restyle the old menu buttons. Pause them before the switch. This is a dashboard task, not a build story.

5. Steps a human must do

  1. Done. max_input_vars is 3000 on production and staging through a .user.ini file in each WordPress root. Verified on 24 September. Revert: delete the file.
  2. Done. WP-CLI 2.12.0 is installed on production at /home/phil/bin/wp. Run it with --path=/var/www/www --skip-themes --skip-plugins, because the theme fails under the command line. Staging has no WP-CLI; the Tools page seeds every environment.
  3. Merge stage 1 to main and freeze its bundle. Stage 2 starts from that commit.
  4. Install the Safe SVG plugin on staging and production, if you choose option A in decision 1.
  5. Pause the Convert experiments 100142955 and 100144149 before the switch. They restyle the old menu buttons.
  6. Give the sector row on the Business hub the id industries, if you choose that in decision 3.
  7. On each environment, open Tools > Seed navigation 2026. Click Seed, then Import icons. Order: local, staging, production.
  8. On production, export the database before the switch: /home/phil/bin/wp --path=/var/www/www --skip-themes --skip-plugins db export.
  9. Deploy stage 2 to production with the switch off. Preview it with ?ctw_nav=2 as an administrator.
  10. Run the Cloudflare purge probe: save the new menu and confirm the edge cache resets within 60 seconds.
  11. Turn the switch on in Settings > Reading, or run wp option update ctw_nav_v2 1. Purge Cloudflare. Run the URL probe.
  12. Rollback at any time: turn the switch off and purge. No deploy needed.
  13. Seven days after the switch: convert and run NAV-020 (cleanup). Later: stage 3 through the full-design preset.

6. Risks

RiskMitigation
The rendered menu drifts from the stage-1 bundle, so Google sees different links.Every markup story must pass the parity checker against the bundle, link by link and in order.
Editors' changes stay invisible for hours because Cloudflare caches whole pages.Every menu change flushes the cache and sends one Cloudflare purge; a production probe proves it.
Code that runs on PHP 7.4 locally fails on PHP 7.2 in production or warns on PHP 8.3 on staging.Every PHP story runs its tests inside PHP 7.2 and PHP 8.3 containers with exit codes checked.
A link to a page that is private, missing or redirecting ships in the menu.Unpublished targets never render, corridor links have no trailing slash, and the launch gate probes every URL.
The first paint flashes an unstyled header on the seven busiest templates.A second critical-CSS set is generated for the new header and selected only when the switch is on.

7. What the adversarial reviews found

Six reviews ran: four rounds of the otto checker (gpt-6-astra), the SEO crawlability audit, and one independent gpt-6-astra review. The table shows what changed.

PassFoundChanged
otto round 11 blocker, 35 major. Cited screenshots did not exist; tooling sat outside the git repository; saves could damage the old menu; dependencies were missing.Real frames cited; tooling moved into the theme repo; Dante's save handler unhooked; dependencies fixed; stories split where two concerns shared one file.
SEO auditStage 2 "pass with fixes". Button tabs would break parity with stage 1; hidden items must be absent from the HTML; group titles must not be heading tags.Tabs stay links; hidden items are omitted; titles use role="heading"; glyphs are hidden from screen readers; the checker script is the acceptance test.
otto round 22 blockers, 37 major. The stage-1 code had landed in the theme; the PRD duplicated it.The PRD was rebased on stage 1: it reuses the switch, the header override, the assets and the section class, and adds one filter line.
otto round 31 blocker, 32 major. Line numbers had shifted; the bundle's stylesheet lacks the full-design rules; the bundle's icons and the media files differ in size units.Symbol anchors; new story NAV-021 for the full-design styles; the normaliser ignores icon internals and screenshots prove the look.
otto round 41 blocker, 31 major. The stage-1 stylesheet underlines only the open tab, so a "current section underline" was not real; the local base URL redirects; the bundle shows shorter overview copy on phones.The section class now preselects the phone tab only; one base URL for every check; a "Subline on phones" field; cache writes guarded against stale builds; unassign, do not delete, the old menus.
Independent gpt-6-astra review (round 5)Running at the time of writing.See the PRD's review log, section 9.

Declined, four rounds running: further splitting of seven stories. The task sizer splits stories at conversion time, and each story is one file or one tool set. The finding count stopped falling after round 2, which is the sign to stop iterating and convert.

Prepared 24 September 2026 from docs/nav-audit-2026-09-22/prd-nav-2026.md. Unlisted page: do not index.