Found while implementing #5750. Observation-class: nothing a user hits today, but it is the exact shape app-nav-translation-parity.test.ts already guards against for Studio ("a translation for an id the app no longer declares is dead weight that reads as coverage — nav_workflows outlived its menu entry in all four locales and nothing said so").
Measurement
Booting the real Setup composition and diffing the merged nav ids against each locale's apps.setup.navigation keys, on origin/main 487a197b5:
| key |
en |
zh-CN |
ja-JP |
es-ES |
nav_approval_processes |
present |
present |
present |
present |
nav_metadata |
present |
present |
present |
present |
nav_verifications |
present |
— |
present |
present |
nav_device_codes |
present |
— |
present |
present |
None of the four is declared by any nav item in the repo:
$ for k in nav_approval_processes nav_metadata nav_verifications nav_device_codes; do
echo "$k: $(grep -rn "id: '$k'" --include=*.ts packages/ | grep -vc node_modules)"
done
nav_approval_processes: 0
nav_metadata: 0
nav_verifications: 0
nav_device_codes: 0
Control probe with a live id (nav_webhooks) returns a hit, so the zeros are real.
Two of them have a recorded reason to be gone. setup-nav.contributions.ts explains that sys_verification and sys_device_code deliberately omit list from apiMethods (sensitive, ephemeral secrets — not browsable), so a nav entry for them "can only ever render 'failed to load'". The entries were removed; their translations were not.
Why this was not just deleted in the #5750 PR
That PR adds pnpm check:app-nav-i18n, which judges the merged Setup app. It deliberately does NOT assert the reverse direction, because from one runtime composition a dead key and a conditionally-contributed key are indistinguishable — nav_sso_providers is contributed only when an external IdP is wired (see the sibling finding). Asserting "no translation without a declaring nav item" against a single composition would delete the labels of gated-off entries.
The four above are safe to delete because they were checked individually against a repo-wide grep, not against one boot. But doing that on a verdict the gate itself cannot reach would leave the deletion unguarded, so it belongs in its own change with its own reasoning — either:
- Delete the four keys (16 lines across four locale files), plainly, citing the grep; or
- Close it structurally together with the sibling finding, by giving the gate a way to see the union of declared contributions rather than one realisation — at which point the reverse direction becomes assertable for Setup exactly as it already is for Studio.
Filed unassigned.
Found while implementing #5750. Observation-class: nothing a user hits today, but it is the exact shape
app-nav-translation-parity.test.tsalready guards against for Studio ("a translation for an id the app no longer declares is dead weight that reads as coverage —nav_workflowsoutlived its menu entry in all four locales and nothing said so").Measurement
Booting the real Setup composition and diffing the merged nav ids against each locale's
apps.setup.navigationkeys, onorigin/main487a197b5:nav_approval_processesnav_metadatanav_verificationsnav_device_codesNone of the four is declared by any nav item in the repo:
Control probe with a live id (
nav_webhooks) returns a hit, so the zeros are real.Two of them have a recorded reason to be gone.
setup-nav.contributions.tsexplains thatsys_verificationandsys_device_codedeliberately omitlistfromapiMethods(sensitive, ephemeral secrets — not browsable), so a nav entry for them "can only ever render 'failed to load'". The entries were removed; their translations were not.Why this was not just deleted in the #5750 PR
That PR adds
pnpm check:app-nav-i18n, which judges the merged Setup app. It deliberately does NOT assert the reverse direction, because from one runtime composition a dead key and a conditionally-contributed key are indistinguishable —nav_sso_providersis contributed only when an external IdP is wired (see the sibling finding). Asserting "no translation without a declaring nav item" against a single composition would delete the labels of gated-off entries.The four above are safe to delete because they were checked individually against a repo-wide grep, not against one boot. But doing that on a verdict the gate itself cannot reach would leave the deletion unguarded, so it belongs in its own change with its own reasoning — either:
Filed unassigned.