Skip to content

feat: gate Setup Org/Invitations nav on multi-org, server-side (ADR-0057 D10) - #2150

Merged
xuyushun441-sys merged 3 commits into
mainfrom
feat/adr-0057-ps2-nav-gate
Jun 22, 2026
Merged

feat: gate Setup Org/Invitations nav on multi-org, server-side (ADR-0057 D10)#2150
xuyushun441-sys merged 3 commits into
mainfrom
feat/adr-0057-ps2-nav-gate

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

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's filterAppForUser (which served only requiredPermissions filtering) now also enforces NavigationItem.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).
  • Applies requiresService: 'org-scoping' to nav_organizations / nav_invitations. org-scoping is 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 explicit business_unit sharing 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 the kind='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 future business-units opt-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-enforcing requiresService doesn't change its behavior.
  • No spec field added (requiresService already existed). No existing nav item uses requiresService, 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

…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>
@vercel

vercelBot commented Jun 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 22, 2026 2:44am

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling size/m labels Jun 22, 2026
@github-actions

github-actionsBot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/platform-objects, @objectstack/rest.

6 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/implementation-status.mdx(via @objectstack/rest)
  • content/docs/concepts/packages.mdx(via @objectstack/platform-objects, @objectstack/rest)
  • content/docs/concepts/setup-app.mdx(via @objectstack/platform-objects)
  • content/docs/guides/api-reference.mdx(via @objectstack/rest)
  • content/docs/guides/packages.mdx(via @objectstack/platform-objects, @objectstack/rest)
  • content/docs/guides/plugins.mdx(via @objectstack/rest)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…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>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@xuyushun441-sys@os-zhuang