Packages can declare a `surfaces` array with per-path access controls,
titles, and layouts. A single package can serve a public form, an
authenticated dashboard, and an admin page — each with independent
access enforcement.
Kernel:
- Manifest validation for surfaces array (path, access, duplicates)
- Auto-synthesis from legacy auth/layout for existing packages
- Unified /s/:slug route tree (RegisterExtensionRoutes) dispatches
between surface rendering and ext API calls
- matchSurface() with Gin-style :param support and specificity ordering
- evaluateAccess() for per-surface access checks
- Nav filters out pending_review packages (pre-existing bug fix)
Frontend:
- __SURFACE_PATH__ and __SURFACE_PARAMS__ template injection
- sw.navigate(path, params) for SPA-style intra-package routing
- surface.navigate event + popstate handling
- SDK version bumped to 0.9.0
Docs:
- MULTI-SURFACE-GUIDE.md — full developer guide
- PACKAGE-FORMAT.md — surfaces field reference
- CHANGELOG.md, ROADMAP.md updated
22 new tests (11 manifest validation, 11 route matching/nav).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>