823a80f663
* refactor(ui): share neutral capability contracts across editions Move SiriusCapability, SiriusPrincipal, the capability snapshot/provider types, and the Community catalog into a React-free contracts module so the browser registry and the incoming server registry cannot hold divergent catalogs. The UI extension modules re-export the same names, so consumers are unchanged. Pin the Community catalog to documentation/product/edition-boundary.yaml with a contract test, since that file is the source of truth for the edition boundary. Co-authored-by: mtoussain <mtoussain@gmail.com> * feat(ui): add server principal resolver and tRPC extension seam Mirror the browser extension registry on the server. A SiriusServerExtension declares tRPC namespaces with their required capabilities, at most one principal resolver, and optional session enrichers; registered.ts is the build-time overlay a private build replaces. protectedProcedure now enforces the capabilities declared for the procedure's namespace, so a contributed namespace is authorized without patching Core procedures. Principal resolution fails closed: a resolver that throws yields no principal instead of inheriting another edition's capability set. Community resolves any authenticated session to its static catalog, leaving Community behavior unchanged. root.ts cross-checks declared namespaces against the composed router in both directions, so an overlay that ships a router without declaring it (or declares a namespace it never serves) fails at startup rather than at request time. The routers stay object literals so tRPC keeps inferring client types. Co-authored-by: mtoussain <mtoussain@gmail.com> * test(ui): run extension contract tests in CI Add the server and capability suites alongside the UI registry suite behind a single test:extensions script, and make it a blocking CI step so the contracts private builds overlay are actually guarded. Co-authored-by: mtoussain <mtoussain@gmail.com> * docs: record the server-side extension seam in ADR-004 and the task board Co-authored-by: mtoussain <mtoussain@gmail.com> * fix(server): allow private principal resolver to replace Community fallback * test(server): prove private resolver can replace Community fallback * docs: record resolver replacement semantics and freeze server contracts at v1 Co-authored-by: mtoussain <mtoussain@gmail.com> * fix(server): split overlay router slot out of the declaration slot Contributing routers from registered.ts cycles: trpc.ts imports the registry to enforce capabilities, so an overlay router module importing createTRPCRouter loads while trpc.ts is still initializing and dies with 'Cannot access createTRPCRouter before initialization'. This was found by composing a private extension against the seam. Routers now come from registered-routers.ts, which only root.ts imports, so they load after trpc.ts is ready. root.ts still cross-checks declared namespaces against composed ones, and a contract test keeps the declaration modules free of tRPC imports. Co-authored-by: mtoussain <mtoussain@gmail.com> * docs: document the overlay module split and cycle constraint Co-authored-by: mtoussain <mtoussain@gmail.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>