docs(android): M12 phase 5 as landed #117

Merged
whitlocktech merged 1 commits from docs/android-theming-nav-phase-5 into edge 2026-08-08 12:12:22 +00:00
Member

§6.2 corrected and amended, §6.1 given the Home decision, and a "Phase 5 as landed" section added with the in §8. Targets edge, like every M12 phase.

§6.2's table was in the wrong order — and the order is now load-bearing

The three news categories were listed Five on Friday / Newsletter / Screenshots. The website's array has them Screenshots / Five on Friday / Newsletter, between News and Wiki.

That did not matter while the table was only a mapping. It matters now: a stored order is an index into the site's nav, so a row the admin never moved has to take its sort key from the same list, and a key from the wrong list scrambles a partially-overridden nav. The rows are now numbered 0–15, the order is called out as verbatim from SiteHeader.jsx, and the reason is stated where someone editing the table will see it.

Also new in §6.2

  • The feature values are deliberately not mirrored into the table, though the website's array carries one on nine of these rows. APP_MENU stays the app's own source of truth for gating: a second copy of a security-relevant value that drifts silently is worth more than it costs.
  • The "no APP_MENU row" rule covers seven entries, not four — the three news categories as well as the hub boards.

Two decisions the org lead settled before code

Both are recorded where the rule lives, not only in the phase notes:

The news categories are ignored for the drawer, on the same rule as the hub four. The mapping still exists for phase 6's added links, where a category tab is a perfectly good destination because the admin named it by path. The alternative — surfacing such a row only when overridden — keeps AC-1 but lets an override introduce navigation after all, so it was rejected. Written into §6.2 as a dated decision block.

An admin may hide the Home row, mirroring the website, where / is hideable from the public header. Home stays the NavHost's start destination and stays reachable by back-press. The contrast that makes it safe, and which the note states: /admin/navigation has three guards because hiding it would strip the only way to undo an override, and nothing about a hidden Home row is unrecoverable. Written into §6.1, where "hiding is subtractive" already lives.

"Phase 5 as landed"

Records the sort-key finding above as the thing the spec did not settle; that an untouched instance gets APP_MENU back by identity, so AC-1's drawer claim is an assertSame rather than a structural comparison, and what "nothing usable in the row" covers; that the app's own rows are partitioned off rather than sorted, with the note that a future APP_MENU interleaving an app-only row among the public ones would see it moved to the tail; that group/section are read and dropped, and that both stored shapes are read; and why Routes.NEWS_ROUTE is declared beside Routes.NEWS rather than replacing it — with the consequence that destination.route now carries a query and is compared on substringBefore('?').

PLAN.md is untouched: refreshing the §9 M12 entry is phase 8's line in §8, and phases 3 and 4 left it alone the same way.

Android-app: RunicGateway/Android-app#38.


  • AI-assisted: written with Claude Code (Claude Opus 5)
§6.2 corrected and amended, §6.1 given the Home decision, and a "Phase 5 as landed" section added with the ✅ in §8. Targets `edge`, like every M12 phase. ### §6.2's table was in the wrong order — and the order is now load-bearing The three news categories were listed Five on Friday / Newsletter / Screenshots. The website's array has them **Screenshots / Five on Friday / Newsletter**, between News and Wiki. That did not matter while the table was only a mapping. It matters now: a stored `order` is an index into the *site's* nav, so a row the admin never moved has to take its sort key from the same list, and a key from the wrong list scrambles a partially-overridden nav. The rows are now numbered 0–15, the order is called out as verbatim from `SiteHeader.jsx`, and the reason is stated where someone editing the table will see it. ### Also new in §6.2 - **The `feature` values are deliberately not mirrored** into the table, though the website's array carries one on nine of these rows. `APP_MENU` stays the app's own source of truth for gating: a second copy of a security-relevant value that drifts silently is worth more than it costs. - **The "no `APP_MENU` row" rule covers seven entries, not four** — the three news categories as well as the hub boards. ### Two decisions the org lead settled before code Both are recorded where the rule lives, not only in the phase notes: **The news categories are ignored for the drawer**, on the same rule as the hub four. The mapping still exists for phase 6's added links, where a category tab is a perfectly good destination because the admin named it by path. The alternative — surfacing such a row only when overridden — keeps AC-1 but lets an override introduce navigation after all, so it was rejected. Written into §6.2 as a dated decision block. **An admin may hide the Home row**, mirroring the website, where `/` is hideable from the public header. Home stays the `NavHost`'s start destination and stays reachable by back-press. The contrast that makes it safe, and which the note states: `/admin/navigation` has three guards because hiding it would strip the only way to *undo* an override, and nothing about a hidden Home row is unrecoverable. Written into §6.1, where "hiding is subtractive" already lives. ### "Phase 5 as landed" Records the sort-key finding above as the thing the spec did not settle; that an untouched instance gets `APP_MENU` back by **identity**, so AC-1's drawer claim is an `assertSame` rather than a structural comparison, and what "nothing usable in the row" covers; that the app's own rows are partitioned off rather than sorted, with the note that a future `APP_MENU` interleaving an app-only row among the public ones would see it moved to the tail; that `group`/`section` are read and dropped, and that both stored shapes are read; and why `Routes.NEWS_ROUTE` is declared beside `Routes.NEWS` rather than replacing it — with the consequence that `destination.route` now carries a query and is compared on `substringBefore('?')`. `PLAN.md` is untouched: refreshing the §9 M12 entry is phase 8's line in §8, and phases 3 and 4 left it alone the same way. Android-app: RunicGateway/Android-app#38. --- - [x] AI-assisted: written with Claude Code (Claude Opus 5)
wtclaude added 1 commit 2026-08-08 12:10:45 +00:00
§6.2 corrected and amended, §6.1 given the Home decision, and a "Phase 5 as
landed" section added with the  in §8.

**§6.2's table was in the wrong order, and the order is now load-bearing.** The
three news categories were listed Five on Friday / Newsletter / Screenshots; the
website's array has them Screenshots / Five on Friday / Newsletter. That did not
matter while the table was only a mapping, but a stored `order` is an index into
the site's nav, so a row the admin never moved takes its sort key from this list —
and a key from the wrong list scrambles a partially-overridden nav. The rows are
now numbered 0-15 and the order is called out as verbatim.

Also written into §6.2: the `feature` values are deliberately **not** mirrored
into the table (`APP_MENU` stays the app's own source of truth for gating), and
the "no `APP_MENU` row" rule covers **seven** entries rather than four — the
three news categories as well as the hub boards.

Two decisions the org lead settled before code, both recorded where the rule
lives rather than only in the phase notes:

- **The news categories are ignored for the drawer**, on the same rule as the hub
  four. The mapping still exists for phase 6's added links, where a category tab
  is a perfectly good destination because the admin named it by path. The
  alternative — surfacing such a row only when overridden — keeps AC-1 but lets an
  override introduce navigation after all, so it was rejected.
- **An admin may hide the Home row**, mirroring the website, where `/` is hideable
  from the public header. Home stays the start destination and stays reachable by
  back-press. The contrast that makes it safe is with `/admin/navigation`, which
  has three guards because hiding it would strip the only way to undo an override;
  nothing about a hidden Home row is unrecoverable.

"Phase 5 as landed" records the sort-key finding above as the thing the spec did
not settle, that an untouched instance gets `APP_MENU` back by **identity** so
AC-1's drawer claim is an `assertSame`, that the app's own rows are partitioned
off rather than sorted (and what that would mean for a future interleaved row),
that `group`/`section` are read and dropped, and why `Routes.NEWS_ROUTE` is
declared beside `Routes.NEWS` rather than replacing it — with the consequence that
`destination.route` now carries a query and is compared on `substringBefore('?')`.

Android-app: RunicGateway/Android-app#38.

Co-Authored-By: Claude <noreply@anthropic.com>
whitlocktech merged commit 79eaa9ceef into edge 2026-08-08 12:12:22 +00:00
whitlocktech deleted branch docs/android-theming-nav-phase-5 2026-08-08 12:12:22 +00:00
Sign in to join this conversation.
No description provided.