Uh oh!
There was an error while loading. Please reload this page.
feat: gate Setup Org/Invitations nav on multi-org, server-side (ADR-0057 D10) - #2150
Merged
Conversation
…ations on multi-org (ADR-0057 D10) Enforce NavigationItem.requiresService server-side in rest-server filterAppForUser: entries whose named kernel service is unregistered are dropped from the served app metadata (fail-open when the kernel can't be probed; previously requiresService was a frontend-only hint). Apply requiresService:'org-scoping' to the Setup app's Organizations + Invitations so they surface only in multi-org (multi-tenant) deployments and vanish in single-tenant. Business Units is intentionally left ungated — open per the open/paid seam + D12 (pick people by BU); only the paid hierarchy rollup is enterprise. Adds a dogfood proof + ADR D10 implementation note. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 6 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
…ments (ADR-0057 D10) resolveExecCtx leaves kernel undefined on the single-kernel fallback path (no kernelManager), so ctx.__kernel was undefined → resolveRegisteredServices returned null → the gate failed OPEN (Organizations still shown in single-tenant). This is the primary OSS deployment mode (and the verify harness). Add a single-env serviceExistsProvider wired from the plugin's ctx.getService; resolveRegisteredServices now probes the per-request kernel (multi-env) OR that provider (single-env). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ogfood (ADR-0057 D10) The platform Setup app's navigation isn't materialized in the verify/showcase harness (GET /meta/app lists only the business app; /meta/app/setup returns a protection stub), so an end-to-end Setup-nav assertion can't see the gated entries. Replace it with direct filterAppForUser unit tests (mirroring the ADR-0045 block): requiresService entries drop when the gate reports the service absent, persist when present, fail-open with no gate, and requiresObject entries stay untouched; plus a resolveRegisteredServices probe test. Validated locally (5 passed). Update the ADR proof note accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
xuyushun441-sysforce-pushed
the
feat/adr-0057-ps2-nav-gate
branch
from
June 22, 2026 02:39
5f97dad to
c243770CompareUh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PS-2 of the ADR-0057 addendum (#2141) — D10, narrowed per review. Completes the addendum (D9–D12 + D10).
What
Gates the Setup app's Organizations / Invitations nav on multi-org, server-side. Leaves Business Units visible in all editions.
How
rest-server'sfilterAppForUser(which served onlyrequiredPermissionsfiltering) now also enforcesNavigationItem.requiresService— entries whose named kernel service isn't registered are dropped from the served app metadata. Fail-open when the kernel can't be probed. This field already existed in spec as a frontend-only hint; PS-2 gives it server-side teeth (ADR-0049: enforced, not just declared).requiresService: 'org-scoping'tonav_organizations/nav_invitations.org-scopingis the canonical multi-org probe (SecurityPlugin already uses it), registered only in multi-tenant mode → single-tenant hides both.Why BU is not gated (narrowed from the original D9/D10)
The only available signal for BU would be
hierarchy-security(the paid rollup resolver). Gating on it would hide the management UI for functionality that is open: BU as owning-unit, the explicitbusiness_unitsharing recipient, and the D12 "pick people by BU" projection. The "ceiling" in D9 is the rollup capability, not BU's data surface. With Organizations hidden in single-tenant and thekind='team'collision removed (D11, #2143), the residual community menu is Users + Teams + Business Units — two distinct, legitimately co-present concepts, which was never the ambiguity we set out to remove. The ADR D10 note records this refinement; a futurebusiness-unitsopt-in can hide BU if vanilla clutter ever becomes a real complaint.Notes
requiresObject(the pre-existing capability gate) is a client-side (objectui) concern, not enforced in this repo — so server-enforcingrequiresServicedoesn't change its behavior.requiresServicealready existed). No existing nav item usesrequiresService, so blast radius = the two entries here.Proof: a rest nav-serving dogfood test — single-tenant omits Organizations/Invitations; multi-org shows them; Business Units present in both.
Changeset:
@objectstack/rest+@objectstack/platform-objectsminor.🤖 Generated with Claude Code