ObjectStackObjectStack

App schema — UI Protocol property reference

App schemas of the ObjectStack UI Protocol: ActionNavItem, App, AppBranding and 12 more — each property with its type, default and a TypeScript example.

Source: packages/spec/src/ui/app.zod.ts

TypeScript Usage

import { ActionNavItemSchema, AppSchema, AppBrandingSchema, AppContextSelectorSchema, ComponentNavItemSchema, DashboardNavItemSchema, DocNavItemSchema, GroupNavItemSchema, NavigationAreaSchema, NavigationContributionSchema, NavigationItemSchema, ObjectNavItemSchema, PageNavItemSchema, ReportNavItemSchema, UrlNavItemSchema } from '@objectstack/spec/ui';
import type { ActionNavItem, App, AppBranding, AppContextSelector, ComponentNavItem, DashboardNavItem, DocNavItem, GroupNavItem, NavigationArea, NavigationContribution, NavigationItem, ObjectNavItem, PageNavItem, ReportNavItem, UrlNavItem } from '@objectstack/spec/ui';

// Validate data
const result = ActionNavItemSchema.parse(data);

ActionNavItem

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'action'✅
actionDef{ actionName: string; params?: Record<string, any> }✅Action definition to execute when clicked

Nested Shape: ActionNavItem.actionDef

PropertyTypeRequiredDescription
actionNamestring✅Action machine name to execute
paramsRecord<string, any>optionalParameters passed to the action

App

Properties

PropertyTypeRequiredDescription
namestring✅App unique machine name (lowercase snake_case)
labelstring | Record<string, string>✅App display label
versionneveroptional[REMOVED] App.version was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — no consumer in framework or objectui). An app is versioned by its owning package: use manifest.version. Delete the key. Run os migrate meta --from 16 to list the mechanical edits for existing sources; --write applies the ones it can prove, and you apply the rest by hand.
descriptionstring | Record<string, string>optionalApp description
iconstringoptionalApp icon used in the App Launcher
branding{ primaryColor?: string; accentColor?: string; logo?: string; favicon?: string }optionalApp-specific branding
activebooleanoptional (default: true)Whether the app is enabled
isDefaultbooleanoptional (default: false)Is default app
hiddenbooleanoptionalHide from the App Switcher; the shell surfaces hidden apps via the avatar menu instead (navigation only — never an access gate)
_unpublishedbooleanoptionalMachine-managed publish gate (ADR-0045 §3) — true = unpublished, externally unobservable. Written by AI materialization, cleared by publish-drafts. Never authored.
navigation({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]optionalFull navigation tree for the app sidebar
areas{ id: string; label: string | Record<string, string>; icon?: string; description?: string | Record<string, string>; … }[]optionalNavigation areas for partitioning navigation by business domain
contextSelectors{ id: string; label: string | Record<string, string>; icon?: string; optionsSource: object; … }[]optionalApp-level scope dropdowns whose value is injected into nav items as {<id>} template vars
homePageIdneveroptional[REMOVED] app.homePageId was removed in @objectstack/spec 17.0.0 (ADR-0049). objectui's console did read it before v17 (resolveLandingRoute), so this key had a consumer — it was retired because the capability is better expressed on the navigation item itself than as an ID cross-reference that silently falls back when it dangles. An app's landing page IS its first navigation item (by order), and the root landing follows isDefault routing. Delete the key; to change where an app opens, reorder navigation so the intended entry is first, and set isDefault on the app that should own the root landing. Run os migrate meta --from 16 to list the mechanical edits for existing sources; --write applies the ones it can prove, and you apply the rest by hand.
requiredPermissionsstring[]optionalPermissions required to access this app
objectsneveroptional[REMOVED] App.objects was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — never read; the spec itself labelled it "config file convenience"). Objects belong to the stack (defineStack({ objects })); an app reaches them through its navigation items. Delete the key. Run os migrate meta --from 16 to list the mechanical edits for existing sources; --write applies the ones it can prove, and you apply the rest by hand.
apisneveroptional[REMOVED] App.apis was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — never read). Delete the key and declare the endpoint one level up, on the STACK: defineStack({ apis }). That surface EXECUTES from protocol 17. Before the executor landed it was refused wholesale — nothing mounted a declared path, so every key including authRequired parsed and gated nothing — and that blanket refusal is now narrowed to five per-endpoint publish gates (namespace, supported target, mapping, policy, uniqueness): an endpoint that passes them is mounted and serves traffic as soon as the stack is published. Two things to get right when you move it: the path must sit inside your own carve-out, /api/v1/apps/<manifest.namespace>/<subpath> with an explicit manifest.namespace (ADR-0121 D1/D2), and authRequired defaults to true — an explicit false is the only thing that opens anonymous access, and ADR-0121 D6 then requires an armed rateLimit: { enabled: true, windowMs, maxRequests }. Read the declarative-apis-endpoints-live entry of the protocol upgrade guide first; it is a security review, not a rename. A route that genuinely needs handler CODE is mounted imperatively instead: resolve the http.server service from your plugin context and register the route on kernel:ready (NOT the manifest contributes.routes key — removed in @objectstack/spec 17: nothing ever read it, and authoring it is now rejected with its own prescription). Run os migrate meta --from 16 to list the mechanical edits for existing sources; --write applies the ones it can prove, and you apply the rest by hand.
sharingneveroptional[REMOVED] App.sharing was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit / ADR-0049 enforce-or-remove) — no public-app route ever read it, so it declared sharing that did not exist. Public access is granted per FORM VIEW (FormView.sharing, the public-data-collection surface). Delete the key. Run os migrate meta --from 16 to list the mechanical edits for existing sources; --write applies the ones it can prove, and you apply the rest by hand.
embedneveroptional[REMOVED] App.embed was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit / ADR-0049) — no iframe route ever read it. Embedding is a per-form-view surface (FormView.sharing), not an app-level switch. Delete the key. Run os migrate meta --from 16 to list the mechanical edits for existing sources; --write applies the ones it can prove, and you apply the rest by hand.
mobileNavigationneveroptional[REMOVED] App.mobileNavigation was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — fully unimplemented; no renderer, including packages/mobile, ever read it). Delete the key; the block returns if/when a real mobile navigation ships. Run os migrate meta --from 16 to list the mechanical edits for existing sources; --write applies the ones it can prove, and you apply the rest by hand.
defaultAgentstringoptionalPlatform agent bound to this app's ambient chat ('ask' is the implicit default; 'build' for authoring surfaces) — ADR-0063 §1
arianeveroptional[REMOVED] App.aria was removed in @objectstack/spec 17.0.0 (2026-06 liveness audit — no renderer read app-level ARIA attributes). Declare aria on the page component that renders the DOM node instead (page.components[].aria; page.aria and the list view aria are live too). Delete the key. Run os migrate meta --from 16 to list the mechanical edits for existing sources; --write applies the ones it can prove, and you apply the rest by hand.
protection{ lock: Enum<'none' | 'no-overlay' | 'no-delete' | 'full'>; reason: string; docsUrl?: string }optionalPackage author protection block — lock policy for this app.
_lockEnum<'none' | 'no-overlay' | 'no-delete' | 'full'>optionalItem-level lock — controls overlay & delete (ADR-0010).
_lockReasonstringoptionalHuman-readable reason shown when a write is refused by _lock.
_lockSourceEnum<'artifact' | 'package' | 'env-forced'>optionalLayer that set _lock (artifact | package | env-forced).
_provenanceEnum<'package' | 'org' | 'env-forced'>optionalOrigin of the item (package | org | env-forced).
_packageIdstringoptionalOwning package machine id.
_packageVersionstringoptionalOwning package version.
_lockDocsUrlstringoptionalOptional documentation link surfaced next to _lockReason.

Nested Shape: App.branding

PropertyTypeRequiredDescription
primaryColorstringoptionalPrimary theme color hex code
accentColorstringoptionalAccent color hex code (highlights, active states). Declared to match the objectui ConsoleLayout read of branding.accentColor (inverse-drift fix, liveness audit /).
logostringoptionalCustom logo URL for this app: a 1:1 square app icon, SVG preferred, at least 64 px. It is the app's one logo asset — each surface scales it to the size it needs, and there is no second size or wordmark slot.
faviconstringoptionalCustom favicon URL for this app

Nested Shape: App.navigation[number][type='object']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'object'✅
objectNamestring✅Target object name
viewNamestringoptionalDefault list view to open. When omitted, the console opens the object's default list view, else its first declared list view; all names the console's fallback tab, which exists only for an object that declares no list view. Ignored when recordId is set.
recordIdstringoptionalNavigate directly to this record id instead of the list view. Supports template vars: {current_user_id}, {current_org_id}.
recordModeEnum<'view' | 'edit'>optionalOpen the record in view (default) or edit mode. Only meaningful when recordId is set.
filtersRecord<string, string>optionalURL filter conditions — targets the /:objectName/data bare surface via filter[<field>]=<value> params instead of a saved view. Values support template vars {current_user_id}, {current_org_id}. Mutually exclusive with recordId/viewName.
runActionstringoptionalAuto-run this declared action once on arrival at the object's list surface (deep-link "navigate = run action"). Must name an action defined in the stack; validated by defineStack and lint. Not combinable with recordId.
children({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]optionalChild navigation items (e.g. specific views)

Nested Shape: App.navigation[number][type='dashboard']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'dashboard'✅
dashboardNamestring✅Target dashboard name

Nested Shape: App.navigation[number][type='page']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'page'✅
pageNamestring✅Target custom page component name
paramsRecord<string, any>optionalParameters passed to the page context

Nested Shape: App.navigation[number][type='url']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'url'✅
urlstring✅Target external URL
targetEnum<'_self' | '_blank'>optional (default: "_self")Link target window

Nested Shape: App.navigation[number][type='report']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'report'✅
reportNamestring✅Target report name

Nested Shape: App.navigation[number][type='action']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'action'✅
actionDef{ actionName: string; params?: Record<string, any> }✅Action definition to execute when clicked

Nested Shape: App.navigation[number][type='component']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'component'✅
componentRefstring✅Component registry key (e.g. "metadata:directory")
paramsRecord<string, any>optionalProps passed to the component

Nested Shape: App.navigation[number][type='doc']

Documentation entry on the app menu (ADR-0046). Targets a book and/or a doc — at least one is required. The entry inherits the docs audience gate (ADR-0046 §6.7): a book entry renders the member's pruned subset of the book's readable pages and is not rendered for a member with no readable page in it; a doc entry the member may not read is not rendered. visible / requiredPermissions can only narrow further.

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'doc'✅
bookstringoptionalBook to open (a declared book name, or the package id for the package's implicit book). Alone: opens the book at its first readable page with the book sidebar; membership is derived by rule, so docs added later appear under this entry with no navigation edit. With doc: that page in this book's context. At least one of book / doc is required.
docstringoptionalDoc to open (the doc name = its source filename stem, lowercase snake_case). Alone: its book context is the doc's own book, else the package's implicit book. At least one of book / doc is required.

Nested Shape: App.navigation[number][type='separator']

PropertyTypeRequiredDescription
type'separator'✅
idstringoptionalOptional id for the separator
ordernumberoptionalSort order within the same level (lower = first)

Nested Shape: App.navigation[number][type='group']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'group'✅
expandedbooleanoptional (default: false)Default expansion state in sidebar
children({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]✅Child navigation items

Nested Shape: App.areas[number]

PropertyTypeRequiredDescription
idstring✅Unique area identifier (lowercase snake_case)
labelstring | Record<string, string>✅Area display label
iconstringoptionalArea icon name
descriptionstring | Record<string, string>optionalArea description
navigation({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]✅Navigation items within this area

Nested Shape: App.contextSelectors[number]

PropertyTypeRequiredDescription
idstring✅Selector id; selected value is exposed as the nav template var {<id>}
labelstring | Record<string, string>✅Dropdown label
iconstringoptionalIcon name
optionsSource{ endpoint: string; valueKey?: string; labelKey?: string; filter?: object[] }✅Option data source
allValuestringoptional (default: "")Sentinel value meaning "no concrete selection yet" (empty string is almost always right)
persistEnum<'query' | 'session' | 'none'>optional (default: "query")Persist selection via URL query, sessionStorage, or not at all

Nested Shape: App.protection

PropertyTypeRequiredDescription
lockEnum<'none' | 'no-overlay' | 'no-delete' | 'full'>✅Lock policy — none | no-overlay | no-delete | full.
reasonstring✅User-visible reason shown when the lock blocks an action.
docsUrlstringoptionalOptional URL the Studio banner links to for more context.

AppBranding

Properties

PropertyTypeRequiredDescription
primaryColorstringoptionalPrimary theme color hex code
accentColorstringoptionalAccent color hex code (highlights, active states). Declared to match the objectui ConsoleLayout read of branding.accentColor (inverse-drift fix, liveness audit /).
logostringoptionalCustom logo URL for this app: a 1:1 square app icon, SVG preferred, at least 64 px. It is the app's one logo asset — each surface scales it to the size it needs, and there is no second size or wordmark slot.
faviconstringoptionalCustom favicon URL for this app

AppContextSelector

Properties

PropertyTypeRequiredDescription
idstring✅Selector id; selected value is exposed as the nav template var {<id>}
labelstring | Record<string, string>✅Dropdown label
iconstringoptionalIcon name
optionsSource{ endpoint: string; valueKey?: string; labelKey?: string; filter?: object[] }✅Option data source
allValuestringoptional (default: "")Sentinel value meaning "no concrete selection yet" (empty string is almost always right)
persistEnum<'query' | 'session' | 'none'>optional (default: "query")Persist selection via URL query, sessionStorage, or not at all

Nested Shape: AppContextSelector.optionsSource

PropertyTypeRequiredDescription
endpointstring✅REST endpoint returning the option rows (e.g. /api/v1/packages)
valueKeystringoptional (default: "id")Row property used as the option value (dotted path allowed, e.g. "manifest.id")
labelKeystringoptional (default: "name")Row property used as the option label (dotted path allowed, e.g. "manifest.name")
filter{ key: string; op?: Enum<'eq' | 'ne' | 'in' | 'nin'>; value: string | string[] }[]optionalPredicates (AND) each option row must satisfy

ComponentNavItem

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'component'✅
componentRefstring✅Component registry key (e.g. "metadata:directory")
paramsRecord<string, any>optionalProps passed to the component

DashboardNavItem

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'dashboard'✅
dashboardNamestring✅Target dashboard name

DocNavItem

Documentation entry on the app menu (ADR-0046). Targets a book and/or a doc — at least one is required. The entry inherits the docs audience gate (ADR-0046 §6.7): a book entry renders the member's pruned subset of the book's readable pages and is not rendered for a member with no readable page in it; a doc entry the member may not read is not rendered. visible / requiredPermissions can only narrow further.

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'doc'✅
bookstringoptionalBook to open (a declared book name, or the package id for the package's implicit book). Alone: opens the book at its first readable page with the book sidebar; membership is derived by rule, so docs added later appear under this entry with no navigation edit. With doc: that page in this book's context. At least one of book / doc is required.
docstringoptionalDoc to open (the doc name = its source filename stem, lowercase snake_case). Alone: its book context is the doc's own book, else the package's implicit book. At least one of book / doc is required.

GroupNavItem

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'group'✅
expandedbooleanoptional (default: false)Default expansion state in sidebar

Properties

PropertyTypeRequiredDescription
idstring✅Unique area identifier (lowercase snake_case)
labelstring | Record<string, string>✅Area display label
iconstringoptionalArea icon name
descriptionstring | Record<string, string>optionalArea description
navigation({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]✅Navigation items within this area

Nested Shape: NavigationArea.navigation[number][type='object']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'object'✅
objectNamestring✅Target object name
viewNamestringoptionalDefault list view to open. When omitted, the console opens the object's default list view, else its first declared list view; all names the console's fallback tab, which exists only for an object that declares no list view. Ignored when recordId is set.
recordIdstringoptionalNavigate directly to this record id instead of the list view. Supports template vars: {current_user_id}, {current_org_id}.
recordModeEnum<'view' | 'edit'>optionalOpen the record in view (default) or edit mode. Only meaningful when recordId is set.
filtersRecord<string, string>optionalURL filter conditions — targets the /:objectName/data bare surface via filter[<field>]=<value> params instead of a saved view. Values support template vars {current_user_id}, {current_org_id}. Mutually exclusive with recordId/viewName.
runActionstringoptionalAuto-run this declared action once on arrival at the object's list surface (deep-link "navigate = run action"). Must name an action defined in the stack; validated by defineStack and lint. Not combinable with recordId.
children({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]optionalChild navigation items (e.g. specific views)

Nested Shape: NavigationArea.navigation[number][type='dashboard']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'dashboard'✅
dashboardNamestring✅Target dashboard name

Nested Shape: NavigationArea.navigation[number][type='page']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'page'✅
pageNamestring✅Target custom page component name
paramsRecord<string, any>optionalParameters passed to the page context

Nested Shape: NavigationArea.navigation[number][type='url']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'url'✅
urlstring✅Target external URL
targetEnum<'_self' | '_blank'>optional (default: "_self")Link target window

Nested Shape: NavigationArea.navigation[number][type='report']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'report'✅
reportNamestring✅Target report name

Nested Shape: NavigationArea.navigation[number][type='action']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'action'✅
actionDef{ actionName: string; params?: Record<string, any> }✅Action definition to execute when clicked

Nested Shape: NavigationArea.navigation[number][type='component']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'component'✅
componentRefstring✅Component registry key (e.g. "metadata:directory")
paramsRecord<string, any>optionalProps passed to the component

Nested Shape: NavigationArea.navigation[number][type='doc']

Documentation entry on the app menu (ADR-0046). Targets a book and/or a doc — at least one is required. The entry inherits the docs audience gate (ADR-0046 §6.7): a book entry renders the member's pruned subset of the book's readable pages and is not rendered for a member with no readable page in it; a doc entry the member may not read is not rendered. visible / requiredPermissions can only narrow further.

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'doc'✅
bookstringoptionalBook to open (a declared book name, or the package id for the package's implicit book). Alone: opens the book at its first readable page with the book sidebar; membership is derived by rule, so docs added later appear under this entry with no navigation edit. With doc: that page in this book's context. At least one of book / doc is required.
docstringoptionalDoc to open (the doc name = its source filename stem, lowercase snake_case). Alone: its book context is the doc's own book, else the package's implicit book. At least one of book / doc is required.

Nested Shape: NavigationArea.navigation[number][type='separator']

PropertyTypeRequiredDescription
type'separator'✅
idstringoptionalOptional id for the separator
ordernumberoptionalSort order within the same level (lower = first)

Nested Shape: NavigationArea.navigation[number][type='group']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'group'✅
expandedbooleanoptional (default: false)Default expansion state in sidebar
children({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]✅Child navigation items

A navigation contribution: a package injecting nav items into an app it does not own (ADR-0029 D7)

Properties

PropertyTypeRequiredDescription
appstring✅Target app name to contribute navigation into (e.g. "setup")
groupstringoptionalTarget group nav-item id to append into (e.g. "group_integrations"); omit to append at the app top level. Naming a group the target app does not declare is not refused: the items are appended at the app top level anyway and a nav_contribution_group_missing diagnostic is emitted — by the runtime at warn, and by os build and os validate at compile time.
priorityintegeroptional (default: 200)Merge priority within the target group — lower applied first (matches object extender priority)
items({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]✅Navigation items contributed into the target app/group

Nested Shape: NavigationContribution.items[number][type='object']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'object'✅
objectNamestring✅Target object name
viewNamestringoptionalDefault list view to open. When omitted, the console opens the object's default list view, else its first declared list view; all names the console's fallback tab, which exists only for an object that declares no list view. Ignored when recordId is set.
recordIdstringoptionalNavigate directly to this record id instead of the list view. Supports template vars: {current_user_id}, {current_org_id}.
recordModeEnum<'view' | 'edit'>optionalOpen the record in view (default) or edit mode. Only meaningful when recordId is set.
filtersRecord<string, string>optionalURL filter conditions — targets the /:objectName/data bare surface via filter[<field>]=<value> params instead of a saved view. Values support template vars {current_user_id}, {current_org_id}. Mutually exclusive with recordId/viewName.
runActionstringoptionalAuto-run this declared action once on arrival at the object's list surface (deep-link "navigate = run action"). Must name an action defined in the stack; validated by defineStack and lint. Not combinable with recordId.
children({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]optionalChild navigation items (e.g. specific views)

Nested Shape: NavigationContribution.items[number][type='dashboard']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'dashboard'✅
dashboardNamestring✅Target dashboard name

Nested Shape: NavigationContribution.items[number][type='page']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'page'✅
pageNamestring✅Target custom page component name
paramsRecord<string, any>optionalParameters passed to the page context

Nested Shape: NavigationContribution.items[number][type='url']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'url'✅
urlstring✅Target external URL
targetEnum<'_self' | '_blank'>optional (default: "_self")Link target window

Nested Shape: NavigationContribution.items[number][type='report']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'report'✅
reportNamestring✅Target report name

Nested Shape: NavigationContribution.items[number][type='action']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'action'✅
actionDef{ actionName: string; params?: Record<string, any> }✅Action definition to execute when clicked

Nested Shape: NavigationContribution.items[number][type='component']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'component'✅
componentRefstring✅Component registry key (e.g. "metadata:directory")
paramsRecord<string, any>optionalProps passed to the component

Nested Shape: NavigationContribution.items[number][type='doc']

Documentation entry on the app menu (ADR-0046). Targets a book and/or a doc — at least one is required. The entry inherits the docs audience gate (ADR-0046 §6.7): a book entry renders the member's pruned subset of the book's readable pages and is not rendered for a member with no readable page in it; a doc entry the member may not read is not rendered. visible / requiredPermissions can only narrow further.

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'doc'✅
bookstringoptionalBook to open (a declared book name, or the package id for the package's implicit book). Alone: opens the book at its first readable page with the book sidebar; membership is derived by rule, so docs added later appear under this entry with no navigation edit. With doc: that page in this book's context. At least one of book / doc is required.
docstringoptionalDoc to open (the doc name = its source filename stem, lowercase snake_case). Alone: its book context is the doc's own book, else the package's implicit book. At least one of book / doc is required.

Nested Shape: NavigationContribution.items[number][type='separator']

PropertyTypeRequiredDescription
type'separator'✅
idstringoptionalOptional id for the separator
ordernumberoptionalSort order within the same level (lower = first)

Nested Shape: NavigationContribution.items[number][type='group']

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'group'✅
expandedbooleanoptional (default: false)Default expansion state in sidebar
children({ id: string; label?: string | Record<string, string>; icon?: string; order?: number; … } | { type: 'separator'; id?: string; order?: number } | … +8 more)[]✅Child navigation items

Union Options

This schema accepts one of the following structures:

Option 1

Type: object

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'object'✅
objectNamestring✅Target object name
viewNamestringoptionalDefault list view to open. When omitted, the console opens the object's default list view, else its first declared list view; all names the console's fallback tab, which exists only for an object that declares no list view. Ignored when recordId is set.
recordIdstringoptionalNavigate directly to this record id instead of the list view. Supports template vars: {current_user_id}, {current_org_id}.
recordModeEnum<'view' | 'edit'>optionalOpen the record in view (default) or edit mode. Only meaningful when recordId is set.
filtersRecord<string, string>optionalURL filter conditions — targets the /:objectName/data bare surface via filter[<field>]=<value> params instead of a saved view. Values support template vars {current_user_id}, {current_org_id}. Mutually exclusive with recordId/viewName.
runActionstringoptionalAuto-run this declared action once on arrival at the object's list surface (deep-link "navigate = run action"). Must name an action defined in the stack; validated by defineStack and lint. Not combinable with recordId.
children[NavigationItem](#navigationitem)[]optionalChild navigation items (e.g. specific views)

Option 2

Type: dashboard

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'dashboard'✅
dashboardNamestring✅Target dashboard name

Option 3

Type: page

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'page'✅
pageNamestring✅Target custom page component name
paramsRecord<string, any>optionalParameters passed to the page context

Option 4

Type: url

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'url'✅
urlstring✅Target external URL
targetEnum<'_self' | '_blank'>optional (default: "_self")Link target window

Option 5

Type: report

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'report'✅
reportNamestring✅Target report name

Option 6

Type: action

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'action'✅
actionDef{ actionName: string; params?: Record<string, any> }✅Action definition to execute when clicked

Nested Shape: NavigationItem[type='action'].actionDef

PropertyTypeRequiredDescription
actionNamestring✅Action machine name to execute
paramsRecord<string, any>optionalParameters passed to the action

Option 7

Type: component

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'component'✅
componentRefstring✅Component registry key (e.g. "metadata:directory")
paramsRecord<string, any>optionalProps passed to the component

Option 8

Documentation entry on the app menu (ADR-0046). Targets a book and/or a doc — at least one is required. The entry inherits the docs audience gate (ADR-0046 §6.7): a book entry renders the member's pruned subset of the book's readable pages and is not rendered for a member with no readable page in it; a doc entry the member may not read is not rendered. visible / requiredPermissions can only narrow further.

Type: doc

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'doc'✅
bookstringoptionalBook to open (a declared book name, or the package id for the package's implicit book). Alone: opens the book at its first readable page with the book sidebar; membership is derived by rule, so docs added later appear under this entry with no navigation edit. With doc: that page in this book's context. At least one of book / doc is required.
docstringoptionalDoc to open (the doc name = its source filename stem, lowercase snake_case). Alone: its book context is the doc's own book, else the package's implicit book. At least one of book / doc is required.

Option 9

Type: separator

Properties

PropertyTypeRequiredDescription
type'separator'✅
idstringoptionalOptional id for the separator
ordernumberoptionalSort order within the same level (lower = first)

Option 10

Type: group

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'group'✅
expandedbooleanoptional (default: false)Default expansion state in sidebar
children[NavigationItem](#navigationitem)[]✅Child navigation items


ObjectNavItem

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'object'✅
objectNamestring✅Target object name
viewNamestringoptionalDefault list view to open. When omitted, the console opens the object's default list view, else its first declared list view; all names the console's fallback tab, which exists only for an object that declares no list view. Ignored when recordId is set.
recordIdstringoptionalNavigate directly to this record id instead of the list view. Supports template vars: {current_user_id}, {current_org_id}.
recordModeEnum<'view' | 'edit'>optionalOpen the record in view (default) or edit mode. Only meaningful when recordId is set.
filtersRecord<string, string>optionalURL filter conditions — targets the /:objectName/data bare surface via filter[<field>]=<value> params instead of a saved view. Values support template vars {current_user_id}, {current_org_id}. Mutually exclusive with recordId/viewName.
runActionstringoptionalAuto-run this declared action once on arrival at the object's list surface (deep-link "navigate = run action"). Must name an action defined in the stack; validated by defineStack and lint. Not combinable with recordId.

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'page'✅
pageNamestring✅Target custom page component name
paramsRecord<string, any>optionalParameters passed to the page context

ReportNavItem

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'report'✅
reportNamestring✅Target report name

UrlNavItem

Properties

PropertyTypeRequiredDescription
idstring✅Unique identifier for this navigation item (lowercase snake_case)
labelstring | Record<string, string>optionalDisplay proper label. Optional. Resolved in one order: (1) the bundle entry apps.<app>.navigation.<id>.label for the active locale chain, keyed by this entry's id — translateApp applies it at the /meta boundary, over the app's navigation tree (not areas); (2) else a present label as authored — its inline locale map's value for that locale, else its text; (3) else (absent) the CURRENT label of what the entry opens, at render time — the view's label when it names a labelled view, else the object's / dashboard's label — localized by the target's own translation. A present label is never replaced by its target's label and never translated by matching its text. Every real destination must have identity and text: identity is the target, text is inherited at render. No stored inherited flag; nothing is materialised for the absent case.
iconstringoptionalIcon name
ordernumberoptionalSort order within the same level (lower = first)
badgestring | numberoptionalBadge text or count displayed on the item
badgeVariantEnum<'default' | 'secondary' | 'destructive' | 'outline'>optionalVisual variant of the nav badge. Declared to match the objectui NavigationRenderer read (inverse-drift fix, liveness audit /).
visiblestring | { dialect: Enum<'cel' | 'cron' | 'template'>; source: string; ast?: any; meta?: object }optionalVisibility predicate (CEL). e.g. P'org_admin' in current_user.positions
requiredPermissionsstring[]optionalPermissions required to access this item
requiresObjectstringoptionalHide/disable this entry unless the named object is registered in the runtime
requiresServicestringoptionalHide/disable this entry unless the named kernel service is registered
type'url'✅
urlstring✅Target external URL
targetEnum<'_self' | '_blank'>optional (default: "_self")Link target window

On this page

TypeScript UsageActionNavItemPropertiesNested Shape: ActionNavItem.actionDefAppPropertiesNested Shape: App.brandingNested Shape: App.navigation[number][type='object']Nested Shape: App.navigation[number][type='dashboard']Nested Shape: App.navigation[number][type='page']Nested Shape: App.navigation[number][type='url']Nested Shape: App.navigation[number][type='report']Nested Shape: App.navigation[number][type='action']Nested Shape: App.navigation[number][type='component']Nested Shape: App.navigation[number][type='doc']Nested Shape: App.navigation[number][type='separator']Nested Shape: App.navigation[number][type='group']Nested Shape: App.areas[number]Nested Shape: App.contextSelectors[number]Nested Shape: App.protectionAppBrandingPropertiesAppContextSelectorPropertiesNested Shape: AppContextSelector.optionsSourceComponentNavItemPropertiesDashboardNavItemPropertiesDocNavItemPropertiesGroupNavItemPropertiesNavigationAreaPropertiesNested Shape: NavigationArea.navigation[number][type='object']Nested Shape: NavigationArea.navigation[number][type='dashboard']Nested Shape: NavigationArea.navigation[number][type='page']Nested Shape: NavigationArea.navigation[number][type='url']Nested Shape: NavigationArea.navigation[number][type='report']Nested Shape: NavigationArea.navigation[number][type='action']Nested Shape: NavigationArea.navigation[number][type='component']Nested Shape: NavigationArea.navigation[number][type='doc']Nested Shape: NavigationArea.navigation[number][type='separator']Nested Shape: NavigationArea.navigation[number][type='group']NavigationContributionPropertiesNested Shape: NavigationContribution.items[number][type='object']Nested Shape: NavigationContribution.items[number][type='dashboard']Nested Shape: NavigationContribution.items[number][type='page']Nested Shape: NavigationContribution.items[number][type='url']Nested Shape: NavigationContribution.items[number][type='report']Nested Shape: NavigationContribution.items[number][type='action']Nested Shape: NavigationContribution.items[number][type='component']Nested Shape: NavigationContribution.items[number][type='doc']Nested Shape: NavigationContribution.items[number][type='separator']Nested Shape: NavigationContribution.items[number][type='group']NavigationItemUnion OptionsOption 1PropertiesOption 2PropertiesOption 3PropertiesOption 4PropertiesOption 5PropertiesOption 6PropertiesNested Shape: NavigationItem[type='action'].actionDefOption 7PropertiesOption 8PropertiesOption 9PropertiesOption 10PropertiesObjectNavItemPropertiesPageNavItemPropertiesReportNavItemPropertiesUrlNavItemProperties