The shell now renders the CORE nav entries — Home · Account for everyone,
Users · Modules only for an admin — alongside the registry entries, with the
discovered `home` dashboard collapsed onto the core Home entry (SPEC-010 §3).
A signed-in user with no passkey, who has not opted out and is not on a
loopback origin, now sees a prominent "Add a passkey" banner linking to the
Account page (SPEC-010 §6). This closes the D-041 gap where the wizard's
direct session mint bypasses the TOTP-login nudge, so the admin was never
prompted.
The door computes (admin, banner) in serveGUID — it already holds the
session, identity and user — and attaches it to the request context; the new
web.PageFor copies it onto every authenticated page (RequestContext is
untouched, so identification stays separate from authorisation, D-003).
- One base layout (layout.html) with the header, the nav from Registry.Nav()
(D-038), a content slot and the CSRF token; every page renders inside it and
a module supplies content only
- Embedded same-origin assets (app.css · app.js · webauthn.js · sw.js ·
manifest.webmanifest · icons) served by the reserved `static` workflow
- webauthn.js drives the three ceremonies from data-* attributes — no inline
script, so the CSP `script-src 'self'` holds (AC-3)
- manifest start_url "/" (D-011); the service worker never caches an
authenticated response or /{GUID} (A5)